Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fcf03a424 | ||
|
|
f201a2b488 | ||
|
|
82b4619574 | ||
|
|
c3226ea02c | ||
|
|
c3dccd8958 | ||
|
|
951ef9724e | ||
|
|
79c6989d52 | ||
|
|
6973a996ae | ||
|
|
131252b746 | ||
|
|
3fff1a7fb5 | ||
|
|
bf12f2d8b0 | ||
|
|
6e2112283e | ||
|
|
933fe263da | ||
|
|
4a2cb19fde | ||
|
|
c6c411a6db | ||
|
|
01ba910685 | ||
|
|
43f2fd4da3 | ||
|
|
08b86183c2 | ||
|
|
1e036e981e | ||
|
|
0b16daf14a | ||
|
|
5bb487795c | ||
|
|
3a3904fea6 | ||
|
|
52d77f6834 | ||
|
|
e4aa3c6d99 | ||
|
|
e2f5729e8f | ||
|
|
c1b0b35352 | ||
|
|
6c04eb24f4 | ||
|
|
acaaaa67e0 | ||
|
|
9d4582a47f | ||
|
|
6a1308c251 | ||
|
|
31daf7f764 | ||
|
|
c51ae06b4d | ||
|
|
fd13a26677 | ||
|
|
cf44b1ed04 | ||
|
|
d259242849 | ||
|
|
a3ee239f22 | ||
|
|
cba4b67a1a | ||
|
|
c313639208 | ||
|
|
6b3031acbd | ||
|
|
bd1d6b86f0 | ||
|
|
da4d016ee1 | ||
|
|
73bbb4cea6 | ||
|
|
bbae238e9d | ||
|
|
945db355fc | ||
|
|
870aa17462 | ||
|
|
6f782991cf | ||
|
|
f4143e58bf | ||
|
|
fb18726132 | ||
|
|
647da98577 | ||
|
|
f01aefa4eb | ||
|
|
5f411499c5 | ||
|
|
034faa4021 | ||
|
|
c0611814aa | ||
|
|
af5093dbd7 | ||
|
|
bcdb30cc55 | ||
|
|
e251c4bd62 | ||
|
|
e9ce9a539e | ||
|
|
d77c6425bc | ||
|
|
da1d185d9b | ||
|
|
bbcff180e0 | ||
|
|
10508d1a00 | ||
|
|
6f0d71a1c3 | ||
|
|
f999d9b292 | ||
|
|
934ee4d803 | ||
|
|
906627b953 | ||
|
|
2cf9edf16e | ||
|
|
a1a50e0e6f | ||
|
|
54d39ef130 | ||
|
|
04f5046f95 | ||
|
|
39e4faf8ed | ||
|
|
ca560ed068 | ||
|
|
8010f9fab6 | ||
|
|
233737e2a3 | ||
|
|
3080be5de9 | ||
|
|
86fd91723a | ||
|
|
3481253c54 | ||
|
|
f9cf63ad49 | ||
|
|
4caee938fd | ||
|
|
cd818a4942 | ||
|
|
748f923b77 | ||
|
|
5783940e4c | ||
|
|
7a21845ff6 | ||
|
|
28bdb45581 | ||
|
|
25a561b047 | ||
|
|
0d473fe866 | ||
|
|
3af3d73d85 | ||
|
|
12e20c6701 | ||
|
|
fb3a8214df | ||
|
|
e4536afda6 | ||
|
|
c53662a6d8 | ||
|
|
b61b8433a3 | ||
|
|
7f49f0668d | ||
|
|
def31f5d4b | ||
|
|
582e7c0f06 | ||
|
|
bc1d1aa43b | ||
|
|
8e66127a76 | ||
|
|
276f885e73 | ||
|
|
c236d3099d | ||
|
|
7b21e6d495 | ||
|
|
c7cb2d8d89 | ||
|
|
b776fe1e4d | ||
|
|
53b1abdec8 | ||
|
|
21fbc9de34 | ||
|
|
f64fe11c55 | ||
|
|
36ec4c1867 | ||
|
|
374ec45b72 | ||
|
|
f608ae5b5b | ||
|
|
61bb93e813 | ||
|
|
4971d0d13d | ||
|
|
6d90860a83 | ||
|
|
1a1c888229 | ||
|
|
4a70ba8d57 | ||
|
|
2fdda63406 | ||
|
|
72e11c5eb8 | ||
|
|
76651f6798 | ||
|
|
0827b81026 | ||
|
|
3bb02a119b | ||
|
|
dfe99d530e | ||
|
|
67e924041e | ||
|
|
9cdb14010c | ||
|
|
f7a68e5882 | ||
|
|
fb06fccfa2 | ||
|
|
4b20983ccd | ||
|
|
dd3b9da619 | ||
|
|
1b296a1773 | ||
|
|
7fe00e052f | ||
|
|
0e9c6710e4 | ||
|
|
53a7d37e6c | ||
|
|
59db26eb9c | ||
|
|
c2b17f620b |
@@ -0,0 +1,150 @@
|
||||
name: governance
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
governance:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GOPROXY: https://goproxy.cn,direct
|
||||
steps:
|
||||
- name: Checkout
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SUBMODULE_TOKEN: ${{ secrets.SUBMODULE_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# 只物化两个治理 gitlink(Guidelines 与 deps/development-manager),非递归;
|
||||
# 其它 gitlink 不物化、不取回。凭据只以 URL 限定的 extraheader 存在于本进程树内。
|
||||
python3 - <<'PY_CHECKOUT'
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
# 服务端基址取运行器注入的 GITHUB_SERVER_URL(平台控制、候选 PR 不可影响)。
|
||||
SERVER = os.environ.get("GITHUB_SERVER_URL", "").rstrip("/")
|
||||
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/"
|
||||
# 审查过的白名单,独立于候选 .gitmodules:仅列出两个治理 gitlink。
|
||||
REPOSITORIES = {
|
||||
"deps/development-guidelines": "Development-Guidelines",
|
||||
"deps/development-manager": "Development-Manager",
|
||||
}
|
||||
TARGET = "weichen/Agent-System-Documents"
|
||||
root_token = os.environ.pop("TOKEN", "")
|
||||
component_token = os.environ.pop("SUBMODULE_TOKEN", "")
|
||||
if not root_token or not component_token:
|
||||
sys.exit("Checkout requires TOKEN and SUBMODULE_TOKEN")
|
||||
if os.environ.get("GITHUB_REPOSITORY") != TARGET:
|
||||
sys.exit("Checkout repository is outside the reviewed allowlist")
|
||||
sha = os.environ.get("GITHUB_SHA", "")
|
||||
if not re.fullmatch(r"[0-9a-fA-F]{40}", sha):
|
||||
sys.exit("Checkout requires a fixed commit SHA")
|
||||
|
||||
# 丢弃继承的 Git 追踪/配置/SSH 钩子;凭据只存在于单个 Git 进程树的精确 URL 头中。
|
||||
clean_env = {k: v for k, v in os.environ.items() if not k.startswith("GIT_")}
|
||||
clean_env.update(GIT_CONFIG_NOSYSTEM="1", GIT_CONFIG_SYSTEM="/dev/null",
|
||||
GIT_CONFIG_GLOBAL="/dev/null", GIT_TERMINAL_PROMPT="0")
|
||||
config = {
|
||||
"core.hooksPath": "/dev/null", "core.fsmonitor": "false",
|
||||
"init.templateDir": "", "credential.helper": "",
|
||||
"fetch.recurseSubmodules": "false", "submodule.recurse": "false",
|
||||
"http.followRedirects": "false", "protocol.allow": "never",
|
||||
"protocol." + urlsplit(SERVER).scheme + ".allow": "always",
|
||||
}
|
||||
|
||||
|
||||
def git(repo, *args, extra=None):
|
||||
values = config | (extra or {})
|
||||
env = clean_env | {"GIT_CONFIG_COUNT": str(len(values))}
|
||||
for index, (key, value) in enumerate(values.items()):
|
||||
env[f"GIT_CONFIG_KEY_{index}"] = key
|
||||
env[f"GIT_CONFIG_VALUE_{index}"] = value
|
||||
return subprocess.run(["git", "-C", str(repo), *args], env=env,
|
||||
check=True, stdout=subprocess.PIPE).stdout
|
||||
|
||||
|
||||
def materialize_governance(root):
|
||||
# -r 列出任意深度的 gitlink,但不进入 submodule 内部;其它 gitlink 只记录、从不取回。
|
||||
links = {}
|
||||
for entry in git(root, "ls-tree", "-rz", "HEAD").split(b"\0"):
|
||||
if not entry:
|
||||
continue
|
||||
metadata, path = entry.split(b"\t", 1)
|
||||
mode, kind, commit = metadata.decode().split()
|
||||
if mode == "160000":
|
||||
links[path.decode()] = commit
|
||||
for name in REPOSITORIES:
|
||||
if name not in links:
|
||||
raise ValueError("Governance gitlink is missing from the fixed commit")
|
||||
raw = git(root, "config", "--no-includes", "--blob", "HEAD:.gitmodules", "--null", "--list")
|
||||
entries = {}
|
||||
for item in raw.split(b"\0"):
|
||||
if not item:
|
||||
continue
|
||||
key, value = item.decode().split("\n", 1)
|
||||
match = re.fullmatch(r"submodule\.(.+)\.(path|url)", key)
|
||||
if not match:
|
||||
continue
|
||||
name, field = match.groups()
|
||||
if name not in REPOSITORIES:
|
||||
continue
|
||||
if field in entries.setdefault(name, {}):
|
||||
raise ValueError("Duplicate candidate .gitmodules setting")
|
||||
entries[name][field] = value
|
||||
# 先整体校验两个治理条目,再进行任何带凭据的取回。
|
||||
for name, repository in REPOSITORIES.items():
|
||||
fields = entries.get(name, {})
|
||||
if fields.get("path") != name:
|
||||
raise ValueError("Governance submodule path is outside the reviewed allowlist")
|
||||
trusted_url = f"{SERVER}/weichen/{repository}.git"
|
||||
if fields.get("url") not in {SSH + repository + ".git", trusted_url}:
|
||||
raise ValueError("Governance submodule URL is outside the reviewed allowlist")
|
||||
for name, repository in REPOSITORIES.items():
|
||||
url = f"{SERVER}/weichen/{repository}.git"
|
||||
# 仅持久化审查过的公开 URL,使 Git 在进程级配置消失后仍识别该 submodule。
|
||||
git(root, "config", f"submodule.{name}.url", url)
|
||||
git(root, "submodule", "update", "--init", "--checkout", "--", name,
|
||||
extra={f"submodule.{name}.url": url,
|
||||
f"submodule.{name}.update": "checkout",
|
||||
f"http.{url}.extraheader": "AUTHORIZATION: token " + component_token})
|
||||
child = root / name
|
||||
if git(child, "rev-parse", "HEAD").decode().strip() != links[name]:
|
||||
raise ValueError("Materialized governance gitlink does not match the fixed SHA")
|
||||
|
||||
|
||||
try:
|
||||
root = Path.cwd()
|
||||
# 必须是干净的临时工作区;不复用既有 Git 状态。
|
||||
if (root / ".git").exists():
|
||||
raise ValueError("Checkout requires a fresh workspace")
|
||||
git(root, "init", "-q")
|
||||
url = f"{SERVER}/{TARGET}.git"
|
||||
git(root, "remote", "add", "origin", url)
|
||||
git(root, "fetch", "--depth=1", "origin", sha,
|
||||
extra={f"http.{url}.extraheader": "AUTHORIZATION: token " + root_token})
|
||||
git(root, "checkout", "-q", "--detach", "FETCH_HEAD")
|
||||
materialize_governance(root)
|
||||
except (ValueError, OSError, subprocess.CalledProcessError) as error:
|
||||
sys.exit(f"Checkout refused: {error}")
|
||||
print("Checkout complete; credentials were not persisted in Git configuration")
|
||||
PY_CHECKOUT
|
||||
unset TOKEN SUBMODULE_TOKEN
|
||||
- name: Install Go 1.27.1
|
||||
run: |
|
||||
set -euo pipefail
|
||||
curl -fsSL -o "$RUNNER_TEMP/go.tgz" https://mirrors.aliyun.com/golang/go1.27.1.linux-amd64.tar.gz
|
||||
tar -C /usr/local -xzf "$RUNNER_TEMP/go.tgz"
|
||||
ln -sfn /usr/local/go/bin/go /usr/local/bin/go
|
||||
ln -sfn /usr/local/go/bin/gofmt /usr/local/bin/gofmt
|
||||
- name: Validate agent execution configuration
|
||||
run: scripts/agent-exec validate --repo .
|
||||
- name: Governance check
|
||||
run: scripts/dm governance check --repo .
|
||||
@@ -0,0 +1,6 @@
|
||||
[submodule "deps/development-guidelines"]
|
||||
path = deps/development-guidelines
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Guidelines.git
|
||||
[submodule "deps/development-manager"]
|
||||
path = deps/development-manager
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Manager.git
|
||||
@@ -0,0 +1,57 @@
|
||||
# Agent-System-Documents 采纳 development-governance-v2 治理套件 任务卡
|
||||
|
||||
任务主记录:[Agent-System-Documents PR #110](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/110)(本文件随 PR 描述维护)。
|
||||
状态:已完成(闭合随本 PR 合入;合入以平台记录为准);owner:weichen。
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:weichen/Agent-System-Documents;root_target:main;immediate_target:main
|
||||
- branch_kind:initiative;initiative_id:governance-adoption-Agent-System-Documents
|
||||
- R0(initial_main_sha):da4d016ee1dee6a418411ed0f8b45911fe9aab02;工作区:/home/weichen/projects/Agent-System-Documents-wt-feature-governance-adoption(worktree);分支:feature/governance-adoption
|
||||
- 父任务信息(仅子任务填写):无
|
||||
- accepting_requirements:false(单仓采纳 initiative,范围固定为下列十步,不接收新需求)
|
||||
- 需求分流:verdict=NEW;selected_initiative=无;候选=无;理由=development-governance-v2 Phase 6 每个正式仓库独立 initiative;triage 收据=无(本仓采纳前尚无 triage 入口)
|
||||
- 授权与交付终点:owner 已授权 development-governance-v2 全部实施(Agent-System-Dev 主记录 docs/superpowers/plans/2026-10-16-development-governance-v2-master.md);终点为本 PR 合入 main 且采纳状态 active。分支保护与 tag 由用户执行。
|
||||
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md;外部 Agent 一单元一新进程/会话/工作区)
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
目标(Phase 6 十步):固定 Guidelines SHA(deps/development-guidelines @ 2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb);增加 AGENT-EXECUTION.md;增加共享执行器薄入口(deps/development-manager @ bd3a7de57a3a9e1a4495b94c5fa5c08d71e7be8c + scripts/dm、scripts/agent-exec、scripts/task);四条路由(implementation/repair/test/review);任务卡模板与分支元数据;CI 中启用 schema 校验(.gitea/workflows/governance.yml:agent-exec validate + governance check);一次正例运行;负例(缺配置、坏收据、越界路径、未知副作用);独立 Review + CI;采纳状态 active。
|
||||
|
||||
非目标:不改业务代码与既有测试;不改分支保护(由用户执行);不发布 tag。
|
||||
|
||||
引导说明:AGENT-EXECUTION.md 由 host 以固定版本治理套件(dm-server governance init @ bd3a7de57a3a9e1a4495b94c5fa5c08d71e7be8c)生成并作为引导配置提交(执行器运行前必须存在有效配置;沿用 DM 采纳先例);其余文件由实施单元生成。
|
||||
|
||||
## Agent 实施收据
|
||||
|
||||
| 单元 ID | 预期范围 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| governance-adoption-Agent-System-Documents-r1 | 13 个允许路径(治理文件 + 两个 gitlink) | | implementation | cursor→antigravity→pi | run 3a6bdcf3(dm-server pinned,attempts=1) | cursor / not-observable | failed-unknown | 无(apply 快进) | 否 | /tmp/gov-receipt-Agent-System-Documents-r1.json |
|
||||
| 对账(r1) | 规范 worktree 仍为 d259242 且干净;无 transport ref。worker 自报外部副作用:并行 worker 共用固定文件 /tmp/gov-scratch-path.txt 记录 scratch 路径,该文件被覆盖后误删非本单元创建的仓外临时目录 /tmp/tmp.2FlZqPmOJM(不可恢复;各单元私有工作区不在该路径,已完成单元收据均为 success) | — | — | — | — | — | failed-unknown 对账完成;单元包追加禁止固定共享 /tmp 路径约束后全新运行 r2 | — | — | — |
|
||||
| governance-adoption-Agent-System-Documents-r2 | 13 个允许路径(治理文件 + 两个 gitlink) | cf44b1ed | implementation | cursor→antigravity→pi | run 8348cbe4(dm-server pinned,attempts=1) | cursor / not-observable | success | fd13a266777b(apply 快进) | 否 | /tmp/gov-receipt-Agent-System-Documents-r2.json |
|
||||
| governance-adoption-Agent-System-Documents-repair-r1 | PROJECT.md、policy/guidelines-adoption.md | repair | cursor→antigravity→pi | run cddbee35(attempts=1) | cursor / not-observable | success | 31daf7f76493(apply 快进) | 否 | /tmp/gov-receipt-Agent-System-Documents-repair-r1.json |
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at | 结果 |
|
||||
|---|---|---|---|---|
|
||||
| 启动 | da4d016ee1dee6a418411ed0f8b45911fe9aab02 | da4d016ee1dee6a418411ed0f8b45911fe9aab02 | 2026-10-17T07:16:27Z | 一致 |
|
||||
| 请求审核 | da4d016ee1dee6a418411ed0f8b45911fe9aab02 | 6a1308c2510e | 2026-10-17T08:47:50Z | 已含 origin/main |
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:治理套件已采纳——Guidelines 与 Development-Manager gitlink 固定、AGENT-EXECUTION.md 四条路由、共享执行器薄入口、pre-commit admit、governance CI;采纳状态 active 随本 PR 合入生效。
|
||||
- 验证:见下表(命令输出由 /tmp/gov-neg/ev.sh 写入 .task/evidence/governance-adoption/,SELF 除非另注)。
|
||||
- 复现:正负例脚本冻结副本 Agent-System-Dev `docs/superpowers/plans/evidence/governance-adopt-cases.py`(sha256 3aa1bf6ea1cd48f3f59c0a307620e4112389a93fe21a113006f54e62eb8f0d06),用法 `python3 governance-adopt-cases.py <仓库根>`;它经本仓 `scripts/agent-exec` 运行假 CLI,不访问网络。
|
||||
- 影响与剩余项:不改业务代码;本地启用钩子需由人执行 `git config core.hooksPath scripts/hooks`;将 governance 检查设为分支保护必需项属用户双钥匙事项(命令见 Agent-System-Dev 治理主记录)。
|
||||
|
||||
| 时间(UTC) | 命令 | 被测 HEAD | exit | 来源 | 摘要/位置 |
|
||||
|---|---|---|---|---|---|
|
||||
| 20261017T074046Z | `scripts/dm governance check --repo .` | fd13a266777b | 0 | SELF | ok fixtures;[输出](../evidence/governance-adoption/00-20261017T074046Z.log) sha256:0ff0ec3150c5162e |
|
||||
| 20261017T074046Z | `scripts/agent-exec validate --repo .` | fd13a266777b | 0 | SELF | validate: ok;[输出](../evidence/governance-adoption/01-20261017T074046Z.log) sha256:7ba43b8b1d0ee152 |
|
||||
| 20261017T074046Z | `python3 /tmp/gov-neg/adopt_cases.py .` | fd13a266777b | 0 | SELF | [verdict] ALL PASS cases=5;[输出](../evidence/governance-adoption/02-20261017T074046Z.log) sha256:b63c5ee476cd94f5 |
|
||||
| 20261017T084129Z | `scripts/dm governance check --repo .` | 31daf7f76493 | 0 | SELF | ok fixtures;[输出](../evidence/governance-adoption/03-20261017T084129Z.log) sha256:809536ab8a8d1caa |
|
||||
| 20261017T084129Z | `scripts/agent-exec validate --repo .` | 31daf7f76493 | 0 | SELF | validate: ok;[输出](../evidence/governance-adoption/04-20261017T084129Z.log) sha256:3d3cf541ce4c6560 |
|
||||
| 2026-10-17T08:47:50Z | CI `governance / governance (pull_request)` | 6a1308c2510e | 0 | GATE | success;[运行](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/actions/runs/3593/jobs/5686) |
|
||||
| — | 候选 HEAD CI | 9d4582a47f4f | 0 | GATE | success governance / governance (pull_request)=success(/weichen/Agent-System-Documents/actions/runs/3611/jobs/5709) |
|
||||
| — | 独立 Review | 9d4582a47f4f | 0 | REPLAY | cursor-agent-stable --mode ask 全新只读会话(fresh_session=true,session id not-observable)闭合重审 VERDICT: APPROVE(对象 9d4582a,与 HEAD 仅 .task/ 不同) |
|
||||
@@ -0,0 +1,19 @@
|
||||
command: scripts/dm governance check --repo .
|
||||
cwd: /home/weichen/projects/Agent-System-Documents-wt-feature-governance-adoption
|
||||
head: fd13a266777b4c794acb879190c49ee980db38af
|
||||
exit: 0
|
||||
utc: 20261017T074046Z
|
||||
---
|
||||
ok gitlink deps/development-guidelines
|
||||
ok gitlink deps/development-manager
|
||||
ok agent-execution
|
||||
ok file AGENTS.md
|
||||
ok file PROJECT.md
|
||||
ok file policy/guidelines-adoption.md
|
||||
ok file .task/templates/task-card.md
|
||||
ok executable scripts/agent-exec
|
||||
ok executable scripts/hooks/pre-commit
|
||||
ok executable scripts/dm
|
||||
ok executable scripts/task
|
||||
ok adoption status
|
||||
ok fixtures
|
||||
@@ -0,0 +1,7 @@
|
||||
command: scripts/agent-exec validate --repo .
|
||||
cwd: /home/weichen/projects/Agent-System-Documents-wt-feature-governance-adoption
|
||||
head: fd13a266777b4c794acb879190c49ee980db38af
|
||||
exit: 0
|
||||
utc: 20261017T074046Z
|
||||
---
|
||||
validate: ok
|
||||
@@ -0,0 +1,13 @@
|
||||
command: python3 /tmp/gov-neg/adopt_cases.py .
|
||||
cwd: /home/weichen/projects/Agent-System-Documents-wt-feature-governance-adoption
|
||||
head: fd13a266777b4c794acb879190c49ee980db38af
|
||||
exit: 0
|
||||
utc: 20261017T074046Z
|
||||
---
|
||||
[object] Agent-System-Documents-wt-feature-governance-adoption HEAD=fd13a266777b4c794acb879190c49ee980db38af
|
||||
PASS positive-run-apply: run exit=0 terminal=success apply exit=0 head=876e934a0187
|
||||
PASS missing-config: run exit=2 terminal=invalid-config validate exit=2
|
||||
PASS bad-receipt: apply exit=4 head_unchanged=True msg=apply: no local integrity record: changed paths do not match the transport diff
|
||||
PASS out-of-scope-path: run exit=5 terminal=scope-expansion transport=False
|
||||
PASS unknown-side-effect: run exit=4 terminal=failed-unknown transport=False
|
||||
[verdict] ALL PASS cases=5
|
||||
@@ -0,0 +1,19 @@
|
||||
command: scripts/dm governance check --repo .
|
||||
cwd: /home/weichen/projects/Agent-System-Documents-wt-feature-governance-adoption
|
||||
head: 31daf7f7649334ddcc385ce4ba46aaca88f2f3b5
|
||||
exit: 0
|
||||
utc: 20261017T084129Z
|
||||
---
|
||||
ok gitlink deps/development-guidelines
|
||||
ok gitlink deps/development-manager
|
||||
ok agent-execution
|
||||
ok file AGENTS.md
|
||||
ok file PROJECT.md
|
||||
ok file policy/guidelines-adoption.md
|
||||
ok file .task/templates/task-card.md
|
||||
ok executable scripts/agent-exec
|
||||
ok executable scripts/hooks/pre-commit
|
||||
ok executable scripts/dm
|
||||
ok executable scripts/task
|
||||
ok adoption status
|
||||
ok fixtures
|
||||
@@ -0,0 +1,7 @@
|
||||
command: scripts/agent-exec validate --repo .
|
||||
cwd: /home/weichen/projects/Agent-System-Documents-wt-feature-governance-adoption
|
||||
head: 31daf7f7649334ddcc385ce4ba46aaca88f2f3b5
|
||||
exit: 0
|
||||
utc: 20261017T084129Z
|
||||
---
|
||||
validate: ok
|
||||
@@ -0,0 +1,31 @@
|
||||
# feature/iam-u3-account-contract 任务卡
|
||||
|
||||
任务主记录:本文件随 PR 描述维护。
|
||||
状态:已完成(合入前闭合);owner:weichen。PR:https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/115
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Documents.git;root_target:main;immediate_target:main
|
||||
- branch_kind:standalone;accepting_requirements:false;跨仓总任务:Agent-System-Dev `feature/iam-u3-account-directory-recovery`([Dev PR #626](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/626) 已合入 `7716b28`)
|
||||
- R0(initial_main_sha):1e036e9;工作区:/home/weichen/projects/Agent-System-Documents-wt-iam-u3-contract-merge;分支:feature/iam-u3-account-contract
|
||||
- 授权与交付终点:用户 2026-10-18 授权按计划完成并清理 IAM 各线 worktree,U3 采用 merge_then_accept。回收 Dev U3 worktree 时发现 U3 已批准合同(Documents `c236d30` r1、`fb3a821` A1–A4 修订、`5783940` 委托投影真实操作者修订)只存在于该 worktree 的子模块元数据中,从未推送,也未进入 Documents main;本任务先把原分支推送到远端保全,再经 PR 合入 main。
|
||||
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)。原分支缺 `AGENT-EXECUTION.md`,因此从 main 新建分支,由 worker 应用 `git merge-tree` 三方合并补丁并解决 `INDEX.md` 冲突;随后以 `merge -s ours` 并入原分支头 `3481253`(树不变),使已批准 SHA 可从 main 到达。
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
- 目标:三份已批准合同正文按原文进入 `docs/proposals/`,`docs/proposals/INDEX.md` 收录 U3 条目并写明当前事实状态。
|
||||
- 非目标:修改已批准正文;推进 Dev 的 Documents gitlink;部署或业务验收。
|
||||
|
||||
## Agent 实施收据
|
||||
|
||||
| 单元 ID | 预期范围 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| iam-u3-documents-contract-onto-main | docs/proposals/INDEX.md 与三份 2026-10-14-iam-u3-*.md | implementation | cursor, antigravity, pi | 1 | cursor-agent / auto(session not-observable,新进程) | success | apply 快进 1e036e9..08b8618 | 否 | /tmp/cleanup-20261018/render/u3-doc-contract-receipt.json |
|
||||
| iam-u3-documents-contract-index-date-repair | docs/proposals/INDEX.md | repair | cursor, antigravity, pi | 1 | cursor-agent / auto(session not-observable,新进程) | success | apply 快进 08b8618..43f2fd4 | 否 | /tmp/cleanup-20261018/render/u3-doc-contract-repair-receipt.json |
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:三份合同正文与 INDEX 条目;修复单元把 Backend PR #198 的合入日期更正为 2026-10-14(Gitea API `merged_at` 核对)。
|
||||
- 验证(SELF,host):三份正文的 blob 与 `origin/feature/iam-u3-account-contract` 逐一相同;`git diff --check` 通过;`merge -s ours` 前后树相同;`c236d30`、`fb3a821`、`5783940` 均为分支头祖先;Backend `v0.5.0` 经 `git ls-remote` 核对指向 `2716b9e`。
|
||||
- Review:host 主模型对照原分支与 Gitea PR 元数据逐项核对 INDEX 事实,无阻塞项。
|
||||
- 影响与剩余项:仅文档。Dev 的 Documents gitlink 未推进(非目标)。
|
||||
@@ -0,0 +1,30 @@
|
||||
# feature/regulations-kb-ext20-proposal 任务卡
|
||||
|
||||
任务主记录:本文件随 PR 描述维护。
|
||||
状态:已完成(合入前闭合);owner:weichen。PR:https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/113
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Documents.git;root_target:main;immediate_target:main
|
||||
- branch_kind:standalone;跨仓总任务:Agent-System-Dev `feature/regulations-kb`([Dev PR #614](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/614))
|
||||
- R0(initial_main_sha):e2f5729;工作区:/home/weichen/projects/Agent-System-Documents-wt-feature-regulations-kb-u9;分支:feature/regulations-kb-ext20-proposal
|
||||
- 授权与交付终点:用户 2026-10-18 /goal 指示按法规知识库计划实现全部内容;本任务登记 U9 的 EXT-20 扩展点提案(与 Backend `feature/regulations-kb-ext20` 实现一致),经 PR 合入 main。
|
||||
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)。此前分支 `feature/regulations-kb-u9-contract` 上的提案由 host 直接撰写且未经准入钩子,作废不合入,收口时删除该远端分支。
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
- 目标:`docs/proposals/2026-10-18-ext-20-regulations-provider.md` 与 `docs/proposals/INDEX.md` 收录条目;内容与 Backend 实现的公开符号逐一一致。
|
||||
- 非目标:实现代码(Backend/KB/RDM 各自任务)。
|
||||
|
||||
## Agent 实施收据
|
||||
|
||||
| 单元 ID | 预期范围 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| documents-ext20-proposal | docs/proposals/2026-10-18-ext-20-regulations-provider.md、docs/proposals/INDEX.md | implementation | cursor, antigravity, pi | 1 | cursor-agent-stable / auto(session not-observable,新进程) | success | apply 快进 e4aa3c6..52d77f6 | 否 | /tmp/regkb-u9doc-receipt.json |
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:EXT-20 提案(场景、现有扩展点不可组合理由、全部公开符号与 DTO 字段、基座强制行为、兼容、验收映射、分工)与 INDEX 收录条目。
|
||||
- 验证(SELF,host 于 52d77f6):`git diff --check` 通过;`scripts/dm governance check --repo .` ok。
|
||||
- Review:host 主模型对照 Backend `pkg/extension/regulations.go`、`internal/app/regulations.go`(PR #212 合入 56a7f9f)逐项核对,无阻塞项。
|
||||
- 影响与剩余项:仅文档。
|
||||
@@ -0,0 +1,66 @@
|
||||
# <任务标题> 任务卡
|
||||
|
||||
任务主记录:<Issue/PR 链接,或注明"本文件随 PR 描述维护">。
|
||||
状态:<进行中 / 待审核 / 已合入 / 已放弃>;owner:<填写>。
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:<仓 URL 或逻辑 ID>;root_target:main;immediate_target:<main 或 feature/initiative>
|
||||
- branch_kind:<initiative | child | standalone>;initiative_id:<稳定 ID,普通任务为空>
|
||||
- R0(initial_main_sha):<完整 SHA>;工作区:<路径>(worktree / clone);分支:<feature|fix|hotfix/...>
|
||||
- 父任务信息(仅子任务填写):parent_branch=<父分支>;parent_head_sha=<SHA>;parent_pr=<父 PR>
|
||||
- accepting_requirements:<true | false>(仅 initiative 可为 true;冻结后为 false)
|
||||
- 需求分流:verdict=<JOIN | NEW>;selected_initiative=<分支或无>;候选=<分支@HEAD 列表或无>;理由=<不适配/适配依据>;triage 收据=<源码外路径与摘要>
|
||||
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
|
||||
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md;外部 Agent 一单元一新进程/会话/工作区)
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
<预期结果、受影响入口/模块/契约;明确不做什么。>
|
||||
|
||||
## Agent 实施收据
|
||||
|
||||
按根目录 AGENT-EXECUTION.md 路由;外部 Agent 一单元一新进程/会话/隔离工作区。实施、修复与测试必须通过登记的候选执行;未配置或候选安全耗尽停在 unavailable/blocked,禁止 host 隐式代写。
|
||||
|
||||
| 单元 ID | 预期范围 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
|
||||
|
||||
## 复用材料(task-start 自动检索结果摘录)
|
||||
|
||||
- 相关近期提交:<git log -- <paths> 命中;无则写无>。
|
||||
- 相关经验条目:<检索命中;无则写无>。
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at | 结果 |
|
||||
|---|---|---|---|---|
|
||||
| 启动 | <R0> | <HEAD> | <日期时间> | <一致/已同步> |
|
||||
| 验收前 | <填写> | <填写> | <填写> | <填写> |
|
||||
|
||||
字段没有发生的写"无",不省略。本卡与 PR 描述同源:开 PR 时将"目标与非目标、结果与验证、影响与剩余项"复制进 PR 描述,不另写第二份。
|
||||
|
||||
## 交付调度(有多个就绪任务时)
|
||||
|
||||
- 调度记录 / entry_id / 当前 attempt_id:<平台或调度服务链接及标识;未入队写无>。
|
||||
- 入队源 HEAD / owner / 依赖:<完整 SHA、身份、依赖或无>。
|
||||
- 固定候选引用:<调度尝试中的 base/head、组件与配置;未固定写无>。
|
||||
- 窗口、最终 CI、Review 与真实合入结果:<引用调度记录及原始证据,不复制全队列>。
|
||||
|
||||
定义见 [合入调度与 CI 分配](../standards/merge-queue.md)。本段在候选固定前整理;固定后先使用源码之外的记录保存运行结果,再按项目闭合流程回填。
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:<交付了什么;未发生写无>。
|
||||
- 验证:<结论性摘要:PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据见下表,来源标注与写入规则见 [按影响选择验证与证据](../standards/verification.md)>。
|
||||
- 影响与剩余项:<影响面、遗留风险、后续任务>。
|
||||
|
||||
| 时间(UTC) | 命令 | 被测 HEAD | exit | 来源 | 摘要/位置 |
|
||||
|---|---|---|---|---|---|
|
||||
| <时间> | <命令;由项目 evidence 工具写入,无工具时附命令+对象 SHA+输出 digest 并标 SELF> | <HEAD> | <exit> | GATE/REPLAY/SELF | <摘要/位置> |
|
||||
|
||||
## 回收(task-finish)
|
||||
|
||||
- 合入核对:<分支已包含于目标分支的核对输出>。
|
||||
- 未跟踪/ignored 文件处置:<归档/可再生/存疑 逐项;无则写无>。
|
||||
- 回收动作:<worktree remove、分支删除、prune;放弃路径注明原因>。
|
||||
@@ -0,0 +1,67 @@
|
||||
# Project Agent Execution Configuration
|
||||
# 项目工程 Agent 执行路由配置
|
||||
|
||||
适用范围:定义本项目中由 AI / Agent 主导的代码实施、修复、测试与审阅所调用的 Agent CLI 路由。
|
||||
解析器识别正文中唯一一个 ```agent-execution 代码块。正文外的说明文字可根据项目需要调整。
|
||||
|
||||
通用硬规则见 Development-Guidelines 的 [Agent 执行与协作契约](deps/development-guidelines/standards/agent-execution.md)。
|
||||
本配置为项目本地路由权威,声明具体的候选 profile、尝试次数上限、超时、集成入口与豁免路径;
|
||||
代码块须通过 `deps/development-guidelines/templates/schemas/agent-execution.schema.json` 校验后才能登记为 active。
|
||||
`fallback_to_host` 只能为 `never`;旧值 `all-unavailable` 仅供迁移工具读取,不能通过准入。
|
||||
下例的 CLI 名称、命令与路径均为占位,按项目实际执行器替换。
|
||||
|
||||
```agent-execution
|
||||
schema: agent-execution/v1
|
||||
|
||||
execution:
|
||||
fresh_process_per_unit: true
|
||||
permission: run-everything
|
||||
fallback_to_host: never
|
||||
max_parallel: 3
|
||||
timeout_seconds: 7200
|
||||
idle_timeout_seconds: 600
|
||||
summary_bytes: 16384
|
||||
raw_output_bytes: 10485760
|
||||
max_attempts_per_profile: 3
|
||||
emergency_profile: codex
|
||||
|
||||
roles:
|
||||
implementation: [cursor, antigravity, pi]
|
||||
repair: [cursor, antigravity, pi]
|
||||
test: [pi, antigravity, cursor]
|
||||
review: [pi, antigravity, cursor, codex]
|
||||
|
||||
profiles:
|
||||
cursor:
|
||||
adapter: cursor
|
||||
executable: "cursor-agent-stable"
|
||||
model: auto
|
||||
enabled: true
|
||||
|
||||
antigravity:
|
||||
adapter: antigravity
|
||||
executable: agy
|
||||
model: auto
|
||||
enabled: true
|
||||
|
||||
pi:
|
||||
adapter: pi
|
||||
executable: pi
|
||||
model: auto
|
||||
enabled: true
|
||||
|
||||
codex:
|
||||
adapter: codex
|
||||
executable: codex
|
||||
model: auto
|
||||
enabled: true
|
||||
|
||||
integration:
|
||||
exempt_paths: [".task/**", "docs/superpowers/specs/**", "docs/superpowers/plans/**"]
|
||||
transport:
|
||||
command: "scripts/agent-exec apply"
|
||||
admission:
|
||||
command: "scripts/agent-exec admit"
|
||||
cleanup:
|
||||
command: "scripts/agent-exec cleanup"
|
||||
```
|
||||
@@ -34,3 +34,23 @@
|
||||
- **SSH key**:`~/.ssh/home_gitea`(ED25519,公钥指纹
|
||||
`SHA256:GYXaOXIMeloQ1fKSfdJ/ndgPQzs/Ix7Hk62ekfkfQ20`,Gitea 侧密钥名 GMKtec);
|
||||
`~/.ssh/config` 已有 `git-ssh.u1680832.nyat.app` 主机条目,克隆/推送直接可用。
|
||||
|
||||
## Agent 执行与新项目准入(强制)
|
||||
|
||||
### 新项目准入(强制)
|
||||
|
||||
1. 缺 Guidelines 固定版本(`deps/development-guidelines` gitlink 未就绪或 HEAD 不符)时,Agent 只能只读分析,不得实施。
|
||||
2. 缺有效 `AGENT-EXECUTION.md`(`scripts/dm governance check` 未通过)时禁止 AI 实施。
|
||||
3. 缺共享执行器(`scripts/agent-exec` 或 `deps/development-manager` 不可用)时,状态为 `blocked/unavailable`,不得改由 host 替代。
|
||||
4. 不允许 host 代写实施单元;实施、修复与测试必须经 `AGENT-EXECUTION.md` 登记的候选执行。
|
||||
5. 人类直接开发按其自身授权与项目规则进行,不受本条款约束。
|
||||
6. 分支保护与规范 tag 由用户负责设置与维护,Agent 不得代为设置。
|
||||
|
||||
入口:
|
||||
|
||||
- 需求分流:`scripts/task triage discover|decide|verify`
|
||||
- 任务启动:`scripts/task start …`
|
||||
- PR 检查:`scripts/task pr-check …`
|
||||
- Agent 执行:`scripts/agent-exec run|apply|admit|validate`
|
||||
|
||||
AI 实施单元仅通过 `scripts/agent-exec run` 按 AGENT-EXECUTION.md 运行,并经 `scripts/agent-exec apply` 集成。
|
||||
|
||||
@@ -17,3 +17,8 @@
|
||||
|
||||
本仓没有可编译程序或独立业务测试套件。跨仓固定组合在 Dev 仓运行 `make test`;
|
||||
过程记录中的命令和环境须按当次任务核实,不能机械重放旧运维命令。
|
||||
|
||||
治理检查(CI `.gitea/workflows/governance.yml` 同步执行):
|
||||
|
||||
- `scripts/agent-exec validate --repo .`:校验 AGENT-EXECUTION.md 的唯一 `agent-execution` 配置块,须输出 `validate: ok`。
|
||||
- `scripts/dm governance check --repo .`:只读核验治理文件与 gitlink,须只输出 ok 行。
|
||||
|
||||
+1
Submodule deps/development-guidelines added at 2688fd2be6
+1
Submodule deps/development-manager added at bd3a7de57a
@@ -501,6 +501,8 @@ taskId 在排队前持久登记并关联同一张卡;runId 表示一次实际
|
||||
|
||||
## 16. 评审与当前进展
|
||||
|
||||
以下为本设计r1.1交付时的记录;后续实施进展见§16.1。
|
||||
|
||||
| 项目 | 当前状态 |
|
||||
|---|---|
|
||||
| 当前源码核对 | SELF;固定对象与输出在任务卡;不等于运行验收 |
|
||||
@@ -515,3 +517,9 @@ taskId 在排队前持久登记并关联同一张卡;runId 表示一次实际
|
||||
辅助审阅覆盖一致性、范围、可行性、设计、产品、对抗与安全七个视角(其中一致性/范围、设计/产品/对抗/安全分别由同一子代理分析,并非七名独立审阅者)。采纳并自行核对后修订五类问题:两次成果检查点只用于代表性长任务;新增要求的生效文案不误导;确认双入口补提交与未知结果状态;材料版本复用需实际内容身份;无 runId 排队任务重启时不能假装仍有执行者。
|
||||
|
||||
r1.1 相对 r1 的定稿修订:R03 切分为 a/b/c;U1 出口白名单与排除项写入 §14;首批锁定仅 U1。摘要次数/窗口与性能数字仍为候选参数。**设计批准不等于实施授权**;批准 U1 实施计划后另开实施任务,本设计任务不自动启动写代码。
|
||||
|
||||
### 16.1 U2/U3候选进展(2026-10-13)
|
||||
|
||||
用户已批准[U2/U3具体实施计划r0.1](2026-10-13-fast-slow-u2-u3-plan.md)并要求连续推进。当前已实施TaskSnapshot/内容身份/原子事件、队列与重启对账、渐进任务/来源预览以及检查点和预算守卫,保留既有三栏、默认简洁及来源/执行详情展开。已有局部、组合、实际HTTP/browser及独立代码重放;具体固定对象和原始证据见[核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。
|
||||
|
||||
U3真实模型质量验收尚未通过:原六样本包含只有一次阶段发布、预算语义误读和预算耗尽无最终结果。已据此收紧原文记录与终态摘要、修复评测上限代表性;原失败不改写。追加一次A01已获授权并执行,仍因来源引用格式与运行额度失败;当前尚未合入、未部署。优先完成该出口及后续精确HEAD CI/合入,U4与既有实例部署保持未启动,10秒用户指标仍未验证。
|
||||
|
||||
@@ -0,0 +1,462 @@
|
||||
# 快慢通道 U2/U3 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. 本计划建议在同一会话原生实施,最后独立 Review;若用户选择子代理方式,改用 superpowers:subagent-driven-development。实施批准依据:2026-10-13用户“确认,继续推进”;连续授权覆盖本计划U2/U3阶段5–10,不包含既有服务部署。任务复选框不是验证证据。
|
||||
|
||||
**Goal:** 让材料整理期间的真实活动和带来源的阶段发现更新同一张任务卡,刷新、并行与重启后仍能准确读取。
|
||||
|
||||
**Architecture:** Core 冻结可选 TaskSnapshot 与检查点候选契约;Backend 在现有 activity_cards.payload 内保存权威快照,并将卡、执行态投影和 card.* 事件原子提交。Runtime 只提交候选;Frontend 的现有 store 是唯一异步状态所有者,UI 继续使用当前渐进卡和 DocBridge。
|
||||
|
||||
**Tech Stack:** Go、既有 SQLite/PostgreSQL Store、agent-native 子代理循环、React/TypeScript、现有 UI/Collapsible、既有 SSE 与 Playwright。
|
||||
|
||||
**Spec:** [已批准快慢通道展示方案 r1.1](2026-10-12-fast-slow-channel-display.md),特别是 §8、§9、§13–15;界面基础以[工作台设计 r0.2](2026-10-12-work-companion-ui-design.md)和[界面实施计划 r1](2026-10-12-work-companion-ui-plan.md)为准。
|
||||
|
||||
状态:**部分收口:阶段5已批准;Task1–6与r0.6零付费机制已合入,Task7模型质量验收未通过(r0.4 A01 FAIL,r0.5/r0.6 A01 NOT_RUN),留待后续任务;未部署**。版本 r0.1;日期 2026-10-13(北京时间);owner weichen;计划作者为本聊天 Codex。来源:用户“继续”并明确选择“推进快慢通道 U2/U3”。本文件补齐上一批明确排除的 U2/U3;不把上一批界面的持续授权自动移作本批授权。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 沿用“左侧找上下文、中间推进对话、右侧处理工作”,不增设通道页面或状态微服务。
|
||||
- 默认展示真实状态、工作、最多三条发现、剩余/下一步;依据与执行记录按需展开,思维链不是成果。
|
||||
- “taskId 在排队前持久登记并关联同一张卡”;排队没有 runId 时不制造 run。
|
||||
- “重启对账不能把展示快照当作执行队列”;无可信执行所有者的排队记录必须中断,不自动重派。
|
||||
- “持久化与事件写入须原子一致”;快照与重放水位一致,不同会话/项目流的 seq 不可比较。
|
||||
- “不同内容不得复用旧任务成果”;内容 hash 与解析/处理配置进入输入身份,文件名和字数不是版本。
|
||||
- 当前批准前不改业务代码、不运行真实模型实验、不操作运行数据库或部署服务。实施批准后仅使用任务独立测试环境;既有实例、凭据、保护规则和正式发布仍不在本计划范围。
|
||||
- 颜色、圆角、字号、动效只消费既有 UI 令牌和 mk-*;折叠仍用 Collapsible。无新增视觉令牌需求。
|
||||
|
||||
## Review Focus
|
||||
|
||||
1. 同名、同字数、不同内容;更新解析器或截断配置后不得返回旧批材料结论。Task 2 给出固定红测。
|
||||
2. 卡已落盘但事件失败、并发终态与晚到阶段候选;不得出现数据库和可重放事件分裂或终态回退。Task 3 注入事务失败与竞争。
|
||||
3. 重启遗留无 runId 的排队卡、PG 中另一实例仍持有执行权;只中断确属本实例失去所有者的任务。Task 4 双实例及队列恢复用例。
|
||||
4. 用户收纳/置顶、窄屏阅读、快照期间后台更新和跨会话迟到响应;不得被工作更新覆盖偏好或移走焦点。Task 5 复用并扩展真实浏览器回归。
|
||||
5. 模型伪造 task/source/verified/动作、来源更新或访问失效、预算耗尽;不提升模型叙述的可信等级,不发布越权文本,不影响主任务收尾。Task 6、7 验证。
|
||||
|
||||
## 1. 当前固定基线及实际差距
|
||||
|
||||
| 对象 | SHA |
|
||||
|---|---|
|
||||
| Dev R0 | 5212fef01e59b7f9e12fa7fc42cd987c6792a786 |
|
||||
| Core | ba289e7b1780a29855aef8477bf1ac49bd563eb2 |
|
||||
| Backend | 0f192a481388184df39f81c28b0587a7e16ec3ca |
|
||||
| Frontend | 43d1933b8c3377ae548eb495305e9f0de29dcb59 |
|
||||
| UI | 0da2e3acd6c8ae8957825b64ddb54b250c0979c0 |
|
||||
| Documents 写作起点 | cf74a200e877d898d928052e6738681be2b670fc |
|
||||
|
||||
来源 SELF:本轮读取固定源码与远端开放 PR;原始审计由 Dev 本任务卡的 make evidence 记录。以下是代码事实,不是新能力运行通过声明。
|
||||
|
||||
| 事实 | 精确入口 | 本批处理 |
|
||||
|---|---|---|
|
||||
| U1 已有 TaskSummaryView 和固定骨架 KV;没有持久 TaskSnapshot | Core task_summary.go、activity.go | 添加可选结构化字段,保留既有 Body 回退 |
|
||||
| 材料键仅取排序后的 filename + runeCount | Backend internal/runmgr/material.go:44 | 内容与配置身份修正是 U2 前置 |
|
||||
| 卡整块 JSON 已持久化,且有卡级 version/CAS | internal/store/cards.go;card_version_test.go | 使用现有 payload/version,不新增任务表 |
|
||||
| SaveCard 与 emitCard 分开;finishBackgroundCard 更新 Body 后另发状态 | internal/cardsvc/cardsvc.go;internal/runmgr/runmgr.go | 新投影事务一次写入正文、状态、tone、事件 |
|
||||
| AppendEvents 在事务中分配 seq,并在 PG 同事务 NOTIFY | internal/store/messages.go:268;dialect.go | 提取事务内事件助手;沿用现有锁与通知 |
|
||||
| bgQueue 在内存;ReconcileInterrupted 只扫描已有 run | internal/runmgr/runmgr.go:95、2240 | 持久排队卡对账,禁止用展示记录恢复执行 |
|
||||
| 子代理 text_delta 的前 80 字成为 agent.progress | internal/runtime/sub_loop.go | 不把该文本截断当业务发现;新增受控检查点 |
|
||||
| 前端已隔离后台 notes,保存卡级观察和恢复保护;无业务 TaskSnapshot.revision | Frontend src/store.ts、test/work-state.test.ts | 扩展既有 store,保留既有锁/恢复/预览意图 |
|
||||
| 新界面与阅读稳定性已交付 | Dev PR493 / 归档 PR494;上述 FE/UI SHA | 复用现有渐进卡、确认和窄屏,不再重复改版 |
|
||||
|
||||
远端核对未发现本方向的开放 U2/U3 PR。已存在审计导出、账户事务、SQLite 活动实例保护及其文档/组合 PR;本批不修改这些任务的记录。它们后续合入时依规 task-sync,并对受到影响的组合重新验证。
|
||||
|
||||
## 2. 本批决定与验收边界
|
||||
|
||||
推荐分期:**U2 → U3**,每期独立可验收;下面 Task 1–5 属 U2,Task 6–7 属 U3。不把 U1 和 U2 再合并成一个含糊出口。
|
||||
|
||||
- 首期结构化任务只使用现有卡 JSON。Core 的可选字段是扩展兼容;旧卡无该字段仍使用 Body。首次不增加 schema migration、不做旧库回填;旧材料卡无法证明内容身份时只保留历史展示,不自动复用其整理结论。
|
||||
- 第一批真实业务成果覆盖**附件材料整理**。运行时检查点能力保持通用;研究、生成、审查的专门提示配方与业务校验作为后续消费者增量,不以本批材料样例宣称全部场景完成。
|
||||
- 摘要附加模型调用 **0 次**:当前子代理在自然检查点提交候选。每次 attempt 最多接受 6 次有实质变化的非终态成果发布;相同检查点重投不扣新次数。首条有效成果立即发布,后续按内容去重;本批不建设额外定时摘要模型或持久延迟候选队列。
|
||||
- 高频活动的展示更新上限 1 次/秒,终态、必要确认与重要更正即时;执行记录不因显示节流而丢失。
|
||||
- “已纳入输入/已提供片段”由服务端输入账本确认;不把它说成模型已完整分析。阶段发现分别标材料记载、分析判断、初步判断、待确认;“已核对”只能来自受控检查结果。
|
||||
- 支持读取、展开依据、打开既有文件和现有 HITL/命令能力。无新暂停、重试或独立取消按钮;后续新尝试保存新 attempt/卡,原失败历史保留。
|
||||
|
||||
| 需求 | 实施项 | 可判定出口 |
|
||||
|---|---|---|
|
||||
| R03-b/R04 活动 | 1、3–5 | 真实工具/执行状态持续更新同一卡;无阶段成果时诚实占位 |
|
||||
| R03-c/R04/R05 成果 | 1、2、6、7 | 长材料至少两个有依据、有工作价值的真实检查点;短任务可直接收尾 |
|
||||
| R06 并行 | 3–5、7 | 3 个后台 + 前台 + 第四任务排队,任务与正文归属正确 |
|
||||
| R09 恢复 | 3–5、7 | 刷新/断线/乱序后不回退;排队失去执行者不永久“排队” |
|
||||
| R12 阅读 | 5、7 | 不抢文件、焦点和滚动;原 FE/UI 阅读用例继续通过 |
|
||||
| R17 尝试与结果 | 1、3、4、6 | attempt 与执行/展示/回投分开;旧执行者与终态后候选不能覆盖结果 |
|
||||
| R07 确认 | 5–7 | 复用既有两入口,后台进展不覆盖提交中/未知结果;服务端 CAS/命令收据证明无重复效果 |
|
||||
| R10 最终结果 | 3、6、7 | 结论、默认最多三点、范围/缺项、真实结果引用;有摘要不等于文件保存成功 |
|
||||
| R14 成本与失败 | 6、7 | 0 次额外摘要模型;限制发布次数,失败保留成果并允许主任务完成 |
|
||||
|
||||
## 3. 契约与文件职责
|
||||
|
||||
### Task 1:冻结 Core 数据与旧客户端兼容(U2)
|
||||
|
||||
**Files:** 新增 Core `task_snapshot.go`、`task_snapshot_test.go`;修改 `activity.go`、`data.go`、`ts/types.ts`、`task_summary.go`;随后 Dev `make contracts` 同步 FE/UI 的 `src/contracts.ts`。
|
||||
|
||||
**Interfaces:** `ActivityCard.Task *TaskSnapshot`,JSON 名 `task`、omitempty。TaskSnapshot 是当前权威投影;检查点类型先随契约定义,U3 才注册执行入口。最低字段如下,子类型全部在本任务定义:
|
||||
|
||||
```go
|
||||
type DocumentOrigin struct {
|
||||
ArtifactID ID
|
||||
ContentHash, ParserRevision string
|
||||
}
|
||||
// DocMeta 增加 Origin *DocumentOrigin,json:"origin,omitempty";旧调用方可不提供。
|
||||
type TaskPhase struct { ID, Label string; ObservedAt time.Time }
|
||||
type TaskSourceRef struct {
|
||||
ID, ArtifactID, ContentHash, ParserRevision string
|
||||
BlockIndex int
|
||||
Label, Quote, Availability string
|
||||
}
|
||||
type TaskResultRef struct {
|
||||
ArtifactID, SurfaceID ID
|
||||
Version, ContentHash, Availability string
|
||||
}
|
||||
type TaskFinding struct {
|
||||
ID, Text, Impact, Kind, Status string
|
||||
Revision int64
|
||||
Sources []TaskSourceRef
|
||||
Assumptions string
|
||||
Corrects string
|
||||
}
|
||||
type TaskSnapshot struct {
|
||||
SchemaVersion int
|
||||
TaskID, AttemptID, CardID, ProjectID, ConversationID, SourceMessageID ID
|
||||
ParentRunID, RunID ID
|
||||
OwnerInstanceID string
|
||||
ExecutionEpoch int64
|
||||
Revision, SourceSeq int64
|
||||
StreamScope, InputRevision, Title, Goal string
|
||||
ExecutionState, OutcomeCompleteness, DeliveryState string
|
||||
Phase TaskPhase
|
||||
Focus, Coverage, Remaining, NextStep string
|
||||
Findings []TaskFinding
|
||||
Actions []UIAction
|
||||
ResultRefs []TaskResultRef
|
||||
LastActivityAt, LastMeaningfulUpdateAt time.Time
|
||||
}
|
||||
type TaskSourceQuote struct { SourceID string; BlockIndex int; Quote string }
|
||||
type WorkCheckpointCandidate struct {
|
||||
CheckpointID, PhaseID, Focus, Remaining, NextStep string
|
||||
Findings []WorkFindingCandidate
|
||||
}
|
||||
type WorkFindingCandidate struct {
|
||||
FindingKey, Text, Impact, Kind, Assumptions, Corrects string
|
||||
Sources []TaskSourceQuote
|
||||
}
|
||||
func (s TaskSnapshot) Validate() error
|
||||
func ValidateWorkCheckpoint(c WorkCheckpointCandidate) error
|
||||
func (s TaskSnapshot) SummaryBody() []UINode
|
||||
```
|
||||
|
||||
实现必须写显式 camelCase JSON tags,TS 采用同一字段名。候选没有 owner/taskId/runId、动作、URL、CardStatus 或“已核对”开关;归属、时间和 revision 由服务端盖章。`ExecutionState` 固定 queued/running/awaiting_user/completed/failed/interrupted;`OutcomeCompleteness` 固定 none/partial/complete;`DeliveryState` 固定 pending/available/reported。`Phase.ID` 允许稳定活动阶段及经注册检查点阶段,不由计时推进。
|
||||
|
||||
- [ ] 先写字段缺失、未知状态、非安全整数 revision/seq、超过限制和旧卡 JSON 回退的红测。单快照总 JSON ≤64KiB;候选 ≤16KiB、单次 findings ≤6、当前有效发现最多12;默认只展示3项,不截掉风险/金额/日期而伪造完整性。超限拒绝候选,已有结果不变。
|
||||
- [ ] 在 Core 运行 `go test ./... -run 'TaskSnapshot|WorkCheckpoint|TaskSummary' -count=1`,确认测试因新契约缺失或不变量失败。
|
||||
- [ ] 按上述类型与枚举实现校验和 Body 纯投影。保留旧 KV 常量;执行状态映射状态词与 tone 一次产生。UI 收纳状态与 executionState 分离;dismissed 不代表已停止。
|
||||
- [ ] Go/TS 字段逐项核对后 `make contracts`;运行完整 Core 测试和 FE/UI 类型检查。提交只包含本单元的契约与兼容变更。
|
||||
|
||||
核心负例:
|
||||
|
||||
```go
|
||||
func TestTaskSnapshotRejectsMissingIdentity(t *testing.T) {
|
||||
s := TaskSnapshot{SchemaVersion: 1, Revision: 1, ExecutionState: "running"}
|
||||
if s.Validate() == nil { t.Fatal("missing scope/attempt must be rejected") }
|
||||
}
|
||||
func TestCheckpointCannotDeclareVerified(t *testing.T) {
|
||||
c := WorkCheckpointCandidate{CheckpointID: "cp1", PhaseID: "crosscheck", Focus: "核对材料",
|
||||
Findings: []WorkFindingCandidate{
|
||||
{FindingKey: "f1", Text: "日期不一致", Impact: "需要确定口径", Kind: "verified",
|
||||
Sources: []TaskSourceQuote{{SourceID: "s1", BlockIndex: 0, Quote: "上线六月"}}},
|
||||
}}
|
||||
err := ValidateWorkCheckpoint(c)
|
||||
if err == nil || !strings.Contains(err.Error(), "kind") {
|
||||
t.Fatal("expected kind rejection, not a missing unrelated field")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Task 2:材料内容身份与可核对来源登记(U2 前置)
|
||||
|
||||
**Files:** 修改 Backend `internal/runmgr/material.go`、`material_test.go`、`runmgr.go`、`internal/server/server.go` 的材料接收装配;新增 `internal/runmgr/material_sources.go`、`material_sources_test.go`。不修改解析器实现或检索排名。
|
||||
|
||||
**Interfaces:** 保留 `materialKey([]core.ParsedDocument) string` 作为解析内容级键,改为确定性 hash 完整 IR、parser 和 warnings;排除 ParsedAt。新增私有 `materialInputRevision(items []materialInputItem, processingRevision string) string` 构成完整复用身份。`materialInputItem` 定义 `ArtifactID core.ID`、`Parsed core.ParsedDocument`、`OriginalHash string`;Server在接收并授权具体artifact_ref、解析其bytes时赋予 Task 1 的DocMeta.Origin,Manager成对记录到runCtx并传给后台binding,禁止按文件名猜匹配。保留现有StartConversationRun/StartClaimedConversationRun方法签名,新Origin是可选扩展。不能假设当前DocMeta/Artifact已存在hash/version字段,也不信任客户端或模型自填Origin;Manager核对实际artifact归属与版本。没有原始hash时使用完整解析内容摘要并标识fallback。配置摘要包含实际解析版本及材料内联/截断设置;集合排序保留重复文件,不能仅按文件名覆盖。
|
||||
|
||||
内容级键排除Origin.ArtifactID等传输标识及ParsedAt,避免同内容重新上传仅因新ID重做。processingRevision还包含实际材料指令/子代理配方内容版本,不能在提示配方已改后复用旧解释。重新上传复用前仍校验旧结果来源可用与权限,没有可取回依据时创建新attempt。
|
||||
|
||||
`material_sources.go` 定义 `materialSourceRegistry`:由当前消息 artifact_ref 和可信 RunCtx.Artifact 建立 sourceId→工件/内容hash/解析版本/实际 DocBlock 的映射;记录已提供全文或片段范围。不得用待发布模型文本构造该账本。
|
||||
|
||||
- [ ] 在现有 `material_test.go` 写同名等长不同内容、顺序交换、ParsedAt变化、重复同名文件、parser/配置变化和图片/空解析的红测。
|
||||
- [ ] 运行 `go test ./internal/runmgr -run 'MaterialKey|MaterialSource|MaterialInput' -count=1`;同名等长变体必须先失败。
|
||||
- [ ] 替换内容身份并记录完整键到受控 TaskSnapshot.InputRevision。新去重只复用同 owner/会话、相同输入/配置、当前来源仍可访问且已完成或实际有执行者的记录。旧12字符 Body KV 不能作为新材料已整理的证明。
|
||||
- [ ] 从真实 ArtifactContent 及 DocBlock 建立来源 registry;无页码就用块/章节片段,不生成页码。新尝试保存新 attempt/卡,旧失败/撤回结果保留。
|
||||
- [ ] 跑相关材料完整测试并提交该前置。普通无附件对话不建任务,也不改变已有材料派发时机。
|
||||
|
||||
```go
|
||||
func TestMaterialKeySameNameSameLengthDifferentText(t *testing.T) {
|
||||
a := []core.ParsedDocument{{Meta: core.DocMeta{Filename: "决定.txt", Parser: "builtin:md"},
|
||||
Blocks: []core.DocBlock{{Type: core.BlockPara, Text: "上线六月"}}}}
|
||||
b := []core.ParsedDocument{{Meta: a[0].Meta,
|
||||
Blocks: []core.DocBlock{{Type: core.BlockPara, Text: "上线七月"}}}}
|
||||
if materialKey(a) == materialKey(b) { t.Fatal("different content reused an old result") }
|
||||
}
|
||||
```
|
||||
|
||||
### Task 3:卡快照、状态、事件与一致水位原子提交(U2)
|
||||
|
||||
**Files:** 新增 Backend `internal/store/task_projection.go`、`task_projection_test.go`、`internal/cardsvc/task_projection.go`、`task_projection_test.go`;修改 `internal/store/messages.go`、`cards.go`、`internal/runmgr/events.go`、`internal/cardsvc/cardsvc.go`、`internal/server/server.go`。
|
||||
|
||||
**Interfaces:** Store 是唯一持久写入 owner。新增以下输入/输出与方法;不把 sql.Tx/DB 句柄交给 Runtime、UI 或插件:
|
||||
|
||||
```go
|
||||
// store 包;Card 与 Task 必须一致,Channels 由宿主策略生成。
|
||||
type TaskProjectionWrite struct {
|
||||
Owner string
|
||||
Card core.ActivityCard
|
||||
Ref string
|
||||
ExpectedCardVersion int
|
||||
ExpectedTaskRevision int64
|
||||
Channels []string
|
||||
}
|
||||
type CardsSnapshot struct { Cards []core.ActivityCard; ReplaySeq int64 }
|
||||
func (s *Store) CommitTaskProjection(w TaskProjectionWrite) ([]core.StreamEvent, error)
|
||||
func (s *Store) CardsAtCursor(owner, conversationID string) (CardsSnapshot, error)
|
||||
```
|
||||
|
||||
`cardsvc` 新增 `CommitTask(owner string, next core.TaskSnapshot, expectedRevision int64) error`,内部读取当前卡及卡 version、保留用户 pin/dismiss 状态,派生 Body/状态/tone;提交时再次校验 owner、归属、attempt、合法迁移和两种版本。读写冲突明确返回 ErrConflict;不得盲写覆盖。
|
||||
|
||||
- [ ] 在 Store 复用 `openTestStore` 与 `newVersionedCard` 写事件插入失败回滚、owner不同、CAS竞争、终态后晚到更新、多流seq独立和快照水位测试。SQLite 用测试 trigger 让 INSERT events 失败;PG 使用本测试独立 schema 的同等触发器,不能修改运行库。
|
||||
- [ ] 运行 `go test ./internal/store ./internal/cardsvc -run 'TaskProjection|CardsAtCursor' -count=1`,先确认故障条件能暴露旧双写问题。
|
||||
- [ ] 提取现有 AppendEvents 的事务内助手,供旧入口和新事务复用。按排序后的 channel 获取现有会话咨询锁,卡 CAS、完整 JSON、冗余状态列、会话/允许的项目 card.updated、PG NOTIFY 同事务;失败全部回滚。唯一性/CAS不能只由 mutex 或“先查后写”保证。
|
||||
- [ ] eventBuffer 增加受控投影提交方法:在现有 flushing 串行边界内取出相关流缓冲、按同一事务先后保存并发布已提交事件;禁止持 flushing 再调用会重取该锁的 flushConversation。新路径不能另走 emitCard 二次分配 seq。只发布成功提交的对象,内存缓存提交失败时不前进。
|
||||
- [ ] 列表保持既有 `{cards: [...]}`,新增可选 `replaySeq`;事务中读取一致的卡与会话水位,PG 使用一致快照。旧消费者忽略新增字段。项目列表水位独立,不与会话水位比较;Task.SourceSeq只表示其会话流。
|
||||
- [ ] 卡收纳/置顶、动作裁决、复制到项目等触及带 Task 的写入口要保持 Task 或拒绝非法覆盖。to_project 是成果引用投影,不创建第二个工作执行 owner;本批优先保留原任务引用,不自动复制可更新执行状态。
|
||||
- [ ] SQLite/PG 原子、并发和故障测试通过后提交。本批不增加任务表或迁移;若证据表明现有 schema 无法实现不变量,先修订计划,不临时加入迁移。
|
||||
|
||||
故障注入骨架(store 包,`newVersionedCard` 是现有测试 helper):
|
||||
|
||||
```go
|
||||
st := openTestStore(t)
|
||||
c, owner := newVersionedCard(t)
|
||||
p, err := st.CreateProject(owner, "task projection")
|
||||
if err != nil { t.Fatal(err) }
|
||||
conv, err := st.CreateConversation(owner, p.ID, "task projection", "")
|
||||
if err != nil { t.Fatal(err) }
|
||||
c.ProjectID, c.ConversationID = core.ID(p.ID), core.ID(conv.ID)
|
||||
c.Task = &core.TaskSnapshot{
|
||||
SchemaVersion: 1, TaskID: "t1", AttemptID: "a1", CardID: c.ID,
|
||||
ProjectID: c.ProjectID, ConversationID: c.ConversationID,
|
||||
SourceMessageID: "m1", ParentRunID: "parent1", RunID: "run1", Revision: 1,
|
||||
OwnerInstanceID: "test-instance", ExecutionEpoch: 1,
|
||||
StreamScope: "conversation:" + conv.ID,
|
||||
InputRevision: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
Title: "测试任务", Goal: "读取测试材料", Phase: core.TaskPhase{ID: "reading", Label: "读取材料"},
|
||||
ExecutionState: "running", OutcomeCompleteness: "none", DeliveryState: "pending",
|
||||
LastActivityAt: c.CreatedAt,
|
||||
}
|
||||
c.Body = c.Task.SummaryBody()
|
||||
if err := st.SaveCard(owner, &c, ""); err != nil { t.Fatal(err) }
|
||||
// SQLite case;PG case 在独立 schema 使用拒绝 INSERT 的函数/trigger。
|
||||
_, err = st.db.Exec(`CREATE TRIGGER reject_task_event BEFORE INSERT ON events
|
||||
BEGIN SELECT RAISE(ABORT, 'task event injection'); END`)
|
||||
if err != nil { t.Fatal(err) }
|
||||
next := c
|
||||
task := *c.Task
|
||||
task.Revision = 2
|
||||
task.Focus = "核对材料"
|
||||
next.Task = &task
|
||||
next.Body = task.SummaryBody()
|
||||
_, err = st.CommitTaskProjection(TaskProjectionWrite{
|
||||
Owner: owner, Card: next, ExpectedCardVersion: 1,
|
||||
ExpectedTaskRevision: 1, Channels: []string{conv.ID},
|
||||
})
|
||||
if err == nil { t.Fatal("injected event failure must roll back") }
|
||||
if !strings.Contains(err.Error(), "task event injection") { t.Fatal("wrong failure trigger") }
|
||||
got, ver, err := st.GetCardVersion(owner, c.ID)
|
||||
if err != nil || ver != 1 || got.Task.Revision != 1 { t.Fatal("card changed without event") }
|
||||
events, err := st.EventsAfter(conv.ID, 0, 100)
|
||||
if err != nil || len(events) != 0 { t.Fatal("rolled-back event leaked") }
|
||||
```
|
||||
|
||||
### Task 4:实际执行生命周期及排队重启对账(U2)
|
||||
|
||||
**Files:** 修改 Backend `internal/runmgr/runmgr.go`、`material.go`、`recovery_test.go`;新增 `internal/runmgr/task_projection.go`、`task_projection_test.go`。复用现有 run/instance/lease,不新建调度器。
|
||||
|
||||
**Interfaces:** `task_projection.go` 定义私有 `taskBinding`(taskId、attemptId、cardId、owner、项目/会话、parentRunId、instanceID、已确认执行epoch);新增 `registerBackgroundTask`、`updateTaskActivity`、`finishTaskProjection`、`reconcileTaskProjections`,只由 Manager 调用。其持久更新统一走 Task 3 的 cardsvc.CommitTask。
|
||||
|
||||
```go
|
||||
func (m *Manager) registerBackgroundTask(parent core.Run, opts bgSpawnOpts) (taskBinding, core.ActivityCard, error)
|
||||
func (m *Manager) updateTaskActivity(binding taskBinding, phase core.TaskPhase) error
|
||||
func (m *Manager) finishTaskProjection(binding taskBinding, payload core.AgentResultPayload, runErr error) error
|
||||
func (m *Manager) reconcileTaskProjections() error
|
||||
func shouldInterruptQueued(ownerInstanceID, currentInstanceID string, hasLiveExecutionWitness bool) bool
|
||||
```
|
||||
|
||||
- [ ] 写四任务槽位、排队晋升保留ID、终态正文/灯一次出现、无run排队重启、PG他实例活租约、失去租约旧写和用户已收纳卡的测试。
|
||||
- [ ] `go test ./internal/runmgr -run 'TaskProjection|TaskQueue|TaskReconcile' -count=1` 先取得失败证据。
|
||||
- [ ] 入队前创建 TaskSnapshot 和卡并持久登记;成功持久后才可说“已登记”。后台实际启动才绑定 runId。工具开始/结束只生成确定性活动,绝不从 progress.Note 截断文本提炼发现。
|
||||
- [ ] 阶段状态、最终摘要、真实工件引用和旧卡 Body 一次提交。completed/failed/interrupted 不接受晚到运行中写;新 attempt 必须有新记录,不擦除旧失败。执行完成与 notice 已汇报分别更新 DeliveryState。
|
||||
- [ ] 启动对账在监听前运行:先沿用既有 ReconcileInterrupted,再对属本实例的 Task 做账。没有 runId/有效持久入队及执行权的 queued→interrupted,文案“排队任务未恢复,未开始执行”,解除相应材料去重。PG不得扫描并封存其他活实例任务;实例/执行epoch必须有可信关联记录,不能以“找不到本地goroutine”推断全局失败。
|
||||
- [ ] OwnerInstanceID/ExecutionEpoch 是服务端持久绑定,不由模型设置;读取执行凭据失败必须停止对账并报告,不能当作“没有执行者”。旧卡没有可信Task/内容身份时仅作历史并标明执行状态未核实,不保持虚假的排队承诺,也不擅自认定失败或重派。
|
||||
- [ ] 将持久通知ID和相同 task/attempt 关联,重投同一结果不会再派一次材料任务。回投失败不撤销已可读结果。跑恢复/材料/通知既有回归后提交。
|
||||
|
||||
```go
|
||||
func TestQueuedReconcileRequiresOwnershipAndLostExecution(t *testing.T) {
|
||||
if shouldInterruptQueued("B", "A", true) { t.Fatal("foreign live instance was sealed") }
|
||||
if shouldInterruptQueued("A", "A", true) { t.Fatal("live execution witness was ignored") }
|
||||
if !shouldInterruptQueued("A", "A", false) { t.Fatal("orphan owned queue remained queued") }
|
||||
}
|
||||
```
|
||||
|
||||
以上是归因策略的最小红测;出口还必须用现有双档 openRecoveryStore/newRecoveryManager 建立实际两实例、真实租约和持久队列卡重跑,单纯布尔策略测试不能作为恢复能力证据。
|
||||
|
||||
### Task 5:单一前端投影、来源入口与阅读恢复(U2)
|
||||
|
||||
**Files:** 修改 Frontend `src/api.ts`、`src/store.ts`、`src/components/ConversationWork.tsx`、`test/work-state.test.ts`、`e2e/work-companion.playwright.ts`;UI `src/activitySummary.ts`、`src/ProgressCardBody.tsx`、`src/progressive-cards.test.tsx`。契约同步归 Task 1,不另手写分叉。
|
||||
|
||||
**Interfaces:** 新 `api.listCardsSnapshot` 读取 Task 3 的 `{cards,replaySeq}`;只在现有 store 合并 TaskSnapshot。新增纯 `mergeTaskSnapshot<T extends {taskId: string; attemptId: string; revision: number}>(current: T, incoming: T): T`:归属相同且新 revision 才替换;未知 schemaVersion 回退 Body,不猜枚举。函数只返回给现有store,不拥有异步状态。UI 摘要从同一个 card.task 派生;旧卡仍可读,但无可信运行绑定的历史队列显示“当前执行状态未核实”,不能伪装正在推进。
|
||||
|
||||
- [ ] 写会话/项目独立seq、重复/乱序revision、快照期间到达新事件、游标缺号、切会话迟到回复和任务终态后的旧更新用例。
|
||||
- [ ] 运行 `npx vitest run test/work-state.test.ts`(Frontend);UI 运行 `npx vitest run src/progressive-cards.test.tsx`,确认新字段/恢复触发尚不能通过。
|
||||
- [ ] 扩展现有卡观察与epoch守护:查询期间缓冲新事件,按快照水位重放;不可仅Math.max推进游标后丢失缺号事件。确认状态仍归现有cardActionStates,unknown不能因阶段更新被清除;不再创建第二套pending map。
|
||||
- [ ] 结构化 findings 默认3条,展开保留当前有效全部项和修正历史。来源只使用受控 DocBridge;UI普通层不显示inputRevision、模型参数或工具脚本。Body回退与结构化字段不能各自更新成不同结果。
|
||||
- [ ] 必要确认、失败原因和关键限制保持默认可见,不占普通发现“三条”的截断预算。来源的处理版本与当前文件不同,在唯一预览中给明确版本提示;无法读取处理时版本时提供保存的合法引用片段并说明限制,不能把最新文件伪装成旧版本。
|
||||
- [ ] 在既有五宽度/大字号、窄屏水合导航、原生DOM移动滚动/焦点与文件预览用例上重跑;新事件不打开 Surface、不更换文件、不夺取焦点。
|
||||
- [ ] 来源更新/访问失效时显示可读限制并请求权威对账;会话/身份切换清理相关缓存。类型、knip、design-guard及相关浏览器检查通过后提交。
|
||||
|
||||
```ts
|
||||
expect(mergeTaskSnapshot(
|
||||
{ taskId: 't1', attemptId: 'a1', revision: 9 },
|
||||
{ taskId: 't1', attemptId: 'a1', revision: 8 },
|
||||
)).toMatchObject({ revision: 9 })
|
||||
expect(mergeTaskSnapshot(
|
||||
{ taskId: 't1', attemptId: 'a1', revision: 9 },
|
||||
{ taskId: 't1', attemptId: 'a2', revision: 10 },
|
||||
)).toMatchObject({ attemptId: 'a1', revision: 9 })
|
||||
```
|
||||
|
||||
### Task 6:可信检查点候选及首批材料成果(U3)
|
||||
|
||||
**Files:** 新增 Backend `internal/runtime/work_checkpoint.go`、`work_checkpoint_test.go`;修改 `sub_loop.go`、`runner.go`;新增 `internal/runmgr/task_checkpoint.go`、`task_checkpoint_test.go`;修改 `material.go` 的材料指令与来源描述;必要读取权限过滤放入 `internal/cardsvc/task_visibility.go`、`internal/server/server.go`,通过窄接口接现有授权策略,不导入RDM域规则。
|
||||
|
||||
**Interfaces:** Runtime 可选 `WorkCheckpointSink`,避免破坏所有 RunCtx/fake 的基础接口:
|
||||
|
||||
```go
|
||||
type WorkCheckpointSink interface {
|
||||
PublishWorkCheckpoint(core.WorkCheckpointCandidate) error
|
||||
}
|
||||
```
|
||||
|
||||
新增本地内置工具 `publish_work_checkpoint`,参数严格按 Task 1 候选结构,unknown JSON keys 拒绝。仅当前材料后台 run、支持 sink 且宿主/现有 ToolPolicy 允许时注册;不绕过 deny/NeedsConfirm,不覆盖同名插件工具。无 sink 的消费者仍走旧路径。实际 task/attempt/run、instance/epoch、检查点序号、来源账本从受控 runCtx 取得,模型不能选这些身份。
|
||||
|
||||
- [ ] 在 Runtime fake stream 与 Manager 测试覆盖:两个有效检查点、原子发布后重读、伪造来源/跨项目/不存在片段、verified提权、重复checkpoint异载荷、终态后/旧attempt候选、次数耗尽、发布失败而主任务完成。
|
||||
- [ ] 分别运行 `go test ./internal/runtime -run 'WorkCheckpoint' -count=1` 与 `go test ./internal/runmgr -run 'TaskCheckpoint' -count=1` 先取得红测。
|
||||
- [ ] 模型调用工具后,校验引用确属本次提供材料或已授权真实工具结果,quote是指定块实际片段,版本/hash仍一致;检查点序号拒绝迟到回退。同checkpointId同载荷幂等返回,异载荷冲突。没有来源的关键事实拒绝,推断必须是analysis/provisional并带依据/限定;verified只能由受控确定性检查入口生成。
|
||||
- [ ] 源文档 quote 只证明片段真实存在,不证明模型解释必然正确。不得用JSON校验取代真实模型质量验收。
|
||||
- [ ] 候选findingKey只是当前attempt内的局部业务键;只由服务端生成全局Finding ID/修订状态,替换或撤回以前结论时保留正确历史关系。曾提示用户采取行动的重要更正立即幂等提醒;无动作的新发现仅改同一卡,不反复发聊天消息。
|
||||
- [ ] 撤回、更正、终态不消耗普通成果发布次数,不因次数用尽保留已知错误。历史保存以明确的finding/revision关系和既有持久事件为依据;超限拒绝新增大载荷,关键撤回仍可提交精炼状态,不能靠剪掉金额/日期满足限制。
|
||||
- [ ] 默认自然检查点目标为读入可用材料、发现实质差异/缺项、形成可用结论;不是所有任务必经动画。没有有用发现就诚实继续,短任务可直接完成。不消费thinking_delta作为发现。
|
||||
- [ ] 必要用户决定绑定已有HITL/命令记录;模型候选不能创建可执行命令。复用已交付两入口反馈,并重跑后端 CAS/命令收据的跨浏览器重复确认与未知结果对账场景。
|
||||
- [ ] needs_user发现本身不是HITL或执行暂停;没有真实待确认记录时,只显示问题/影响和现有输入入口,不造确认按钮,也不将executionState改成awaiting_user。
|
||||
- [ ] 首批0次额外摘要模型;有效非终态发布最多6次,重复不计,超过上限返回保留成果的说明,终态仍可提交。子代理预算通过现有 loopCaps/toolBudget 及 RunBudget 绑定,不能沿用无界maxTurns而声称预算有效。
|
||||
- [ ] 每次新读、重放与重新呈现缓存均重新校验任务和来源访问。拒绝时隐藏受限发现正文、来源名称及由其生成的Body,而不只是禁用链接;从当前账号撤权不意味着已合法送达用户的信息能够收回。不扩大会话卡项目镜像权限,沿用MirrorConvCards策略。
|
||||
- [ ] 引用绑定处理当时不可变的输入内容/hash。当前工件更新后旧版本仅进入有明确版本提示的历史,当前摘要/建议标明依据已更新并重新核验;不能把旧quote伪装成当前文件内容。权限过滤同时覆盖Focus、Coverage、Remaining、NextStep、结果摘要等由受限来源派生的文本。耗时的文件hash和模型调用在事务外进行,提交时校验可信版本/范围凭据;无法提供可证明版本一致性的来源不进入有效发现。
|
||||
- [ ] Runtime、Manager、源权限与工具策略回归通过后提交 U3 业务单元。
|
||||
|
||||
有效候选格式(示例数据只定义合同,不是验收证据):
|
||||
|
||||
```json
|
||||
{
|
||||
"checkpointId": "material-difference-1",
|
||||
"phaseId": "crosscheck",
|
||||
"focus": "核对需求与会议决定",
|
||||
"remaining": "评审意见仍在核查",
|
||||
"nextStep": "整理需要确认的口径",
|
||||
"findings": [{
|
||||
"findingKey": "launch-date",
|
||||
"text": "两份材料中的上线月份不一致",
|
||||
"impact": "安排交付前需要确定权威版本",
|
||||
"kind": "material_record",
|
||||
"sources": [
|
||||
{"sourceId": "src_a", "blockIndex": 0, "quote": "上线六月"},
|
||||
{"sourceId": "src_b", "blockIndex": 0, "quote": "上线七月"}
|
||||
]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### Task 7:真实模型、真实接口及固定组合验收(U2/U3)
|
||||
|
||||
**Files:** 新增 Backend `eval/live/work_checkpoints_test.go`,复用该目录现有 `helpers_test.go`/`live_test.go` 的凭据与模型入口;新增 Frontend `e2e/work-checkpoints.playwright.ts`;更新本计划关联的 Dev 任务卡和既有设计进展入口。真实材料、模型输出和评测记录存仓外。
|
||||
|
||||
**Interfaces:** live harness 固定 baseline/candidate 的 Dev与组件SHA、同材料、同任务、同模型/参数;采集actual task/attempt/run/card IDs、事件seq/revision、原始来源和Usage。浏览器通过真实HTTP取回记录,不能仅给DOM注入示例卡冒充后端链路。
|
||||
|
||||
当前live_test.go使用`//go:build live`和AGENT_EVAL_BASE/AGENT_EVAL_MATERIALS/AGENT_EVAL_OUT。新测试复用HTTP基础助手,但不复用其自动选第一个HITL选项的策略;必要决定保留或使用明确的测试专属答复,不能无条件批准业务动作。
|
||||
|
||||
测试启动器提供`WORK_CHECKPOINT_EVAL_OWNERSHIP_MANIFEST`,内容只含本任务PID、二进制/组件SHA、地址和独立data目录;不含凭据/DSN。新测试先核验该进程和隔离目录,再允许HTTP写入;只有localhost地址不能证明是本任务实例。缺少/不匹配该清单即失败,不使用旧harness的默认实例作为兜底。
|
||||
|
||||
- [ ] 先完成所有机制红绿与固定组合 `make test && make build`;PG执行 `make test-backend-pg`,缺环境不能把SKIP记录为通过。真实评测前先验证预算与当前chat路由,服务与数据目录均为任务独立临时实例。
|
||||
- [ ] 初批真实模型对照3种材料整理任务:A01三长附件无文字、A02带明确分析重点、A04部分解析缺失;baseline/candidate各一次,共最多6个素材任务(每个含其前台即时答复和后台run),不自动重跑失败样本。A06同名等长更新另由真实HTTP/机制用例覆盖,无需为哈希问题额外消费模型。
|
||||
- [ ] 每个run建议MaxTurns=8、MaxToolCalls=12、MaxTokens=20000、300秒;每个素材任务最多1个前台和1个后台,本批最多6个素材任务/12个run、0次附加摘要模型。必须验证主/子run均受预算约束,统计逐调用实际token和可得费用;按已返回Usage对账的全批tokens目标上限240000。请求内可能发生的预算超额须由单次输出上限和停止规则约束,未回报Usage的重试不能冒充已计费上界。当前provider无法给出可核费用/限额时,真实实验标NOT_RUN并先确认上限,不修改密钥或擅自更换路由。
|
||||
- [ ] A01长任务至少两个在结束前落盘的真实成果点;对照已知材料独立检查每条结论、影响和引用,记录错误/遗漏/更正。实际生成但没有有用成果不算通过;不使用模型自评作为独立质量证据。短任务直接完成合法,不延长任务凑次数。
|
||||
- [ ] 真实接口/浏览器覆盖3后台+前台+第4排队、刷新、断线补号、会话切换、终态乱序、来源更新/移除/拒绝、双入口确认、无run排队重启以及PG活实例不被错封。记录Actor、被测版本及受信来源等级,不能将SQLite单机结果写为多实例证明。
|
||||
- [ ] 比较材料整理、主要发现、需要处理与来源定位的可读性;10秒目标作为待测指标记录实际时间/错误,不以作者直觉宣称达标。精炼度首先看风险和限定是否保留。
|
||||
- [ ] 验收、请求审核、合入前按project门禁task-sync,固定新候选,原始命令由make evidence记录。最终独立审阅者先重放最小检查,再读作者证据;组件提交精确SHA及Dev组合当前HEAD全部CI通过后才可按依赖合入。
|
||||
|
||||
建议运行入口(实验门控变量及现有 harness 行为应在本任务开工时核对):
|
||||
|
||||
```bash
|
||||
# 机制:在Backend根目录,真实实验不由这些命令自动启动
|
||||
go test ./internal/store ./internal/cardsvc ./internal/runmgr ./internal/runtime -count=1
|
||||
# 组合:在Dev任务工作区
|
||||
CMD='make test && make build' make evidence
|
||||
# 真实模型:只在本计划和评测预算批准、两实例均为任务独立环境后运行
|
||||
: "${WORK_CHECKPOINT_EVAL_BASE:?必须指定本任务独立实例地址}"
|
||||
: "${WORK_CHECKPOINT_EVAL_MATERIALS:?必须指定仓外材料目录}"
|
||||
: "${WORK_CHECKPOINT_EVAL_OUT:?必须指定仓外原始记录路径}"
|
||||
: "${WORK_CHECKPOINT_EVAL_OWNERSHIP_MANIFEST:?必须指定本任务进程与数据归属清单}"
|
||||
AGENT_EVAL_BASE="$WORK_CHECKPOINT_EVAL_BASE" \
|
||||
AGENT_EVAL_MATERIALS="$WORK_CHECKPOINT_EVAL_MATERIALS" \
|
||||
AGENT_EVAL_OUT="$WORK_CHECKPOINT_EVAL_OUT" \
|
||||
go test ./eval/live/ -tags live -run TestWorkCheckpoints -count=1 -v -timeout 35m
|
||||
# 浏览器:使用本任务的现有Playwright运行器及独立HTTP实例配置
|
||||
# 新测试文件名固定为e2e/work-checkpoints.playwright.ts,原展示/导航/附件用例继续运行。
|
||||
```
|
||||
|
||||
## 4. 交付、停止条件与当前状态
|
||||
|
||||
每个业务单元沿用模块各自任务分支与固定组合版本;Core契约先行,Backend和消费方在同一Dev候选组合验证。U2达到出口后才进入U3真实成果发布。先保留确实需要的图形/日志在展开层,不另造示例业务状态。
|
||||
|
||||
触发以下任一情形,停止受影响增量并保留现场:来源越权;状态/结果串任务;原子性破裂;终态或修正历史被旧写覆盖;无有效执行权的任务被再次派发;预算无法证明有效;真实模型连续生成无依据成果。试验失败如实记FAIL/NOT_RUN,不降低“真实且有用”的出口。
|
||||
|
||||
| 项目 | 本次状态 |
|
||||
|---|---|
|
||||
| 当前实现与在途核对 | SELF,基线/原始审计见Dev任务卡 |
|
||||
| 既有r1.1方向、阶段1–4 | 原批准继续有效;本计划新增具体接口、约束和验证需阶段5评审 |
|
||||
| U2/U3范围来源 | 2026-10-13本聊天用户明确选择推进U2/U3 |
|
||||
| 本实施计划 | r0.1,2026-10-13用户“确认,继续推进”批准,阶段5–10连续授权 |
|
||||
| Task1–6 | 本地实施与独立代码复审已完成;原子持久化、来源绑定、队列/恢复、渐进展示与预算守卫有SELF/REPLAY依据 |
|
||||
| Task7真实模型 | 原六样本、第一次额外A01及第6节另行批准的v7后续A01均已执行;后续A01两付费run、五次provider调用、57997 reported tokens;两次running态检查点确已落盘,但无后台最终结果且有无依据的“已批准决定”断言 |
|
||||
| 当前出口 | U3质量验收仍FAIL;第6节一次性授权已用完,不自动重跑 |
|
||||
| 平台CI/合入/既有实例部署 | Dev旧HEAD 7692503的三项平台CI已通过;新组合待验,质量门禁未通过故未合入;部署不在本批授权内 |
|
||||
|
||||
计划评审入口只维护本文件;Dev任务卡维护当前动作、授权、原始证据及交付进展。用户已批准并按本文件的U2→U3顺序实施;下一阶段建议不自动启动U4或既有实例部署。
|
||||
|
||||
## 5. 实施核验与剩余出口(2026-10-13)
|
||||
|
||||
实际进展及证据边界见[本批核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。原计划Task1–6源码变更已完成,Task7保留失败而非将引用存在视为语义正确。原六样本不因后续修复自动改为PASS。
|
||||
|
||||
等价整改:材料记录由宿主以经过核验的原文和文件名展示,省略模型对该类型的转述、影响和前提;分析/推断保持独立类别及前提,不提升为verified。正文与执行过程分开;失败/中断的下一步不得承诺仍在自动处理。输入配方版本已递增,旧成果不因文件名相同而复用。评测仅收紧输出上限,不能放大生产预算。
|
||||
|
||||
第6节的一次后续A01质量复验已另行获批、执行并失败。下一步先分析无依据的批准状态断言、第二检查点紧贴预算失败与缺失最终结果,再评审修订方案及资源边界;本次授权不延伸为再次付费试验。U3质量出口未通过,不进入合入。U4和既有实例部署保持未启动。
|
||||
|
||||
## 6. 质量出口后续试验(另行批准一次并执行;结果FAIL)
|
||||
|
||||
**触发和证据。** 已批准的额外A01实际使用两个run、四次provider调用、42203 returned Usage token,零接受的阶段发现。模型先提交含未知字段和错误嵌套的五条发现,随后尝试用省略号拼接来源引文;严格校验正确拒绝,两轮后台调用达到原每run 20000 token阈值,任务失败。独立逐项分析与原始收据见[核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md)及额外A01评估。不能把错误引用当有效证据,也不能重用旧失败run补写成果。
|
||||
|
||||
**已准备的等价整改。** 模型侧检查点声明最多引导1–3条新增发现,要求单段落连续的短原文引用;宿主仍只接受可信来源、完整原文和当前版本,不更改Core最多6项的受控上界或来源权限。材料处理配方递增至v7,避免把旧结果复用为新行为。SQLite完整后端套件通过;后续真实模型结果见下文。
|
||||
|
||||
**已批准的资源边界。** 用户2026-10-13另行明确批准同一A01合成材料的一次受控试验:两个付费run为上限,每run MaxTurns=8、MaxToolCalls=12、MaxTokens从20000调为30000、最长300秒;已返回Usage的本次合计目标不超过60000 token,单次输出上限4000并继续保留生产更低的剩余额度,缺Usage立即停止后续调用。不换模型/路由、不使用重试或回退、不自动确认HITL。该目标不是严格账单上界,一次在途请求可能越过剩余额度。
|
||||
|
||||
**验收和停止。** 仍要求至少两个真正有用、结束前保存的不同成果点;逐条检查数字、意见/决定、假设、引文与文件归属,明确无最终结果或因预算中断。模型JSON错误、非原文引用、未知Usage、超出两run或额度目标时停止,保留现场且不重跑。该一次性授权已经执行,不覆盖任何后续付费重跑;CI通过也不放行合入。
|
||||
|
||||
**实际结果与读数修正。** Backend 7f8674f/Dev c1c1942 的隔离样本确有两个付费run、五次provider调用、57997 returned Usage token;通知run零调用。检查点1含3项发现,检查点2累计6项发现、10处引用均可匹配原文;两次检查点均以running态原子落盘。第二次仅比失败终态早约1毫秒,250毫秒轮询客户端漏读并误报“少于两个落盘成果”;独立数据库事件重放纠正该读数,不追溯改写原评测exit1。后台run因每run 30000 token阈值失败,没有最终结果;首批已发布内容把材料中的预算/范围错误称为“已批准决定”,缺乏依据。因此有两次持久化并不等于两个可用成果,U3质量出口仍FAIL。原件和独立复审见核验报告;没有再次付费试验授权。
|
||||
|
||||
**执行停止边界偏差。** 原计划上段明确要求“非原文引用时停止”。本次后台第2次候选因非原文引文被拒绝后,同一个子run又发起第3次付费provider请求,返回14231 Usage token并修正引用;它没有新开run或执行传输重试,但仍违反该停止条件。57997低于本次60000目标也不能抵消这一偏差。评测入口已增加“检查点工具拒绝后阻止任何后续provider请求”的零付费RED→GREEN门禁;原样本、原exit1和偏差照实保留,不因代码修复追溯改为合规或质量通过。
|
||||
|
||||
## 7. U3 质量修订 r0.2(书面方案已批准,实施计划待评审)
|
||||
|
||||
用户已在本会话确认“来源一次呈现、批准状态不由模型推断、为最终答复留预算”的修订方向。可审阅的[质量修订设计 r0.2](2026-10-13-fast-slow-u3-quality-revision.md)另行固定三个职责、备选取舍、旧失败证据、零付费门禁与真实模型出口;本文 r0.1 已实施的 U2 契约、持久化、权限和三栏界面不因方向确认而重写。r0.2 书面方案已获批准;[实施计划 r0.2](2026-10-13-fast-slow-u3-quality-implementation-plan.md)仍待阶段 5 人工评审,新的付费样本尚未授权。
|
||||
@@ -0,0 +1,259 @@
|
||||
# 快慢通道 U3 质量修订 Implementation Plan r0.2
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. 本任务沿用已登记的 Dev worktree 和原生逐项实施方式;不再创建同名任务或重复启动 precheck。本文已获阶段 5 人工批准并开始零付费实施,**不是**新增付费模型授权。
|
||||
|
||||
**Goal:** 让同一任务卡的材料阶段成果忠于已提供原文、清楚标出待核对判断,并在受控预算内尽量形成真实最终答复。
|
||||
|
||||
**Architecture:** Backend 用现有 `materialSourceRegistry` 把来源编号和实际提供的原文块一次呈现,不改变来源权限或 Core JSON。Backend 在检查点提交前挡住模型生成的肯定批准断言,材料子代理依据已返回 Usage 为最终答复留请求空间;UI 在既有卡片中区分材料记载与待核对判断。旧失败样本、执行偏差和现有三栏仍是验收基线。
|
||||
|
||||
**Tech Stack:** Go、`agent-native/runtime` 子代理循环、SQLite/PostgreSQL、React/TypeScript、现有 `@ui`/Vitest/Playwright、Dev `make evidence` 与 Gitea CI。
|
||||
|
||||
**Spec:** [已批准书面设计 r0.2](2026-10-13-fast-slow-u3-quality-revision.md)。原 [U2/U3 计划 r0.1](2026-10-13-fast-slow-u2-u3-plan.md) 的 U2 契约、执行权及失败恢复不重做。用户已批准本实施计划开始零付费阶段;真实模型样本的资源边界仍待单独批准。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 保留现有三栏、同一任务卡及右栏「工作 / 文件」;不增加通道页、命令详情或新的确认能力。
|
||||
- 不改变 Core `WorkCheckpointCandidate` JSON、Store 表、SSE 事件、owner/project 约束及来源 quote 必须为连续原文的校验。
|
||||
- 不新增摘要/审核模型回合;旧样本及其原始 `exit=1`、57,997 Usage、14,231-token 停止规则偏差不重写。
|
||||
- 本轮只做零付费代码与浏览器验证。任何新真实模型样本须**另行明确批准** run 数、单 run/总 Usage 目标、在途越额风险和停止条件;未获批准为 `NOT_RUN`。
|
||||
- UI 颜色/圆角/字号只消费 `@ui/tokens.css`,动效只用 `@ui/motion.css`,折叠只用 `@ui` Collapsible;异步状态仍由现有 Frontend store 单一所有者按 seq 处理。
|
||||
- 组件先各自提交;Dev gitlink 每次推进后跑 `make test && make build`。正式验收、请求审核与合入前按 `policy/delivery.md` 和 AGENTS.md 执行 `make task-sync`;SELF 原始输出经 `make evidence` 进入任务卡。新候选的 GATE 只能引用准确 HEAD。
|
||||
|
||||
## Review Focus
|
||||
|
||||
1. **重复文字/无 Origin/截断末块**:模型只得到注册表授权的 sourceId,输入文字仍与实际提供前缀一致;Task 1 的 `TestMaterialSourceInlineAnnotationsPreserveProvidedPrefix` 和 `TestMaterialSourceInlineAnnotationsNeverExposeHiddenBlocks` 覆盖。
|
||||
2. **否定、疑问与肯定审批表达**:“审批尚未完成”“是否已批准”“防止把50万写成已批准”不能被误拒;“预算是已批准决定”必须整批拒绝;Task 2 的表驱动测试覆盖。
|
||||
3. **默认摘要把 analysis 当事实**:既有材料记载可见,待核对判断带限定且总默认项数不超过三;Task 3 的 UI 组件测试覆盖。
|
||||
4. **两个检查点后仍无限继续/只有一个检查点时余额不足**:优先真实最终答复或诚实部分结果,不多发 provider 请求;Task 4 的假 provider 用量序列覆盖。
|
||||
5. **正常通知、来源导航与停止边界**:测试通知不代表生产通知质量;Task 5 的实际 HTTP/browser 用例及 Task 6 的独立真实样本出口分别覆盖,任何工具拒绝后不继续付费。
|
||||
|
||||
---
|
||||
|
||||
### Task 1:一次呈现原文和可引用来源(Backend)
|
||||
|
||||
**Files:** Modify `modules/backend/internal/runmgr/material_sources.go`、`material.go`、`material_sources_test.go`、`material_test.go`;update the live-tag, zero-paid mechanism fixture in `modules/backend/internal/server/work_checkpoint_eval_test.go` and its regression in `work_checkpoint_eval_budget_test.go`;不改 `modules/core/task_snapshot.go`。
|
||||
|
||||
**Interfaces:** `materialSources(docs, perDoc)` 继续产出唯一授权注册表。给内部 `materialSource` 增加 `Start, End int`(相对于 `strings.TrimSpace(d.PlainText())` 的 byte offset),新增 `annotateProvidedMaterial(d core.ParsedDocument, provided string, sources materialSourceRegistry) string`。`buildMaterialTask` 仅渲染各文档提供的前缀与紧邻的 `sourceId/blockIndex`,删除末尾重复索引;`validate` 原语义不动。测试专用 `mechanismCheckpointSources(text string) [][]string` 仍返回正则组 `[full,id,blockIndex,providedLine]`,只适配新内联格式。
|
||||
|
||||
- [ ] **Step 1: 在既有测试写 RED。** `material_sources_test.go` 用含重复段落、截断段落、缺 Origin 和表格的文档,断言只对注册表里的块插入 `sourceId=... blockIndex=...`;移除这些标记后,正文与当前 `strings.TrimSpace(d.PlainText())` 的实际提供前缀逐字节相同。`material_test.go` 断言同一个短事实只出现一次、每个可引用标记紧邻其实际块、超长提示仍出现。
|
||||
|
||||
```go
|
||||
func TestMaterialSourceInlineAnnotationsPreserveProvidedPrefix(t *testing.T) {
|
||||
d := materialDocs()[0]
|
||||
d.Meta.Origin = &core.DocumentOrigin{ArtifactID: "art1", ContentHash: strings.Repeat("a", 64), ParserRevision: "docx1"}
|
||||
docs := []core.ParsedDocument{d}
|
||||
provided := strings.TrimSpace(d.PlainText())
|
||||
got := annotateProvidedMaterial(d, provided, materialSources(docs, 48000))
|
||||
markers := regexp.MustCompile(`(?m)^sourceId=src_[a-f0-9]+ blockIndex=[0-9]+\n`)
|
||||
if !markers.MatchString(got) { t.Fatal("provided block has no source marker") }
|
||||
if markers.ReplaceAllString(got, "") != provided {
|
||||
t.Fatal("source annotations changed the provided material bytes")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在 live-tag 夹具新增 `TestMechanismSourceExtractionAfterSourceOnce`:给它 `sourceId=src_... blockIndex=0\n上线六月。验收条件需要补齐`,断言读取到真实 ID、索引和连续原句。当前夹具只接受尾部“引用定位片段:”行,故此测试须先 RED;它不发真实模型请求。
|
||||
|
||||
```go
|
||||
func TestMechanismSourceExtractionAfterSourceOnce(t *testing.T) {
|
||||
id := "src_" + strings.Repeat("a", 24)
|
||||
got := mechanismCheckpointSources("sourceId=" + id + " blockIndex=0\n上线六月。验收条件需要补齐")
|
||||
if len(got) != 1 || got[0][1] != id || got[0][2] != "0" || !strings.Contains(got[0][3], "上线六月") {
|
||||
t.Fatalf("inline source unavailable to mechanism fixture: %v", got)
|
||||
}
|
||||
}
|
||||
```
|
||||
- [ ] **Step 2: 运行 RED。** 在 Backend 分别运行 `go test ./internal/runmgr -run 'TestMaterialSourceInlineAnnotations|TestBuildMaterialTaskInlineBudget' -count=1` 和 `go test -tags live ./internal/server -run '^TestMechanismSourceExtractionAfterSourceOnce$' -count=1`;期望新增的“一次呈现/标记权限”和夹具内联读取断言各自失败,而旧来源 CAS 测试仍可运行。
|
||||
- [ ] **Step 3: 实现最小改动。** 在 `materialSources` 记录已提供块的 byte 起止;按 `Start` 排序,在原 `provided` 字符串里只插入来源标记,保持所有非标记字节、顺序和截断位置不变;缺 Origin 不赋 ID。`buildMaterialTask` 只构造一次注册表,不再调用末尾的 `prompt()`;`materialRevision` 的 `material-recipe.v7` 更新为 `v8`,旧完成结果不被新输入布局复用。同步更新 `evalMechanismStream` 的测试专用 source 提取器,使它读取新内联标记后面的已提供原句;它仍只提交来自可信 ID 和字面引用的假 provider 检查点,不替代真实模型验收。
|
||||
|
||||
```go
|
||||
sources := materialSources(docs, perDoc)
|
||||
// 原有每份文档的 cap/left 计算保持不变。
|
||||
take := cap
|
||||
if runes < take { take = runes }
|
||||
provided := string([]rune(text)[:take])
|
||||
b.WriteString(annotateProvidedMaterial(d, provided, sources))
|
||||
```
|
||||
- [ ] **Step 4: 验证 GREEN 与权限。** 重跑 Step 2,加 `go test ./internal/runmgr -run 'TestMaterialSourceQuoteRequiresActualProvidedBlock|TestMaterialSourceDuplicateTextDoesNotAuthorizeUnprovidedBlock|TestMaterialInputRevisionIncludesProcessingVersion' -count=1`,以及 `go test -tags live ./internal/server -run '^TestMechanismSourceExtractionAfterSourceOnce$' -count=1`。用旧 A01 材料在离线诊断中记录新旧输入字符数、sourceId 集合与 hash;只声明实际测得的长度,不推断新模型 token 使用量。
|
||||
- [ ] **Step 5: 自审并提交 Backend 独立提交。** 检查 `git diff --check`、新增 ID 与注册表一一对应、没有未提供文本或权限放宽;按本仓 `Why/Evidence/Impact/Refs` 提交。此项可被独立退回而不影响 Task 2 的审批防误判实现。
|
||||
|
||||
### Task 2:检查点审批断言守卫(Backend)
|
||||
|
||||
**Files:** Create `modules/backend/internal/runmgr/checkpoint_claim_guard.go` 与 `checkpoint_claim_guard_test.go`;modify `task_checkpoint.go`、`task_checkpoint_test.go`、`internal/runtime/work_checkpoint.go` 的工具说明。生产拒绝只作用于系统材料整理的受控检查点,不修改一般对话正文。
|
||||
|
||||
**Interfaces:** `validateMaterialApprovalClaims(candidate core.WorkCheckpointCandidate) error` 在 `PublishWorkCheckpoint` 的 Core 基础校验后、任何持久写入前调用。检查 `analysis/provisional` 的 `Text/Impact/Assumptions` 及默认可见的 `Focus/Remaining/NextStep`。`material_record` 继续由宿主重写成原文;`needs_user` 可询问审批状态。肯定审批表达至少覆盖“已批准/已获批/审批通过/批复同意/已通过审批”,否定与待核对表达单列测试;返回稳定的 `checkpoint.claim: approval needs explicit source record` 错误,不把它包装成已通过校验。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 在 `task_checkpoint_test.go` 复用 `checkpointEnvironment` 的合法“上线六月”quote,却让 analysis 无依据声称“预算是已批准决定”,断言 `PublishWorkCheckpoint` 返回 `checkpoint.claim` 且卡 revision/发现数/事件数均不变。表驱动测试覆盖 `Text/Impact/Assumptions/Focus/Remaining/NextStep`,并包含“审批尚未完成”“是否已批准”“防止把50万写成已批准”、确有批准原文的 `material_record` 与 `needs_user` 问句,断言不误拒。
|
||||
|
||||
```go
|
||||
func TestTaskCheckpointRejectsUnsupportedApproval(t *testing.T) {
|
||||
c := checkpointEnvironment(t)
|
||||
cp := validCheckpoint(c, "unsupported-approval")
|
||||
cp.Findings[0].Kind = "analysis"
|
||||
cp.Findings[0].Text = "需求规定50万元,是已批准决定"
|
||||
cp.Findings[0].Assumptions = "把需求条目作为项目基线"
|
||||
if err := c.PublishWorkCheckpoint(cp); err == nil || !strings.Contains(err.Error(), "checkpoint.claim") {
|
||||
t.Fatalf("unsupported approval was published: %v", err)
|
||||
}
|
||||
}
|
||||
```
|
||||
- [ ] **Step 2: 运行 RED。** `cd modules/backend && go test ./internal/runmgr -run 'TestTaskCheckpointRejectsUnsupportedApproval|TestMaterialApprovalClaims' -count=1`;期望错误分析目前被接受,修复后转为拒绝。
|
||||
- [ ] **Step 3: 实现有限守卫。** 新文件按中文句子边界检查明确的肯定审批短语,排除同句的未批准/疑问/防止误写语境;仅以此处理可确定的表达,不宣称通用语义正确。`PublishWorkCheckpoint` 先运行守卫,再走原有来源、owner、版本、CAS 与事务路径;工具说明要求批准事实只作为明确原文 `material_record`,推断为待核对。
|
||||
|
||||
```go
|
||||
if err := core.ValidateWorkCheckpoint(candidate); err != nil { return err }
|
||||
if err := validateMaterialApprovalClaims(candidate); err != nil { return err }
|
||||
// 原有来源、权限、版本及 CommitTaskSources 路径继续执行。
|
||||
```
|
||||
- [ ] **Step 4: 跑 GREEN 与邻接回归。** Step 2 加 `go test ./internal/runmgr -run '^TestTaskCheckpoint' -count=1` 和 `go test ./internal/runtime -run '^TestWorkCheckpoint' -count=1`。若短语误拒或遗漏已批准变体,补夹具后只调整这个守卫;不借更宽泛的模型分数降低原来源门禁。
|
||||
- [ ] **Step 5: 自审并提交 Backend 独立提交。** 复核分析仍保留来源和 assumptions、材料记载的原文不被删除、被拒批次无半落盘;`git diff --check` 后按四段提交。
|
||||
|
||||
### Task 3:任务卡把原文与判断分层(UI)
|
||||
|
||||
**Files:** Modify `modules/ui/src/ProgressCardBody.tsx`、`src/activitySummary.ts`、`test/progressive-cards.test.tsx`;仅在现有卡内分组,不修改 Frontend store 或新增 UI token。
|
||||
|
||||
**Interfaces:** `TaskProgressBody` 保持同一个 `ActivityCard.Task`。默认最多三条:优先展示至多两条 `material_record`,其余位置可放带“待核对的判断”标识的 analysis/provisional;`needs_user` 与更正继续即时可见。`activitySummary` 给模型判断加限定,不得把 analysis 的原始句子作为无保留的摘要事实;完整依据仍在现有 Collapsible。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 在 `test/progressive-cards.test.tsx` 构造两条材料记载、一条 analysis “预算已批准”、一条 `needs_user` 和第四条普通记录,断言默认三个以内且 analysis 所在区域有“待核对的判断”标签;`activitySummary` 的摘要不能出现无前缀的“预算已批准”;点击现有“查看依据/全部发现”仍能读原 quote 与历史更正。另用仅 analysis 的卡断言说明“已有待核对判断”,不冒称“已核对”。
|
||||
|
||||
```tsx
|
||||
// 在 test/progressive-cards.test.tsx 增加 activitySummary 与 TaskFinding import。
|
||||
const subject = card()
|
||||
const source = { id: 's', artifactId: 'art', contentHash: 'h', parserRevision: 'txt', blockIndex: 0, label: '需求.txt · 段落1', quote: '预算50万尚未审批', availability: 'available' }
|
||||
const finding = (id: string, kind: string, text: string): TaskFinding =>
|
||||
({ id, kind, text, status: 'active', revision: 1, sources: [source] })
|
||||
subject.task = { schemaVersion: 1, taskId: 't', attemptId: 'a', cardId: subject.id,
|
||||
projectId: subject.projectId, conversationId: subject.conversationId!, ownerInstanceId: 'i',
|
||||
revision: 3, sourceSeq: 3, streamScope: 'conversation:' + subject.conversationId,
|
||||
title: subject.title, executionState: 'running', outcomeCompleteness: 'partial',
|
||||
deliveryState: 'available', phase: { id: 'crosscheck', label: '核对材料' },
|
||||
findings: [finding('r1', 'material_record', '材料记载1'), finding('r2', 'material_record', '材料记载2'),
|
||||
finding('a', 'analysis', '预算已批准'), finding('q', 'needs_user', '请确认预算'),
|
||||
finding('r3', 'material_record', '材料记载3')] }
|
||||
render(<ActivityCardView card={subject} />)
|
||||
expect(screen.getByText('待核对的判断')).toBeTruthy()
|
||||
expect(screen.getByText('预算已批准').closest('.acard-findings')?.textContent).toContain('待核对')
|
||||
expect(activitySummary(subject).findings).not.toContain('预算已批准')
|
||||
```
|
||||
- [ ] **Step 2: 运行 RED。** `cd modules/ui && npm test -- test/progressive-cards.test.tsx`;预期当前同组“当前发现”会把 analysis 当普通项。
|
||||
- [ ] **Step 3: 实现最小 UI。** 沿用 `@ui` Collapsible 和现有 `acard-*` 类;按 kind 投影到材料记载/待核对判断/需要留意,默认总数上限三,剩余到“查看全部发现与更正记录”;更新摘要选择,不改变卡片状态或来源导航。若需 CSS,只消费现有 `@ui/tokens.css`、`--fs-ui-*` 和 `mk-*`。
|
||||
|
||||
```tsx
|
||||
const records = ordinary.filter(f => f.kind === 'material_record')
|
||||
const judgments = ordinary.filter(f => f.kind === 'analysis' || f.kind === 'provisional')
|
||||
const visibleRecords = records.slice(0, 2)
|
||||
const visibleJudgments = judgments.slice(0, 3 - visibleRecords.length)
|
||||
// needs_user/更正仍走既有关键项路径;未展示项保留在原 Collapsible。
|
||||
```
|
||||
- [ ] **Step 4: 跑 GREEN 与设计守护。** `cd modules/ui && npm test -- test/progressive-cards.test.tsx test/design-guard.test.ts test/contrast-guard.test.ts && npm run typecheck`;检查浅/深色和窄屏文本层级,没有新裸色、私有 keyframes 或 `<details>`。
|
||||
- [ ] **Step 5: 提交 UI 独立提交。** 自审普通用户能一眼区分原文与模型判断,`git diff --check` 后按四段提交;它独立于 Task 4 的预算实现。
|
||||
|
||||
### Task 4:材料子代理的最终答复预留(Backend)
|
||||
|
||||
**Files:** Create `modules/backend/internal/runtime/material_final_reserve.go`、`material_final_reserve_test.go`;modify `sub_loop.go`、`usage_n3_test.go`;replay the existing `run_budget_stream_test.go` unchanged。一般子代理、前台、生产模型路由和 `budgetedStream` 的已返回 Usage 守卫不扩大。
|
||||
|
||||
**Interfaces:** `type materialBudgetState struct { Limit, Used, LastPrompt, OutputCap, SavedCheckpoints, Responses int; UsageKnown bool }` 与 `materialFinalDecision(s materialBudgetState) (finalOnly, stop bool)` 只处理 `agent.sub.material`。`Responses=0` 是尚未产生调用的初态;已有响应但 Usage 未知则 fail-closed。增长余量 `margin=max(1024, LastPrompt/4)`;最终预留 `reserve=LastPrompt+OutputCap+margin`,再做一次检查点的估算成本也取同一值。`Limit-Used <= LastPrompt+margin` 时停止;否则 `SavedCheckpoints>=2` 或 `Limit-Used <= 2*reserve` 时进入 final-only。首个响应前不套用该估算。这样保留一次最终请求的空间,且一次成果后发现下一次发布会挤占预留时优先收尾,明确这是部分结论而非第二项。final-only 不再向 provider 声明 `publish_work_checkpoint`,并添加系统拥有的简短最终答复指令;若剩余额度不容纳预计最终 prompt,则不发新请求,保留已保存卡和真实失败状态。它不保证在途请求不越过总目标。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** `material_final_reserve_test.go` 用假 stream 顺序返回用量,断言“初始零响应允许首个请求”“两个合法检查点→下一次仅最终答复”“只有一个检查点且额度临界→真实部分最终答复”“额度不足→0 次额外 provider 请求”“已有响应而全部 Usage 缺失→停止”“非材料子代理保持原行为”。`usage_n3_test.go` 补一条 `TotalTokens=0` 但 prompt/completion 有值时按两者之和入账的回归,与现有 `budgetedStream` 口径一致。故意让假 provider 在 final-only 中仍请求隐藏的检查点,断言 `runTool` 拒绝、设置本次执行的停止标记,下一轮在 provider 前停止且没有持久发布。测试检查 provider 请求里的工具声明和系统提醒,而非只检查内部布尔值。
|
||||
|
||||
```go
|
||||
func TestMaterialFinalReserveAfterTwoCheckpoints(t *testing.T) {
|
||||
finalOnly, stop := materialFinalDecision(materialBudgetState{Limit: 30000, Used: 16000, LastPrompt: 5000, OutputCap: 4000, SavedCheckpoints: 2, Responses: 2, UsageKnown: true})
|
||||
if !finalOnly || stop { t.Fatalf("want one final-only request: final=%v stop=%v", finalOnly, stop) }
|
||||
finalOnly, stop = materialFinalDecision(materialBudgetState{Limit: 30000, Used: 27000, LastPrompt: 8000, OutputCap: 4000, SavedCheckpoints: 1, Responses: 2, UsageKnown: true})
|
||||
if !stop { t.Fatalf("insufficient final prompt budget started another request: final=%v", finalOnly) }
|
||||
}
|
||||
```
|
||||
- [ ] **Step 2: 运行 RED。** `cd modules/backend && go test ./internal/runtime -run 'TestMaterialFinalReserve|TestRunBudgetStreamStopsReportedTokenExhaustion' -count=1`;期望当前两检查点之后仍继续暴露发布工具或临界余额耗尽。
|
||||
- [ ] **Step 3: 实现调度。** `subRun.runTool` 仅在检查点真实成功时增加 `savedCheckpoints`,在 final-only 阶段拒绝模型凭旧记忆仍提交的检查点并设置停止标记;`wrapped` 下一次调用先检查此标记,直接返回错误而不接触 provider;`onEvent(message_end)` 用返回 Usage 更新 `Used/LastPrompt/Responses/UsageKnown`。`TotalTokens=0` 时仅在 prompt+completion 大于零才采用其和;三项均为零才标 Usage 未知并阻断后续请求。该回退也修复子 run 的 `AddUsage` 记账,不修改前台或 `budgetedStream`。在 `SubLLMRunner.Execute` 的 `wrapped` 调用前计算决策;final-only 只改当前请求的工具声明和系统提示,不写回历史、不提高 `MaxTokens` 或单次输出上限。预算不能证明可用时保留原失败/部分投影,不伪造正文。
|
||||
|
||||
```go
|
||||
if st.finalOnlyRejected {
|
||||
out := make(chan agentllm.Event, 1)
|
||||
out <- agentllm.Event{Kind: agentllm.KindError, Err: fmt.Errorf("budget_exceeded: checkpoint requested after final-only transition")}
|
||||
close(out)
|
||||
return out
|
||||
}
|
||||
limit := *rc.Profile().Budget.MaxTokens // 仅在 MaxTokens 非 nil 且 >0 的材料分支调用
|
||||
outputCap := outputTokenCap(rc.Profile().Budget, rc.Settings(), "models.chat.maxOutputTokens")
|
||||
finalOnly, stop := materialFinalDecision(materialBudgetState{Limit: limit,
|
||||
Used: st.usageTotal.TotalTokens, LastPrompt: st.usageTotal.LastPromptTokens,
|
||||
OutputCap: outputCap, SavedCheckpoints: st.savedCheckpoints,
|
||||
Responses: st.responses, UsageKnown: st.usageKnown})
|
||||
if stop {
|
||||
out := make(chan agentllm.Event, 1)
|
||||
out <- agentllm.Event{Kind: agentllm.KindError, Err: fmt.Errorf("budget_exceeded: final-answer reserve unavailable")}
|
||||
close(out)
|
||||
return out
|
||||
}
|
||||
requestDecls := append([]agentllm.ToolDecl(nil), decls...)
|
||||
requestMessages := append([]agentllm.Message(nil), messages...)
|
||||
if finalOnly {
|
||||
filtered := make([]agentllm.ToolDecl, 0, len(requestDecls))
|
||||
for _, d := range requestDecls { if d.Name != workCheckpointTool { filtered = append(filtered, d) } }
|
||||
requestDecls = filtered
|
||||
requestMessages = append([]agentllm.Message{{Role: agentllm.RoleSystem, Content: "阶段成果已保存;现在用现有材料写出真实最终结论与未决项,不再发布检查点。"}}, requestMessages...)
|
||||
}
|
||||
in := stream(ctx, model, requestMessages, requestDecls, opts)
|
||||
```
|
||||
- [ ] **Step 4: 跑 GREEN 与现有子代理回归。** Step 2 加 `go test ./internal/runtime -run 'TestWorkCheckpoint|TestSub|TestRunBudget' -count=1`。用 A01 离线 Usage 序列(6,778/10,134/11,343 prompt,整体 35,632)验证决策会在原子预算检查之前转入 final-only 或诚实停止;不能把这个离线判断当新版真实模型通过。
|
||||
- [ ] **Step 5: 自审并提交 Backend 独立提交。** 检查无隐藏的附加模型回合、无流式并发数据竞争、无“两个检查点”计数伪造;按四段提交。
|
||||
|
||||
### Task 5:固定组件组合、零付费回归与独立 Review(Dev)
|
||||
|
||||
**Files:** Modify Dev `modules/backend`、`modules/ui`、`modules/documents` gitlinks、`.task/feature-fast-slow-u2-u3-plan.md` and Documents 核验报告;Core/Frontend 不变。若测试证明公开契约或 Frontend store 必须改变,先返回方案评审再扩围。
|
||||
|
||||
- [ ] **Step 1: 确认每个组件工作树干净、提交 SHA 与 PR HEAD 一致。** Backend 完整 `go test ./... -count=1`,UI `npm test && npm run typecheck`,Frontend 受影响的现有 store/阅读测试重放;每项保留真实命令、SHA 和输出。
|
||||
- [ ] **Step 2: 在已登记 Dev 任务 worktree 固定 gitlink 和任务卡。** 先提交组件,再推进 Dev 指针;不要把旧样本的 `SELF` 或旧 HEAD CI 当新候选证据。
|
||||
- [ ] **Step 3: 正式组合验收。** 在干净的 Dev HEAD 以 `RECEIPT=/tmp/fast-slow-u2-u3-r02-sync-20261013.json CMD='make task-sync' make evidence` 同步最新主干,导入工具收据;随后以 `RECEIPT=/tmp/fast-slow-u2-u3-r02-combination-20261013.json CMD='make test && make build' make evidence` 捕获完整 SELF 输出并导入任务卡。执行前检查同名收据不存在;若已占用则用新的任务专用时间后缀,不覆盖。对数据库、来源 CAS 和预算路径执行直接相关 SQLite/真实 PG 测试。
|
||||
|
||||
```bash
|
||||
test ! -e /tmp/fast-slow-u2-u3-r02-sync-20261013.json
|
||||
RECEIPT=/tmp/fast-slow-u2-u3-r02-sync-20261013.json CMD='make task-sync' make evidence
|
||||
IMPORT_RECEIPT=/tmp/fast-slow-u2-u3-r02-sync-20261013.json make evidence
|
||||
# 先提交任务卡中的同步收据,确保组合测试从干净 HEAD 开始。
|
||||
test ! -e /tmp/fast-slow-u2-u3-r02-combination-20261013.json
|
||||
RECEIPT=/tmp/fast-slow-u2-u3-r02-combination-20261013.json CMD='make test && make build' make evidence
|
||||
IMPORT_RECEIPT=/tmp/fast-slow-u2-u3-r02-combination-20261013.json make evidence
|
||||
```
|
||||
- [ ] **Step 4: 实际浏览器验收。** 用任务自有、带 PID/二进制 SHA/数据目录 manifest 的 mechanism 实例运行 `e2e/work-checkpoints.playwright.ts`;该 manifest 必须由本轮启动过程写入并在执行前验证,不复用旧文件。证明来源跳转、后台不抢阅读、刷新/旧版本、材料记载标签与浅色默认阅读;analysis 的限定标签由 Task 3 组件测试证明。不得使用旧端口或旧服务作为新版本证据。
|
||||
|
||||
```bash
|
||||
mkdir -p /tmp/fast-slow-u2-u3-r02
|
||||
test ! -e /tmp/fast-slow-u2-u3-r02/mechanism-data
|
||||
test ! -e /tmp/fast-slow-u2-u3-r02/mechanism-manifest.json
|
||||
test ! -e /tmp/fast-slow-u2-u3-r02/server-eval.test
|
||||
cd modules/backend
|
||||
go test -tags live -c ./internal/server -o /tmp/fast-slow-u2-u3-r02/server-eval.test
|
||||
# 在保持打开的任务终端中执行前台服务,不用 nohup 后台启动。
|
||||
backend_sha="$(git rev-parse HEAD)"
|
||||
dev_sha="$(git -C ../.. rev-parse HEAD)"
|
||||
WORK_CHECKPOINT_SERVER_MODE=mechanism WORK_CHECKPOINT_SERVER_DATA=/tmp/fast-slow-u2-u3-r02/mechanism-data WORK_CHECKPOINT_SERVER_MANIFEST=/tmp/fast-slow-u2-u3-r02/mechanism-manifest.json WORK_CHECKPOINT_BACKEND_SHA="$backend_sha" WORK_CHECKPOINT_DEV_SHA="$dev_sha" /tmp/fast-slow-u2-u3-r02/server-eval.test -test.run='^TestServeWorkCheckpointEval$' -test.v
|
||||
```
|
||||
|
||||
在任务终端 B 从 Dev 根目录验证 manifest,启动预览。代理目标必须从本轮 manifest 读取,不能沿用旧端口;4179 若已占用则停止并选择另一个本任务专用空闲端口,不能接管既有预览:
|
||||
|
||||
```bash
|
||||
cd modules/frontend
|
||||
npm run build
|
||||
python3 -c 'import hashlib,json,os; m=json.load(open("/tmp/fast-slow-u2-u3-r02/mechanism-manifest.json")); assert m["mode"]=="mechanism" and m["dataDir"]=="/tmp/fast-slow-u2-u3-r02/mechanism-data" and m["base"].startswith("http://127.0.0.1:") and os.path.realpath("/proc/%s/exe" % m["pid"])==m["binary"] and hashlib.sha256(open(m["binary"],"rb").read()).hexdigest()==m["binarySHA256"]'
|
||||
api_target="$(python3 -c 'import json; print(json.load(open("/tmp/fast-slow-u2-u3-r02/mechanism-manifest.json"))["base"])')"
|
||||
PLAYWRIGHT_API_TARGET="$api_target" PLAYWRIGHT_PREVIEW_PORT=4179 npm run preview -- --host 127.0.0.1 --strictPort
|
||||
```
|
||||
|
||||
在同时保持打开的任务终端 C,从 Frontend 目录执行浏览器用例;结束后只停止这两个任务拥有的前台进程并保存截图/追踪:
|
||||
|
||||
```bash
|
||||
cd modules/frontend
|
||||
PLAYWRIGHT_BASE_URL=http://127.0.0.1:4179 WORK_CHECKPOINT_HTTP_MANIFEST=/tmp/fast-slow-u2-u3-r02/mechanism-manifest.json npm run e2e -- e2e/work-checkpoints.playwright.ts
|
||||
```
|
||||
- [ ] **Step 5: 独立代码审阅与草稿 PR。** 审阅准确的 Backend/UI/Docs/Dev SHA,重放来源映射、审批误判、预算、停止边界及浏览器最小集;修正发现后只重跑受影响的检查。推送草稿 PR 并核验当前 HEAD 的 Gitea CI 运行身份、SHA、每个必需 job/step;质量出口仍 `NOT_RUN` 时不合入。
|
||||
|
||||
### Task 6:真实模型质量出口与交付决策(单独资源授权)
|
||||
|
||||
**Files:** Backend `eval/live/work_checkpoints_test.go` 仅在固定候选所需的受控入口/读数缺口确有证据时修改;Dev 任务卡、Documents 核验报告写入结果。旧原始样本不覆盖、不补写。
|
||||
|
||||
- [ ] **Step 1: 先准备可审查资源提案。** 固定 Backend/Dev/Frontend/UI/Docs 精确 SHA、模型路由来源及受保护配置引用、A01 同一合成材料、Run/单 run/returned Usage 目标、输出上限、300 秒、缺 Usage、任何检查点拒绝、越额的停止规则与成本边界。明确在途调用可能越过目标;不给出虚假的账单硬上限。
|
||||
- [ ] **Step 2: 等待用户另行明确批准该一次性付费范围。** 未获批准时只记录 `NOT_RUN`,不以本计划或“继续”推定新样本授权;保持六个 PR 草稿。
|
||||
- [ ] **Step 3: 只在批准范围内运行一次。** 启动新的隔离数据目录与一份独立结果文件,启动前验证 PID/二进制哈希、route 文件权限及零既有 run;运行后逐调用对账真实付费 run ID、Usage、检查点持久事件、来源字面与语义、用户可读窗口和最终正文。拒绝工具候选后全实例停止,不自动重试或补写。
|
||||
- [ ] **Step 4: 独立审阅与门禁。** 若两个阶段、逐项语义、最终结果或停止规则任一 FAIL,就保留证据与草稿 PR,不合入或部署。若全部 PASS,依 `policy/delivery.md` 再同步 base/head、复核独立 Review 与当前 HEAD CI,然后由智能体合入、核验实际结果并按任务卡规则安全收口;部署仍不在本计划授权内。
|
||||
@@ -0,0 +1,45 @@
|
||||
# 快慢通道 U3 质量修订设计 r0.2
|
||||
|
||||
状态:三处修订方向、本文书面设计及[实施计划 r0.2](2026-10-13-fast-slow-u3-quality-implementation-plan.md)已于 2026-10-13 在本会话获用户确认,零付费实施已获批准。新的付费模型样本仍须另行明确授权;合入须满足真实模型质量出口,既有实例部署不在范围。原 [U2/U3 计划](2026-10-13-fast-slow-u2-u3-plan.md)的 U2 持久化、执行权、来源权限和三栏工作台目标继续有效;其 Task7 质量出口仍为 FAIL。
|
||||
|
||||
## 目标与已证实的问题
|
||||
|
||||
目标仍是让普通用户在同一张卡里及时看到有用、可追溯的阶段成果,随后得到真实的最终整理结果。材料原文、模型判断、待用户确认的决定须易于区分;默认视图不把未经证实的判断当成已批准事实。保留左侧找上下文、中间推进对话、右侧处理工作,不新增页面或命令展示。
|
||||
|
||||
已获批的 v7 A01 样本在 Backend `7f8674f` 上产生两次 running 态落盘,但后台因 30,000-token 运行目标耗尽而没有最终正文;首批 analysis 把需求里的“规定总预算/包含12项”说成“已批准决定”,引用原文没有该批准事实,会议还写明审批尚未完成。第二批距失败终态仅 1.076 毫秒,不能作为两个用户可感知阶段窗口的证明。该样本使用两个付费 run、五次 provider 调用、57,997 reported tokens;非原文引用被拒后仍继续一次 14,231-token 调用,违反原计划停止条件。原始失败与[独立核验](../reports/2026-10-13-fast-slow-u2-u3-validation.md)保留,不追溯改判。后续评测入口的实例级停止门禁已独立复审通过,但没有新的模型行为证据。
|
||||
|
||||
离线复盘:后台首轮输入 10,657 字符,其中单独追加的 33 条来源索引约 6,355 字符,主要重复已内联的材料。后台三次调用的 prompt tokens 分别为 6,778/10,134/11,343,累计 Usage 35,632;最后一次请求前没有为最终答复留下可用额度。来源引文的字面校验只证明片段存在,不能证明 analysis 对批准状态的解释正确。上述成本结构是可测的改进机会,**尚不能证明压缩后模型必定完成**。
|
||||
|
||||
## 方案选择
|
||||
|
||||
| 路径 | 取舍 | 结论 |
|
||||
|---|---|---|
|
||||
| 仅加强提示词或提高预算 | 改动少,但 v7 已经证明提示词无法独自防止批准误判;提高额度会增加付费且不修正语义 | 不作为下一候选 |
|
||||
| 增加第二个模型审核/摘要回合 | 可检查部分判断,但违反本批零附加模型调用边界,也引入新成本与时序 | 本轮不选 |
|
||||
| 来源一次呈现、宿主限制批准断言、为最终答复留额度 | 利用既有来源账本和检查点,不扩大权限或页面;需要回归验证映射、误拒与模型实际行为 | **推荐,分三项实施** |
|
||||
|
||||
## 设计一:来源与正文合并呈现
|
||||
|
||||
`materialSources` 仍是唯一可信来源注册表,`validate` 的 owner/project、原件 hash、blockIndex、连续原文 quote 与版本检查不放宽。构造子任务输入时,按原文块顺序把已提供片段与它的 `sourceId`/`blockIndex` 放在一起;不再把相同内容以最多 180 字的索引片段重复附在末尾。模型只看到本次真正提供的前缀及其来源标识,未提供、无 Origin 或已截断的块不得获得可引用标识;原解析警告、文件名、表格文字与超长提示仍保留。这样来源编号紧挨着可引用原文,模型无需从两份文本间反查。
|
||||
|
||||
改变输入布局时递增材料处理配方版本,旧完成结果不复用为新行为。验收不仅比较字数,还要逐块证明:可见文本与原已提供前缀等价,来源 ID 集合与注册表一致,重复文本、截断块、表格、空文档和缺失 Origin 不越权。目标是显著减少 A01 输入重复量;数字由代码和固定材料实测给出,不事先声称节省 token 的比例。
|
||||
|
||||
## 设计二:批准状态和用户可见层级
|
||||
|
||||
`material_record` 继续由宿主以文件名和通过校验的原文片段生成,不接受模型转述。模型生成的 `analysis`/`provisional` 不能把审批、批复、通过等**肯定的批准状态**直接写成已成立事实;有明确批准原文时,让用户看到该原文记录,需要推断时写成待核对或 `needs_user`。宿主在检查点提交前拒绝可确定的肯定批准断言,保持整批原子拒绝,不把“尚未批准/待确认是否批准”误当肯定句。该规则只收紧这一类高后果断言,不能冒称通用语义验证器;A01 的每条分析仍须由独立审阅逐项核对。
|
||||
|
||||
现有任务卡继续展示真实状态、材料记载、判断、剩余工作与下一步。默认摘要优先呈现来源字面可核对的材料记载;模型判断明确标为“待核对的判断”,与原文记录分组,来源仍可在原 Collapsible 中展开。既有阅读、焦点、窄屏和三栏布局不变;颜色、字号、圆角、动效只用已有 UI 令牌。若只剩判断没有原文记录,卡片说明“已有待核对判断”,不写“已核对”或隐含批准。错误分析在独立样本中出现时不得进入无保留的默认摘要。
|
||||
|
||||
## 设计三:阶段成果后的最终答复额度
|
||||
|
||||
只对系统派发的材料整理子任务增加最终答复预算调度,不改变其他子代理与前台运行。依据 provider **已返回 Usage**、最新 prompt tokens、当前剩余额度、生产单次输出上限和已成功保存的检查点数,在下一次请求前预留至少一次完整最终答复的空间。已有两个有用检查点时,下一轮仅提供最终答复所需工具/提示,不再鼓励新增检查点;若只完成一项而继续发布会吃掉最终预留,优先给用户真实的部分结论,不伪造第二项。若连预计最终请求都放不下,就在发起新付费请求前停止并保留已保存成果。
|
||||
|
||||
预算是基于已返回 Usage 的请求前守卫,不宣称对在途请求构成严格账单上限。未知 Usage、检查点拒绝、达到 run/批次目标均按受控评测停止规则处理;不得因为缺额而自动扩大额度、换模型、回退或重新启动样本。正常产品路径可以继续按现有策略报告失败/部分成果,不能把阶段卡冒充最终正文。具体预留公式和最小可接受答复由后续实施计划固定,并用假 provider 覆盖高输入、两次发布、只完成一次、缺 Usage 与临界额度。
|
||||
|
||||
## 范围、验证与出口
|
||||
|
||||
预计修改 Backend 的材料输入组装、检查点提交守卫和材料子代理预算路径;UI 仅调整现有任务卡的来源/判断分组和摘要选择。Core 候选 JSON、数据库表、SSE 事件、权限模型、确认入口、并行/恢复所有权、生产路由和既有服务部署不在本修订范围。若实施发现必须改变上述公开契约或数据/权限设计,返回方案评审,不把它归为局部修复。
|
||||
|
||||
零付费门禁:来源映射与前缀等价测试;“需求规定50万、会议审批未完成”的错误批准候选先 RED 后 GREEN,明确批准原文与否定/待确认表达不误拒;预算假 provider 的两阶段加最终、临界额度与失败保持;UI 现有阅读、窄屏、焦点、设计守护及实际 HTTP 浏览器回归;Backend SQLite/真实 PostgreSQL 与 Dev 组合测试;独立代码审阅和精确组件 SHA。旧样本可用于离线回归,**不能当成新版真实模型前后对照**。
|
||||
|
||||
真实模型出口仍用同一合成 A01 及正常材料整理路径,至少两个真正有用、结束前可感知的不同阶段成果,逐项数字/审批/意见/引文正确,并有真实最终正文和完整 Usage;同时遵守任何检查点拒绝后停止的独立边界。行为面改动依 [Dev 交付政策](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/src/branch/feature/fast-slow-u2-u3-plan/policy/delivery.md)须在固定新候选上做任务级真实模型前后对照。新的付费样本、run 数、token 目标及停止条件要在候选代码和零付费审阅准备好后另行明确批准;未获批准标 `NOT_RUN`,全部 PR 保持草稿,不合入、不部署。
|
||||
@@ -0,0 +1,56 @@
|
||||
# U3 r0.3:有依据的阶段判断
|
||||
|
||||
状态:**书面设计与[详细实施计划](2026-10-13-fast-slow-u3-r03-evidence-implementation-plan.md)均于 2026-10-13 获用户批准,零付费实施与验证进行中**。用户选择“保留阶段判断,数字和归属须有可验证依据;不能证明就标待确认;不增加模型调用”。计划批准不授权新付费模型样本、合入或部署。
|
||||
|
||||
关联:[U2/U3 原计划](2026-10-13-fast-slow-u2-u3-plan.md)、[r0.2 质量设计](2026-10-13-fast-slow-u3-quality-revision.md)、[r0.2 实施计划](2026-10-13-fast-slow-u3-quality-implementation-plan.md)及[真实样本核验](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。既有任务卡、来源权限、执行权和三栏工作台继续有效。
|
||||
|
||||
## 要解决的具体失败
|
||||
|
||||
r0.2 唯一获批 A01 在固定 Dev `501ae35` / Backend `d89c72e` 上有两个运行中阶段成果(相隔约13秒,第二次至终态约21秒)和真实最终正文,五次 provider 调用返回 Usage 共46,154 tokens。第二批 `analysis` 却把“总12项中3项依赖外部接口”和“第一期8项”推成“剩余4项**包含**这3项”。原文未说明接口依赖项位于哪一期。该条仍是最终卡的 active finding,独立只读重放判质量 **FAIL**;测试入口 exit0、11处字面引文正确都不能改变此结论。
|
||||
|
||||
当前材料配方 v8 已明确写着“原文没有给出的分期归属不能写成事实”,仍未阻止错误。现有宿主守卫只阻断部分肯定“已批准”措辞,无法判断集合关系;`assumptions` 是模型自述,也可能重复错误前提。用户要看到及时、可用的判断,但不能把不可推出的归属当事实。界面继续把原文、判断和待确认事项分层,后台细节不默认呈现。
|
||||
|
||||
## 方案取舍
|
||||
|
||||
| 路线 | 收益 | 主要代价 | 结论 |
|
||||
|---|---|---|---|
|
||||
| 只加提示词、自检句 | 接口变化小 | v8 的明确禁令已在真实样本失效,无法给宿主可复核依据 | 不单独采用 |
|
||||
| 再加一个语义审核模型 | 可覆盖更多自然语言 | 新付费回合、延迟和第二模型的误判,且仍不能证明正确 | 本轮不选 |
|
||||
| **结构化依据 + 宿主保守归一化** | 在不加模型调用的条件下保留可证明的判断,未知关系变成明确问题 | 需收紧候选契约和支持的关系范围;不认识的表达会降为待确认 | 推荐 |
|
||||
|
||||
## 用户可见结果
|
||||
|
||||
沿用同一张任务卡和现有分组:原文仍显示为“材料记载”;能由宿主核对的算式显示为带前提的“待核对的判断”;无法确定的归属显示为“需要留意/待确认”,例如“已提供片段没有说明3项接口依赖需求分别属于哪一期,请核对”。宿主不复述模型原来的肯定归属句。来源仍可在原有“查看依据”中展开;没有新页面、命令详情或确认按钮。
|
||||
|
||||
本文限定的是**阶段检查点**。最终正文仍须在单独真实模型样本中逐项核验,不能因为阶段归一化就称全文语义已由宿主证明。已有 r0.2 错误卡和原始结果不追溯改写;后续纠正沿现有版本/更正历史走。
|
||||
|
||||
## 候选与宿主边界
|
||||
|
||||
`WorkFindingCandidate` 增加可选的 `evidence` 对象,仅给本轮材料整理工具使用;已有 `TaskFinding` 展示字段、来源引用、事件序号与持久化表保持不变。模型一次工具调用仍提交1–3条新增发现,不新增摘要或审核模型回合。处理配方从 `material-recipe.v8` 递增,旧完成结果不当成新规则结果复用。
|
||||
|
||||
`evidence` 先支持三种明确结果:
|
||||
|
||||
1. **原文直接关系。** 候选给出 sourceId、blockIndex 和连续原句。宿主沿既有 owner/project、原件 hash、解析版本和可见前缀校验,只把原句明确说出的归属或决定作为材料记载展示;自由转述不提升可信等级。
|
||||
2. **可复算数量。** 候选给出“总量”“已明确子范围”两个带原文短引的整数前提及减法。宿主只在受支持的数量/范围表述能从各自原文定位时计算差额并生成文字,如“12−8=4(推算)”;这个差额不自动等于第二期清单,也不推出3项接口依赖位于差额中。未知措辞、单位不一致、前提超出已提供片段或算式不符,都不发布肯定数量判断。
|
||||
3. **关系未定。** 如材料只给总量12、第一期8、其中3项依赖接口,宿主能算出剩余4,但接口项与剩余部分的交集可能是0–3,不能确定为3。宿主将该条归一化为 `needs_user` 的待核对问题,保留经校验的来源;模型提供的肯定归属原句不进入任务卡。只有原文直接给出接口项的分期归属,或受支持的前提把可能范围收敛成唯一值时,才可发布确定关系。
|
||||
|
||||
任何带数字、集合包含、阶段/批次归属或“已决定/已批准”状态的**模型自由判断**,若没有受支持的 `evidence`,走保守待确认通道,不以模型 `assumptions` 代替证明。普通没有这些高后果关系的分析仍保留 r0.2 “待核对的判断”标签和来源展开,不宣称通用自然语言蕴含验证。输入语义解析只采用公开、有限、可测试的表述模式;遇到同义或复杂句不猜测而转待确认。校验器应记录归一化原因供审阅,但不把内部术语放到默认界面。
|
||||
|
||||
提交顺序仍是“校验全部来源与候选 → 归一化可确定/待确认条目 → 一次 CAS 事务提交同批结果”。来源无效、伪造 ID、版本漂移或候选结构不合法时整批拒绝,并遵守既有“拒绝后不再发付费请求”的受控试验边界;**关系证据不足但来源合法**时不是工具错误,而是由宿主在同一批中安全生成待确认条目,不丢弃同批有效发现。工具结果须明确告知模型该条已转待确认,供正常下一轮最终答复使用,不增加额外模型回合或自动重跑。
|
||||
|
||||
## 接口、权限和失败恢复
|
||||
|
||||
- Core 只扩展候选 JSON 的可选依据结构及校验;Backend 的工具声明、材料配方和检查点校验实现证据处理。Frontend/UI 跟随 Core 生成类型镜像,但既有卡片显示原语不变;若实施发现必须改展示契约,再回设计评审。
|
||||
- 来源登记表、actor/owner/project、引用必须是已提供原文连续片段、原件 hash/解析版本与原子提交边界不放宽。不存在“模型说有依据,所以宿主接受”的路径。
|
||||
- 新字段只作用于后续候选,旧卡、旧事件和原 r0.2 结果只读保留,无数据库迁移。中断恢复仍按宿主 attempt/epoch 执行;同一候选幂等键及原有更正语义不变。
|
||||
- 预算依赖真实返回 Usage 与已修复的宿主 run ID 分组;依据字段可能增加输入/输出 token,实施时需离线比较上下文体积。没有额外调用或静默提高额度。任何新付费 A01 必须重新提交 run 数、用量目标和在途越额边界并取得单独批准。
|
||||
|
||||
## 零付费验证与真实出口
|
||||
|
||||
先写失败用例再实现,至少覆盖:本次 A01 的错误归属不能作为分析落盘;同样数字但**明确写明**3项均在第二期的原句可作为材料记载;12−8=4可显示为推算但不附加接口归属;交集可能范围0–3转待确认;已批准/尚未批准/是否批准与“六月已决定”无直接决定原句时的状态区分;同批一条有效一条证据不足的原子归一化;伪造来源和版本漂移仍整批拒绝;旧检查点幂等、刷新/阅读焦点不回退。Backend SQLite/真实 PostgreSQL、Core/类型镜像、UI设计守护、Dev `make test && make build`、任务自有 HTTP 浏览器和独立代码复审均固定准确 SHA。
|
||||
|
||||
真实质量出口沿用同一 A01 合成材料:至少两个真正有用、终态前可感知的阶段成果;所有金额、决定状态、日期意见、12/8/3数字、来源及集合归属逐项正确;有完整最终正文与 Usage;任何拒绝后零后继付费请求。阶段问题可诚实写“未明确”,不得靠删除判断、隐藏错误历史或降低验收条件放行。新模型样本在书面设计与实施计划获批、零付费候选完成后另行申请资源;失败保留草稿 PR,不合入或部署。
|
||||
|
||||
## 已知边界与待审决定
|
||||
|
||||
有限原文模式可能把真实但陌生的表述降为待确认,这是偏保守的可用性成本;需在真实材料与测试中量化,不能把它描述为通用语义正确性证明。依据字段增加模型输出负担,可能缩短最终答复余量,仍由已返回 Usage 调度;质量样本必须验证不牺牲最终正文。设计审批时请确认这一“保守降级,保持来源可查看”的取舍;若不可接受,需重新评估独立语义审核或人工处理的成本与边界。
|
||||
@@ -0,0 +1,144 @@
|
||||
# U3 r0.3 有依据的阶段判断 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. 本计划已于 2026-10-13 获用户阶段5批准,授权在现有任务工作区内做零付费实施与验证;新付费样本仍须单独批准。
|
||||
|
||||
**Goal:** 保留同一任务卡中有用的阶段判断;数字、集合归属和决定状态没有可核对依据时,只显示待确认问题,不把模型的肯定句当成事实。
|
||||
|
||||
**Architecture:** Core 为材料检查点候选增加可选结构化依据;Backend 沿既有来源注册表校验短引与有限数量关系,把可复算结论或未定关系归一化,再用现有 CAS 一次提交。UI 仍消费原有 `material_record`、`analysis`、`needs_user`;不增页面、按钮、数据库表或模型回合。真实模型质量仍须另行授权验证。
|
||||
|
||||
**Tech Stack:** Go、Core Go/TypeScript 契约、Backend runmgr/runtime、SQLite/PostgreSQL、React/TypeScript、Vitest、Playwright、Dev `make evidence` 与 Gitea CI。
|
||||
|
||||
**Spec:** [U3 r0.3 书面设计](2026-10-13-fast-slow-u3-r03-evidence-backed-judgments-design.md);失败依据在[U2/U3 核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。初始工作区沿用已登记的 Dev `feature/fast-slow-u2-u3-plan`,不重做本任务 precheck、不创建第二份任务卡。r0.2 唯一 A01 的 `46,154` Usage、语义 FAIL 和原始文件均不改判。书面设计与本计划均已获用户批准;付费资源未获新授权。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- **阶段边界:** 本计划获人工批准后才改 r0.3 语义代码;真实模型样本仍须另外固定 run/Usage/在途风险并单独批准。旧授权已用尽,不自动重试。新样本任一语义或停止规则失败,六 PR 保持草稿,不合入或部署。
|
||||
- **既有能力:** 不改 TaskSnapshot 数据表、事件序号、owner/project/attempt/epoch 权限、连续原文引用、历史更正与最终正文所有者。来源无效/版本漂移仍整批拒绝;依据不足但来源有效则安全归一化,并将同批结果一次 CAS 保存。
|
||||
- **界面:** 左侧上下文、中间对话、右侧工作/文件不变;默认最多三项普通发现,关键 `needs_user` 可见,历史和依据仍用 `@ui` Collapsible。颜色/字号/圆角仅用 `@ui/tokens.css`,动效仅用 `@ui/motion.css`;异步状态唯一所有者仍是 Frontend store,旧 seq 丢弃。
|
||||
- **成本:** 不增摘要/审核模型回合,不改生产路由或默许提高预算;依据字段增加 token 的影响必须离线量化,最终答复预留按真实返回 Usage 继续生效。
|
||||
- **治理:** 实施首步先核对并同步已推进的权威 main,组件各自提交后推进 Dev gitlink;已有任务不重复 `make precheck`。验收、请求审核和合入前分别以 `CMD='make task-sync' make evidence` 同步;组合 `make test && make build` 的完整 SELF 收据由工具导入任务卡。独立 REVIEW/REPLAY 与精确 HEAD GATE 分开标记,禁止用旧 SHA CI 放行。
|
||||
|
||||
## File Map and Interfaces
|
||||
|
||||
| 单元 | 文件 | 职责 |
|
||||
|---|---|---|
|
||||
| 候选契约 | `modules/core/task_snapshot.go`、`task_snapshot_test.go`、`ts/types.ts` | 可选 `WorkFindingEvidence`,只约束候选,不改持久 TaskFinding;`sourceIndex` 指向同条现有 `sources` |
|
||||
| 原文计数 | `modules/backend/internal/runmgr/material_evidence.go`、`material_evidence_test.go` | 在已校验来源短引中识别有限的总量/首期/依赖数量,算差额和可能交集,未知降级 |
|
||||
| 提交与提示 | `modules/backend/internal/runmgr/task_checkpoint.go`、`material.go`、`material_sources.go`、相关测试;`internal/runtime/work_checkpoint.go` | 全字段风险检查、单批归一化/CAS、工具 JSON、归一化回执与 v9 处理配方 |
|
||||
| 类型镜像/展示 | `modules/frontend/src/contracts.ts`、`modules/ui/src/contracts.ts`(`make contracts` 生成);`modules/ui/test/progressive-cards.test.tsx`、`modules/frontend/test/work-state.test.ts` | 消费相同现有卡片类别,待确认默认可见、历史/阅读无回退;无新页面 |
|
||||
| 组合和记录 | Dev gitlinks、`.task/feature-fast-slow-u2-u3-plan.md`、Documents 核验报告 | 精确 SHA、SQLite/PG/浏览器、独立评审、草稿 PR 和结果出口 |
|
||||
|
||||
候选新增的内部契约固定为:
|
||||
|
||||
```go
|
||||
type WorkEvidencePremise struct {
|
||||
Role string `json:"role"` // total, phase, dependent, direct_relation
|
||||
SourceIndex int `json:"sourceIndex"` // index into this finding's Sources
|
||||
Value *int `json:"value,omitempty"`
|
||||
}
|
||||
type WorkFindingEvidence struct {
|
||||
Mode string `json:"mode"` // direct_relation, difference, unresolved_relation
|
||||
Premises []WorkEvidencePremise `json:"premises"`
|
||||
Result *int `json:"result,omitempty"` // only difference
|
||||
}
|
||||
// Add to existing WorkFindingCandidate only:
|
||||
Evidence *WorkFindingEvidence `json:"evidence,omitempty"`
|
||||
```
|
||||
|
||||
Core 只验证枚举、数量、索引、字段组合和现有 16KiB 候选上限。Backend 的 `normalizeMaterialEvidence(candidate core.WorkCheckpointCandidate, sources materialSourceRegistry) (core.WorkCheckpointCandidate, []string, error)` 对已验短引、数值角色和关系作安全归一化:返回归一化候选、给工具结果看的简短说明、或必须整批拒绝的错误。实现时用 `TaskFinding` 原有类别和 `Sources/Assumptions` 保存输出,不引入新表。`direct_relation` 仅允许 `material_record`,只在短引本身明确写出关系时按现有宿主路径展示原文;`difference` 由宿主生成 `analysis` 和 `total-phase` 算式及“推算”;`unresolved_relation` 对可验证的三个计数计算交集范围,范围不唯一时由宿主生成 `needs_user`,范围唯一时也只由宿主生成有前提的判断,均不复制模型肯定归属句。现有无依据的 `material_record` 原文路径继续有效。
|
||||
|
||||
有限识别只接受短引中明确的“总/包含 N 项”“第一期 N 项”“其中 N 项依赖外部接口”等受支持中文数量语法及直接关系原句;超过已提供前缀、单位不一致、多个无法消歧的数字、陌生表述均走待确认。**不声称通用自然语言蕴含证明**。风险检查同时覆盖 findings 的 text/impact/assumptions 和 focus/remaining/nextStep;后者不能携带未经证明的归属或决定肯定句,必要时由宿主替换为中性进度/待核对说明。结构合法但原文不能证明的依据按“待确认”处理;sourceId/版本/权限不合法仍整批拒绝。
|
||||
|
||||
## Review Focus
|
||||
|
||||
1. **数字同句多义:** “第一期8项、第二期4项”不能把第二个数字当首期;单位“万元/项”不得交叉计算。Task 2 的多数字/混合单位 RED 用例必须保守降级。
|
||||
2. **来源重复与截断:** 相同文字在两个文件、无 Origin、或来源只提供了首段时,`sourceIndex` 不得越权引用另一个块。Task 2 的来源映射与版本 RED 用例必须整批拒绝伪造来源。
|
||||
3. **旁路字段:** findings 正确但 focus/remaining/nextStep 称“已决定第二期含3项”时,默认卡不能泄露该肯定句。Task 3 的全字段投影测试必须验证中性替换。
|
||||
4. **混合批次:** 一条有效差额、一条归属未定、一条来源无效:前两者可在来源均合法时原子归一化;来源无效时全部不提交,且没有后继付费请求。Task 3 的 CAS/拒绝/幂等测试覆盖。
|
||||
5. **预算和阅读回归:** 结构化依据扩大提示后,final-only 仍为最终正文留额度;待确认发现刷新/窄屏/来源跳转不抢文件和焦点。Task 4 的 fake-stream、UI/Frontend 与真实 HTTP 浏览器测试覆盖。
|
||||
|
||||
---
|
||||
|
||||
### Task 1:Core 候选依据契约
|
||||
|
||||
**Files:** Modify `modules/core/task_snapshot.go`、`task_snapshot_test.go`、`ts/types.ts`;不改 `TaskSnapshot`/`TaskFinding` 和数据库。
|
||||
|
||||
**Interfaces:** `WorkFindingCandidate.Evidence *WorkFindingEvidence`;`SourceIndex` 只引用同一 finding 的 `Sources`。Core 的 `ValidateWorkCheckpoint` 验证 `direct_relation` 恰一条关系前提且无 Result;`difference` 恰有 total/phase 两项且有 Result;`unresolved_relation` 恰有 total/phase/dependent 三项且无 Result。整数范围 `0..1,000,000`,同一模式不允许重复 role,索引须 `0 <= index < len(Sources)`;计算与原文语义交给 Backend。
|
||||
|
||||
- [ ] **Step 0: 在现有任务工作区同步基线。** 确认当前 Root/组件提交及任务卡收据已保存,使用 `RECEIPT=/tmp/fast-slow-u3-r03-first-sync-20261013.json CMD='make task-sync' make evidence`;导入原始收据。先核对最新 main 的项目成员/公开契约差异,遇到需改变本设计的冲突停在计划阶段。组件分支随后以同一权威主干处理各自合并;不得用旧 r0.2 组合假定兼容。
|
||||
- [ ] **Step 1: 写 RED。** 在 `task_snapshot_test.go` 用现有合法候选加 `Evidence`,表驱动覆盖三个模式的合法组合、索引越界、负数、重复 role、未知 mode、difference 缺结果、unresolved 偷带结果以及候选 JSON 不超过现有16KiB工具上限。TS `types.ts` 增加同名可选字段后,构建期校验生成镜像一致。
|
||||
|
||||
```go
|
||||
candidate.Findings[0].Evidence = &WorkFindingEvidence{Mode: "difference", Premises: []WorkEvidencePremise{
|
||||
{Role: "total", SourceIndex: 0, Value: intPtr(12)},
|
||||
{Role: "phase", SourceIndex: 1, Value: intPtr(8)},
|
||||
}, Result: intPtr(4)}
|
||||
if err := ValidateWorkCheckpoint(candidate); err != nil { t.Fatal(err) }
|
||||
```
|
||||
- [ ] **Step 2: 跑 RED。** `cd modules/core && go test ./... -run 'TestWorkCheckpointEvidence' -count=1`;预期新类型/校验缺失。
|
||||
- [ ] **Step 3: 实现 Core 类型与结构校验。** 仅增加上述候选字段及 `ValidateWorkCheckpoint` 的有限模式检查;TS 权威镜像同步,不增加状态枚举或前端行为。
|
||||
- [ ] **Step 4: 跑 GREEN。** `cd modules/core && go test ./... -count=1`;检查 `git diff --check` 和 Go/TS 字段名一致。
|
||||
- [ ] **Step 5: 独立提交 Core。** 主题行英文祈使,body 写 `Why:/Evidence:/Impact:/Refs:`;Dev 指针留到 Task 4 统一绑定。
|
||||
|
||||
### Task 2:Backend 纯依据判定与保守降级
|
||||
|
||||
**Files:** Create `modules/backend/internal/runmgr/material_evidence.go`、`material_evidence_test.go`;Backend 内嵌 `deps/agent-system-core` 指向 Task 1 精确 SHA。组件同步若涉及权限/公开契约取舍,暂停并交人工决定。
|
||||
|
||||
**Interfaces:** `normalizeMaterialEvidence(core.WorkCheckpointCandidate, materialSourceRegistry) (core.WorkCheckpointCandidate, []string, error)` 不写库、不调用模型;调用方先对全部 `sources` 执行 `registry.validate` 与持久原件校验,函数只使用已提供前缀和候选中的同条来源短引。`parseCountPremise(quote, role, value) bool` 只识别受支持数量模式。`difference` 由宿主重新计算 result;`unresolved_relation` 用 `remaining=total-phase`、`low=max(0,dependent-phase)`、`high=min(dependent,remaining)`,`low!=high` 时把对应 finding 改为 `needs_user`、清空模型肯定 text/impact、填入宿主文字与真实来源;`low==high` 时也只发布宿主生成的、附前提的确定数量关系。前提数值超出总量安全降级,绝不输出伪算式。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 用 r0.2 A01 的三份首段构造来源注册表及候选:错误 `phase-list-gap` 不得保存“剩余4项包含3项”;12−8=4可保留为带“推算”的判断;明确原句“第二期包含3项依赖外部接口”可展示原文;0–3的未定交集转待确认。另覆盖 `12项/8万元`、同句两个阶段数字、来源重复、无 Origin、截断块、旧 parserRevision 和陌生数词。
|
||||
|
||||
```go
|
||||
normalized, notes, err := normalizeMaterialEvidence(candidate, sources)
|
||||
if err != nil { t.Fatal(err) }
|
||||
if normalized.Findings[0].Kind != "needs_user" || strings.Contains(normalized.Findings[0].Text, "其中包含3项") {
|
||||
t.Fatal("unsupported phase membership escaped", normalized.Findings[0])
|
||||
}
|
||||
if len(notes) == 0 { t.Fatal("model was not told that the claim became pending") }
|
||||
```
|
||||
- [ ] **Step 2: 跑 RED。** `cd modules/backend && go test ./internal/runmgr -run 'TestMaterialEvidence|TestMaterialSetBounds' -count=1`;预期未实现或错误断言失败。
|
||||
- [ ] **Step 3: 实现最小纯函数。** 原文直接关系优先保留 quote 的字面展示;仅支持 `total/phase/dependent` 的有限角色和一致单位。自由文本中 `已决定/已批准/其中/包含/属于/剩余/第一期/第二期` 与数量或归属共现、却无可验证依据时,产出通用待确认句,不原样回显风险词句;不认识的表达也走保守路径。
|
||||
- [ ] **Step 4: 跑 GREEN 与现有审批边界。** `go test ./internal/runmgr -run 'TestMaterialEvidence|TestMaterialSetBounds|TestMaterialApprovalClaims|TestMaterialSource' -count=1`;测试未触发的普通分析仍带“待核对”,否定/疑问审批表达不误拒。
|
||||
- [ ] **Step 5: 自审并提交 Backend 独立提交。** 记录识别语言的有限范围及未知降级成本,不声称通用语义正确性。
|
||||
|
||||
### Task 3:一次提交、提示与预算兼容
|
||||
|
||||
**Files:** Modify `modules/backend/internal/runmgr/task_checkpoint.go`、`task_checkpoint_test.go`、`material.go`、`material_sources.go`、`material_sources_test.go`;modify `modules/backend/internal/runtime/work_checkpoint.go`、`work_checkpoint_test.go`。不改已经落盘的 r0.2 样本、数据库表或 SSE 契约。
|
||||
|
||||
**Interfaces:** `PublishWorkCheckpoint` 先结构校验和**全部**来源合法性,再调用 Task 2 纯函数归一化与审批/全字段风险守卫,最后沿现有 `CommitTaskSources` 做一次 CAS。Backend 对所有模型文本和结果文本都做守卫;有明确原文的 `material_record` 沿现有宿主引用路径显示。有效来源但不唯一的关系提交 `needs_user`;来源伪造、hash/版本漂移、JSON未知字段或越权依旧整个检查点失败。`runtime.WorkCheckpointSink.PublishWorkCheckpoint` 从 `error` 改为 `(string,error)`,`runCtx` 在 CAS 成功后才返回简短归一化回执;`publishCheckpoint` 将回执附在既有成功消息,供正常下一轮模型看见,不新增 provider 调用。处理配方从 `material-recipe.v8` 到 `material-recipe.v9`。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** `task_checkpoint_test.go` 用 SQLite 断言“有效差额+未定关系”同批一次提交、无伪造肯定句;同批再加非法 sourceId 后整个批次零提交且已保存旧成果不丢;幂等同 ID 不重复计数,更正旧 finding 保留历史。`work_checkpoint_test.go` 的假 stream 断言工具成功消息说明“转待确认”,仍只有既有最终答复请求;focus/remaining/nextStep 注入无依据决定句会被中性化。
|
||||
|
||||
```go
|
||||
before := card.Task.Revision
|
||||
receipt, err := ctx.PublishWorkCheckpoint(mixedCandidate)
|
||||
if err != nil { t.Fatal(err) }
|
||||
if !strings.Contains(receipt, "待确认") { t.Fatal(receipt) }
|
||||
after, _ := store.GetCard(owner, card.ID)
|
||||
if after.Task.Revision != before+1 || after.Task.Findings[len(after.Task.Findings)-1].Kind != "needs_user" {
|
||||
t.Fatal("mixed batch was not normalized atomically")
|
||||
}
|
||||
```
|
||||
- [ ] **Step 2: 跑 RED。** `cd modules/backend && go test ./internal/runmgr ./internal/runtime -run 'TestWorkCheckpointEvidence|TestMaterialFinalReserve' -count=1`。
|
||||
- [ ] **Step 3: 连接校验与工具说明。** 更新严格 JSON schema 的可选 evidence;将 `WorkCheckpointSink`、`runCtx` 与现有单测调用点一起迁移到 `(string,error)`,使同一 checkpointId 幂等重发也能返回同一安全说明。材料任务提示只说明三种依据及未知归属要转待确认,不重复整份来源索引;工具结果回报归一化原因但不向默认UI暴露 sourceId。完整来源/阶段状态仍由宿主唯一拥有。
|
||||
- [ ] **Step 4: 跑 GREEN 与失败恢复。** `go test ./internal/runmgr ./internal/runtime -count=1`,加 `go test -tags live ./internal/server -run 'TestMechanismSourceExtractionAfterSourceOnce|TestEvaluationStops' -count=1`;离线比对 A01 输入与工具 schema 字符数/估算 token,若最终预留明显不足,停下来重新评审预算策略,不能私自提高额度。
|
||||
- [ ] **Step 5: 提交 Backend。** 精确记录 Core gitlink、新配方版本、RED/GREEN、正常/拒绝路径,不把假 stream 称为模型质量证明。
|
||||
|
||||
### Task 4:组合、真实数据库与既有阅读界面
|
||||
|
||||
**Files:** Update generated `modules/frontend/src/contracts.ts`、`modules/ui/src/contracts.ts` only through `make contracts`;add/adjust `modules/ui/test/progressive-cards.test.tsx` and `modules/frontend/test/work-state.test.ts` if the current behavior is not already covered;update Dev component gitlinks and task card。任何新视觉令牌、页面、store 所有权或公开 TaskSnapshot 字段需求须回设计评审。
|
||||
|
||||
- [ ] **Step 1: 同步后的组件核对。** 复查 Task 1 的权威 main 同步记录和 Core/Backend 分支来源;组件各自与最新权威 main 核对,解决不改变设计的冲突。当前主干已含项目成员相关 Backend/Frontend/Documents 变化,不能用旧 r0.2 组合声称兼容。
|
||||
- [ ] **Step 2: 类型镜像 RED→GREEN。** 固定 Core SHA 后先运行 `make contracts`,用 `git diff --exit-code` 检查生成镜像与 Core 类型一致;该命令预期在两个镜像尚未提交时指出差异,随后按生成结果提交。UI 断言材料记载优先、待核对判断限量、`needs_user` 在“需要留意”默认可见;Frontend 断言刷新/迟到来源响应不抢文件/焦点,旧 seq 丢弃。`cd modules/ui && npm test && npm run typecheck`、`cd modules/frontend && npm test && npm run build`。
|
||||
- [ ] **Step 3: PostgreSQL 与 SQLite。** Backend 全量 `go test ./... -count=1`;用任务自有新数据目录/端口启动隔离 PostgreSQL,`AGENT_PG_TEST_DSN` 仅指向该测试库,运行 `go test ./internal/runmgr ./internal/cardsvc ./internal/store -count=1` 并停止任务进程;来源CAS、混合批次和预算路径须在两档一致。输出经 `make evidence` 记录。
|
||||
- [ ] **Step 4: Dev 组合与真实浏览器。** 组件都提交后推进 gitlink,干净 HEAD 上用 `CMD='make test && make build' make evidence` 捕获完整输出并导入任务卡。启动带 PID/二进制 SHA/数据目录/组件 SHA manifest 的新任务自有 mechanism 实例;`PLAYWRIGHT_BASE_URL`、`WORK_CHECKPOINT_HTTP_MANIFEST` 均从本轮 manifest 验证后传入 `e2e/work-checkpoints.playwright.ts`。用真实 HTTP 验证待确认卡、来源跳转、版本变化、刷新和后台不抢阅读;仅停止本任务进程,保留 trace。
|
||||
- [ ] **Step 5: 独立代码复审与草稿 PR。** 审阅者用准确 Core/Backend/Frontend/UI/Docs/Dev SHA 重放五类 Review Focus;修复 Important 后按影响补测。六个 PR 继续草稿,推送当前 HEAD,核验 Dev `test/test-pg/svc-realcombo`、Backend `vet-and-test`、UI `test` 的受信 runner、SHA、所有必需步骤;Core/Frontend/Documents 无独立工作流时由 Dev 组合 CI 覆盖其 gitlink。真实模型仍 `NOT_RUN`,不合入。
|
||||
|
||||
### Task 5:真实模型质量出口(另行资源审批)
|
||||
|
||||
**Files:** 只在受控评测入口确有缺口时改 `modules/backend/eval/live/work_checkpoints_test.go`/`internal/server/work_checkpoint_eval_test.go`;结果写 Dev 任务卡与 Documents 核验报告。旧 r0.2 A01 的原始 exit0、46,154 Usage 和语义 FAIL 不改写。
|
||||
|
||||
- [ ] **Step 1: 准备可审查、一次性的资源提案。** 固定新 Dev/Backend/UI/Frontend/Docs SHA、同一 A01 材料哈希、受保护路由来源(不输出 key)、新结果文件名、最多 run 数、单 run 与整批**返回 Usage 目标**、输出上限/300秒、缺 Usage/检查点拒绝/超额停止规则;明确在途调用可越过目标,无法凭源码承诺货币硬上限。
|
||||
- [ ] **Step 2: 等待用户明确批准。** 没有新授权则 `NOT_RUN`,六 PR 草稿且不合入;r0.2 的“授权”只覆盖已经执行的一次,不能复用标签或重跑。
|
||||
- [ ] **Step 3: 获批后只运行一次。** 全新隔离数据/manifest/输出,启动前重验 PID、二进制哈希、路由权限、零既有 run;逐调用核对实际 paid run ID、工具次数、Usage、持久阶段窗口、每条原文与逻辑归属、最终正文;任何工具拒绝后不再发 provider 请求。结果与失败用 `make evidence` 原样保存,不补写或重试。
|
||||
- [ ] **Step 4: 独立 REPLAY 与交付裁决。** 两个实质阶段、数字/决定/归属语义、完整最终答复及停止边界全部 PASS 后提交阶段 6/7 产物供人工评审;人工通过后才进入 `policy/delivery.md` 的重新同步、独立代码复审、精确 HEAD CI 和智能体 PR 合入。任一 FAIL 保留真实证据与草稿,修订设计/资源后再单独评审。部署不在本计划范围;合入成功后按已授权的任务卡归档和安全工作区回收规则收尾。
|
||||
@@ -81,6 +81,10 @@ product_contract_source: legacy-requirements
|
||||
|
||||
## 四、文档查找与职责分配
|
||||
|
||||
> 2026-10-15:本节的职责页交互(文档清单加选中详情、章节级入口、整文审签)已被
|
||||
> [文档职责矩阵整改 r2](2026-10-15-rdm-duty-matrix-rework.md) 取代。成员校验、版本冲突、
|
||||
> 在途审签确认和历史保全仍然有效。下文保留作被取代前的记录。
|
||||
|
||||
文档职责页面采用“**文档清单+选中文档的职责详情**”:
|
||||
|
||||
- 上方提供统一搜索框,支持文档 ID 精确检索、标题精确/模糊匹配。
|
||||
@@ -162,9 +166,9 @@ product_contract_source: legacy-requirements
|
||||
| P2 系统设置闭环 | Core 设置描述、Backend 设置 API/存储/生效链/模型及密钥解析;系统管理入口 | P1;**基座发版与 RDM/Dev 升 pins**(见评审补充 1) | 系统受管项只能由有权管理员配置,旧个人/项目值不能覆盖 |
|
||||
| P3 人员与成员接口 | 扩展公开账号搜索;RDM 专业角色摘要、成员查询、项目身份调整与提交校验 | P1;姓名来源核实(见评审补充 3) | 账号/姓名/角色过滤同源,添加与身份调整明确分离 |
|
||||
| P4 文档与职责接口 | 专用文档目录、当前职责读取、统一职责服务、版本校验、变更失效及成员移除联动 | P1、P3 | 跨项目/非成员指派被拒,职责与审签变更全成或全败 |
|
||||
| P5 通用选择器 | UI 仓搜索选择、单/多选、键盘操作、分页与状态;Frontend 人员/文档适配 | P1,接线依赖 P3、P4 | 三类使用场景共享交互,无自由文本误提交 |
|
||||
| P5 通用选择器 | UI 仓搜索选择、单/多选、键盘操作、分页与状态;Frontend 人员适配。文档职责页的文档选择器改由 r2 三视图承接 | P1,接线依赖 P3、P4 | 人员选择共享交互,无自由文本误提交。职责页交互见 r2 |
|
||||
| P6 权限解释与矩阵 | RDM 项目动作目录、单人/批量解释、覆盖三态、来源与拒绝原因 | P1、P3 | 矩阵与执行规则一致,系统动作无法写入项目覆盖 |
|
||||
| P7 项目设置集成 | 重构现有项目页,连接四个页面、能力状态、读取回填与保存结果 | P2—P6 | 创建者、普通成员、职责人员均有对应可用流程 |
|
||||
| P7 项目设置集成 | 重构现有项目页,连接设置、成员与权限页。文档职责页改为 r2 的三视图,不再包含整文审签 | P2—P6 | 创建者、普通成员、职责人员均有对应可用流程。职责页验收以 r2 为准 |
|
||||
| P8 迁移与组合验收 | 旧配置处置、真实数据库与浏览器验收、精确组件组合验证、证据回填 | P2—P7 | 需求到证据闭合,无越权、隐私泄露或数据丢失 |
|
||||
|
||||
前端主要改动落在现有 `ProjectSettingsModal`、`adminRdmSections`、`rdmManagement`、`api` 和 `store`;按业务拆分成员、职责及权限组件,避免继续扩大一个管理组件文件。
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# U3 r0.4:可靠的首条阶段发现与失败收口
|
||||
|
||||
状态:**书面设计待人工评审**。用户于 2026-10-14(Asia/Shanghai)认可“先发布一条有来源的短事实,再按需检索,并补足异常诊断与失败展示”的设计方向;这只授权写本文,不授权实施代码、再次调用付费模型、降低验收条件或合入。关联 [U2/U3 计划](2026-10-13-fast-slow-u2-u3-plan.md)、[r0.3 设计](2026-10-13-fast-slow-u3-r03-evidence-backed-judgments-design.md)及[核验记录](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。
|
||||
|
||||
## 目标、边界与实际失败
|
||||
|
||||
普通用户上传材料后,应先在对话中获得简短即时反馈,再在同一张工作卡上及时看到有原文依据的阶段发现、仍需核对的问题和最终整理结果;失败时应知道已保存了什么、接下来能做什么。沿用三栏工作台、任务卡、现有“材料记载/待核对的判断/待确认”层级和来源展开;不新增默认命令、脚本、模型过程页或确认按钮。
|
||||
|
||||
r0.3 固定 Dev `e31443a8ff1f099f9b2ef320c295b0ddcdaf503d`、Backend `5f834544b0b808cb16214a36725f2ae3cb90bfd4` 的唯一获批 A01 已执行,**质量 FAIL**。快通道及时给出正确的三份材料概览;慢通道先作三次无命中的 `knowledge_search`,第一次 `publish_work_checkpoint` 的参数停在 `"findings": `,没有一条可用阶段发现或最终整理正文。两次付费 run、四次 provider 调用共返回 37,134 Usage tokens;检查点拒绝后没有再发 provider 请求,隔离实例已停止。原件和逐调用、SQLite、SELF 收据在受限归档 `/home/weichen/.local/share/agent-system-evidence/fast-slow-u3-r03-a01-20261014/`,清单哈希在 `archive-manifest.json`。旧 r0.2 的语义 FAIL 和本次 r0.3 的执行 FAIL 分别保留,不相互改判。
|
||||
|
||||
只读重放确认三份附件确已入本次 SQLite 索引;实际“文件名+多个中文关键词”查询在 FTS 和整串 LIKE 兜底均零命中,单独文件名各命中一条。另用合成 SSE 证明:当前 Agent-Native 解析器在 `finish_reason=tool_calls` 却缺 `[DONE]` 时仍可能放行半截工具参数。**本次未保存服务商原始 SSE,不能断定该机制就是 A01 参数截断的来源。**本次生成的失败通知还在无可用整理结果时要求交付物选择;评测关闭了通知模型回合,因此不能声称浏览器实际发出了选择卡。
|
||||
|
||||
## 方案取舍
|
||||
|
||||
| 路线 | 能解决的事 | 不足 | 结论 |
|
||||
|---|---|---|---|
|
||||
| 原样再跑同一候选 | 检查一次是否偶发 | 已批准额度耗尽;即使通过,也不修复已证实的流终态和失败通知缺口 | 不选 |
|
||||
| 工具调用出错后自动请求模型修补 | 可能挽救一次格式错误 | 增加付费回合和延迟,可能让来源错误绕过停止规则,违背本轮“无额外模型调用”边界 | 不选 |
|
||||
| **首条短事实优先+材料范围内的检索兜底+流终态守卫+状态感知通知** | 同时改善阶段可见性、来源检索和失败诚实性;保持模型调用边界 | 涉及 Agent-Native 与 Backend 的跨组件验证,模型是否遵循顺序仍须真实样本判定 | 推荐 |
|
||||
|
||||
## 用户可见行为
|
||||
|
||||
当已内联的材料含有可直接引用的实质事实,慢通道第一轮先尝试发布 **一条** `reading` 阶段 `material_record`:短句、原文连续引文、当前材料的 sourceId 与 blockIndex;先落到现有任务卡,再做可选检索和跨文档核对。它不是“已收到文件”或工作过程,也不得把日期、预算审批、分期归属等推断装成材料原句。第二条及之后只发布新增的、不同的核对结果;r0.3 的数字、归属、决定状态及来源校验原样保留。材料无可用原文时不强凑首条;模型未遵循顺序时如实记录,不能由宿主捏造一条发现来满足计数。
|
||||
|
||||
仅在已内联片段不足以完成当前工作时,慢通道调用现有 `knowledge_search`。材料子任务应先用**精确文件名**定位被截断的附件;如果模型仍把唯一附件文件名和关键词混成一个查询且常规检索无命中,宿主只在本任务已登记的附件集合中做一次同工具调用内的精确文件名兜底。兜底结果必须同时匹配 owner、project、附件 artifactId/ref 和本次输入版本;可从当前任务的解析快照证明版本,无法证明时就保持无命中。重名或多个匹配不猜,索引/原件版本不一致不返回旧内容。它不扩大通用知识检索的可见范围,兜底本身也不增加 provider 回合;返回内容仍按现有工具结果大小限制处理,检查点引用仍经原件与连续短引校验。首条检查点改为优先发布可能改变既有工具驱动回合的实际时序和总数,但不引入独立摘要、审核或自动修复模型;仍受每 run 的轮数、工具数、时间及 Usage 边界约束,必须在真实样本中逐调用核对。
|
||||
|
||||
任务失败时,工作卡保留已原子提交的旧阶段发现,并明确标注“整理未完成”和未完成范围;若从未保存阶段发现,就明确说没有可用整理结果。此时对话只给出简短恢复说明,**不**从不存在的“建议后续处理”生成交付物选择卡,也不使用默认四选项兜底。只有成功终态且有可用整理结论与实际建议时,才允许既有 `confirm_choice` 流程;成功但没有可用建议时请用户说明下一步目标,不伪造建议。通知和终轮兜底应读取宿主终态/成果可用性,不以“材料整理已结束”字面串代替成功判断。
|
||||
|
||||
## 组件职责与安全契约
|
||||
|
||||
**Agent-Native 流边界。** OpenAI 兼容 SSE 的工具调用在终态完整性得到证明前不进入执行层:需要受支持的正常结束原因、完整终止信号和每个工具调用的非空 ID/名称、合法且为对象的 JSON 参数。缺 `[DONE]`、参数不完整、流解码失败或结束原因表明截断时,返回**不可自动重试**的失败;已经返回的 Usage 仍纳入本次 run 和整批预算,后续 provider 请求被阻断。具体事件形状须在实施计划中与现有 `consume`/runner 的 Usage 累加契约一起固定,不得只丢弃 tool call 后把空正文误报为成功。普通无工具文本、合法多片工具调用与现有供应商兼容路径不能因守卫回退。仅保存诊断元数据(run ID、调用序号、结束原因、是否完整终止、参数长度/哈希与 JSON 有效性、Usage 是否存在),不记录原始 SSE、密钥或额外完整提示词。
|
||||
|
||||
**Backend 材料任务。** 在 `buildMaterialTaskFor` 的 r0.3 来源语义守卫之上,收敛首批发布指令,先一条短事实、再核对差异;材料配方从 v10 递增到 v11,防止旧完成任务以新规则复用。材料范围内的检索兜底沿 `runCtx.Retrieve`/工具授权链执行,不接受客户端指定 artifactId 作为权限证明。`publish_work_checkpoint` 的来源登记、原件 hash/解析版本、CAS 一次提交、幂等与更正历史保持不变。失败通知从持久终态和可用成果判断;无成果时不触发 `confirm_choice` 或其 stop 兜底,不静默重复派发整理任务。
|
||||
|
||||
**Frontend/UI。** 先复用现有卡片状态和失败文案、来源展开、刷新和文件预览;只有实际浏览器验证证明现有表述无法解释“部分成果已保存/没有成果”时,才在同一张卡上做最小文案调整,仍消费 `DESIGN.md` 与 UI 令牌、`@ui` 原语。异步卡片与对话仍各有单一状态所有者,按 seq 丢弃过期事件,不抢文件、输入焦点和阅读位置。没有新的页面、弹窗或模型内部日志。
|
||||
|
||||
Core 的可选 evidence 契约和 TaskSnapshot 持久字段不变;无数据库迁移、生产模型路由或预算放宽。流守卫若落在独立的 Agent-Native 仓,将在现有六个草稿 PR 之外增加该组件的 PR,并由 Backend 更新其固定 gitlink、Dev 再固定 Backend;不能只改 Backend 的嵌套检出后声明已交付。Documents 与 Dev 的记录也各按本仓任务分支提交、推送和组合验证;设计审批不等于合入授权或已通过模型验收。
|
||||
|
||||
## 失败恢复、验证与交付门槛
|
||||
|
||||
零付费先证明失败和正常路径:
|
||||
|
||||
1. 合成流覆盖 `tool_calls` 有结束原因却无 `[DONE]`、有 `[DONE]` 却参数不完整、`length` 截断、合法多片参数、正常纯文本;逐例断言是否执行工具、错误是否不可自动重试、已返回 Usage 是否保留。不得把坏 JSON 自动补全后调用工具。
|
||||
2. SQLite/PostgreSQL 的材料检索覆盖本次三条“文件名+关键词”原查询、单文件名、重名、跨 owner/project、artifactId 不匹配和输入版本漂移;断言兜底只在本任务唯一附件内命中,同一次工具调用内完成且不泄露其他资料。
|
||||
3. 假流和真实 HTTP 覆盖首条有用 `reading` 检查点先于可选检索、第二批不同 `crosscheck` 发现、无实质原文时不凑数、非法来源/数字关系整批拒绝、旧成果保留。失败通知和终轮兜底均不得在无可用建议时发选择卡;成功且有建议仍走原确认链。
|
||||
4. 浏览器覆盖运行中阶段卡、失败零成果、失败有部分成果、成功交付、刷新和来源版本变化;默认界面只给用户行动所需信息,后台不抢阅读。执行组件测试、Dev `make test && make build`、独立代码复审及当前 HEAD 平台 CI,收据与 SHA 分别标 SELF/REPLAY/GATE。
|
||||
|
||||
真实模型质量仍使用同一 A01 合成材料:至少两个真正有用、终态前可感知的不同阶段成果,完整最终正文,六月计划与七月评审意见、50 万元预算及审批状态、总 12/第一期 8/接口依赖 3 项的关系与验收缺项均准确;无法证明接口项属于哪一期时标待确认。逐调用核对实际 run ID、工具数、返回 Usage 与停止规则。**新付费样本必须在本设计及实施计划分别获批、零付费候选固定后单独提交资源提案;不沿用 r0.3 已用完的授权。**任何质量失败或安全门禁失败,相关 PR 保持草稿,不合入或部署。
|
||||
|
||||
## 已知风险与待评审取舍
|
||||
|
||||
首条短事实能减小工具参数负担,但不能保证模型一定按顺序调用,亦不能证明本次 A01 的半截参数来自服务商而非流适配。要求完整流终态可能暴露某供应商的非标准结束行为;若发现这种事实,须先提出受限、可重放的等价终态定义,经评审后处理,不静默放宽守卫。材料精确文件名兜底可能取回比关键词检索更多的同附件文本,必须有既有结果大小与来源限制。若这些取舍不可接受,需要重新评估增加模型纠错回合或人工恢复的成本;当前版本不预授权两者。
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
# U3 r0.4 Reliable First Checkpoint Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 上传材料后先产生一条真实、有来源的阶段事实;材料检索、模型工具流和失败通知均按可复核边界工作,使慢通道能够逐步帮助普通用户而不展示内部过程。
|
||||
|
||||
**Architecture:** Agent-Native 在流终态阻断不完整工具调用并保留已返回 Usage;Backend 从本任务附件快照提供受限检索兜底,收敛材料任务的首批发布顺序,并以实际终态和可用建议决定是否发交付物选择卡。沿用 r0.3 的 TaskSnapshot、来源与语义守卫、同一张卡和现有 UI 原语。
|
||||
|
||||
**Tech Stack:** Go 1.27、SQLite/PostgreSQL、Agent-Native SSE/runtime、Backend runmgr/runtime、React/Vite/Playwright、Dev `make test`/`make build` 与 Gitea CI。
|
||||
|
||||
**Spec:** [已批准的 r0.4 书面设计](2026-10-14-fast-slow-u3-r04-reliable-first-checkpoint-design.md),Documents `7b21e6d495e99e15c458d608db47c517b2fdc599`;[r0.3 A01 失败记录](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。本计划版本仍待阶段 5 人工批准;设计批准不授权代码或新付费模型请求。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 保留 r0.3 的来源原文连续短引、owner/project、artifact hash/解析版本、数字/分期/决定状态守卫和 CAS;旧结果不追溯改写。Core 候选契约、TaskSnapshot 持久字段、数据库表和生产模型路由不变。
|
||||
- 只沿现有三栏、同一张任务卡和“材料记载/待核对的判断/待确认”分层呈现;默认不展示模型调用、命令或原始 SSE。UI 变更先读 Dev `DESIGN.md`,只用 `@ui` 令牌与原语,事件按 seq 丢弃过期项。
|
||||
- 不增加独立摘要、审核或自动修复模型;自然工具回合仍受每 run 的轮数、工具数、300 秒及返回 Usage 边界约束。工具拒绝、缺 Usage 或额度耗尽后不得追加 provider 请求。新付费 A01 必须单独审批,不沿用 r0.3 的额度或标签。
|
||||
- 旧 r0.2 语义 FAIL 与 r0.3 执行 FAIL 保留。新 A01 仍须两个真正有用、终态前可感知的不同阶段成果和完整准确正文;来源字面匹配、单测、假流或绿色 CI 均不能代替这项真实模型质量出口。
|
||||
- Agent-Native、Backend、Documents、Dev 各在自己的任务分支提交;不要直接编辑 Backend 内嵌的 detached Agent-Native 后把本地文件当已交付。新 Agent-Native PR 是现有六个草稿 PR 的依赖,固定指针和合入顺序为 Agent-Native → Backend → Dev。
|
||||
- 启动/恢复、`make evidence`、`task-sync`、Review、当前 HEAD CI、阶段 6/7 人工结论和安全回收遵循 Dev `AGENTS.md` 与 `policy/delivery.md`。本计划只申请零付费实施与验证;不得从计划批准推导新模型资源或部署授权。
|
||||
|
||||
## Review Focus
|
||||
|
||||
1. **看似正常的 `tool_calls` 结束原因但没有 `[DONE]`:** 不得执行任何工具,返回不可自动重试的失败,已返回 Usage 仍计入预算。Task 1 的 `TestParseSSEToolFinishWithoutDone` 和 `TestRunTerminalToolFailureKeepsUsage` 钉住。
|
||||
2. **同名附件或其他 owner/project 的知识命中:** 文件名兜底必须拒绝歧义和越界,不将其他人的材料带入当前任务。Task 2 的 `TestMaterialAttachmentFallbackScope` 钉住。
|
||||
3. **本次附件注册后原件被替换:** 同 artifactId 的旧解析快照和索引不得继续供模型读取。Task 2 的 `TestMaterialAttachmentFallbackVersionDrift` 钉住。
|
||||
4. **后台失败但旧阶段发现已保存:** 卡保留已验证发现并明确未完成,不出现“全部完成”或交付物选择卡。Task 4 的 `TestFailedMaterialNoticeKeepsPartialFindingsWithoutChoice` 钉住。
|
||||
5. **后台成功但没有实际建议项:** 不生成默认四选项,也不触发弱模型选择卡兜底;让用户自由说明下一步。Task 4 的 `TestMaterialNoticeWithoutSuggestionsDoesNotNudge` 钉住。
|
||||
|
||||
## 文件与交付顺序
|
||||
|
||||
| 单元 | 主要文件(均相对于对应组件仓根目录) | 单一职责与可独立验证的产物 |
|
||||
|---|---|---|
|
||||
| Agent-Native 流终态 | `runtime/llm/{types,sse,sse_test}.go`、`runtime/{loop,loop_test}.go` | 完整工具调用才可执行;错误保留 Usage、不可自动重试。单独 Agent-Native PR。 |
|
||||
| Backend 材料检索 | `internal/runmgr/{runmgr,material_retrieve,material_retrieve_test}.go` | 仅本次材料子任务从唯一附件快照兜底,拒绝歧义、越权和版本漂移。 |
|
||||
| Backend 首条发布 | `internal/runmgr/{material,material_test}.go`、`internal/runtime/{work_checkpoint,work_checkpoint_test}.go` | v11 配方和一条短事实优先;不伪造发现、不增加独立模型回合。 |
|
||||
| Backend 失败交互 | `internal/runmgr/{runmgr,material_test}.go`、`internal/runtime/{verify,llm_direct,material_flow_test}.go` | 成功且有实际建议才发选择卡;失败和无建议不强制选择。 |
|
||||
| Backend 评测与组合 | `internal/server/{work_checkpoint_eval_test,work_checkpoint_eval_budget_test}.go`、`eval/live/work_checkpoints_test.go`、`modules/frontend/e2e/work-checkpoints.playwright.ts`(从 Dev 根目录) | 诊断元数据、预算停止、实际 HTTP/浏览器和固定组合证据。 |
|
||||
|
||||
以上单元紧扣同一材料整理链路,接口按表格顺序依赖;暂不拆成互不关联的新项目。UI 仅在实际浏览器证明现有失败文案不足时修改 Frontend/UI,届时在同一任务卡记录影响并重跑各自设计守护;不预设新增组件。
|
||||
|
||||
### Task 1: Agent-Native 完整工具终态与 Usage
|
||||
|
||||
**Files:** Agent-Native `runtime/llm/types.go`、`runtime/llm/sse.go:53-180`、`runtime/llm/sse_test.go:65-155`、`runtime/loop.go:320-360`、`runtime/loop_test.go`。
|
||||
|
||||
**Interfaces:** 扩展内部 `llm.Event` 的 `StreamComplete bool`;对不完整工具调用发一个含 `Usage`、`StopReason=StopError`、非空 `Err` 且无 `ToolCalls` 的 `KindMessageEnd`。`runtime.Run` 计入该终态已返回 Usage 后以不可重试错误结束;Backend 既有逐调用 wrapper 仍能从 `KindMessageEnd` 计量。普通文本和合法完整工具调用保持原行为。
|
||||
|
||||
- [ ] **Step 1: 建 Agent-Native 隔离分支并写 RED。** 从其权威 `origin/main` 建 `feature/fast-slow-u3-r04-stream-guard`(不要在 Backend 的 detached gitlink 上写);在 `sse_test.go` 增加两例:`tool_calls` 结束但无 `[DONE]`,及有 `[DONE]` 但参数停在 `"findings": `。使用与既有 `TestParseSSEToolCallIncrements` 相同的 SSE 输入写法,断言:
|
||||
|
||||
```go
|
||||
if end.Kind != KindMessageEnd || end.Message.StopReason != StopError ||
|
||||
len(end.Message.ToolCalls) != 0 || end.Err == nil || end.Retryable ||
|
||||
end.Usage.TotalTokens != 17 {
|
||||
t.Fatalf("unsafe incomplete terminal: %#v", end)
|
||||
}
|
||||
```
|
||||
|
||||
同时在 `loop_test.go` 用假 stream 发上述错误终态(Usage 17),工具处理器计数必须为 0,`res.Err != nil`、`res.Usage.TotalTokens == 17`、没有第二次 provider 调用。
|
||||
|
||||
- [ ] **Step 2: 重放 RED。** 在 Agent-Native 根运行 `GOWORK=off go test ./runtime/llm ./runtime -run 'TestParseSSEToolFinishWithoutDone|TestParseSSEInvalidToolArguments|TestRunTerminalToolFailureKeepsUsage' -count=1`;记录预期失败的原始 SELF 收据,不能把旧 `TestParseSSEUncleanEndDropsToolCall` 当作已覆盖 `finish_reason=tool_calls` 的情况。
|
||||
|
||||
- [ ] **Step 3: 最小 GREEN。** 在 `emitParsed` 拼完工具片段后要求 `sawDone`、受支持结束原因、每个非空 ID/名称及可解为 JSON 对象的参数;不完整时构造错误终态,不修补参数。实现形状:
|
||||
|
||||
```go
|
||||
func terminalToolFailure(content string, usage Usage, reason string, complete bool, why string) Event {
|
||||
err := &StreamError{Message: why, Retryable: false}
|
||||
return Event{Kind: KindMessageEnd, Message: Message{Role: RoleAssistant,
|
||||
Content: content, StopReason: StopError}, Usage: usage,
|
||||
FinishReason: reason, StreamComplete: complete, Err: err,
|
||||
ErrorMessage: why, Retryable: false}
|
||||
}
|
||||
```
|
||||
|
||||
`runtime.Run` 在现有 Usage 累加之后、工具执行与 stop-hook 之前,遇 `end.Err != nil` 即返回 `Result{StopReason: llm.StopError, Usage: usage, Err: end.Err, Retryable: false}`;更新与新语义相冲突的旧 `length`/断流测试预期。`KindToolCallDelta` 可以作为过程事件,但不得据此执行工具。
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN 与正常回归。** 运行定向测试、`GOWORK=off go vet ./...`、`GOWORK=off go test -count=1 ./...`,另断言合法多片工具调用和无工具正常文本仍 PASS。用 `make evidence` 保存完整 SELF 输出;审阅返回 Usage 的终态错误不会被上层误报为成功,也不会触发 LLM 自动重试。
|
||||
|
||||
- [ ] **Step 5: 提交并开草稿 PR。** 仅提交本任务 Agent-Native 文件;英文祈使句主题、`Why/Evidence/Impact/Refs` body。推送该组件分支并记录准确 SHA 和草稿 PR,不修改其 `main` 或发布版本。
|
||||
|
||||
### Task 2: Backend 只读、限域的附件检索兜底
|
||||
|
||||
**Files:** Backend `internal/runmgr/runmgr.go:966-1018`;新建 `internal/runmgr/material_retrieve.go`、`internal/runmgr/material_retrieve_test.go`;必要时复用 `task_projection.go:358-370` 的原件 hash 检查。
|
||||
|
||||
**Interfaces:** `func (c *runCtx) materialAttachmentFallback(q core.RetrievalQuery) ([]core.RetrievalHit, error)` 仅在 `c.subAgent == materialSubagentID`、正常检索成功但零命中时调用;消耗 `c.attachments`(`startBackgroundSlot` 已从受信 `bgSpawnOpts.documents` 固定),不得从客户端 query 中取 artifactId 作权限。返回的每条 hit 的 `Doc.Ref` 必须等于当前任务唯一附件 artifactId。
|
||||
|
||||
- [ ] **Step 1: 写 RED 与版本负例。** 用 `newCardSpawnEnv`、`materialDocs()` 及真实 SQLite knowledge/artifact fixture,让本次 A01 的 `需求.txt 上线 预算 验收 接口` 在当前常规路径零命中,而兜底应找到当前任务的 `需求.txt`;重复文件名、另一 owner/project、同 ID 原件内容修改和 `Task.Inputs` 中 hash/解析版本不匹配时,兜底必须零命中或返回不含旧正文的明确错误。核心断言:
|
||||
|
||||
```go
|
||||
if len(got) != 1 || got[0].Doc.Ref != string(docs[0].Meta.Origin.ArtifactID) ||
|
||||
got[0].Doc.ProjectID != rc.run.ProjectID ||
|
||||
got[0].Doc.Owner != rc.run.Owner {
|
||||
t.Fatal("material fallback crossed the task boundary")
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 重放 RED。** `go test ./internal/runmgr -run 'TestMaterialAttachmentFallbackScope|TestMaterialAttachmentFallbackVersionDrift|TestMaterialAttachmentFallbackQuery' -count=1`,记录每例失败原因,不用未授权共享知识充当正例。
|
||||
|
||||
- [ ] **Step 3: 实现受限兜底。** 从 `q.Text` 识别**恰好一个**当前附件文件名;核对该 origin artifactId/hash/解析版本与 `card.Task.Inputs`;经 `GetArtifact(owner,id)`、`ArtifactContent(owner,id)` 和项目 ID/sha256 再读确认后,从本次 `ParsedDocument` 快照构造有限 `RetrievalHit`(`Source=upload`、`Ref=artifactId`)。若查询有其余词,优先返回包含这些词的有界原文片段;仅文件名时返回尚未内联的部分或当前文档的有限原文,最多遵守现有 `MaxToolResultChars`。在 `runCtx.Retrieve` 的正常结果为零、错误为 nil 时调用:
|
||||
|
||||
```go
|
||||
if err == nil && len(hits) == 0 && c.subAgent == materialSubagentID {
|
||||
return c.materialAttachmentFallback(q)
|
||||
}
|
||||
return hits, err
|
||||
```
|
||||
|
||||
不得改变通用检索的 FTS/LIKE、共享授权或其他子代理结果;重名和版本证明失败时 fail closed,不猜测最相近文件。
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN、权限与存储回归。** 运行上述三例、`go test ./internal/runmgr ./internal/store -count=1`,再在任务自有 PostgreSQL 上重放材料兜底与权限负例;相同文档多段、中文关键词和超长结果必须保持有限输出。记录被测 Backend SHA、数据库实例及 SELF 收据。
|
||||
|
||||
- [ ] **Step 5: 提交 Backend 检索单元。** 只提交本任务文件并核对 `git diff --check`;此时仍未改变阶段提示或失败交互,单元测试可独立审阅。
|
||||
|
||||
### Task 3: 首条有来源事实优先,配方 v11
|
||||
|
||||
**Files:** Backend `internal/runmgr/material.go:88-132,286-303`、`internal/runmgr/material_sources.go:144`、`internal/runmgr/material_test.go`、`internal/runtime/work_checkpoint_test.go`。
|
||||
|
||||
**Interfaces:** 不改 `WorkCheckpointCandidate` 或 `publish_work_checkpoint` JSON 契约。`buildMaterialTaskFor` 在已有实质内联片段时要求首个 `reading` 工具调用只含一条 `material_record`、当前 `sourceId/blockIndex/quote`;第二阶段沿 r0.3 evidence 守卫产生新的差异/待确认。材料输入修订从 `material-recipe.v10` 改为 `material-recipe.v11`,旧完成卡只读保留。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** `material_test.go` 用三份完整内联 A01 和一份空/不可读材料分别断言:前者任务指令明确“首条一项短事实、先于检索”;后者不要求凑发现。`work_checkpoint_test.go` 的假流先发布原文事实、再可选检索、后发布不同的 crosscheck 条目,核对运行中卡片 seq、两批不同 findingKey/来源及最终正文;再用无效 sourceId 断言整批零提交。关键检查形状:
|
||||
|
||||
```go
|
||||
if first.Task.CheckpointSeq != 1 || second.Task.CheckpointSeq != 2 ||
|
||||
first.Task.Findings[0].Kind != "material_record" ||
|
||||
second.Task.Findings[1].Kind != "needs_user" {
|
||||
t.Fatal("reading and crosscheck did not remain distinct")
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 重放 RED。** `go test ./internal/runmgr ./internal/runtime -run 'TestMaterialFirstFindingBeforeOptionalSearch|TestMaterialNoForcedFindingWithoutSource|TestWorkCheckpointTwoUsefulPhases' -count=1`。如果假流只证明宿主接受顺序、无法证明真实模型会遵循,明确在任务卡标“机制 PASS / 模型 NOT_RUN”。
|
||||
|
||||
- [ ] **Step 3: 最小 GREEN。** 把材料任务的首条指令放在长篇最终正文要求之前,避免模型先写完整计划或做已提供材料的冗余检索;提示只要求一条已提供原文短引,不复制全部来源索引或增加新工具。实现形状:
|
||||
|
||||
```go
|
||||
task = "先从已提供的实质原文发布一条 reading 材料记载:只写一项,附当前 sourceId、blockIndex 和连续短引;发布成功后再按需检索、核对差异和形成完整正文。\n\n" + task
|
||||
```
|
||||
|
||||
空文本或只有处理警告时不追加强制首条要求;将配方常量更新到 v11。Host 不凭规则自行合成内容,模型未按顺序调用时如实失败或继续原有受控流程。
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN 与预算体积检查。** 运行前述定向测试和 Backend `go test ./... -count=1`;离线比对 v10/v11 任务提示及工具 schema UTF-8 字节和粗估 token 增量,不能将粗估当真实 Usage。补测旧 r0.3 数字、决定、来源及 CAS 回归。
|
||||
|
||||
- [ ] **Step 5: 提交 Backend 首条发布单元。** 仅提交提示、配方与相关测试,记录“优先顺序不等于模型质量保证”的限制。
|
||||
|
||||
### Task 4: 失败通知按终态与建议可用性分流
|
||||
|
||||
**Files:** Backend `internal/runmgr/runmgr.go:2254-2400`、`internal/runmgr/material_test.go:198-230`、`internal/runtime/verify.go:34-44`、`internal/runtime/llm_direct.go:148-161,634-648`、`internal/runtime/material_flow_test.go:146-225`。
|
||||
|
||||
**Interfaces:** `materialChoiceReady(bgNotice, core.ActivityCard) bool` 仅在 `material && Status==completed`、任务卡确有可用最终正文且正文“建议后续处理”包含 3–4 条带依据的真实选项时为真。只有该路径加入新的内部 `materialChoiceReadyMarker` 并开启 stop 兜底;失败、取消、零成果及成功但无建议时只投递状态/恢复说明,保留已经持久化的旧发现,不出现默认四选项。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 扩展 `TestMaterialNoticeContract`:失败零成果、失败但卡已有一条合法 finding、取消、完成但无建议、完成且有 3 条建议。前四种系统提醒均不得含 `confirm_choice`/ready marker;第五种仍含两者。`material_flow_test.go` 加失败及无建议通知回合,断言不会产生 HITL 或 `materialNoticeBackstopReason`,成功有建议仍生成选择卡。
|
||||
|
||||
- [ ] **Step 2: 重放 RED。** `go test ./internal/runmgr ./internal/runtime -run 'TestMaterialNoticeContract|TestFailedMaterialNoticeKeepsPartialFindingsWithoutChoice|TestMaterialNoticeWithoutSuggestionsDoesNotNudge|TestMaterialNoticeChoiceChain' -count=1`;保存失败原件。
|
||||
|
||||
- [ ] **Step 3: 最小 GREEN。** 从 `bgNotice.payload.Status`、任务卡 `Task.OutcomeCompleteness`/结果和正文里的实际建议列表判断选择资格;只接受“建议后续处理”标题下 3–4 个非空选项,每项有材料依据文本。保守解析失败时提示用户自行说明目标,不生成虚构选项。`verify.go` 用与“已结束”不同的内部 ready marker;`llm_direct.go` 只按该 marker 设置 `st.materialNotice`。实现门槛示意:
|
||||
|
||||
```go
|
||||
func materialChoiceReady(n bgNotice, card core.ActivityCard) bool {
|
||||
return n.material && n.payload.Status == core.RunCompleted &&
|
||||
card.Task != nil && card.Task.OutcomeCompleteness == "complete" &&
|
||||
len(parseMaterialSuggestions(n.payload.Text)) >= 3
|
||||
}
|
||||
```
|
||||
|
||||
若当前 Task 的实际完成枚举或结果落点不同,以 `core.TaskSnapshot` 的现有定义修正该判断并在同一测试证明;不要硬编码“状态:completed”字符串。通知正文和终轮兜底保持一致,失败时不再要求 `delegate_task` 基于不存在的建议启动工作。
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN。** 重跑定向测试、`go test ./internal/runmgr ./internal/runtime ./internal/cardsvc -count=1` 和正常完成链;检查旧阶段发现/失败终态的持久事件没有被新通知写成成功。所有结果由 `make evidence` 写入任务卡。
|
||||
|
||||
- [ ] **Step 5: 提交 Backend 失败交互单元。** 只提交相关文件和测试,通知文字使用普通用户能理解的状态,不输出 tool/JSON/Usage 细节。
|
||||
|
||||
### Task 5: 评测诊断与停止规则零付费重放
|
||||
|
||||
**Files:** Backend `internal/server/work_checkpoint_eval_test.go:347-455`、`internal/server/work_checkpoint_eval_budget_test.go:201-300`、`eval/live/work_checkpoints_test.go:146-295`;Agent-Native `runtime/llm/types.go` 提供 Task 1 的 `StreamComplete`。
|
||||
|
||||
**Interfaces:** 评测逐调用记录增加 `finishReason`、`streamComplete`、`toolArgumentBytes`、`toolArgumentsValid` 和 `usagePresent`;原有 run ID、调用数、reported Usage、输出上限保留。诊断字段不含 API key 或原始 SSE;`KindMessageEnd` 的错误终态仍计入 Usage,任一检查点拒绝或缺 Usage 后零后继 provider 请求。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 用本地 `httptest` SSE 服务分别发送“合法工具调用”“有 `tool_calls`、已返回 Usage、缺 `[DONE]`”“有 `[DONE]` 但参数半截”“无 Usage”四种结果;每次从全新隔离 SQLite 和 0 个既有 run 开始。断言坏结果后第二次请求没有到达服务端、记录 Usage 如实、`toolArgumentsValid=false`、结果卡为失败。不得调用外部模型。
|
||||
|
||||
- [ ] **Step 2: 重放 RED。** 在 Backend 根运行 `go test -tags live ./internal/server -run 'TestEvaluationStopsAfterMalformedToolTerminal|TestEvaluationKeepsUsageOnTerminalFailure' -count=1`;在 `eval/live` 用 `go test -tags live ./eval/live -run 'TestFollowupA01KeepsItsOwnOneShotResult|TestPersistedRunningCheckpointMaxDoesNotMissShortWindow' -count=1` 保留既有零付费结果名与窗口回归。`TestWorkCheckpoints` 必须保持 `NOT_RUN`,此步不提供模型实例或路由。
|
||||
|
||||
- [ ] **Step 3: 最小 GREEN。** 从 Task 1 的终态字段和每个 `ToolCall.Arguments` 的 `json.Valid` 生成诊断布尔值;错误终态的 `Usage` 必须先进入 `reportedTokens` 与 provider record,再向 runner 发出非重试失败。评测 wrapper 增加批次级 `terminalFault`,遇此错误后与 `checkpointRejected`/`usageUnknown` 一样拒绝所有后继 provider 请求;即使直接再次调用 stream,也只返回本地错误。不要把失败伪装成正常 `message_end` 或用下一轮模型修补参数。
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN 与上限。** 运行上述 live-tag 假 provider 集及 `go test ./internal/server -count=1`;`eval/live` 只用上述 `-tags live -run` 选择零付费用例,避免无 manifest 时误执行 `TestWorkCheckpoints`。核对每 run 30,000 配置、8轮/12工具/300秒、单次输出4,000、整批返回 Usage 停止目标的既有逻辑未变。对失败和正常路径分别保存 SELF 收据。
|
||||
|
||||
- [ ] **Step 5: 提交 Backend 评测单元。** 记录新诊断只证明机制,不能把旧 r0.3 A01 或未运行的 r0.4 模型质量改判。
|
||||
|
||||
### Task 6: 固定组合、真实浏览器、复审与资源出口
|
||||
|
||||
**Files:** Dev `modules/backend`、`modules/documents` gitlink、`.task/feature-fast-slow-u2-u3-plan.md`、`PROJECT.md`;Backend `deps/agent-native` gitlink;视需要 Frontend `e2e/work-checkpoints.playwright.ts`(若 UI 确需文字调整,再列明 Frontend/UI 文件和设计守护)。
|
||||
|
||||
**Interfaces:** 对外的 TaskSnapshot、卡片事件 seq 和来源跳转保持现有契约。各组件分支自己的 commit/PR 是唯一交付对象;Dev 组合 pin 明确 Core、Backend、Frontend、UI、Documents、嵌套 Agent-Native 的 SHA。
|
||||
|
||||
- [ ] **Step 1: 固定依赖与 RED/GREEN 组合。** 先把 Agent-Native 草稿 PR 的准确 SHA 固定进 Backend gitlink,在 Backend 跑 `GOWORK=off go test ./...`;提交/推送 Backend。Dev 再固定 Backend 与已批准计划 Documents SHA,跑 `RECEIPT=/tmp/fast-slow-u3-r04-20261014-combo-implementation.json CMD='make test && make build' make evidence`(该路径必须尚不存在;若已占用,选新的带序号绝对路径,绝不覆盖),导入原始收据并提交/推送 Dev gitlink。任何 pin 漂移、活动 Git 锁或其他工作区未保存内容均停止,不强删锁或覆盖。
|
||||
|
||||
- [ ] **Step 2: PG 与 HTTP/浏览器。** 启动**本任务独有** PostgreSQL 和 HTTP 假流实例;manifest 记录 PID、二进制 SHA、Dev/Backend/Agent-Native SHA 与数据目录,测试前验证绑定。PG 重放 runmgr/cardsvc/store;`PLAYWRIGHT_BASE_URL` 指向受验 manifest 的本地地址后运行 `e2e/work-checkpoints.playwright.ts`,覆盖两次 running 阶段、零成果失败、部分成果失败、成功建议选择、刷新和来源版本变化、后台不抢文件/焦点。只停止任务自有进程并保留 trace。
|
||||
|
||||
- [ ] **Step 3: 独立 Review 与正式固定。** 在请求审核前、验收前及合入前分别按 Dev `AGENTS.md` 用 `CMD='make task-sync' make evidence` 同步最新权威 main;同步改变 base/head 或组件时按影响重跑组合、PG、浏览器和代码复审。独立审阅者对 Agent-Native 流边界、检索权限/版本、成功/失败通知、预算停止、UI 状态投影和计划范围作最小重放;不能把作者 SELF 升格为 REPLAY。Dev 当前 HEAD 的 `test`、`test-pg`、`svc-realcombo` 与 Agent-Native/Backend/适用 UI 的必需 CI 必须核对实际 SHA、runner 和所有步骤。
|
||||
|
||||
- [ ] **Step 4: 阶段 6 与模型资源分开审阅。** 将零付费候选、独立 Review、精确 HEAD CI 和实际浏览器结果交用户确认阶段 6;只有候选固定且用户另行批准一次性资源提案后,才能用原 A01 材料、受保护路由、全新 0-run 数据目录和独立输出名运行真实模型。提案必须列明最多付费 run、单 run token/轮/工具/时间、批次返回 Usage 目标、输出 cap、在途超额风险、停止规则及不自动重试;**本计划不预填或授权新的用量数字**。
|
||||
|
||||
- [ ] **Step 5: 依据真实结果决策。** 只读重放 SQLite、逐调用 Usage、运行中卡片窗口、每条短引及逻辑归属、完整正文;任何 FAIL 保留所有相关 PR 草稿,不自动重跑或合入。质量 PASS 后仍须阶段 7 人工验收,随后按 Dev 策略完成 Agent-Native → Backend → 其他组件 → Dev 的独立 Review、准确 HEAD CI、串行 PR 合入、合入后内容核验、任务卡闭合和安全回收;未获阶段结论时写 NOT_RUN,不能提前标完成。
|
||||
|
||||
## 计划自检与停止条件
|
||||
|
||||
每个实现单元的 RED、GREEN、独立审阅、失败原件和版本都进入同一 Dev 任务主记录;Documents 设计/计划仅作引用,不复制第二份状态。局部代码修复若只改变等价实现,在已批准阶段内按影响补测;若改变工具公开契约、权限、模型调用数/预算、阶段验收条件或组件职责,回到设计/计划人工评审。真实模型样本一旦缺 Usage、检查点拒绝、预算停、输出不完整或语义错误,停止后续请求,保留原件并报告,不通过“再试一次”抹平失败。计划获批后才开始 Task 1;目前 Task 1–6 均 **NOT_RUN**。
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
# U3 r0.5:安全终态证据与可信快通道反馈
|
||||
|
||||
状态:**书面设计已获人工评审通过**。批准对象为 Documents `0d473fe866703eab32f715ddf12d1b25913b822b`、Dev `c7ff687c1de6911b43163433bc19e4e55df24eed`;用户于 2026-10-14(Asia/Shanghai)答复“批准设计,继续实施计划”。此前用户认可的方向是“保持不完整工具流的安全拒绝,增加无原始内容或凭据的终态/传输诊断与零付费重放;快通道数字和分期归属缺少依据时标待确认”。这两次答复只授权写设计及详细实施计划,**不授权产品代码、付费模型请求、合入或部署**。负责人 weichen;实施候选与验收主记录为 Dev `feature/fast-slow-u2-u3-plan` 任务卡,历史结果见[核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md),前版见 [r0.4 设计](2026-10-14-fast-slow-u3-r04-reliable-first-checkpoint-design.md)和[实施计划](2026-10-14-fast-slow-u3-r04-reliable-first-checkpoint-implementation-plan.md)。
|
||||
|
||||
## 目标与已知事实
|
||||
|
||||
用户上传材料后应立即知道“已收到、正在做什么、何处看结果”;阶段发现和最终整理仍由同一张工作卡逐级呈现,并且数量、分期、审批状态与来源一致。非专业用户默认只看简短状态、有用发现和待确认问题,不看 SSE、脚本或 token 细节。沿用左侧上下文、中间对话、右侧工作/文件,不增加页面或独立模型回合。
|
||||
|
||||
r0.4 唯一获批 A01 固定在 Dev `d38dbdc396b7b8c6a9e34142ea8e6018abbed1fc`、Backend `37e2cb7adb6202902345d38bc591e12be7aa79c0`、Agent-Native `a5e3c7c817166865d75b764337b15ca7d505d131`。原始样本和独立只读评估(原件路径见[核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md))确认:两个付费 run、三次调用、29,062 已返回 Usage tokens;工具回合有 `finishReason=tool_calls`、合法 JSON 参数片段和 Usage,但解析器未观察到 `[DONE]`,所以没有工具执行、运行中检查点或最终整理正文。三次终态的 `streamComplete` 均为 false,前两次纯文本仍被当作正常结束。**没有保存原始 SSE,无法区分服务端未发结束标记、连接中途结束或适配器遗漏;不能把“JSON 可解析”当成完整工具调用的证明。**
|
||||
|
||||
快通道问题中的“剩余 4 项(含 3 项依赖接口)”也没有材料依据:原文只给总 12、第一期 8、总量中接口依赖 3,未给依赖项与分期的交集。问号不撤销括号内的肯定关系。r0.3 的结构化检查点守卫没有覆盖前台自由文本;r0.4 `materialStartedNote` 仍要求模型即时给“初步判断、需要澄清的问题”。这条未经来源校验的可见路径必须收敛。
|
||||
|
||||
原候选还漏记失败子 run 的 7,148 tokens。Backend `0637547cc5640d51e2d67b65ab07b184269f8371` 已在 r0.4 授权诊断范围内完成零付费修复并通过独立复审(原件 `/tmp/fast-slow-u3-r04-20261014/usage-fix-final-review.md`)及准确 HEAD CI;该修复晚于样本,不改写原结果,也不证明流终态或快通道质量已通过。八个相关 PR 仍是草稿,r0.4 质量出口为 **FAIL**。
|
||||
|
||||
## 方案取舍
|
||||
|
||||
| 路线 | 收益 | 代价与风险 | 取舍 |
|
||||
|---|---|---|---|
|
||||
| 仅修改提示词,要求模型“谨慎” | 改动小 | 前台自由文本已出现无依据归属;提示不能构成发布门禁,也不能解释缺 `[DONE]` | 不选 |
|
||||
| **保留严格工具门禁,补不含内容的终态诊断;自动材料入口用宿主确认反馈,来源判断进任务卡** | 不执行不完整工具;即时反馈不依赖模型推断;零新增模型调用 | 暂不使缺 `[DONE]` 的工具请求成功;复杂材料的首条实质发现仍取决于慢通道 | **推荐** |
|
||||
| 将“干净 EOF+结束原因+合法 JSON”直接视作 `[DONE]`,或自动让模型补发工具参数 | 可能减少一次失败 | 缺失尾帧也可能是截断;无本次原始流可证等价,补发增加付费回合并违反停止条件 | 不选;未来如有证据须另审 |
|
||||
|
||||
本修订先补“为什么终止”和“哪些话可以立即显示”的可靠边界。它不是宣布供应商终态已兼容,也不以更宽松的模型质量标准换取通过。
|
||||
|
||||
## 用户可见行为与快通道边界
|
||||
|
||||
系统**已确定性启动或复用**材料整理任务时,立即由宿主在原对话给一条短确认,并保持同一张任务卡:例如“已收到 3 份材料,正在核对;有依据的发现会陆续出现在‘材料整理’中,尚不能确认的关系会明确标注”。材料数量、文件名及任务状态只能来自当前授权的附件快照与任务卡,不能由模型猜测。任务排队、已有活动任务、失败启动和已完成复用分别读实际状态,不把“已启动”发给启动失败的任务,不重派同一批材料。
|
||||
|
||||
对于这个**自动材料入口的首个可见快通道回复**,模型自由文本不作为已核对的材料结论直接流给用户。若要显示实质数量、分期、决定或跨文件关系,必须走已有来源、原句、范围和归属校验后成为 `material_record`/`needs_user` 等阶段条目;在此之前,只给宿主确认与“待确认”状态。样本中的正确表达是“总量、首期和接口依赖数量分别有记载;依赖项属于哪一期待确认”,不能写“剩余 4 项含 3 项依赖接口”。不凭单独的问号、免责声明或“可能”放行前面的肯定关系。这个选择减少即时推断,但用户会更早得到真实进度,稍后通过右侧卡片查看带来源的内容。
|
||||
|
||||
方案优先覆盖 **系统预启动材料整理的首回合**:无文字上传及达到材料阈值的文字+材料。后者原用户工作重点已由 `buildMaterialTaskFor` 带给慢通道;短确认应说明稍后将结合该重点汇报,而非假称当场已经回答。文字+小材料仍走普通对话与既有 stop 兜底,不把它伪装成本方案已验收的路径;实施计划须列出这一路径的风险与回归,并评估是否需要后续独立范围。原始模型候选若被抑制,不得进入用户可见事件、会话持久转录或后续模型上下文。实现时若不能保证这一点,选择直接跳过该首回合模型请求,由宿主正常落一条确认消息;不得先流出不可信片段再撤回。省略首回合模型请求是少一次请求,不是新增模型摘要或审核调用;对预算和 A01 基线的影响仍须如实记录。
|
||||
|
||||
后台成果不因快通道收敛而降格:首条仍须真实、短、有连续原文来源的 `reading` 事实,第二批是不同且有用的 `crosscheck` 发现,最终有准确完整正文。未验证阶段不得显示虚构的进度百分比、ETA 或“全部完成”;失败沿用 r0.4 的零成果/部分成果分流,不生成无依据的交付物选择卡。
|
||||
|
||||
## 终态诊断与安全契约
|
||||
|
||||
Agent-Native 是 SSE 读取与工具执行边界的所有者。保留现有规则:工具调用只有在受支持的完成原因、完整终止标记及 ID/名称/对象 JSON 参数全部满足时才交给执行器;缺 `[DONE]`、读取错误、取消或参数不完整时继续安全失败,已返回的 Usage 仍计入预算,不因失败自动补发请求。文本回合当前在缺 `[DONE]` 时可正常结束的事实需要单列诊断,不能借此推断工具回合也安全。Backend 的受控评测 wrapper 仍在终态故障、检查点拒绝、缺 Usage 或额度边界后阻断后继 provider 请求;不改模型路由、轮数、工具数、时间与输出上限。
|
||||
|
||||
新增**有界、无内容**的每次调用终态收据,与既有 `runId`、调用序号和逐调用 Usage 关联。字段建议为:HTTP 状态与可判定的响应完成类型、读结果(正常 EOF/读错误/取消)、`[DONE]` 是否观察到、最后一个 SSE 事件是否完整 JSON、已观察到的 `finishReason`、是否含工具片段及片段数量、参数总字节数与 JSON 对象有效性、Usage 是否出现与 token 数、最终是否放行工具。只记录枚举、计数、布尔值及受限错误类别;**不保存原始 SSE、prompt、正文、推理文本、工具名/参数、API key 或请求头**。不可从无内容收据反推出尾帧原文;读取错误细节需脱敏并限长,日志与归档采用任务自有权限。模型失败时诊断与失败状态同一调用保存,不让观测失败触发重试。
|
||||
|
||||
`bufio.Scanner.Err()==nil` 的 EOF 仅说明读取器没有报告错误,不证明供应商发送了所有预期事件;完整 `finishReason`、Usage 和合法 JSON 也不能独立补足 `[DONE]`。诊断先回答“解析器看到了什么、底层读取如何结束、工具是否被执行”。若零付费重放显示解析器漏认合法终止形式,或未来经单独批准的受限真实试验取得足够的供应商终态证据,才提出**按路由受限的等价终态定义**及正反例,回到方案评审;r0.5 本身不放宽工具门禁。
|
||||
|
||||
Backend 只消费 Agent-Native 的终态分类和 Usage,保留 run/card/source 版本权威;Frontend/UI 只显示“整理中/未完成/待确认”等用户可行动状态,不展示诊断字段。核心 `TaskSnapshot`、公开工具契约、数据库结构、权限和服务配置保持现有版本。若需持久诊断,优先落在已受控的评测记录/运行诊断面,实施计划须说明清理期限与是否需要新增内部字段;不得以完整原始流作为默认遥测。
|
||||
|
||||
## 零付费验证与阶段出口
|
||||
|
||||
1. **传输/解析重放。** 用 `httptest` 和人工 SSE 帧覆盖有 `[DONE]`、正常 EOF 却无 `[DONE]`、半个 JSON 帧、结束原因与工具片段不一致、读错误、取消、缺 Usage、纯文本缺终止标记。逐一断言收据分类、工具执行次数、返回及持久 Usage、后继 provider 请求数。特别验证“干净 EOF+合法工具 JSON”仍为 **0 次工具执行**。
|
||||
2. **快通道投影。** 对附件仅发送、文字+长材料预启动、排队、活动任务复用、启动失败、已完成复用分别用真实 HTTP/浏览器核对首条确认、卡片与会话转录。以 A01 的 12/8/3 和跨文档改写变体作反例,断言首回合任何可见文字均不包含未经证明的交集关系,明确标“待确认”;原用户文字仍在慢任务重点中,普通文字+小材料路径没有被误改。
|
||||
3. **渐进成果与失败。** 零付费假流核对第一条 `reading`、第二批不同 `crosscheck`、终态完整正文、零成果/部分成果失败,以及刷新、来源跳转和后台不抢阅读焦点;不能把宿主确认算成一个阶段发现。SQLite 与隔离 PostgreSQL 分别核对事件 seq、任务快照及已返回 Usage。
|
||||
4. **组合与审阅。** Agent-Native、Backend、适用的 Frontend/UI 和 Dev 固定准确 SHA 后做组件测试、`make test && make build`、真实浏览器、独立最小重放与准确 HEAD 平台 CI。源码、收据和独立审阅按 `SELF`/`REPLAY`/`GATE` 标识;没有运行的项目写 `NOT_RUN`。界面若确需修改,先读 Dev `DESIGN.md` 并只用 `@ui` 令牌、动效与折叠原语。
|
||||
|
||||
正式 A01 质量标准仍是至少两条**真正有用且终态前可感知**的不同阶段成果、完整准确最终正文、原文来源和数字/决定状态正确,逐调用核对实际 run ID、Usage、工具数和停止规则。宿主确认不计入两条;零付费重放只证明机制,不证明模型会完成任务。r0.4 的一次性资源已用尽;新的真实模型调用必须在本设计与详细实施计划分别获批、零付费候选固定和单独资源提案获批后才可运行。任何安全、语义或质量 FAIL 保持八个 PR 草稿,不进入阶段 7、合入或部署。
|
||||
|
||||
## 风险与待评审决定
|
||||
|
||||
- **诊断不等于修复供应商行为。** 当前原件缺原始 SSE,因此只能证明“未观察到 `[DONE]`”;本版保守失败可能继续导致零阶段成果。是否再做受限供应商探针或提出等价终态,必须依据新证据和单独资源审批,不在本设计中偷渡。
|
||||
- **快通道即时信息减少。** 宿主先确认真实状态,实质判断等来源核验后再上卡。若用户更看重未经核实的即时概览,需要另行决定风险,而不能把模型自由文本称为已核对结论。
|
||||
- **首回合跳过/隔离的实现选择。** 两者都不得让候选文本先进入事件或持久转录;实施计划应以最小零付费探针比较对已有会话、通知、计费、重入和用户文字重点的影响,推荐更小且可证明的路径。若探针显示需要改变公开消息契约或异步所有者,返回设计评审。
|
||||
- **范围边界。** 本版优先关闭预启动材料入口的快通道错误;普通文字+小附件问答仍需单列验证,不从 A01 推断全路径正确。若评审要求覆盖该路径,应在计划前扩展设计和验收矩阵。
|
||||
|
||||
请人工重点审阅:是否接受“先可信确认、实质判断稍后上卡”的体验取舍;是否同意缺 `[DONE]` 的工具流继续严格拒绝,并先以无内容诊断求证;以及短文字+小材料是否纳入同一增量。书面设计批准后才写详细实施计划,批准计划后才进行零付费代码实施;真实模型资源仍单独批准。
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
# U3 r0.5 Safe Terminal Evidence and Fast Feedback Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 上传材料后立即给出可信的收件与工作状态,让实质结论经来源核对后逐步上同一张卡;为未见 `[DONE]` 的模型流保存无内容诊断,同时继续拒绝执行不完整工具调用。
|
||||
|
||||
**Architecture:** Agent-Native 的 OpenAI SSE 解析器为每次终态附加有界、无原文的读取观察;Backend 评测入口把它与实际 run ID、Usage 和停止决定一起落到受限记录。Backend 在系统预启动材料整理的首回合选择宿主确认 runner,不调用前台模型,因此不会先流出无法核对的自由文本;后台仍按 r0.4 的来源、阶段和失败规则运行。普通文字+小材料与已完成任务上的新提问继续原路径,并单独验证其范围限制。
|
||||
|
||||
**Tech Stack:** Go 1.27、Agent-Native SSE/runtime、Backend runmgr/受控评测、SQLite/隔离 PostgreSQL、React/Vite/Playwright、Dev `make test`/`make build` 与 Gitea CI。
|
||||
|
||||
**Spec:** [已批准的 r0.5 书面设计](2026-10-14-fast-slow-u3-r05-terminal-evidence-and-fast-feedback-design.md),Documents `0d473fe866703eab32f715ddf12d1b25913b822b`;[r0.4 A01 核验记录](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。用户只批准**编写本计划**;计划本身待阶段 5 人工评审,不授权产品代码、付费模型、合入或部署。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- r0.4 原始 A01(Dev `d38dbdc`,2 个付费 run/3 次调用/29,062 返回 Usage,0 个检查点)与受限归档原样保留,质量判定 **FAIL**。Backend `0637547` 的失败子 run Usage 修复也不追溯改写样本。
|
||||
- 缺 `[DONE]`、读取错误、取消、工具身份或对象 JSON 参数不完整时,工具执行次数必须为 0;合法 JSON、`finish_reason`、Usage 或正常 EOF 均不能单独替代完整终止标记。不新增自动重试、补参数、供应商切换或模型摘要调用。
|
||||
- 新终态诊断只保存枚举、布尔值、计数、HTTP 状态、实际 run ID/调用序号和 Usage;**不保存新的原始 SSE、prompt、正文、思考文本、工具名/参数、API key、请求头**。旧历史原件保持只读;新评测记录要移除现有 `messages`、`toolDeclarations`、`terminal` 的原始内容副本。
|
||||
- 保留 r0.3/r0.4 的 sourceId、owner/project、artifact hash/解析版本、原句、数字归属、CAS、seq、失败通知与建议选择条件。Core `TaskSnapshot`、HTTP 公开契约、数据库表、生产模型路由、预算与既有普通聊天入口不改。
|
||||
- 宿主确认不计入两个有用阶段成果。自动材料入口只有在系统确实预启动或复用活动任务时跳过前台模型;排队、运行、复用、启动失败与已完成复用按真实卡片状态分流。用户原文字重点继续进入慢任务;文字+小材料仍走原直连路径,不能用 A01 证明其质量。
|
||||
- 默认仍是三栏与一张任务卡。若实际浏览器证明必须修改 UI 代码,先读 Dev `DESIGN.md`,只消费 `@ui` 令牌、`mk-*` 动效和 Collapsible 原语;相关计划范围与组件 PR 需按影响重新评审。异步投影仍按 seq 丢弃过期事件,不抢文件、焦点和阅读位置。
|
||||
- 所有实施、真实 HTTP、PG、浏览器、审阅与 CI 都是**零付费**;只用 `httptest`/本地假流,不能运行 live `TestWorkCheckpoints` 或受保护模型路由。后续受限供应商探针或 A01 必须分别提交资源提案;本计划不预填、不授权任何 token/run 额度。
|
||||
- Dev `AGENTS.md` 的唯一 precheck 收据、`task-resume`、请求审核/验收/合入前 `task-sync`、`make evidence`、独立 REPLAY、准确 HEAD GATE 和任务工作区保护全部适用。计划实施需另获用户阶段 5 批准;质量 FAIL 时八个 PR 保持草稿。
|
||||
|
||||
## Review Focus
|
||||
|
||||
| 容易伤害用户的输入/状态 | 所属任务的固定用例与预期 |
|
||||
|---|---|
|
||||
| `tool_calls` 有合法参数、Usage、正常 EOF,却没有 `[DONE]` | Task 1 `TestTerminalObservationCleanEOFWithoutDone`、Task 3 `TestEvaluationStopsAfterUnmarkedToolEOF`:记录 clean EOF,0 次工具执行、0 次后继请求。 |
|
||||
| SSE 最后一帧半个 JSON,或 HTTP 读取错误/取消 | Task 1 `TestTerminalObservationMalformedAndReadError`:分类不同、已返回 Usage 不丢、原始内容不入诊断。 |
|
||||
| 三个后台槽已满,材料排队;同批材料重发 | Task 2 `TestMaterialAckQueueAndReuse`:确认文字与卡片真实状态一致,只有一个材料子任务、前台 provider 0 次调用。 |
|
||||
| 用户带文字+长材料,或文字+小材料 | Task 2 `TestMaterialAckPreservesUserFocusAndSmallPath`、Task 4 浏览器用例:前者重点进入慢任务且前台只确认,后者仍走原模型路径。 |
|
||||
| prompt、工具参数或 provider 错误含敏感文本;诊断文件写入失败 | Task 3 `TestEvaluationTerminalRecordContainsNoPayload`、`TestEvaluationStopsWhenTerminalRecordUnavailable`:文件无哨兵原文,写入失败不放行工具终态或下一次请求。 |
|
||||
|
||||
## 文件责任与依赖顺序
|
||||
|
||||
| 单元 | 文件(相对对应仓根) | 产物/消费者 |
|
||||
|---|---|---|
|
||||
| 1 Agent-Native 终态观察 | 修改 `runtime/llm/{types,sse,client,sse_test}.go`,新建 `runtime/llm/client_test.go` | `llm.Event.TerminalObservation`;Task 3 消费。Agent-Squad 与 Backend 的 Agent-Native gitlink随后固定同一 SHA。 |
|
||||
| 2 Backend 可信快反馈 | `internal/runmgr/{material,material_ack,runmgr,material_test,material_ack_test}.go` | 内部 `materialIntakeDecision` 与 `materialAckRunner`;Task 4 的 HTTP/浏览器消费。 |
|
||||
| 3 Backend 受控评测记录 | `internal/server/{work_checkpoint_eval_test,work_checkpoint_eval_budget_test}.go` | 内容最小化的 `provider-records.json` 与故障停止证据;Task 5 消费。 |
|
||||
| 4 整条用户链 | Backend `internal/runmgr/material_notice_failure_test.go`、`internal/server/work_checkpoint_eval_test.go`;Frontend `e2e/work-checkpoints.playwright.ts` | 真实 HTTP、SQLite、隔离 PG、浏览器的收件→阶段→终态证据。Frontend 仅按需要改测试,不预设 UI 生产代码。 |
|
||||
| 5 固定与评审 | Agent-Squad `deps/agent-native`;Backend `deps/agent-native`;Dev `deps/agent-native`、`deps/agent-squad`、`modules/backend`、可选 `modules/frontend`、任务卡与 Documents 指针 | 单一准确组件组合、独立复审、当前 HEAD CI、阶段 6 人工评审材料及资源决策。 |
|
||||
|
||||
接口顺序:Task 1 的只读终态观察由 Task 3 记录;Task 2 的宿主确认由 Task 4 从真实浏览器观察;Task 1–4 的组件 SHA 进入 Task 5。Task 2 与 Task 3 可在各自包内分别验证,但 Backend 提交和 Dev 固定仍按上述依赖顺序完成。已有登记任务工作区与草稿 PR 继续使用,不从嵌套 detached gitlink 直接交付。
|
||||
|
||||
### Task 1: Agent-Native 有界终态观察,不放宽工具门禁
|
||||
|
||||
**Files:** 修改 `runtime/llm/types.go`、`runtime/llm/sse.go`、`runtime/llm/client.go`、`runtime/llm/sse_test.go`;新建 `runtime/llm/client_test.go`。**Interfaces:** 生产现有 `llm.Event` 的 `FinishReason`、`StreamComplete`、`Usage`、`HTTPStatus` 保留;新增只在终态/错误事件上出现的 `*TerminalObservation`,字段为 `ReadOutcome`(`done_marker|clean_eof|read_error|cancelled|invalid_frame|provider_error`)、`LastFrameJSONComplete`、`UsagePresent`、`ToolFragments`、`ToolArgumentBytes`(饱和计数)、`ToolArgumentsValid`。不包含原文、工具名或错误原句。Task 3 只消费这些标量。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 以现有 `TestParseSSEToolFinishWithoutDone`、`TestParseSSEReaderErrorAfterUsageKeepsUsage` 为底,新增 `TestTerminalObservationCleanEOFWithoutDone`:SSE 有合法工具 JSON、`finish_reason=tool_calls`、Usage 17,却在正常 EOF 结束;断言终态错误、`ReadOutcome=clean_eof`、`StreamComplete=false`、`ToolArgumentsValid=true`、`ToolFragments=1`、`ToolArgumentBytes>0`、`len(Message.ToolCalls)==0`。`TestTerminalObservationMalformedAndReadError` 表驱动比较半帧 JSON、注入读错误、取消;断言分类及返回 Usage。`client_test.go` 的本地 `httptest` 断言成功 HTTP 200 只作为标量传到终态,不保存 URL/请求头。
|
||||
|
||||
```go
|
||||
if end.Err == nil || end.StreamComplete || len(end.Message.ToolCalls) != 0 ||
|
||||
end.TerminalObservation == nil || end.TerminalObservation.ReadOutcome != "clean_eof" ||
|
||||
end.Usage.TotalTokens != 17 {
|
||||
t.Fatalf("unsafe or unclassified terminal: %#v", end)
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 记录 RED。** `GOWORK=off go test ./runtime/llm -run 'TestTerminalObservationCleanEOFWithoutDone|TestTerminalObservationMalformedAndReadError|TestClientTerminalObservationHTTPStatus' -count=1`;预计因新观察字段/分类缺失而失败,使用 Dev `make evidence` 保存原始 SELF 输出。不得用旧 r0.4 守卫测试的 PASS 代替新诊断测试。
|
||||
- [ ] **Step 3: 最小 GREEN。** 在 `sseEventReader`/`emitParsed` 区分 `[DONE]`、扫描器 clean EOF、`sc.Err()`、坏 JSON 和取消;仅维护布尔、枚举与计数,参数字节数饱和到 `4*1024*1024+1`。为诊断先计算已收参数的对象 JSON 有效性,**再**运行原有“缺 `[DONE]` 必拒绝”的工具释放门禁,不能因 `ToolArgumentsValid=true` 绕过它。创建终态 Event 时附观察;`client.run` 对成功响应复制 `resp.StatusCode` 到终态,不读取或记录头/body。现有 `toolFinishExecutable` 与“缺 `[DONE]` 不发 ToolCalls”的顺序一字不放宽;`KindError` 路径也要给出可判定的失败类别,不伪造正常终态。
|
||||
|
||||
```go
|
||||
type TerminalObservation struct {
|
||||
ReadOutcome string
|
||||
LastFrameJSONComplete bool
|
||||
UsagePresent bool
|
||||
ToolFragments int
|
||||
ToolArgumentBytes int
|
||||
ToolArgumentsValid bool
|
||||
}
|
||||
// 仅 llm.Event 追加:TerminalObservation *TerminalObservation
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN 与兼容。** 重跑 Step 2;另跑 `GOWORK=off go vet ./... && GOWORK=off go test -count=1 ./...`,重点复看合法多片工具、纯文本缺 `[DONE]` 的既有行为,以及 `runtime.Run` 的 Usage/不重试测试。测试诊断序列化后不含哨兵 prompt、工具名、参数原文。记录若当前 `client.go` 的 HTTP 状态只在错误事件有值,新增正常 200 不影响 fallback 选择。
|
||||
- [ ] **Step 5: 提交 Agent-Native。** 仅提交该组件文件;描述 `Event` 的加法式 Go 契约及 Agent-Squad/Backend 固定指针依赖,不宣布供应商行为已修复。推送现有草稿 PR,核对它的准确 HEAD CI。
|
||||
|
||||
### Task 2: Backend 预启动材料的宿主确认
|
||||
|
||||
**Files:** `internal/runmgr/material.go`、新建 `internal/runmgr/material_ack.go` 与 `material_ack_test.go`、`internal/runmgr/runmgr.go`、`internal/runmgr/material_test.go`。**Interfaces:** 内部 `materialIntakeDecision{Note string, State materialIntakeState, CardID core.ID}`;`State` 仅为 `none|queued|running|reused_running|completed|failed|unknown`。`materialAckRunner` 实现已有 `runtime.Runner`,只消费可信附件数、工作重点是否存在与卡片状态。`completed`/`none` 继续原 runner;`queued|running|reused_running|failed|unknown` 走宿主确认,不请求前台 provider。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 用 `newCardSpawnEnv` 和实际 `Store` 增加 `TestMaterialAckAttachmentOnlyDoesNotCallParentModel`:三附件无文字时先建任务卡,再在同一对话 run 保存一条不含“剩余4项含3项依赖接口”的宿主消息;前台 stream 调用数 **0**,慢任务数 **1**,宿主消息不增加 `checkpointSeq`。`TestMaterialAckQueueAndReuse` 将三个后台槽占满再发送,断言卡为 queued、确认文案不称“正在执行”;同批重发只复用一张卡,后台刚完成但内存活动键尚未释放时以卡片终态为准。`TestMaterialAckPreservesUserFocusAndSmallPath` 断言文字+长材料的原文重点在 `buildMaterialTaskFor`,文字+小材料仍调用原 runner;完成态重发仍可进入普通问答。`TestMaterialAckSkipsSquadEntrypoint` 将 `runtime.entry=squad`,断言系统预启动分支也不调用小队 runner。`TestMaterialAckFailureAndUnknown` 注入注册/读卡错误,断言不称已启动、不追加模型请求。
|
||||
|
||||
```go
|
||||
if parentProviderCalls != 0 || materialChildren != 1 || card.Task.CheckpointSeq != 0 ||
|
||||
strings.Contains(visibleReply, "剩余 4 项(含 3 项依赖接口)") ||
|
||||
!strings.Contains(visibleReply, "待确认") {
|
||||
t.Fatalf("first reply is not a truthful host acknowledgement")
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 记录 RED。** `GOWORK=off go test ./internal/runmgr -run 'TestMaterialAckAttachmentOnlyDoesNotCallParentModel|TestMaterialAckQueueAndReuse|TestMaterialAckPreservesUserFocusAndSmallPath|TestMaterialAckSkipsSquadEntrypoint|TestMaterialAckFailureAndUnknown' -count=1`;旧实现会调用前台 runner/缺状态分流,预计失败。原始 SELF 收据经 Dev `make evidence`,不要手抄输出。
|
||||
- [ ] **Step 3: 最小 GREEN。** 把 `materialIntake`、`materialExisting`、`materialSpawn` 的内部返回收敛为 `materialIntakeDecision`,更新同包调用和现有测试;从已注册的、同 owner/project/inputRevision 的卡片读取 queued/running/terminal 状态,读不到就 `unknown`,不靠中文 note 判断分支。`startClaimedRun` 在 `materialIntake` 后按 `State` 将 `runner` 替换为 `materialAckRunner`;该 runner 发一次既有 `EvRunPhase(Responding)`/`EvMessageDelta`,再用 `SetAssistantParts` 交给 `finishRun` 正常持久化。短文案只用可信附件数/状态,并明确未经核对的关系“待确认”;失败态提示可重新提出请求但不自动重试。原始模型候选不调用、不进入事件、转录或后续上下文。`none`/`completed` 保留原模型入口;`ensureMaterial` 的文字+小材料兜底继续原路径。
|
||||
|
||||
```go
|
||||
type materialIntakeState string
|
||||
const (
|
||||
materialNone materialIntakeState = "none"
|
||||
materialQueued materialIntakeState = "queued"
|
||||
materialRunning materialIntakeState = "running"
|
||||
materialReusedRunning materialIntakeState = "reused_running"
|
||||
materialCompleted materialIntakeState = "completed"
|
||||
materialFailed materialIntakeState = "failed"
|
||||
materialUnknown materialIntakeState = "unknown"
|
||||
)
|
||||
func (s materialIntakeState) needsAcknowledgement() bool {
|
||||
return s == materialQueued || s == materialRunning || s == materialReusedRunning ||
|
||||
s == materialFailed || s == materialUnknown
|
||||
}
|
||||
decision := m.materialIntake(rc)
|
||||
rc.materialNote = decision.Note
|
||||
if decision.State.needsAcknowledgement() {
|
||||
runner = materialAckRunner{decision: decision, attachmentCount: len(rc.attachments), hasUserFocus: messageText(rc.userMessage) != ""}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN 与并发。** 重跑 Step 2,再跑 `GOWORK=off go test -count=1 ./internal/runmgr ./internal/runtime ./internal/cardsvc` 与 `GOWORK=off go test -race -count=1 ./internal/runmgr -run 'TestMaterialAckQueueAndReuse|TestMaterialIntakeAttachmentOnlyLifecycle'`。核对授权关闭、无附件、任务注册失败、取消、重启后的活动卡去重、原已有完成结果、任务来源版本变化与后台 notice;宿主确认不能被通知当作最终整理正文或建议列表。
|
||||
- [ ] **Step 5: 提交 Backend 快反馈单元。** 只提交此任务相关文件,保留消息/卡片的现有 Core 契约;说明首回合少一次模型请求及其 Usage 可比性变化,不把普通小材料问答标成已整改。
|
||||
|
||||
### Task 3: 受控评测的无内容记录与停止规则
|
||||
|
||||
**Files:** `internal/server/work_checkpoint_eval_test.go`、`internal/server/work_checkpoint_eval_budget_test.go`。**Interfaces:** 消费 Task 1 `Event.TerminalObservation`、既有 `FinishReason`/`StreamComplete`/`Usage`/`HTTPStatus`;`provider-records.json` 保留 `runId`、调用号、输出上限、返回 Usage、结束原因及诊断标量,移除以后样本里的 `messages`、`toolDeclarations` 和原样 `terminal`。历史 r0.4 文件哈希不变。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** `httptest` 分别返回带 `[DONE]` 的合法工具调用、正常 EOF 无 `[DONE]` 且 JSON/Usage 合法、半帧 JSON、读错误、缺 Usage。新增 `TestEvaluationRecordsContentFreeTerminal`:将哨兵 `PRIVATE_PROMPT_R05` 放入请求消息、`PRIVATE_ARGUMENT_R05` 放入工具参数,断言新 `provider-records.json` 不含两串和原始 `messages`/`toolDeclarations`/`terminal` 键,但有 run ID、调用号、`readOutcome`、`usagePresent`、`reportedTokens`。`TestEvaluationStopsAfterUnmarkedToolEOF` 与 `TestEvaluationStopsWhenTerminalRecordUnavailable` 分别断言无 `[DONE]` 和 0600 写入失败后第二次 provider 调用数仍为 **0**;已返回 Usage 必须保留。
|
||||
|
||||
```go
|
||||
raw, err := os.ReadFile(filepath.Join(dir, "provider-records.json"))
|
||||
if err != nil { t.Fatal(err) }
|
||||
if bytes.Contains(raw, []byte("PRIVATE_PROMPT_R05")) ||
|
||||
bytes.Contains(raw, []byte("PRIVATE_ARGUMENT_R05")) ||
|
||||
bytes.Contains(raw, []byte(`"toolDeclarations"`)) {
|
||||
t.Fatal("evaluation record contains model payload")
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 记录 RED。** `GOWORK=off go test -tags live ./internal/server -run 'TestEvaluationRecordsContentFreeTerminal|TestEvaluationStopsAfterUnmarkedToolEOF|TestEvaluationStopsWhenTerminalRecordUnavailable' -count=1`。只运行这些本地假 provider 测试;**不得**用无 `-run` 的 live-tag 命令误启动 `eval/live/TestWorkCheckpoints`。
|
||||
- [ ] **Step 3: 最小 GREEN。** 在 `evalProviderStreamWithProvider` 的“先关流、落 Usage/停止记录、再释放终态”顺序内生成只含标量的记录;`terminal==nil` 时使用有限的 `missing_terminal` 类别,错误信息仅记录枚举,不保存 `Err.Error()` 的可能敏感原文。`terminalFault`、`usageUnknown`、`checkpointRejected`、批次与单 run 上限继续在下次请求前拒绝。记录写入失败则终态不执行工具、下一次请求继续被本地拒绝;原始历史记录不迁移。
|
||||
|
||||
```go
|
||||
type evalCallRecord struct {
|
||||
RunID string `json:"runId"`
|
||||
Call int `json:"call"`
|
||||
OutputCap int `json:"outputCap"`
|
||||
ReportedTokens int `json:"reportedTokens"`
|
||||
FinishReason string `json:"finishReason"`
|
||||
StreamComplete bool `json:"streamComplete"`
|
||||
Observation *agentllm.TerminalObservation `json:"terminalObservation,omitempty"`
|
||||
FailureClass string `json:"failureClass,omitempty"`
|
||||
}
|
||||
// 不再包含 messages、toolDeclarations 或整个 terminal Event。
|
||||
```
|
||||
- [ ] **Step 4: 跑 GREEN 与控制组。** 重跑 Step 2,再跑 `GOWORK=off go test -count=1 ./...`;仅用精确正则执行 `GOWORK=off go test -tags live ./internal/server ./eval/live -run 'TestEvaluationRecordsContentFreeTerminal|TestEvaluationStopsAfterUnmarkedToolEOF|TestEvaluationStopsWhenTerminalRecordUnavailable|TestFollowupA01KeepsItsOwnOneShotResult|TestFollowupA01UsesNewBoundedAuthorization' -count=1`。保存合法 `[DONE]` 工具调用成功、纯文本缺标记仍按旧行为且诊断清楚、坏工具终态失败三种记录,不能把诊断字段出现当作质量 PASS。
|
||||
- [ ] **Step 5: 提交 Backend 诊断单元。** 与 Task 2 合并前确认没有 `messages`、原始终态或工具参数在新的评测文件中,且 A01 标签/路由/模型预算没有变化。推送 Backend 草稿 PR 并核对准确 HEAD CI。
|
||||
|
||||
### Task 4: 用户链零付费组合重放
|
||||
|
||||
**Files:** Backend `internal/runmgr/material_notice_failure_test.go`、`internal/server/work_checkpoint_eval_test.go`;Frontend `e2e/work-checkpoints.playwright.ts`。**Interfaces:** 只通过现有 HTTP 消息、run、卡片、事件及 `TaskSnapshot` 观察 Task 2/3;不新增前端状态所有者或 API 字段。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 在 `e2e/work-checkpoints.playwright.ts` 的 `Scenario` 联合类型中增加 `fast-ack`,并在任务自有 HTTP 假流夹具加入“附件仅发送”“文字+长材料”“三个槽位已满”“同批重发”“启动失败”“已完成复用”“文字+小材料”场景;浏览器先断言宿主确认在原对话可见、任务卡在右侧同一入口、未出现无依据的 `剩余4项含3项依赖接口`、宿主确认不增加 finding/checkpoint。文字+小材料断言仍有原直连答复;后台失败零发现、部分成果、成功建议选择仍按 r0.4 规则。先让新增用例在旧前台模型路径失败,保存 SELF RED。
|
||||
|
||||
```ts
|
||||
test('attachment-only material intake shows a safe first reply', async ({ page, request }) => {
|
||||
const seed = await setup(request, 'fast-ack', false)
|
||||
await open(page, seed)
|
||||
await expect(page.getByText(/已收到.*份材料.*待确认/)).toBeVisible()
|
||||
await expect(page.getByText(/剩余\s*4\s*项.*含\s*3\s*项依赖接口/)).toHaveCount(0)
|
||||
const card = (await (await request.get(manifest.base + `/api/conversations/${seed.conv.id}/cards`)).json()).cards.find((c: any) => c.task)
|
||||
expect(card.task.checkpointSeq).toBe(0)
|
||||
})
|
||||
```
|
||||
- [ ] **Step 2: 完成受控机制夹具。** Backend 夹具在每个场景使用新的隔离 SQLite、固定三份合成文本与人工 SSE;父回合计数器记录 provider 调用数,子回合按场景给合法 `[DONE]`/阶段工具/失败终态。保留实际 HTTP 的 owner/project 与来源哈希核验;不把 fixture 中的 `reading`/`crosscheck` 当成真实模型遵循顺序的证明。
|
||||
|
||||
```go
|
||||
// 每个 scenario 使用新 dataDir;stream 只连 httptest.Server。
|
||||
parentCalls := atomic.Int32{}
|
||||
parentStream := func(ctx context.Context, model string, messages []agentllm.Message,
|
||||
tools []agentllm.ToolDecl, opts agentllm.StreamOptions) <-chan agentllm.Event {
|
||||
parentCalls.Add(1)
|
||||
out := make(chan agentllm.Event, 1)
|
||||
out <- agentllm.Event{Kind: agentllm.KindMessageEnd,
|
||||
Message: agentllm.Message{Role: agentllm.RoleAssistant, Content: "本地夹具答复", StopReason: agentllm.StopEnd},
|
||||
Usage: agentllm.Usage{PromptTokens: 2, CompletionTokens: 1, TotalTokens: 3}, StreamComplete: true}
|
||||
close(out)
|
||||
return out
|
||||
}
|
||||
// 自动材料入口完成后断言 parentCalls.Load()==0;文字+小材料对照为 1。
|
||||
```
|
||||
- [ ] **Step 3: 跑 GREEN 与视觉回归。** 启动本任务独有的 mechanism 二进制和数据目录,manifest 固定 PID、可执行文件 SHA、Dev/Backend/Agent-Native/Frontend SHA、模式与地址;先用 manifest 的 `pid` 核查对应 `/proc/` 可执行文件和目录归属,再将 manifest 的 `base` 设为 `PLAYWRIGHT_BASE_URL`、manifest 路径设为 `WORK_CHECKPOINT_HTTP_MANIFEST`,运行 `npx playwright test e2e/work-checkpoints.playwright.ts`。至少覆盖 1440px 桌面与 390px 窄屏:默认只见短确认,任务卡阶段发现、来源、失败和选择卡按现有层级展示,刷新和后台更新不抢文件、输入焦点或阅读位置;禁止新增命令/SSE 展示。只停止任务自有 PID,保留 trace/截图及 SELF 收据。
|
||||
- [ ] **Step 4: 隔离 PG 与完整 Backend。** 使用本任务独有的 PostgreSQL/Redis 实例和 DSN(不能连接既有服务),先验证实例 PID、数据根和数据库身份;设置 `AGENT_PG_TEST_DSN`、`AGENT_REDIS_TEST_ADDR` 后运行 `make test-backend-pg`,缺变量不得跳过。另运行 Backend `GOWORK=off go vet ./... && GOWORK=off go test -count=1 ./...`,以及纯文档/Frontend 受影响的正常路径。记录失败与修复版本;PG 和 SQLite 都核对 seq、宿主消息、来源卡和失败 Usage。
|
||||
- [ ] **Step 5: 提交实际测试增量。** Backend/Frontend 只提交本单元实际新增的夹具与浏览器测试;若需要改 Frontend/UI 生产组件才能表达正确状态,停止该部分,补设计与计划评审,再读 `DESIGN.md`、固定 `@ui` 令牌 PR 和设计守护测试。真实模型质量继续 `NOT_RUN`。
|
||||
|
||||
### Task 5: 固定跨仓候选、复审与资源出口
|
||||
|
||||
**Files:** Agent-Squad `deps/agent-native`、Backend `deps/agent-native`、Dev `deps/agent-native`/`deps/agent-squad`/`modules/backend`/可选 `modules/frontend`、`.task/feature-fast-slow-u2-u3-plan.md`、`PROJECT.md`、Documents 的核验报告。**Interfaces:** 公开 Core/HTTP/TaskSnapshot 不变;准确 gitlink 与运行 manifest 是唯一测试对象。
|
||||
|
||||
- [ ] **Step 1: 按依赖提交并固定。** Agent-Native 先提交并推送准确 SHA;Agent-Squad 在自己分支固定同一 SHA,完整 Go vet/test 后提交;Backend 固定嵌套 Agent-Native(及现有 Core)并完成 Task 2/3/4 的全量测试后推送;Frontend 如只改 e2e 则提交相应用例。Dev 最后暂存全部新 gitlink,先跑 `make test-pins`,再用 `CMD='make test && make build' make evidence` 保存组合;禁止用 detached 嵌套检出的未提交代码冒充可交付组件。
|
||||
- [ ] **Step 2: 记录最小重放集。** 任务卡列明 r0.5 需求/设计/用例/结果矩阵:`[DONE]` 与 EOF、半帧、读取错误、缺 Usage、queue/reuse/failed/completed、附件仅发送、文字+长/小材料、0/部分/两批成果、刷新与来源版本。每条标 `SELF`/`REPLAY`/`GATE`,旧 r0.4 A01 继续 FAIL;新真实模型 A01 为 `NOT_RUN`。文档补齐精确 SHA、原件保存路径和已知限制,不写未经验证的供应商终态原因。
|
||||
- [ ] **Step 3: 独立复审与当前 HEAD CI。** 请求审核前、验收前、将来合入前各用 `CMD='make task-sync' make evidence` 纳入最新权威 main;同步若改变代码、依赖、配置或 head,按影响重跑 Task 1–4 与组合。独立审阅者重放终态无内容记录、坏工具零执行、前台零 provider、队列/失败真实性、原文归属、Usage 与脚本权限,整改到无 Critical/Important。逐仓核验 Agent-Native、Agent-Squad、Backend、适用 Frontend 及 Dev 的准确 HEAD CI,Dev 的 `test`、`test-pg`、`svc-realcombo` 全部作业/步骤均须 GATE 成功;源外 RECEIPT 留固定后检查。
|
||||
- [ ] **Step 4: 提交阶段 6 人工评审。** 交付零付费候选、实际 HTTP/浏览器和 PG 的 SELF、独立 REPLAY、准确 HEAD GATE、未解决风险与八个草稿 PR 链接。用户仅评审 r0.5 实施候选;即使代码机制 PASS,仍不等于真实模型质量、阶段 7 或合入批准。没有人工阶段 6 结论,不进入资源决策。
|
||||
- [ ] **Step 5: 单独资源决策,不自动跑 A01。** 先判断无内容终态诊断是否仍不能证明缺 `[DONE]` 的工具流可安全执行。若不能,记录“工具仍保守失败”,向用户提交独立的、受限供应商终态探针或后续设计修订选择;**不得**直接复用 r0.4 A01 额度、放宽门禁或自动再跑。仅在后续必要设计/计划评审和单独资源提案获批、质量候选固定后,才按实际授权的 run/token/时间/输出/停止边界执行新真实模型对照。真实质量 PASS 后仍须阶段 7 人工验收,随后才按 Dev 策略做最终 Review、准确 HEAD CI、串行 PR 合入、合入核验与安全回收;质量 FAIL 则保持全部 PR 草稿。
|
||||
|
||||
## 计划自检与停止条件
|
||||
|
||||
- 本计划的终点是**可审阅的零付费实施候选**和阶段 6 材料;当前用户只授权编写计划,Task 1–5 的代码与测试均 `NOT_RUN`。不得将本计划的绿色文档 CI、未来单测或假流当成真实 A01 通过。
|
||||
- Task 1 的观察字段只增加无内容诊断,不更改 `toolFinishExecutable`;Task 2 只接管预启动首回合,保持用户重点与既有消息合同;Task 3 先持久 Usage/故障记录再放终态;Task 4 以真实 HTTP/浏览器检验用户看到的内容;Task 5 只固定实际提交的组件与证据。接口消费和责任边界按此顺序复核。
|
||||
- 任何需要接受无 `[DONE]` 的工具请求、增加模型调用、变更公开消息/TaskSnapshot 契约、数据库迁移、扩大权限或改变验收标准的发现,立即停止受影响实现,返回书面设计与计划人工评审;未受影响的零付费调查可继续。任何付费请求必须另有明确资源批准,失败不自动重跑。
|
||||
@@ -0,0 +1,51 @@
|
||||
# U3 r0.6:当前路由的传输完成性证据设计
|
||||
|
||||
状态:**书面设计已获阶段 4 人工评审通过。** 用户先于 2026-10-14 的同会话答复“认可证据优先,写设计(推荐)”,随后审阅 Documents `54d39ef13034b2ce84cb84681566ea21311f79a0`、Dev `89125b8dda5f8f988a8a760ed64bf00827e1de5c` 的文稿及准确 HEAD CI,并明确答复“批准设计,继续实施计划”。该批准只允许编写详细实施计划;**不授权产品代码、额外付费请求、A01 复验、合入或部署。** 本次状态行仅记录评审结论,不改已批准设计的技术取舍。负责人 weichen;目标仍是让非专业用户在同一张任务卡上先看到可信收件反馈、再看到有来源的两批阶段成果和准确最终正文。既有[U2/U3 主计划](2026-10-13-fast-slow-u2-u3-plan.md)、[r0.5 设计](2026-10-14-fast-slow-u3-r05-terminal-evidence-and-fast-feedback-design.md)、[核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md)及 Dev `feature/fast-slow-u2-u3-plan` 任务卡是本设计的上下文;本版只处理阻断后台工具流的终态归因,不重新设计界面或降低业务质量标准。
|
||||
|
||||
## 事实、问题与目标
|
||||
|
||||
r0.4 A01 在固定候选上有两次付费 run、三次 provider 调用,工具流返回 `tool_calls` 和 Usage,但客户端未见 `[DONE]`;工具安全拒绝,质量 FAIL。r0.5 随后保留严格门禁、增加无内容终态观察,并把自动材料入口首回合改成可信宿主确认。其零付费实施与阶段 6 已获人工确认。用户另行批准的**唯一**小型 MiniMax-M3 工具流探针在 Dev `0959e1c1566df9766878b2122eccc0ab42af10a3` 上返回 HTTP 200、`finishReason=tool_calls`、`ReadOutcome=clean_eof`、最后一帧已观察到的 JSON 完整、返回 Usage **513 tokens**,但 `StreamComplete=false`,工具放行/执行 **0/0**。一次性授权已消耗,不得补跑;见[作者判定](/tmp/fast-slow-u3-r05-20261014/probe-result-assessment.md)和[独立结果复核](/tmp/fast-slow-u3-r05-20261014/probe-result-independent-assessment.md)。本设计中的“当前路由”只指该探针 `SELF` 预检核对的 MiniMax-M3、`api.minimaxi.com/v1`、无 fallback,受保护路由文件 SHA-256 `2a92569d2416d74e8d07029219af88474cb6f860c2aa897a5ffdd10fcbe9b495`;身份漂移即重新评审,不复制或公开 API key。r0.5 真实 A01 仍 **NOT_RUN**,八个 PR 仍为草稿。
|
||||
|
||||
这一次短工具请求重现了“有结束原因和 Usage,但未见 `[DONE]`”的**客户端观察**,排除了“只在三材料长任务中才出现”作为必要条件;它没有原始 SSE、HTTP 尾部元数据或供应商侧记录,无法判断服务端未发送、传输途中结束,还是适配器漏认。`clean_eof` 表示读取器没有报告扫描错误;它不证明供应商已交付预期的全部 SSE 事件。当前 [MiniMax Chat Completions API 文档](https://platform.minimax.cn/docs/api-reference/text-chat-openai)列出流式、工具和 Usage 字段,但没有在这页给出该路由以字面 `[DONE]` 结束工具流的可核验契约;不能把 OpenAI 兼容接口的惯例当作该路由的事实。
|
||||
|
||||
本版要回答两个分开的判断:**HTTP 响应体在客户端边界如何结束?SSE 应用层是否有经证实的完整工具调用终态?** 成功标准是形成可重放、无内容的诊断与决策证据,减少原因的不确定性;本版不承诺 r0.6 代码一落地就让工具流成功,也不把一次小探针等同于 A01 质量验收。
|
||||
|
||||
## 方案取舍
|
||||
|
||||
| 路线 | 能回答什么 | 代价与结论 |
|
||||
|---|---|---|
|
||||
| **A. 当前路由上分层观察 HTTP 读取与 SSE 终态,先保守拒绝** | 区分已知长度、分块、HTTP/2、关闭分隔等响应体结束类型;定位解析器是否漏认本地合法终止形式 | **推荐。** 零付费重放先行;真实路由若仍缺应用层契约,保持拒绝,再单独评审兼容规则或替代路由 |
|
||||
| B. 直接换成另一个终态已验证的模型路由 | 可能绕开当前路由的兼容性问题 | 需要新模型质量基线、路由配置与资源评审;当前证据不足以指定替代对象,作为 A 无法得到可信终态时的后备方向 |
|
||||
| C. 将 `clean_eof + tool_calls + Usage + JSON` 直接等同 `[DONE]` | 可能放行这类响应 | **不采纳。** 已观察到的最后一帧完整不等于整条业务流完整;尾帧缺失仍可能留下看似合法的参数 |
|
||||
|
||||
选择 A 不排斥后续 B。只有在明确证据与另行批准下,才能提出限路由的等价终态;本设计本身不定义一个可直接放行的 EOF 组合。
|
||||
|
||||
## 职责、数据流与隐私
|
||||
|
||||
Agent-Native 的 `Client.Stream` 已拿到 `http.Response`,`ParseSSE` 已拥有 `[DONE]`、`finishReason`、Usage、帧完整性与工具片段观察;**只有 Agent-Native** 可以在同一次调用中把两层事实关联成一条有界终态观察。Backend 只按现有 run ID/调用序号消费分类和 Usage,保留 r0.5 的拒绝后停止、预算和归档规则。Frontend/UI 沿用已实现的“整理中/未完成/待确认”、同一张任务卡、来源和失败展示;默认不显示协议字段、命令或 token。异步事件仍由原所有者按 seq 丢弃过期项,诊断记录不能成为另一个进度状态源。
|
||||
|
||||
建议在 Agent-Native 的内部终态观察中增加**有限枚举与饱和计数**,而非另存一份响应:
|
||||
|
||||
- HTTP 层:状态码、协议大类 `http1|http2|other`、响应体定界类别 `known_length|chunked|http2_stream|close_delimited|unknown`、声明长度是否存在、客户端实际读取字节数的有界计数、是否到达 `io.EOF`、读取错误类别、是否发生自动解压。已知长度时可给出“读取字节数与声明长度相符/不符”;未知长度不得伪造相符结论。Go [`net/http.Response`](https://pkg.go.dev/net/http#Response) 暴露 `ContentLength`、`TransferEncoding`、协议版本及 `Uncompressed`,并说明 `Body` 在读取时流式返回;这些字段支持**客户端边界**的分类,不暴露供应商上游到代理之间的完整性。
|
||||
- SSE 层:沿用 `done_marker|clean_eof|read_error|cancelled|invalid_frame`、`StreamComplete`、受限 `finishReason`、Usage 是否存在及数量、最后一个**已观察**帧是否完整;只增加尾部事件的结构类别与有界计数,如 `done_literal|json_frame|empty_data|comment|unknown_non_json|partial_frame`,用于区分本地解析遗漏与真正未见标记。**不记录未知帧文字、尾部字节、原始 SSE 或其内容哈希。**
|
||||
- 工具边界:分别记录“工具片段存在”“ID/名称齐全”“参数为 JSON 对象”“放行/实际执行次数”。现有 `ToolArgumentsValid` 只证明 JSON 对象可解析,不能偷换成 schema 或业务语义有效;本版不顺带新增工具 schema 校验器。缺 `[DONE]`、读取错误、取消、半帧、身份/参数不完整时仍为零放行、零执行。
|
||||
|
||||
所有字段只允许枚举、布尔和饱和计数;HTTP header/trailer 的名称与值、URL 查询、IP、请求 ID、证书细节、正文、思考、工具名及参数、prompt、API key、原始错误句均不入日志、评测记录或 UI。响应体计数只在流式读取时累计字节,不额外缓冲或复制模型内容。评测文件仍置于任务自有 0700 目录、0600 文件,保留期限沿现有受控评测清理规则;若需新增内部持久字段,实施计划须明确存储 owner、模式兼容与清理期限。公开 Core/HTTP/TaskSnapshot 合同和数据库表默认不变;发现必须改变时回到本设计重审。
|
||||
|
||||
`net/http` 可能自动解分块或解压,某些传输细节在 `Response.Body` 之上已不可见。实现计划应先用本地实验确定哪些字段能可靠观察;**不能观测就记 `unknown`**,不能为了满足一张表而声称看到了原始 HTTP 分块终止符或 HTTP/2 帧。响应体按协议完整读到 EOF,也只证明客户端收到的**响应体**结束,不能单独证明提供方本来就打算结束业务 SSE。真实路由的上游代理与供应商侧仍需外部契约或受控证据,不由客户端元数据代签。
|
||||
|
||||
## 决策规则与失败恢复
|
||||
|
||||
本版实现目标是**诊断,不放宽执行门禁**。终态首先按现有规则确定能否释放工具;新观察字段只给出原因与证据等级,不参与 `toolFinishExecutable` 的放行条件。非工具纯文本目前可以在缺 `[DONE]` 时按旧行为结束,但必须独立标注,不能把文本容忍路径借给工具。已返回 Usage 继续记账;诊断写入失败时保持原失败与停止决定,不让观察故障触发重试。取消、读错或多终态按保守失败处理;单次模型请求最多产生一条受限终态收据,Backend 不建立第二个状态所有者。
|
||||
|
||||
后续若要**提出**当前路由的等价终态规则,至少需要同时满足:① 可复核的供应商契约或该路由、模型、版本的授权外部证据,明确没有字面 `[DONE]` 时怎样表示业务完成;② 本地解析器能识别所约定的终止形式,并有正常、截断、半帧、缺 Usage、重定向/错误、取消的正反例;③ 客户端可区分响应体按协议结束与未知关闭,工具身份和参数完整性可验证,预算与停止门禁仍成立;④ 该规则只绑定经核验的路由身份,不对其他 OpenAI 兼容服务泛化。若还需声明 schema 校验,应在该轮方案中明定,不从当前 JSON 对象有效性推得。满足这些条件只进入**另一轮方案/计划评审**,不能自动改代码放行。若外部契约缺失、传输完整性未知或证据彼此矛盾,保持工具拒绝,并评估替代路由;不得因本次 513-token 探针成功返回 Usage 而补跑 A01。
|
||||
|
||||
## 零付费验证与阶段出口
|
||||
|
||||
详细实施计划获批前,本节只规定验收边界,不分派代码任务:
|
||||
|
||||
1. 本地 `httptest`/TLS HTTP/2 假流覆盖有 `[DONE]`、无 `[DONE]` 的完整 JSON、已知长度与字节不符、合法 chunked、连接中断、HTTP/2 正常结束、关闭分隔未知、自动解压、半帧、尾部非 JSON、缺 Usage、重定向、取消。对每例核对 HTTP 与 SSE 分层分类、已返回 Usage、工具放行/执行次数和后继请求数;至少一组证明“响应体按协议结束但无应用终止契约”仍拒绝工具。
|
||||
2. 以哨兵正文、思考、工具名、参数、header/trailer、凭据与未知错误文字扫描新终态记录、日志和浏览器可见面;不得出现这些原文。计数边界、负值/溢出、未知枚举和多终态都须保守。正常 `[DONE]` 工具调用与 r0.5 快通道确认、排队/失败卡、来源跳转、刷新及按 seq 更新不得回退。
|
||||
3. 固定 Agent-Native 与消费它的组件 SHA 后,做组件测试、Dev 组合 `make test && make build`、适用的真实 HTTP/浏览器及隔离 PostgreSQL 回归、独立重放和准确 HEAD CI;`SELF`、`REPLAY`、`GATE` 分开标注。零付费测试只证明观测机制,不证明 MiniMax 真实流或 A01 质量。真实模型、供应商账单和业务成果均标 `NOT_RUN`,直至另获资源批准。
|
||||
|
||||
阶段 4 的用户结论已记录在文首;现进入**详细实施计划编写**,计划仍待阶段 5 人工评审。计划获批后才可零付费改代码和验证。任何新付费探针或 A01 都须在固定新候选、单独资源提案与明确批准后进行;r0.5 一次性授权不能沿用。真实 U3 质量仍要求两条在终态前可感知且有用、有来源的阶段成果、准确完整最终正文及全部调用 Usage/停止规则,宿主收件确认不计入两条。质量未通过时八个 PR 保持草稿,不合入或部署。
|
||||
@@ -0,0 +1,257 @@
|
||||
# U3 r0.6 Transport Completion Evidence Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 在当前 MiniMax-M3 工具流上留下可重放、无内容的 HTTP 响应体与 SSE 业务终态分层证据,同时保持缺 `[DONE]` 时工具零执行。
|
||||
|
||||
**Architecture:** Agent-Native 在现有 `Client.Stream → ParseSSE` 链路里流式计数响应体并归类最后的 SSE 结构,合成一条只含有限枚举、布尔和饱和计数的 `TerminalObservation`。Backend 受控评测白名单归一化该观察,与实际 run ID、调用号和 Usage 一起落到受限记录;普通用户界面仍只展示任务卡的真实状态与有来源成果。此版不把 HTTP EOF 变成工具放行条件,也不修改模型路由或加请求。
|
||||
|
||||
**Tech Stack:** Go 1.27、`net/http`/`httptest`、Agent-Native OpenAI 兼容 SSE、Backend 受控评测与 SQLite、任务自有 Playwright 机制实例、Dev 组合测试和 Gitea CI。
|
||||
|
||||
**Spec:** [已获阶段 4 人工批准的 r0.6 书面设计](2026-10-14-fast-slow-u3-r06-transport-completeness-design.md)。批准对象 Documents `54d39ef13034b2ce84cb84681566ea21311f79a0`、Dev `89125b8dda5f8f988a8a760ed64bf00827e1de5c`;用户答复“批准设计,继续实施计划”。本计划本身**待阶段 5 人工评审**;该答复只授权编写计划,不授权以下代码步骤、付费探针、A01、合入或部署。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 范围固定为已核验的 MiniMax-M3、`api.minimaxi.com/v1`、无 fallback 的路由身份(保护文件 SHA-256 `2a92569d2416d74e8d07029219af88474cb6f860c2aa897a5ffdd10fcbe9b495`)。代码观察可以复用在 OpenAI 兼容客户端,但**解释与未来兼容决策只针对该路由**;路由字节或模型改变须重新评审。不得把 API key、路由文件原文或供应商数据写进仓库与收据。
|
||||
- 保持 `toolFinishExecutable` 原有判据:缺 `[DONE]`、读错、取消、半帧、工具身份或 JSON 对象参数不完整时,不释放或执行工具;不新增自动重试、补参数、模型回退、摘要模型调用或额外 provider 回合。文本缺标记的既有容忍路径不得扩给工具。
|
||||
- 新观察只保存有限枚举、布尔和饱和计数。不得保存原始 SSE/尾部字节及其内容哈希、正文、思考、prompt、工具名/参数、HTTP header/trailer 名称或值、URL 查询、IP、请求 ID、证书细节、API key、原始错误句。诊断不进入普通用户 UI,异步状态仍由原所有者按 seq 处理。
|
||||
- Agent-Native 的终态事件是唯一诊断来源;Backend 只白名单消费并保留已返回 Usage、实际 run ID、停止边界。既有公开 Core/HTTP/TaskSnapshot 合同、数据库表、前端状态 owner、r0.5 宿主确认及来源判定不改。若证明必须改公开契约、权限、持久模式或 UI,停止受影响单元,返回设计评审;UI 修改前先读 Dev `DESIGN.md` 并使用 `@ui` 令牌/原语。
|
||||
- r0.5 唯一付费探针已消耗授权,结果 `incomplete_terminal`、返回 Usage 513、工具 0;r0.4 A01 仍 FAIL,r0.5 真实 A01 仍 `NOT_RUN`。本计划实施阶段只跑假流、真实本地 HTTP/浏览器与隔离 PG/CI,不运行 `TestWorkCheckpoints`、不使用 `WORK_CHECKPOINT_SERVER_MODE=model`、不读取保护路由 key。新的供应商试验和 A01 均须候选固定后另交资源提案并获明确批准。
|
||||
- 每个源代码单元先 RED、再最小 GREEN、再组件测试与提交;证据经 Dev `make evidence` 保存,例如 `RECEIPT=/tmp/fast-slow-u3-r06-task1-red.json CMD='GOWORK=off go -C deps/agent-native test ./runtime/llm -run TestClientBodyBoundary -count=1' make evidence`,来源为 SELF。每次换一个未使用的收据路径。独立审阅重跑为 REPLAY;准确 HEAD CI 为 GATE。正式用户验收与所有 PR 合入仍在后续阶段,八个 PR 维持草稿。
|
||||
|
||||
## Review Focus
|
||||
|
||||
以下五类容易被“有 EOF/有 Usage”掩盖的输入必须由相应任务的测试直接覆盖:
|
||||
|
||||
1. 声明长度大于实际响应体:`TestClientBodyBoundaryShortRead`(Task 1)应记读取错误或长度不符,仍零工具。
|
||||
2. 自动 gzip 解压使线上长度不可直接比:`TestClientBodyBoundaryUncompressed`(Task 1)应记长度关系 `unknown`,不能伪造匹配。
|
||||
3. 合法 `[DONE]` 在客户端未读到 HTTP EOF 前出现:`TestClientDoneDoesNotNeedBodyEOF`(Task 1)应维持原有合法工具终态,不把新观测变成额外放行门槛。
|
||||
4. Usage 后出现注释、空 `data:`、未知非 JSON 或半帧:`TestSSETailStructure`(Task 2)只记结构类别,不泄漏原文;缺 `[DONE]` 的工具仍零释放。
|
||||
5. 上游或测试注入未知枚举、负数、超上限计数:`TestEvaluationTransportObservationSanitized`(Task 3)应归 `unknown`/钳制计数,不让供应商可控文字入评测记录。
|
||||
|
||||
## File Ownership Map
|
||||
|
||||
| 文件/组件 | 单一职责 |
|
||||
|---|---|
|
||||
| Agent-Native `runtime/llm/body_observation.go`、`client.go` | 只观察 HTTP 响应体读取与有限传输类别,不碰 SSE 内容或工具准入 |
|
||||
| Agent-Native `runtime/llm/sse.go`、`types.go` | SSE 尾部结构、现有 `[DONE]` 门禁及一个终态观察合同 |
|
||||
| Backend `internal/server/work_checkpoint_eval_test.go` | 在既有受控评测记录边界深拷贝并白名单化 Agent-Native 标量 |
|
||||
| Agent-Squad/Backend/Dev gitlinks | 使各消费方固定同一已提交 Native SHA;Dev 验证真实组合 |
|
||||
| Frontend 既有 Playwright 文件 | 只重放用户可见状态;本计划不修改前端生产代码 |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Agent-Native 流式 HTTP 响应体观察
|
||||
|
||||
**Files:**
|
||||
- Create: `deps/agent-native/runtime/llm/body_observation.go`(只计数和归类,不缓冲响应内容)
|
||||
- Modify: `deps/agent-native/runtime/llm/types.go`(`TerminalObservation.BodyBoundary` 加法字段)
|
||||
- Modify: `deps/agent-native/runtime/llm/client.go`(在既有响应上附观察,不改请求体/重定向/重试)
|
||||
- Test: `deps/agent-native/runtime/llm/client_test.go`
|
||||
|
||||
**Interfaces:** `TerminalObservation.BodyBoundary *BodyBoundaryObservation`;`BodyBoundaryObservation` 只包含 `ProtocolClass`(`http1|http2|other`)、`FramingClass`(`known_length|chunked|http2_stream|close_delimited|unknown`)、`DeclaredLengthKnown`、饱和的 `BytesRead`、`BytesSaturated`、`EOFSeen`、`LengthRelation`(`match|mismatch|unknown`)及 `Uncompressed`。`ParseSSE(ctx, io.Reader)` 的签名、`Event.StreamComplete` 和工具门禁不变;独立调用 `ParseSSE` 时 `BodyBoundary=nil`。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 在 `client_test.go` 增加上述三个 Review Focus 测试与 `TestClientBodyBoundaryChunkedAndHTTP2`。用 `httptest.NewServer` 显式设置正确/过长 `Content-Length`,用 `Flush` 生成 chunked,`httptest.NewUnstartedServer`+`EnableHTTP2`+`StartTLS` 生成 HTTP/2;gzip 用 `gzip.NewWriter` 返回压缩体。`TestClientDoneDoesNotNeedBodyEOF` 复用本文件已有的 `terminalRoundTripFunc`,返回含 `[DONE]`、但不要求随后读取到 `io.EOF` 的本地 `http.Response`,避免依赖真实网络调度。工具帧为本地固定 JSON;无 `[DONE]` 的用例必须同时断言 `len(end.Message.ToolCalls)==0`、返回 Usage 不丢、HTTPStatus 200。合法 `[DONE]` 用例必须保留当前可释放的 ToolCalls。测试只用本地假响应,不使用保护路由。
|
||||
|
||||
```go
|
||||
// 关键断言形状;同一表驱动覆盖已知长度、chunked、HTTP/2、gzip、短读。
|
||||
if end.TerminalObservation == nil || end.TerminalObservation.BodyBoundary == nil {
|
||||
t.Fatal("missing body boundary observation")
|
||||
}
|
||||
body := end.TerminalObservation.BodyBoundary
|
||||
if body.FramingClass != wantFraming ||
|
||||
body.LengthRelation != wantLengthRelation || body.EOFSeen != wantEOF {
|
||||
t.Fatalf("wrong body boundary: %+v", body)
|
||||
}
|
||||
if !wantDone && (end.StreamComplete || len(end.Message.ToolCalls) != 0) {
|
||||
t.Fatalf("unfinished tool stream was released: %+v", end)
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 记录 RED。** 在 Dev 工作树运行 `GOWORK=off go -C deps/agent-native test ./runtime/llm -run '^(TestClientBodyBoundary.*|TestClientDoneDoesNotNeedBodyEOF)$' -count=1`,由 Dev `make evidence` 保存原始 SELF 失败;预期因 `BodyBoundary` 字段/分类尚不存在而编译失败,不改测试绕过。
|
||||
- [ ] **Step 3: 最小 GREEN。** 在 `types.go` 定义上面的导出结构;`body_observation.go` 用 `io.Reader` 包装 `resp.Body`,仅对 `Read` 返回的 `n` 累加,饱和上限 `32*1024*1024+1`,记录 `io.EOF`,绝不复制 `p[:n]`。以 `resp.ProtoMajor`、`ContentLength`、`TransferEncoding`、`Close` 和 `Uncompressed` 归类;已知长度只在未自动解压、未饱和且读到 EOF 时比较,其他情况记 `unknown`。`client.run` 对一次 `http.Client.Do` 的成功响应把计数器传给 `ParseSSE`,只在终态事件附上快照;HTTP 错误/请求前错误仍保留原错误分类。
|
||||
|
||||
```go
|
||||
type BodyBoundaryObservation struct {
|
||||
ProtocolClass, FramingClass string
|
||||
DeclaredLengthKnown bool
|
||||
BytesRead int64
|
||||
BytesSaturated, EOFSeen bool
|
||||
LengthRelation string
|
||||
Uncompressed bool
|
||||
}
|
||||
// 现有 TerminalObservation 追加:BodyBoundary *BodyBoundaryObservation `json:"bodyBoundary,omitempty"`
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN 与边界。** 重跑 Step 2;再从 Dev 运行 `GOWORK=off go -C deps/agent-native vet ./runtime/llm` 与 `GOWORK=off go -C deps/agent-native test ./runtime/llm -count=1`。补一例关闭分隔/无法可靠判断的响应,必须为 `unknown`;检查取消、HTTP 4xx、重定向和读取失败都不产生虚假的 `EOFSeen=true`。`resp.Body.Close` 的结果不得被解释成业务流已完成。
|
||||
- [ ] **Step 5: 提交 Agent-Native Task 1。** 仅提交列出的结构、读取包装和测试,英文祈使句主题及 Why/Evidence/Impact/Refs 正文;推送现有 Agent-Native 草稿 PR #46,核对准确组件 HEAD 的 CI。此时 `BodyBoundary` 仍不影响工具执行。
|
||||
|
||||
### Task 2: Agent-Native SSE 尾部结构分类
|
||||
|
||||
**Files:**
|
||||
- Modify: `deps/agent-native/runtime/llm/types.go`(`TailEventKind`、`TailEventCount`)
|
||||
- Modify: `deps/agent-native/runtime/llm/sse.go`(在现有 reader/解析器内部统计结构,不存 data 内容)
|
||||
- Test: `deps/agent-native/runtime/llm/sse_test.go`
|
||||
|
||||
**Interfaces:** `TerminalObservation.TailEventKind` 为 `done_literal|json_frame|empty_data|comment|unknown_non_json|partial_frame|unknown`,`TailEventCount` 饱和到 `10000`。它们与 Task 1 的 `BodyBoundary` 并列,不能设置 `StreamComplete` 或绕过 `toolFinishExecutable`。`sseEventReader.next()` 可在内部增观察状态,但不改公开 `ParseSSE` 签名。
|
||||
|
||||
- [ ] **Step 1: 写 RED。** 新增 `TestSSETailStructure` 表驱动假流:合法 JSON+Usage 后分别接注释、空 `data:`、`data: NOT_DONE`、截断 `data: {`;另加 `[DONE]` 与纯文本无 `[DONE]` 正常对照。每例断言精确尾部枚举、计数范围、`ReadOutcome`、`StreamComplete` 和已返回 Usage;缺 `[DONE]` 或坏帧时工具调用零释放,合法 `[DONE]` 工具对照仍释放一条但本测试不执行工具。序列化观察不得含 `PRIVATE_TAIL_R06` 哨兵。`TestSSETailCountSaturates` 连续发超过 10000 个无内容注释并检查计数不溢出。
|
||||
|
||||
| 两个 JSON 帧后的尾部(纯文本例只有一个 JSON 帧) | `TailEventKind` | `TailEventCount` | `ReadOutcome` |
|
||||
|---|---|---:|---|
|
||||
| `[DONE]` | `done_literal` | 3 | `done_marker` |
|
||||
| 直接 EOF | `json_frame` | 2 | `clean_eof` |
|
||||
| 单独注释后 EOF | `comment` | 3 | `clean_eof` |
|
||||
| 空 `data:` | `empty_data` | 3 | `invalid_frame` |
|
||||
| `data: NOT_DONE` | `unknown_non_json` | 3 | `invalid_frame` |
|
||||
| 截断 `data: {` | `partial_frame` | 3 | `invalid_frame` |
|
||||
| 单个纯文本 JSON 后 EOF | `json_frame` | 1 | `clean_eof` |
|
||||
|
||||
```go
|
||||
got := end.TerminalObservation
|
||||
if got == nil || got.TailEventKind != wantKind || got.TailEventCount != wantCount {
|
||||
t.Fatalf("wrong tail observation: %+v", got)
|
||||
}
|
||||
raw, err := json.Marshal(got)
|
||||
if err != nil || strings.Contains(string(raw), "PRIVATE_TAIL_R06") {
|
||||
t.Fatalf("unsafe tail observation: %s err=%v", raw, err)
|
||||
}
|
||||
if wantToolRejection && len(end.Message.ToolCalls) != 0 {
|
||||
t.Fatal("tail evidence released an incomplete tool")
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 记录 RED。** 从 Dev 运行 `GOWORK=off go -C deps/agent-native test ./runtime/llm -run '^(TestSSETailStructure|TestSSETailCountSaturates)$' -count=1`;用 Dev evidence 收据保存失败,预期新字段缺失。
|
||||
- [ ] **Step 3: 最小 GREEN。** `sseEventReader` 在完成一个结构事件时更新有限 `tailKind` 和饱和 `tailCount`;`emitParsed` 在成功 JSON、字面 `[DONE]`、空 data、非 JSON 与 JSON 末尾截断时归类。仅以 `json.SyntaxError` 的类别/结束位置区分 `partial_frame` 与其他 `unknown_non_json`,不能记录错误原句或帧字节。注释在 reader 中计数但继续保持原忽略行为;超出计数上限只饱和。`observation()` 把标量送到原终态事件,绝不修改 `sawDone` 的唯一设置点。
|
||||
|
||||
```go
|
||||
const maxObservedTailEvents = 10000
|
||||
func noteTail(kind string, count *int, last *string) {
|
||||
if *count < maxObservedTailEvents { *count = *count + 1 }
|
||||
*last = kind
|
||||
}
|
||||
// sawDone 仍仅在 data == "[DONE]" 分支设为 true。
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 跑 GREEN 与全量组件回归。** 重跑 Step 2,另外从 Dev 运行 `GOWORK=off go -C deps/agent-native vet ./...` 与 `GOWORK=off go -C deps/agent-native test -count=1 ./...`,保留现有多片工具参数、缺 `[DONE]`、读错、取消、纯文本与合法 `[DONE]` 正反例。检查单次流只发一个终态,且新增字段不带未知文本。
|
||||
- [ ] **Step 5: 提交并推送 Agent-Native Task 2。** 只提交本单元差异;当前 Agent-Native HEAD 成为 Backend/Agent-Squad 的唯一嵌套 pin,等待其准确 HEAD CI。若本地假流暴露解析器确实漏认合法结束形式,仅记录发现并回到方案评审,不能顺手放宽工具门禁。
|
||||
|
||||
### Task 3: Backend 无内容归一化与失败后停止
|
||||
|
||||
**Files:**
|
||||
- Modify: `modules/backend/deps/agent-native`(固定 Task 2 Agent-Native SHA)
|
||||
- Modify: `deps/agent-squad/deps/agent-native`、`modules/backend/deps/agent-squad`(先固定 Agent-Squad 的相同 Native SHA,再由 Backend 消费)
|
||||
- Modify: `modules/backend/internal/server/work_checkpoint_eval_test.go`(`evalTerminalObservation` 白名单复制)
|
||||
- Test: `modules/backend/internal/server/work_checkpoint_eval_budget_test.go`(现有 `live` tag、本地 fake provider)
|
||||
|
||||
**Interfaces:** 消费 Task 1/2 的 `TerminalObservation.BodyBoundary`、`TailEventKind`、`TailEventCount`,只写入既有 `evalCallRecord.TerminalObservation`;`evalCallRecord` 的 run ID/调用号/Usage/failureClass 及 Backend 预算停止逻辑不变。必须深拷贝嵌套观察并将所有字符串缩至已定义枚举、负数钳为 0、过大计数钳至 Agent-Native 上限。没有公开 API、数据库或生产模型路由改动。
|
||||
|
||||
- [ ] **Step 1: 固定消费依赖。** 在 Agent-Squad 草稿分支将 `deps/agent-native` 固定到 Task 2 的提交,从 Dev 运行 `GOWORK=off go -C deps/agent-squad vet ./...`、`GOWORK=off go -C deps/agent-squad test -count=1 ./...`,提交并推送 PR #53。随后在 Backend 草稿分支将嵌套 `deps/agent-native` 与 `deps/agent-squad` 固定到这两个**已提交**的 SHA;用 `git rev-parse HEAD` 分别核对组件及嵌套指针,不以游离工作树代码作为依赖。Dev 的完整 `make test-pins` 留到 Task 4 暂存最新三条主 gitlink 后再运行。
|
||||
- [ ] **Step 2: 写 RED。** 在 `work_checkpoint_eval_budget_test.go` 新增 `TestEvaluationTransportObservationSanitized`:fake provider 传入 `TailEventKind="PRIVATE_TAIL_R06"`、`ProtocolClass="PRIVATE_HEADER_R06"`、负数/超上限计数和含正文的终态,同时给出 Usage 17;断言新 `provider-records.json` 只有归一后的 `unknown`、0/上限、run ID 和 Usage,不含哨兵、原始 `messages`/`terminal`。再加 `TestEvaluationTransportEvidenceStopsAfterUnmarkedToolEOF`:fake provider 仿照当前 Agent-Native 的失败终态发 `KindMessageEnd`、`StopReason=StopError`、非 nil `Err`、`FinishReason=tool_calls`、Usage17、`ReadOutcome=clean_eof`、`StreamComplete=false`、空 ToolCalls;第二次请求被拒,provider 调用数仍 1、落盘 Usage17、工具 0。沿用现有 `TestEvaluationStopsAfterMalformedToolTerminal` 的停止构造。
|
||||
|
||||
```go
|
||||
clean := evalTerminalObservation(terminal.TerminalObservation)
|
||||
if clean.TailEventKind != "unknown" || clean.BodyBoundary.ProtocolClass != "other" ||
|
||||
clean.TailEventCount < 0 || clean.BodyBoundary.BytesRead < 0 {
|
||||
t.Fatalf("unbounded observation: %+v", clean)
|
||||
}
|
||||
if strings.Contains(string(recordJSON), "PRIVATE_TAIL_R06") || providerCalls.Load() != 1 {
|
||||
t.Fatal("content leaked or a failed terminal caused another request")
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 记录 RED。** 只运行本地假 provider:从 Dev 执行 `GOWORK=off go -C modules/backend test -tags live ./internal/server -run '^(TestEvaluationTransportObservationSanitized|TestEvaluationTransportEvidenceStopsAfterUnmarkedToolEOF)$' -count=1`,用 Dev evidence 保存原始失败。**不得**运行宽泛 `go test -tags live ./...`、`TestServeWorkCheckpointEval` 的 `model` 模式或任何受保护路由。
|
||||
- [ ] **Step 4: 最小 GREEN。** `evalTerminalObservation` 从输入构造新 `TerminalObservation`,分别白名单 `ReadOutcome`/`TailEventKind`、BodyBoundary 的 `ProtocolClass`/`FramingClass`/`LengthRelation`,再复制布尔与钳制计数;未知协议类归 `other`,未知其他枚举归 `unknown`。不给 `evalCallRecord` 加原始 Event、header/trailer 或错误消息。先持久化 Usage 与失败记录,再按现有 gate 放行终态;记录失败仍阻止后继调用。
|
||||
|
||||
```go
|
||||
func clampCount(value, limit int64) int64 {
|
||||
if value < 0 { return 0 }
|
||||
if value > limit { return limit }
|
||||
return value
|
||||
}
|
||||
// 对 *observation.BodyBoundary 深拷贝后逐字段白名单,不保留输入指针。
|
||||
```
|
||||
|
||||
- [ ] **Step 5: 跑 GREEN 与控制组。** 重跑 Step 3,并从 Dev 运行 `GOWORK=off go -C modules/backend test -tags live ./internal/server -run '^(TestEvaluationRecordsContentFreeTerminal|TestEvaluationRedactsProviderControlledTerminalLabels|TestEvaluationStopsAfterMalformedToolTerminal|TestEvaluationKeepsUsageOnTerminalFailure|TestEvaluationStopsWhenProviderRecordUnavailable)$' -count=1`;再运行 Backend `GOWORK=off go -C modules/backend vet ./...`、`GOWORK=off go -C modules/backend test -count=1 ./...`。`go test -tags live` 的每条命令都必须有上述**精确锚定的 `-run`**,不触发真实模型样本。
|
||||
- [ ] **Step 6: 提交 Backend。** 将已固定的 Agent-Native/Squad gitlink 与归一化代码、测试一起提交到现有 Backend 草稿 PR #193;核对 Backend 真实 HEAD、Agent-Native/Squad 嵌套 pin 和组件 CI,保持两个消费方使用同一 Native SHA。
|
||||
|
||||
### Task 4: 组合重放、独立审阅与阶段 6 候选
|
||||
|
||||
**Files:**
|
||||
- Modify: Dev `deps/agent-native`、`deps/agent-squad`、`modules/backend` gitlinks
|
||||
- Modify: Dev `.task/feature-fast-slow-u2-u3-plan.md`、`PROJECT.md` 和 Documents `docs/reports/2026-10-13-fast-slow-u2-u3-validation.md`(只记录实际结果)
|
||||
- Test without product edits: `modules/frontend/e2e/work-checkpoints.playwright.ts` 的现有宿主确认、失败和来源场景
|
||||
|
||||
**Interfaces:** 固定 Task 1–3 的精确 Agent-Native/Agent-Squad/Backend SHA;不变更 Frontend/UI/Core 的公开契约或代码。Dev、Backend 和 Squad 的嵌套 Agent-Native gitlink 必须同值,Backend 嵌套 Squad 指针与 Dev 同值;平台 PR 都保持草稿。任务自有 HTTP 机制实例必须 `WORK_CHECKPOINT_SERVER_MODE=mechanism`,不得接入业务实例或真实模型。
|
||||
|
||||
- [ ] **Step 1: 固定 pin 并跑组合。** Agent-Native → Agent-Squad/Backend → Dev 按依赖顺序提交并推送;Dev 暂存实际 gitlink 后用 evidence 分别运行 `make test-pins`、`make test`、`make build`。文档记录准确 SHA、原始退出码及来源,任何子仓未提交的工作树差异不能冒充 pin。若上游主干推进,按 Dev `make task-sync` 解决冲突并据影响重跑。
|
||||
- [ ] **Step 2: 建立任务自有机制实例。** `modules/frontend/e2e/work-checkpoints.playwright.ts` 与 `TestServeWorkCheckpointEval` 都要求数据目录名含 `fast-slow-u2-u3-`。先验证 `/tmp/fast-slow-u2-u3-r06-20261014` 不存在,创建 0700 目录;在 Dev 工作树执行下面的命令。`mode=mechanism` 使用代码内 fake stream;`env -u` 确保旧模型路由和 A01 标签不被继承。将启动命令与 PID 写入 SELF 收据,不把 server 日志中的模拟内容当成供应商证据。
|
||||
|
||||
```bash
|
||||
R06_RUN_ROOT=/tmp/fast-slow-u2-u3-r06-20261014
|
||||
mkdir -m 0700 "$R06_RUN_ROOT"
|
||||
GOWORK=off go -C modules/backend test -tags live -c -o "$R06_RUN_ROOT/server.test" ./internal/server
|
||||
R06_DEV_SHA=$(git rev-parse HEAD)
|
||||
R06_BACKEND_SHA=$(git -C modules/backend rev-parse HEAD)
|
||||
env -u WORK_CHECKPOINT_ROUTE_FILE -u WORK_CHECKPOINT_EXTRA_A01 \
|
||||
WORK_CHECKPOINT_SERVER_MODE=mechanism \
|
||||
WORK_CHECKPOINT_SERVER_DATA="$R06_RUN_ROOT/mechanism-data" \
|
||||
WORK_CHECKPOINT_SERVER_MANIFEST="$R06_RUN_ROOT/manifest.json" \
|
||||
WORK_CHECKPOINT_MECHANISM_NOTICES=1 \
|
||||
WORK_CHECKPOINT_DEV_SHA="$R06_DEV_SHA" WORK_CHECKPOINT_BACKEND_SHA="$R06_BACKEND_SHA" \
|
||||
"$R06_RUN_ROOT/server.test" -test.run '^TestServeWorkCheckpointEval$' \
|
||||
>"$R06_RUN_ROOT/server.log" 2>&1 &
|
||||
R06_SERVER_PID=$!
|
||||
printf '%s\n' "$R06_SERVER_PID" >"$R06_RUN_ROOT/server.pid"
|
||||
chmod 0600 "$R06_RUN_ROOT/server.pid"
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 验证实例身份并启动预览。** 从任务自有 `server.pid` 读取 `R06_SERVER_PID`;用 `python3 -c 'import json; print(json.load(open("/tmp/fast-slow-u2-u3-r06-20261014/manifest.json"))["base"])'` 取本地 API;核对 manifest PID、`binary` 与 `/proc/$R06_SERVER_PID/exe`、`binarySHA256` 与 `sha256sum`、Dev/Backend SHA 与当前 HEAD。另分别用 `git -C deps/agent-native rev-parse HEAD`、`git -C deps/agent-squad rev-parse HEAD` 及 Backend 嵌套 gitlink 对照 Dev pin;当前 manifest 不包含 Native/Squad 字段,不能声称它自己已核对这两个 SHA。确认 `127.0.0.1:4186` 未被占用后运行下面的 preview;若端口被占,停在本步骤并选一个新的任务自有端口,记录实际值,不连接已有服务。
|
||||
|
||||
```bash
|
||||
R06_RUN_ROOT=/tmp/fast-slow-u2-u3-r06-20261014
|
||||
R06_SERVER_PID=$(cat "$R06_RUN_ROOT/server.pid")
|
||||
for R06_WAIT in $(seq 1 80); do
|
||||
test -s "$R06_RUN_ROOT/manifest.json" && break
|
||||
sleep 0.25
|
||||
done
|
||||
test -s "$R06_RUN_ROOT/manifest.json"
|
||||
R06_API_BASE=$(python3 -c 'import json; print(json.load(open("/tmp/fast-slow-u2-u3-r06-20261014/manifest.json"))["base"])')
|
||||
python3 -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1",4186)); s.close()'
|
||||
PLAYWRIGHT_API_TARGET="$R06_API_BASE" npm --prefix modules/frontend run preview -- --host 127.0.0.1 --port 4186 --strictPort \
|
||||
>"$R06_RUN_ROOT/preview.log" 2>&1 &
|
||||
R06_PREVIEW_PID=$!
|
||||
printf '%s\n' "$R06_PREVIEW_PID" >"$R06_RUN_ROOT/preview.pid"
|
||||
chmod 0600 "$R06_RUN_ROOT/preview.pid"
|
||||
for R06_WAIT in $(seq 1 80); do
|
||||
curl -fsS -o /dev/null http://127.0.0.1:4186/ && break
|
||||
sleep 0.25
|
||||
done
|
||||
curl -fsS -o /dev/null http://127.0.0.1:4186/
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 跑浏览器并清理任务实例。** 在 Frontend 工作树运行下面的命令,核对可信首回合、零/部分失败、来源、刷新和 390px 窄屏;不改变现有 UI 文案、焦点或 seq 投影。使用 Dev `make evidence` 的源码外收据捕获完整输出,保存 trace;核对 `server.pid`、`preview.pid` 和 `/proc` 身份后,只停止这两个任务自有进程。
|
||||
|
||||
```bash
|
||||
PLAYWRIGHT_BASE_URL=http://127.0.0.1:4186 \
|
||||
WORK_CHECKPOINT_HTTP_MANIFEST=/tmp/fast-slow-u2-u3-r06-20261014/manifest.json \
|
||||
npx playwright test e2e/work-checkpoints.playwright.ts --reporter=list
|
||||
```
|
||||
|
||||
- [ ] **Step 5: 隔离 PG 与 CI。** Dev 必需 `test-pg` 作业在新容器中启动真实 PostgreSQL/Redis,执行 `make test-backend-pg` 和双进程生命周期;不得把 SQLite 或 SKIP 当成 PG。先核对 Agent-Native #46、Agent-Squad #53、Backend #193 以及 Dev #512 的准确 HEAD CI,再核对 Dev 的 `test`、`test-pg`、`svc-realcombo` 三项作业和全部步骤在**同一最新 Dev HEAD** 成功,记录 GATE 运行链接、runner 和 SHA。若本地另起隔离 PG,先查数据根/实例 PID 与 DSN 身份,不能连接现有 8788 实例。
|
||||
- [ ] **Step 6: 独立复审。** 未参与实现的审阅者对固定候选重跑 Task 1 的已知长度/gzip/DONE 对照、Task 2 的尾部结构、Task 3 的脱敏/停止最小集,先读命令×SHA×输出再读作者解释;审阅重点是正常 HTTP 结束不被写成 SSE 完成、未知类别不落原文、JSON 对象不被说成 schema 有效、缺 `[DONE]` 零工具且 Usage 保留。Critical/Important 闭合并在实际新 HEAD 补测之前,不提交阶段 6 结论。
|
||||
- [ ] **Step 7: 提交阶段 6 人工评审材料。** 任务卡与 Documents 核验报告映射 r0.6 设计条款 → 文件/测试 → SELF/REPLAY/GATE 证据,写明真实 MiniMax 再测和 r0.5 A01 `NOT_RUN`、r0.4 FAIL、当前路由原因仍可能 `unknown`。给用户审阅零付费机制候选;即使阶段 6 通过,仍须单独资源提案才可进行新的真实请求,再经阶段 7 人工验收。安全/质量失败时八个 PR 继续草稿,不合入或部署。
|
||||
|
||||
## Plan Self-Review And Stop Conditions
|
||||
|
||||
| r0.6 设计条款 | 实施/验证归属 |
|
||||
|---|---|
|
||||
| HTTP 响应体协议、定界、读数、EOF 与未知处理 | Task 1 的 `BodyBoundary`、已知长度/gzip/chunked/HTTP2/DONE 对照 |
|
||||
| SSE 尾部结构、不泄漏未知帧、缺 `[DONE]` 继续拒绝 | Task 2 的 `TailEventKind`、饱和计数和无标记反例 |
|
||||
| 实际 run ID/Usage、有限白名单、失败后零后继请求 | Task 3 的归一化与 fake provider 拒绝测试 |
|
||||
| 普通用户界面、来源、失败状态和 seq 不回退 | Task 4 的任务自有 HTTP/Playwright 与准确 HEAD 组合 |
|
||||
| 供应商契约不足时不放宽、真实 A01 另审 | Global Constraints、Task 4 阶段 6 材料与以下停止条件 |
|
||||
|
||||
Task 1 拥有 HTTP 读取边界,Task 2 拥有 SSE 结构,Task 3 拥有持久评测白名单,Task 4 只固定真实组合和用户链回归;没有第二个异步状态 owner、公开 schema 变更或额外模型回合。五项 Review Focus 都指向各任务的命名测试。
|
||||
- 发现 Go `net/http` 无法可靠暴露某种原始传输分隔方式时,记录 `unknown` 与零付费证据,不读取原始网络字节“补齐”;发现供应商另有终止形式时仅记录事实,**不**在本计划中放宽工具门禁。需要新的路由、公开字段、数据库迁移、权限、模型预算或 UI 变更时,停止受影响单元并返回设计/计划人工重审。
|
||||
- 本计划的交付终点是零付费、可审阅的阶段 6 候选。当前用户只批准**写计划**,Task 1–4 的代码、浏览器/PG 重放、真实模型对照和合入均 `NOT_RUN`。书面计划获阶段 5 人工批准后,按既有任务 worktree 同会话实施;任何真实 provider 请求仍须候选固定和单独资源批准。
|
||||
@@ -0,0 +1,211 @@
|
||||
# IAM U3:账号资料、有效态、受控目录与本人恢复
|
||||
|
||||
版本:r1 草案;日期:2026-10-14;owner:weichen。状态:待阶段 4–5 人工评审,未实施、未验收、未合入、未部署。
|
||||
|
||||
主任务:Dev `feature/iam-u3-account-directory-recovery`。承接用户对下一步 U3 的“授权”、[统一方案 r1](2026-10-13-identity-role-permission-plan.md) U3 及 [IAM-D/IAM-C 合同](2026-10-13-iam-i1-permission-contract.md) §5–6。统一方案原文 SHA256 为 `39b8e9a6e078dc509bd80118c1807ce6ed23e4466e5902b51f4bfa255d55c0a1`,本补充不修改其正文,不扩展到 U4–U9。
|
||||
|
||||
本文落实已经批准的人员资料、管理员业务隔离和本人恢复原则,补齐实际公共接口与切换方法。网页建号不再接受初始密码/管理员位、旧凭据不能自动成为本人证明,是本次需要明确审阅的兼容取舍。用户的启动授权不代替新对象的阶段评审。Review、CI 与合入按 Dev `policy/delivery.md`;生产迁移、部署、服务/真实账户操作、异常人工恢复和清理另行授权。
|
||||
|
||||
## 1. 核查对象与现状
|
||||
|
||||
以下仅为固定源码观察(SELF),不是运行结果。业务测试、真实 PostgreSQL 重放、浏览器、部署及迁移均 `NOT_RUN`。
|
||||
|
||||
| 对象 | 固定版本/位置 | 观察及影响 |
|
||||
|---|---|---|
|
||||
| Dev 启动基线 | `add097d06137c4912a4ed9279e98ca353e4e4cf1` | 已取得启动收据并建立独立任务工作区;原 I1 已交付,不重做 |
|
||||
| Backend | `5d5fc9891c0eb8994545ccb8b740535d9b99fb0e`,`internal/store/auth.go` | `users.id/owner` 稳定,已有姓名、原子建号及 auth_version;缺资料版本与停用状态 |
|
||||
| 当前扩展面 | 同 Backend,`pkg/extension/extension.go`、`internal/app/hostcaps.go` | 实际为 `2.12.0-experimental`,EXT-19 已有 Name 和姓名搜索;目录直接取所有账号,Valid 恒 true,无提供者字段授权 |
|
||||
| 认证与恢复 | 同 Backend,`internal/server/accounts.go`、`internal/store/login_keys.go` | 管理员仍直接取目标明文 Key/设置密码;SessionInfo 不核对当前账号版本;部分最终写缺同账号锁/CAS |
|
||||
| RDM 消费源码 | `6fcb256205c2384abed35d3b6ab96ca7216e9297` | 成员目录有 member.manage 检查;缺能力时有效性检查放行、调用者丢弃错误;三权只校验项目成员关系 |
|
||||
| Frontend | Dev 基线所固定版本,`src/components/adminSections.tsx`、`src/api.ts` | 管理页提供签发/复制目标恢复 Key;必须随新合同收口,不能只改 Backend |
|
||||
| 本文 Documents 起点 | 权威 `origin/main`:`7bd4e17827d4c7c88647bf3c9199c495b60cb107` | 独立 `feature/iam-u3-account-contract`;不在 Dev 的固定子模块里改源码 |
|
||||
|
||||
Backend `account_lifecycle_test.go`、`login_keys_test.go` 和现有 HTTP auth helper 大量硬编码 OpenSQLite。仅设置 PG DSN 不会让这些场景在 PostgreSQL 执行;历史报告中的 PG 覆盖不能作为本轮证据。
|
||||
|
||||
在途 `feature/svc-account-durability-plan` 当前授权集中于文档/svc 帮助及其测试,不替代 U3 业务实施。实施前再核验 Backend/RDM 权威 HEAD、在途迁移及写者范围;迁移编号和扩展面次版本由当时基线分配,不预占 v31 或 2.13。
|
||||
|
||||
## 2. 需求、范围与验收对象
|
||||
|
||||
| 需求 | 本轮具体结果 | 可判定验收条件 |
|
||||
|---|---|---|
|
||||
| R3/R5 | 可选资料及独立资料写面 | 姓名、电话、邮箱、工号、部门、备注全部可空;填写/清空保持原 userId、owner、角色、凭据和业务数据;本人不能借资料 patch 改权限 |
|
||||
| R4/R5 | 精确/模糊、字段与状态过滤、分页及最小候选投影 | 同名不误选;未授权字段不返回、不匹配、不影响数量/分页;稳定 ID 决定选择对象;职位过滤明确留 U4 |
|
||||
| R11/R12 账号部分 | 有效态、认证与执行边界检查 | 停用拒绝新请求/登录/兑换,旧会话与 API key 不再认证,候选人不能提交,持续流停止新输出;启用不恢复已撤会话和 Key |
|
||||
| R7/R12 恢复部分 | 管理员提案、独立本人确认、受限兑换 | 管理员拿不到目标设密能力;初始密码/旧 Key 派生链不成为证明;无独立证明线上拒绝;完成后本人重新密码登录 |
|
||||
|
||||
U3 不建设通用职位权威、多职绑定、角色 cap 配置、完整管理矩阵、项目职位重选或统一跨库 authorityEpoch。现有 RDM 单角色、项目成员及文档职责保持各自权威。本人资料和恢复只在必要的既有界面中闭合;完整系统用户/职位配置体验仍是 U7。
|
||||
|
||||
## 3. 单一账号权威与数据
|
||||
|
||||
Backend 复用 `users.id` 与唯一 `owner`;owner 仍为登录名/兼容定位,不允许资料修改改变身份。RDM 不复制账号表,不把显示名或工号当身份主键。
|
||||
|
||||
| 数据 | 规则 |
|
||||
|---|---|
|
||||
| Profile | `name/phone/email/staffNo/department/notes` 默认空;`profileVersion` 独立递增,显式空值表示清空;未知字段整体拒绝 |
|
||||
| AccountState | `enabled`、`stateVersion`;valid 表示账号存在且 enabled。未设密码/强制改密是独立认证限制,不混作停用 |
|
||||
| Credential lineage | 持久来源及是否具备本人证明资格;`legacy_unknown` 默认无资格,普通管理员路径永远不能提升资格 |
|
||||
| Sessions | 保存受信认证方式、凭据来源、auth_version;受限会话关联确切 activation/recovery grant;未知来源不作证明 |
|
||||
| Directory revision | 独立、持久、事务内更新;候选目录版本只受其可见辨识资料/有效态变化影响,私密联系方式编辑不能成为候选查询的侧信道 |
|
||||
| Recovery | 独立 proposal/proof-session 引用/grant 记录;仅存随机凭据摘要,保留目标、用途、到期、状态、版本、操作者与因果关联 |
|
||||
|
||||
建议长度上限:姓名 128、电话 64、邮箱 254、工号 64、部门 128、备注 2000 个 Unicode 字符;邮箱空值合法,非空做基础格式校验。电话只 trim,不猜国家码/号码归一化;文本不强制唯一。拒绝控制字符和超限输入,不静默截断。搜索限制 128 字符,参数化查询,并转义 LIKE 通配符。
|
||||
|
||||
资料 patch 只允许六个字段,要求 expectedProfileVersion;读取/写入按稳定 userId。请求中的 owner 若用于兼容,必须与服务端 ID 映射一致。`isAdmin/enabled/roles/password/proof` 等字段不能混入 profile 或普通建号请求。
|
||||
|
||||
网页账号管理只创建无凭据的普通账号,可选资料全空成功;初始密码/管理员位参数明确拒绝,不能忽略后继续建号。新建记录持久标识 pending initialization,迁移中的既有未知账号不能推断为该状态。首管及新账号首凭据建立由可信本地 owner/bootstrap 边界完成,其来源持久为可信 owner 初始化;网页管理员不能通过旧 activate 接口补领凭据。
|
||||
|
||||
补充窄 CLI `user initialize-account <userId>`:由受信机器/DB owner 为尚无密码、无历史完成初始化、无其他既有凭据的新待初始化账号建立首 activation grant,要求 expectedStateVersion/初始化 generation,保持原 userId、owner、管理员位及业务关系。网页创建后的待初始化账号和本地新账号都走同一服务。Key 过期、交付失败或已兑换但尚未完成首次设密时,可信 owner 可以显式续办:在同账号事务中撤旧 activation grant/派生受限会话,推进 generation 后重新交付;不得重复建号,不改变已完成初始化账号的密码。完成首次设密的事务把状态改为 initialized,后续所有 initialize/reissue 都拒绝。
|
||||
|
||||
首管 bootstrap 的建号/首 activation grant 保持同事务;其过期续办也仅限上述已明确来源的 pending 状态,不借“用户库非空”重建首管。generic activate、reset 与该 initializer 明确分开,普通系统管理员、HTTP/Host/角色 grant 均不能调用 initializer。CLI 来源记录实际本地操作者及目标,不接受 --actor 自报成为授权;秘密仅交受信 owner 的保护交付通道。代码与隔离测试纳入 U3,真实机器/DB owner 身份核对、首次交付及续办运行仍须另行批准的操作计划,不用可选资料验证收件人。
|
||||
|
||||
## 4. 受保护系统动作与资料权限
|
||||
|
||||
U4 前保留一份 Backend 受保护账号管理适配器,仅识别 `system.users.view/create/edit/disable` 与 `credential.recover`,以当前有效的既有系统管理员资格为过渡来源。该适配器不是通用 Role/SystemGrant 新权威,不给项目 grant 赋予系统资料权限,也不把插件 `Host.IsAdmin()` 布尔当新目录授权回执。
|
||||
|
||||
本人可读/改六个非授权资料字段,须正常、有效完整密码会话;受限设密会话只走设密门。系统资料读取和搜索需 system.users.view,编辑需 edit,停用需 disable,恢复提案需 credential.recover。调用方、对象、资格及 expectedVersion 在写事务中重验;资格读取失败拒绝。
|
||||
|
||||
启用/停用与资料分别提交、分别版本化。停用事务锁定受保护管理者集合,保证至少一个有效且具备可用正常认证能力的系统管理者;PG 使用共同的锁顺序/管理者保护锁,SQLite 使用写事务,禁止“先 count 后独立 update”。并发停用最后两名管理者最多成功一个。
|
||||
|
||||
停用不物理删除账号或密码摘要,不改历史业务归属。事务内推进认证版本、撤销 API key、会话、激活/恢复 grant 与提案,并审计;启用后必须重新认证,已撤对象永不自动恢复。
|
||||
|
||||
## 5. IAM-D 提供者、授权与候选范围
|
||||
|
||||
新增可选 `AccountDirectoryProvider`,不向既有 Host 增加必实现方法;提供查询与精确候选查验两个入口。下列是冻结的语义形态,Go 的具体命名及签名可在同语义下按仓内规范落实:
|
||||
|
||||
| 合同 | 输入/输出 |
|
||||
|---|---|
|
||||
| Query | schemaVersion、purpose、领域及 project/document locator、exact/fuzzy 模式、query、searchFields、状态过滤、cursor、limit;不接受 Actor、isAdmin 或 allowedFields 输入 |
|
||||
| Page | userId、owner、valid、获准 name/staffNo;opaque directoryVersion、nextCursor。候选目录不提供全系统总数或 bulk export |
|
||||
| Exact lookup | 在同一 purpose/locator 下指定稳定 userId(兼容 owner 必须显式标识并解析);只返回确定身份、valid 与当前版本,不扫描整个目录 |
|
||||
| 专用注册口 | 可选目录授权 Registrar,由受信进程内 RDM 注册;重复/冲突注册拒绝。Backend 构造 actor/plugin/purpose/locator,回调解析真实项目/文档并返回当前资格、可见字段、可匹配字段及候选范围 |
|
||||
|
||||
Backend 首先验证受信 dispatch actor 的有效态,再咨询专用领域回调。purpose 与 locator 只是待验证请求,不能授予资格。项目选人查当前 member.manage;职责候选查目标文档/项目当前 duty.assign,并从服务端得到当前项目成员集合。候选范围在匹配、排序、分页前施加,不能取全系统页再由 RDM 删掉非成员。
|
||||
|
||||
系统管理查询由 Backend 适配器决定。领域回调不能返回联系方式权限;系统资料授权不能绕过 RDM 项目资格。未知 purpose、字段、模式、状态、职位过滤,文档/项目不一致,actor 为空,提供者/回调缺失或报错,一律拒绝;不用 ResourceAuthorizer V1、旧宽松 EXT-19 或手填 owner 兜底。
|
||||
|
||||
| 使用面 | 默认可见/可匹配字段 | 范围 |
|
||||
|---|---|---|
|
||||
| 系统资料管理 | userId、owner、valid、六个获准资料字段 | system.users.view;资料查询独立于候选 DTO |
|
||||
| 本人资料 | 本人六个字段 | 身份从认证上下文取得,不接受目标 owner 参数 |
|
||||
| 项目成员候选 | userId、owner、name、valid | 当前 member.manage;enabled 账号;无私密字段 |
|
||||
| 文档职责候选 | userId、owner、name、valid | 当前 duty.assign;当前项目成员且账号 enabled;现有职责规则再检查 |
|
||||
|
||||
staffNo 仅在回调有明确受信字段授权时披露/匹配;本期项目默认不授予,不能因用户填了工号便自动开放。电话、邮箱、部门、备注仅在独立资料面出现。searchFields 必须是当前允许匹配/返回字段的子集;被禁止字段不能通过默认全文搜索暗中参加匹配。
|
||||
|
||||
精确 ID/owner 命中也要先授权。模糊候选必须让用户明确选一个稳定 ID,名称与 ID 不混用。候选查询无词时不枚举全系统,返回提示输入账号/姓名;模糊词至少两个字符,最大页 50,系统管理最大页 100。keyset 按稳定 owner、userId 排序;游标签名绑定 actor、purpose、真实领域范围、字段、模式、过滤、查询及授权/可见目录版本。串用或过期拒绝,要求重新查询,不悄悄换页。
|
||||
|
||||
EXT-19 保留现有 Owner/Name/Valid 隐私范围,Valid 改为真实状态。旧签名缺领域 locator,只允许明确系统目录管理上下文,或已有可信 dispatch 领域上下文经同一授权服务判定;无此上下文拒绝。U3 的 RDM 消费者要求新能力,不回落旧宽松行为。此为明确的授权收紧,登记兼容变化,禁止描述成旧行为完全不变。
|
||||
|
||||
RDM 成员/三权写入共享服务先检当前领域管理资格,再做精确账号查验;有效态错误必须传播。检查覆盖成员添加/任命、章节、整文、批量三权,选人查询不是提交授权。三权仍要求项目成员、相异人员、轮次/冻结条件;不因提供者确认账号有效而省略领域规则。
|
||||
|
||||
## 6. IAM-C:本人证明与恢复
|
||||
|
||||
### 6.1 最小可交付证明
|
||||
|
||||
首期只实现“提案之前已经存在的、具备可信凭据来源的完整密码会话”这一分支;不新增短信、邮件、SSO、恢复码或 WebAuthn。姓名/电话/邮箱/工号不参与证明建立、搜索或匹配。
|
||||
|
||||
具备资格须同时满足:目标本人、auth-on、确切 cookie/password 会话、full、非强制改密、未过期/撤销、当前 auth_version、enabled、可信 owner 初始化或可信本人恢复的凭据来源。API key、auth-off、restricted、混合/冲突 Bearer+cookie、客户端自报 actor/scope/proof、管理员密码/Key 派生链和 legacy_unknown 均拒绝。
|
||||
|
||||
提案事务在同账号锁内记录当时已存在的合格会话摘要引用,确认只能使用记录中的仍有效会话;不靠客户端时间,也不因提案后新登录得到资格。新登录/凭据变更遵守同一锁顺序,避免时间相等或并发插入绕过。
|
||||
|
||||
管理员给初始密码 → 自行强制改密 → 再密码登录的 full 会话仍继承不可信来源。主动改密不能提升证明资格,资料修改不能提升,管理员不能改变来源。历史密码保留正常登录,但来源默认 legacy_unknown;不得把“用户再次登录”解释为证明历史管理员从未掌握密码。若未来要信任某些历史账号,需另有用户批准的可信 owner 证明建立方案。
|
||||
|
||||
无合格旧会话时线上明确拒绝,不能签 Key 给管理员“代交”。丢失全部会话/凭据的异常本人恢复仍由另行批准的物理 owner 操作处理,U3 不提供新的旁路。
|
||||
|
||||
### 6.2 提案、确认、兑换与完成
|
||||
|
||||
| 路径/动作 | 合同 |
|
||||
|---|---|
|
||||
| POST `/api/admin/users/{userId}/recovery-proposals` | credential.recover、版本及幂等校验;仅提案 ID/目标/状态/期限/版本。不改目标密码、不删正常会话、不改变 must_change,不返回证明或 Key |
|
||||
| GET/DELETE 同目标提案 | 管理者仅状态/撤销;路径目标与记录绑定;没有恢复秘密或会话摘要输出 |
|
||||
| GET `/api/me/recovery-proposals`(含按 id 查状态) | 目标只能是当前本人;返回 pending/confirmed/completed/revoked/expired、版本/generation 及非秘密来源说明,不接受 owner 注入,不返回 Key/证明摘要 |
|
||||
| POST `/api/auth/recovery-proposals/{id}/confirm` | 本人 cookie 证明、pending、expectedVersion/auth_version 在最终事务重验;一次 confirmed 并发 grant;仅该本人 HTTP 响应获得明文 |
|
||||
| POST `/api/auth/recovery-proposals/{id}/rotate-grant` | 仅原合格本人证明,confirmed、expectedVersion/generation 与当前账号版本;原能力及派生会话同事务撤销后仅本人获得新明文;不重新确认、不给管理员补领 |
|
||||
| POST `/api/auth/recovery-grants/redeem` | body 中凭据;摘要定位目标,无 URL/Bearer 形式;一次消费与建立 set_password_only 会话同事务 |
|
||||
| POST `/api/auth/password`(grant 设密) | 复用既有入口;此分支须有确切可信 activation/proof-linked grant;最终事务再核状态/来源/版本/期限/撤销;成功更新密码、撤相关能力与全部旧会话、审计,返回 reloginRequired,清 cookie |
|
||||
| 同入口(有密码的强制改密) | 仅服务端标记为 password-authenticated 的确切受限 cookie 会话;必须校验 current 密码、enabled、auth_version、must_change。在最终事务更新、撤旧会话并重新登录;继承原来源,不获得本人恢复证明资格;legacy Key 派生会话不得进入此分支 |
|
||||
| 普通主动改密 | 保留 current 校验;继承凭据来源;若保留当前会话,事务内同步其 auth_version,其余会话撤销 |
|
||||
|
||||
提案默认 24 小时;grant 5 分钟;受限会话 10 分钟。grant 256-bit CSPRNG、摘要存储,绑定 target/purpose/proposal generation/issued auth_version。响应 no-store,不写日志/审计/localStorage/剪贴板自动复制。确认或兑换不生成业务会话;设密后必须正式密码登录。
|
||||
|
||||
确认成功但响应丢失,不重放明文。页面进入“结果待核验”,读取本人提案当前非秘密状态;pending 才可再次显式确认,confirmed 显示“原能力无法读回”,仅仍具备原合格证明的本人可点“重新生成设密能力”,走 rotate-grant 后继续兑换。过期、撤销、完成或证明失效则说明当前状态并退出;不能自动循环签发或让管理员补领。幂等重复返回非秘密状态。若兑换响应丢失而 cookie 已成为合法受限会话,先经 `/api/me` 确认当前模式,再继续设密;若结果仍未知,查状态后由本人显式续办。
|
||||
|
||||
登录/`/api/me` 输出服务端确定的非秘密 `passwordChangeMode`:grant_setup 或 current_required;UI 据此在可信 activation/recovery 设密时省略 current、强制/普通改密时要求 current。客户端自报模式无效,未知模式拒绝。明确失败整体回滚;结果未知先查状态,不能盲目自动重试秘密签发。
|
||||
|
||||
PG 同账号凭据事务统一锁顺序 user → proposal → grant → session;最终 UPDATE 使用版本谓词,不能仅先 SELECT。SQLite 复用 immediate 写事务。提案/确认/撤销/补发/兑换/设密/主动改密/停用/正常会话建立共享版本栅栏;审计与写入同事务,故障无部分成功。
|
||||
|
||||
### 6.3 公共扩展与旧入口
|
||||
|
||||
可选 `RecoveryProposalProvider` 只公开提案、状态和撤销的 metadata DTO;actor 从 Host 绑定。插件不确认本人、不接收恢复 Key,不按 actor 字符串推导 cookie 证明。本人恢复 grant 的秘密交付只在 Backend 本人 HTTP 会话入口;若未来工具需要本人确认,须另有不可伪造证明 handle 合同。本期无必要消费者则不增加无人消费的 Host 写方法,只冻结 DTO 与 HTTP 合同。
|
||||
|
||||
旧 POST `/api/admin/users/{owner}/password`、POST `.../login-keys` 明确拒绝并给出新提案路径,不能返回成功兼容。建议稳定 410/`RECOVERY_CONTRACT_REPLACED`;目标不存在也不进行凭据写。旧 Key 的读取仅限无秘密 metadata;撤销必须校验 path owner 与 key 真属主。
|
||||
|
||||
generic CLI `user reset-password`、`issue-login-key --purpose recover/activate` 对既有账号拒绝;在打开/迁移 Store、撤 apiKey/session、生成密码之前校验,避免先产生副作用再拒绝。新账号可信 owner 初始化和无用户首管 bootstrap 按§3保留窄路径;本地创建同事务建号/首 activation grant,已登记新 pending 账号由 initializer 续办,不把它们扩展成已有凭据账号恢复。svc 包装器/帮助同步,不新增 --force 旁路;真实运行仍另行授权。
|
||||
|
||||
## 7. 账号停用、Host 与后台边界
|
||||
|
||||
SessionInfo 与 AuthOwner 必须读取当前 enabled;会话同时比较当前 auth_version。密码验证与最终创建会话在同账号栅栏内复验。权威状态读取错误拒绝,修正当前 password gate 读错误放行。
|
||||
|
||||
Host 各账号能力及保留的 dispatch Host 在调用时读当前状态,不能把构造时 actor 当永久 allow。run start/resume、工具执行、HITL 确认后、Backend 有后果写入和新输出前核验账号状态;停用通过既有取消机制停止本实例活动任务,其他实例在持久状态重验时停止。SSE 每个新帧/重放前复验,安静流继续周期复验,不能只等待 15 秒定时检查后继续输出旧数据。
|
||||
|
||||
U3 只承诺账号有效态和 Backend 自有凭据/写事务边界。RDM 在实际写入前再次做当前账号查验;Backend 与 RDM 独立数据库间,最后一次查验与 RDM commit 仍非同一事务,不能据此宣称零窗口的跨库提交 fencing。完整角色/成员/三权撤销、跨实例运行 fencing 和旧模型上下文整体重建是 U8。若验收要求 RDM 并发停用后绝不提交任何在途写入,则需将该 fencing 作为新增契约重审,不能扩大 U3 的通过声明。
|
||||
|
||||
## 8. 迁移、切换与回退
|
||||
|
||||
增量迁移保留账号 ID、owner、密码摘要、业务/角色/成员/历史职责。name 原值保留;新资料空、不从聊天或联系方式推断。enabled 对既有账号按已批准的既有有效态初始化,profile/state 版本设固定初值。旧来源均标 legacy_unknown;不给历史记录补造本人证明。
|
||||
|
||||
恢复切换必须同时处理未兑换 legacy Key、已兑换 legacy restricted session,以及既有 full session 的证明资格。无 proof-linked 来源的旧恢复/激活能力不能在新线上免 current 设密;不可仅禁止新签发。有既有密码但 must_change 的账号仍可通过密码认证及 current-required 分支完成强制改密,来源继续 legacy_unknown/原不可信来源。旧 full 会话业务策略与证明资格分开,正常业务认证继续遵守当前有效态与版本,恢复资格默认拒绝;保留历史密码不意味着能证明历史管理员从未掌握它。
|
||||
|
||||
新 schema 可读不代表旧认证协议可安全写。切换要求所有 HTTP、CLI、后台写者固定新版本;旧 writer 不得与新合同并行。迁移兼容登记/启动守卫须阻止旧程序静默重开恢复及忽略 disabled;若当前版本机制不足,列为实施停止条件并提出具体栅栏修订。回退只到保留新安全协议的修复版本,不能恢复旧越权接口/有效凭据。
|
||||
|
||||
本轮仅在新建隔离 SQLite/PG 副本演练迁移、重启和失败回滚;现有服务、真实账号及生产数据库均不触碰。生产切换另交备份/身份/writer 清单与恢复演练方案,且必须先具备获批的两份 owner 操作安排:新 pending 账号首次初始化/过期续办的身份及秘密交付手册,以及丢失全部凭据的历史账号异常恢复/证明建立手册。由 weichen 指定实际可信机器/DB owner 操作者、固定目标和接口并批准运行;两者缺一不得切换,不用临时数据库手术代替。本文不批准对 legacy 账号提升证明来源,也不提供异常重置旁路。
|
||||
|
||||
## 9. 实施顺序、负责人及文件范围
|
||||
|
||||
协调 owner 为根智能体;组件在各自权威 origin/main 建登记工作区,固定来源及组合,不编辑 pins。各项由新上下文实施者承担,根智能体验收实际 diff、记录证据及提交;共享 schema/公开合同先串行冻结,文件和语义不独立的工作不并行。
|
||||
|
||||
| 工作项 | 依赖与范围 | 完成条件 |
|
||||
|---|---|---|
|
||||
| U3-1 资料/状态/凭据来源模型 | Backend store、migrate、compat、account events;核对最新迁移编号 | 双档空值/CAS/重启;固定数据模型和安全兼容门槛,原身份不变 |
|
||||
| U3-2 当前认证及停用 | U3-1;auth、accounts、sessions、Host、runmgr、SSE | 事务锁/CAS及最终认证检查;最后管理者;停用/启用不复活已撤能力;关键拒绝路径先写红测试 |
|
||||
| U3-3 受控目录提供者 | U3-1/2;accounts service、hostcaps、extension、registry、surface/version | 授权/字段/范围先于查询,exact lookup、签名分页、EXT-19收口;真实 provider 测试 |
|
||||
| U3-4 恢复与旧入口收口 | U3-1/2;store recovery、server HTTP、CLI/svc 帮助;新 pending initializer/续办与首管窄路径 | 管理员绕行全拒;可信本人正例完整链;待初始化稳定ID续办;历史强制改密current分支;旧能力拒绝和失败原子性;双连接竞争 |
|
||||
| U3-5 RDM 最小消费 | U3-3;RDM public pins、注册回调、accountdir、members、chapter/doc/batch duty shared service | 缺能力拒;候选范围在提供者内;提交重验;保留 I1项目/三权规则;新提供者真实组合测试 |
|
||||
| U3-6 既有界面及契约记录 | U3-3/4/5;Frontend api、UsersPanel、本人既有设置入口/恢复确认、RDM selector;Documents/Dev svc 合同 | 删除密钥复制/旧重置承诺,建号无密码/管理员位;本人资料与确认闭合;提示待 owner 初始化/无证明;未知结果查状态及本人显式更换;按服务端模式要求current;错误与过期响应不覆盖新状态 |
|
||||
| U3-7 固定组合验证和阶段出口 | 全部;Backend/RDM/Frontend/Documents PR 与 Dev pins、任务卡 | SQLite/PG、组合/build、浏览器及独立 Review;用户阶段6/7评审,当前HEAD CI 后智能体合入;运行/部署状态另列 |
|
||||
|
||||
U3-1 是共享前置;U3-2 冻结账号栅栏后目录/恢复才有稳定基础。目录与恢复如仍碰 auth/schema/extension 由根智能体串行整合;仅独立测试或文件在已提交合同后并行。Frontend UI 修改前重新按 DESIGN.md 核对,消费既有令牌、motion、Collapsible,不新增完整管理中心。
|
||||
|
||||
阶段 1–3 承接已批准统一方案的 U3 需求和本轮启动授权,不重走未受影响的用户意图。本文涉及公开契约、数据/证明及兼容切换细化,需阶段 4–5 审阅本版本后进入实施;阶段 6/7 保留人工出口,阶段 8/9 按仓规由智能体完成。不得用测试通过代签人工评审。
|
||||
|
||||
## 10. 验证计划与证据
|
||||
|
||||
所有下列测试当前 `NOT_RUN`。优先更新已有错误合同测试,观察期望红失败,再实现;不复制仅镜像实现的测试。测试对象为隔离临时数据,真实模型/线上账号不在本轮验证范围。
|
||||
|
||||
| 验证组 | 关键正常/拒绝/竞争场景 | 对象与方法 |
|
||||
|---|---|---|
|
||||
| 资料与身份 | 全空建号、填写清空、同名不同ID、格式/长度、未知/权限字段注入;同 expectedVersion 两写只有一胜者 | 真实 Store+HTTP,SQLite/PG 共用合同用例 |
|
||||
| 目录与隐私 | self/system/member/duty权限矩阵;仅禁用电话命中的哨兵不改变结果/数量/游标;空词、限额、过期/跨范围cursor、未知过滤拒绝 | 真实 Backend provider;字段授权回调失败;序列化输出和错误无秘密 |
|
||||
| 当前账号 | 密码/full/restricted/APIkey/旧Host/HITL/run/SSE;停用与建会话/兑换/最终写交错;启用不复活已撤对象;最后两管理者并发 | 两个独立 Store/连接;可控 barrier;双档,不靠 SQLite 单连接证明 PG |
|
||||
| 恢复正例 | 网页建号→可信owner按原ID初始化,activation过期/交付失败/已兑换未设密可续办,首次完成后initializer拒绝;可信 owner 初始化→正式密码会话→管理员 metadata 提案→本人确认→一次受限兑换→设密→正式重新登录,身份和业务数据不变 | 真实HTTP、同源cookie;两HTTP实例共享隔离PG;无 mock 身份认证 |
|
||||
| 恢复负例 | 初始密码/旧Key/reset 派生full、unknown lineage、APIkey/auth-off/提案后会话、错误owner、Bearer混合、管理员代确认均拒;资料不改proof | 实际旧/新HTTP链+CLI拒绝,确认前后数据库无不应发生的变更 |
|
||||
| 原子与恢复 | confirm/revoke、redeem/reissue、completion/disable/activechange、登录insert/改密强制交错;100并发至多一有效能力;audit/commit失败回滚;响应丢失无管理员补领 | SQLite同文件双Store/PG同schema双连接;显式测试日志证实 PG 场景确实执行 |
|
||||
| RDM 消费 | 项目管理先授权后lookup;不存在/disabled/provider缺失报错;章节/整文/批量三权拒失效候选;职责仍要求成员;正例I1隔离/cap保持 | 固定新Backend/RDM的实际注册提供者+命令/HTTP,不只 mock Host |
|
||||
| UI 与兼容 | 管理员不见明文;全空资料建号;本人确认/无证明拒绝;确认/兑换响应丢失查状态、显式更换、失效退出;grant_setup/current_required正确显示;同名明确选择;旧接口迁移提示;桌面/移动无错位,design guard | 真实浏览器;surface snapshot/version/导出边界;不开放额外用户流程 |
|
||||
| 迁移/组合 | 原ID保留;legacy Key restricted不能继续设密;既有密码强制态要求current且继承无proof来源;旧full无proof;disabled重启不复活;旧writer/不安全回退拒绝;组件固定pins+build | 隔离双档;Dev make test/build、test-pg及相关治理检查;当前HEADCI |
|
||||
|
||||
本地与作者工具结果为 SELF;独立审阅者重放须记录身份、命令、精确对象才是 REPLAY;当前 HEAD CI 有运行链接/受信执行身份才是 GATE。命令、对象SHA、完整脱敏输出由 `make evidence` 写入,任务卡/PR引用,不手抄测试通过。设计源码观察不冒充运行 FAIL 或 PASS。
|
||||
|
||||
## 11. 备选、代价及停止条件
|
||||
|
||||
主要备选是直接补资料、沿用旧目录和一次性 Key 交付。成本更低,但字段搜索仍可探测、管理员仍可接管目标账号,不满足已批准 IAM-D/IAM-C。另一个备选是本期同时建设外部身份/邮件/恢复码及 U4 授权权威,能改善无会话恢复,但扩大基础设施及迁移边界,当前不采用。
|
||||
|
||||
推荐本方案:一个账号权威、受控提供者、来源可追溯的本人会话、默认拒绝旧恢复旁路。代价是新账号需可信 owner 初始化,历史未知来源/丢失全部会话者不能线上恢复;最小搜索兼容也收紧,完整管理体验仍需 U7。方案批准不等于批准任何真实账号初始化或迁移。
|
||||
|
||||
遇到以下情况暂停受影响实施并修订:无法可靠判断 credential lineage 或默认拒绝旧能力;旧 writer/回退守卫不能落实;提供者必须依赖请求自报资格;新契约要求通用角色迁移、不可伪造插件本人proof、跨库 fencing 或外部身份证明;双档结果不一致;新的公共合同/权限设计需要改变本文取舍。已授权且不受影响工作可继续,不静默扩大范围或降低验收。
|
||||
|
||||
## 12. 交付出口
|
||||
|
||||
评审出口是本 r1 的明确兼容取舍及 U3 实施/测试范围。实施后分别给出需求到证据映射、剩余 U4–U9 差距、组件PR/固定组合、阶段6/7候选和独立Review记录。合入按有效 Review+当前HEADCI执行;生产上线、历史owner证明建立与工作区回收保持待授权;上线前须批准并演练§8的首次初始化/续办及异常恢复两份owner操作安排。
|
||||
|
||||
原 r1 仍是总方向,本补充是 U3 的具体设计对象。完成后主记录只更新真实推进状态,下一步优先核对 U4 的职位权威与现有在途工作,再提出具体任务建议;不得将本轮启动授权扩展到 U4。
|
||||
@@ -0,0 +1,40 @@
|
||||
# IAM U3 委任项目改名真实操作者围栏修订与实施计划 r1
|
||||
|
||||
状态:待阶段 4–5 人工重审;日期:2026-10-14。本文是已批准 U3 r1 及其 [A1–A4 增量修订](2026-10-14-iam-u3-stage6-review-amendment.md) 的**单点补充**。仅涉及 I1 已交付的委任项目改名投影在 U3 账号停用围栏下的真实操作者传递;不改变 RDM 项目职责规则,不启动 U4–U9,不授权 PR、合入、生产迁移、部署或真实账号操作。
|
||||
|
||||
## 1. 问题、对象与边界
|
||||
|
||||
独立只读复核在 Backend `4053c4d038b1d13a356e0196db56ab11c0e4f8e1` 后的 U3 未提交修复候选中发现:RDM `internal/rdmapp/system_projects.go` 已对请求主体 Bob 检查当前 `project.settings`,但委任 Bob 改创建者 Alice 的项目时,`internal/rdmapp/host_projection.go` 调用 `extension.NewScopedHost(Alice, "rdm")` 重建创建者 Host;Backend `internal/app/project_lifecycle.go` 的 `RenameOwnedProject` 将 Host owner Alice 同时作为最终 Store 事务 actor。若 Bob 通过 RDM 的最后授权检查后被停用,Backend 的 `projects` 表仍可在停用提交后由 Alice 身份完成改名。RDM 与 Backend 之间的授权快照窗口依旧不可原子关闭;**此次可关闭的是 Backend 同一账号数据库内 Bob 有效态与项目投影写入的窗口**,不能把后者归入已批准的跨库限制。
|
||||
|
||||
需求不变:项目创建者决定项目权限;获其委任且当前具有 `project.settings` 的成员可改名;系统管理员本身不因此获得项目内容或改名权。委任操作者停用后,已在途的物理投影不得在 Backend 最终事务中成功;创建者停用亦不应由旧 Host 句柄继续投影。项目 ID、创建者 owner 和委任 actor 是三个不同字段,不能互相代用。I1 的持久失败/恢复记录仍是跨库失败出口,不能假定两库提交原子性。
|
||||
|
||||
## 2. 推荐契约与备选
|
||||
|
||||
推荐新增**由当前受信请求 Host 派生**的可选项目投影能力,例如 `extension.DelegatedProjectProjectionHost.ProjectProjectionForCreator(creator, projectID) (ProjectHost, error)`。RDM 的 HTTP 生命周期回调和 `rdm.project.rename` 命令处理器都把当前认证主体绑定到各自传入的 `requestHost`;两条入口都必须从**该次收到的 Host**派生,不能另造操作者身份。派生句柄继承操作者 Bob、仅把资源 owner 收窄为 Alice。方法不接收调用方自填的 `operator`,也不复用按任意 owner 重建的全局 `NewScopedHost` 作为委任写入口。普通 `NewScopedHost` 继续服务既有读取/恢复能力,但不得替代新委任写入口。能力只向已注册的 RDM 项目生命周期/命令提供者开放;缺少能力、绑定不一致、项目不存在或插件来源不符时拒绝,不回退为创建者身份执行。
|
||||
|
||||
Backend 派生时核对原 Host 的操作者、插件来源、目标项目 ID 与持久创建者;RDM 仍按现有顺序检查 Bob 的当前 `project.settings`、项目 HostBinding 和改名意图。`RenameOwnedProject` 将**真实 actor Bob**、**创建者 owner Alice**、目标 ID 与名称分开送入 Store。最终 Store 事务按账号 owner 稳定排序锁定 Bob 与 Alice 并读取两者有效态,再取项目名称锁、读取持久项目 owner、校验名称并更新同一 `projects` 行;创建者本人改名时只锁一次。停用先提交则拒绝改名,改名先提交则停用等待;账号锁不授予 Bob 项目权限,RDM `project.settings` 检查继续独立存在。`auth-off` 缺失本地默认 owner 的例外只对该 owner 生效,明确停用记录拒绝。
|
||||
|
||||
未采用的方案:在全局 `NewScopedHost` 增加可自填 actor 参数,无法从受信请求句柄证明该 actor 是本次操作者;只在 RDM 最后授权后再查一次账号,仍有检查到 Backend SQL 之间的同库晚到窗口;把委任投影从 A1 承诺中豁免,则保留已知的 Backend 同库晚到写,与获批的 A1 契约不符。
|
||||
|
||||
## 3. 数据流、失败恢复与兼容
|
||||
|
||||
1. HTTP 认证主体 Bob → Backend 生命周期回调或命令分发的 requestHost(Bob)→ RDM 当前 `project.settings` 判定与 HostBinding/意图校验。
|
||||
2. RDM 从**同一个** requestHost 派生 Alice 项目的投影能力;能力内部固定 `actor=Bob, owner=Alice, projectID=既定项目`,RDM 不提交自选 actor。
|
||||
3. Backend Store 在最终事务中锁定并复核两个账号、项目 owner 与名称后提交物理改名;RDM 随后按 I1 原流程完成自己的数据库投影和意图记录。
|
||||
4. 派生能力在改名意图建立前不可用时直接拒绝,RDM 数据保持原状;意图建立后的账号停用、权限撤回、超时或 Backend 写入失败按 I1 规则标记失败并保留恢复信息。重试需新的受信请求 Host 和原意图 actor,重新检查当前权限/账号;不可把旧创建者 ScopedHost 当作跳过 Bob 的恢复捷径。
|
||||
|
||||
这个修订增加一个可选公开 Go 能力,不改 HTTP 请求/响应、迁移表或现有 `ProjectHost` 方法集合;RDM 的测试替身需要显式实现派生能力。若正式 Backend 尚未发布该能力,RDM 委任改名须返回能力不可用,不能默默回退。Frontend 无需新控件;已有项目改名错误提示可显示拒绝。两个数据库之间以及 RDM 权限撤回后的瞬时窗口仍不能声称零窗口,按 I1 持久意图和人工核对规则处理。
|
||||
|
||||
## 4. 实施计划与可判定验证
|
||||
|
||||
1. 固定 Backend、RDM 和 Documents 候选 SHA;在 Backend `pkg/extension` 定义可选受信派生接口,在 `internal/app` 实现请求绑定、来源/项目核对。逐一追踪 HTTP 生命周期与 `rdm.project.rename` 命令两条入口;旧全局 ScopedHost 的委任写用法在两条改名路径全部替换,其它读取调用保持原状。
|
||||
2. Backend Store 增加两账号稳定排序的最终事务围栏,仅在项目投影入口使用;检查 Bob 与 Alice 有效态、持久项目 owner、全局名称唯一性和 rows affected。保持单账号项目创建路径与 U7 bootstrap 锁序;不得在 RDM 回调或模型/网络调用期间持有 Backend DB 事务。
|
||||
3. RDM 改名与失败重试从当前回调 Host 派生投影句柄,继续执行现有 `project.settings` 和 HostBinding/意图检查。缺少新能力时明确失败;已建立的意图按原规则保留,未建立意图的请求不凭空新增。补创建者本人、委任成员、停用创建者、错误绑定和权限撤回场景。
|
||||
4. 用可控屏障在 Backend 最终投影 SQL 前暂停,分别在隔离 SQLite 双 Store、PG 双连接/两进程停用 Bob,再继续,断言 Backend 项目名不变、无创建者身份回退;反向顺序验证先改名后停用。并发 Alice/Bob 锁顺序测试不得死锁。RDM 组合测试同时覆盖无会话 `rdm.project.rename` 命令和 HTTP PATCH:委任成员仅有 `project.settings`、无 `doc.read` 时均可改名;两入口的停用围栏、授权撤回与失败意图恢复均成立,不宣称跨库原子性。
|
||||
5. 重跑 Backend 全包/构建、隔离 PG、RDM 源码外 Go overlay、相关 Frontend 构建与浏览器路径;固定 SHA、命令和完整脱敏输出进入 Dev 任务卡 `SELF` 收据。随后重新提交阶段 6 人工评审;正式 pin、阶段 7、独立 Review/GATE、PR 与合入按既有前置分别处理。
|
||||
|
||||
停止条件:不能从受信请求 Host 得到真实操作者、测试发现 RDM 的回调来源并非可信身份、两账号锁序与 U7 冲突、或必须更改现有 `ProjectHost` 公开方法/持久数据设计时,先修订本文并重审,不以创建者代替 actor 继续交付。
|
||||
|
||||
## 5. 本次评审请求
|
||||
|
||||
请仅裁定本文件的阶段 4–5 契约与计划。批准后才实施上述新增接口与委任投影修复,并重跑受影响验证,再提交阶段 6 人工评审。本次不请求阶段 6 结论、阶段 7 验收、PR/合入、受信 tag、生产迁移或部署。
|
||||
@@ -0,0 +1,58 @@
|
||||
# IAM U3 阶段 6 审阅后契约修订与补测计划 r1
|
||||
|
||||
状态:待阶段 4–5 人工重审;日期:2026-10-14。本文是已批准 [U3 r1](2026-10-14-iam-u3-account-contract-and-plan.md) 的增量修订,不替换其已批准正文。对象是 U3 实施候选在合并 Backend U7 账号事务后暴露的四项缺口;U4–U9、生产迁移、部署和真实账户操作不在本次授权申请内。
|
||||
|
||||
## 1. 当前证据与为什么要重审
|
||||
|
||||
U3 r1 的实施候选为 Backend `4053c4d038b1d13a356e0196db56ab11c0e4f8e1`、RDM 源码 `ad815febce522d029a74cd90217409efc9a81c35`、Frontend `a961b19ebb793d6c02a72002050d269700b1a5bd`。Backend 在此后有**未提交的审阅修复候选**;它们不是已批准或已验收版本。Dev 任务卡 `feature/iam-u3-account-directory-recovery` 保存上述固定版本的 SELF 收据,RDM 任务卡保存源码外 Go overlay 的 SELF 收据。正式 pin、独立重放、GATE、生产与部署均 `NOT_RUN`。
|
||||
|
||||
独立只读代码审阅发现以下可复现缺口;现有绿色单测不推翻这些代码路径事实:
|
||||
|
||||
| ID | 触发与证据位置 | 对 U3 r1 的影响 |
|
||||
|---|---|---|
|
||||
| A1 在途写入 | `internal/server/server.go` 的 `createProject` 在读取请求体后调用 `Store.CreateProject`;`internal/store/projects.go` 插入时不读取当前账号。请求通过认证后暂停,另一连接停用账号,再继续请求,项目仍可在停用提交之后写入。其它非 GET 业务入口须同样盘点,不能只修这一条。 | 违反 r1 §7 Backend 有后果写入前检查有效态;同库可闭合的窗口尚未闭合。 |
|
||||
| A2 API key 隐式建号 | `internal/app/app.go` 的 `CreateAPIKey` 调用 `Store.CreateAPIKey`;后者 `EnsureUser` 可创建启用、来源为 legacy 的账号,再签发完整 API key。 | 绕过 r1 §3 待初始化账号及首凭据边界;纯集成账号的历史读取兼容与新增建号须分开。 |
|
||||
| A3 锁顺序 | 合并 U7 后普通建号走 account 锁再取 bootstrap 锁;首管及本地建号曾反向取得两锁,同 owner 并发有 PG 死锁风险。 | 影响首管与并发建号的活性及 U7 的准入保证。 |
|
||||
| A4 游标与可见版本 | `internal/app/account_directory.go` 和 `internal/server/account_search.go` 以进程内随机密钥签游标,负载均衡切到另一实例时下一页 409。受限候选的版本又组合了全局 public revision,域外账号改名也会使该域游标过期。 | 违反 r1 §5 多实例分页及“目录版本只受可见辨识资料/有效态变化影响”的范围;后一问题还可成为域外活动侧信道。 |
|
||||
|
||||
本次提出的处理改变持久数据设计(共享游标签名密钥)和账号入口兼容行为(阻断 API key 隐式建号),并需要把原计划的“写前复验”细化为同库提交围栏。按 Dev `policy/delivery.md` 的“技术路线、模块职责、公开契约、数据或权限设计……修订方案或计划,经人工重审后继续”,阶段 6 评审暂缓,先审本文阶段 4–5 修订。
|
||||
|
||||
## 2. 修订后的契约
|
||||
|
||||
### A1:同库账号写入围栏
|
||||
|
||||
Backend 自有数据库内,每个以账号身份执行的有后果业务写入,必须在**最终写事务**内按统一顺序取得该 actor 的账号锁,读取当前 `enabled` 并在同事务提交业务变更。若目标资源另有 owner,仍由领域授权决定可写范围;账号锁不能授予项目或文档权限。停用事务取得相同账号锁并推进有效态,因此并发结果只能是业务写入先提交、停用后提交,或停用先提交、业务写入拒绝;不得出现停用提交后旧请求再写入成功。
|
||||
|
||||
实现采用显式 Store 事务入口和逐路由终点映射,不在请求全程持有额外数据库连接,也不以“handler 刚检查过”代替事务内复验。先盘点 Backend 当前 `66` 条非 GET API 路由,将凭据/资料写入(已有或补充最终事务复验)、Backend 自有业务写入、外部副作用/运行控制、只读或无业务后果动作分别记录。项目、会话消息、工件、设置、任务、工具/命令等适用的 Backend 自有写入改由同一账号锁和事务检查;文件或外部工具在真正执行前重验并使用既有取消机制,不能宣称跨外部系统原子性。`auth-off` 的本地默认 owner 继续按 r1 的嵌入式隐式身份规则处理;若存在明确停用记录则拒绝。独立 RDM 数据库的最终提交窗口沿用 r1 §7 已声明限制,不在 U3 声称零窗口跨库 fencing。
|
||||
|
||||
变更须给出“路由 → 最终 sink → actor/owner 来源 → 围栏方式 → 重放用例”清单;有未覆盖的有后果入口即阻止阶段 6 完成。对同一数据库中的认证版本、会话/API key 在途撤销窗口另作影响分析;若需要扩大本次安全承诺,先再修订本文,不用账号 enabled 检查冒充凭据撤销栅栏。
|
||||
|
||||
### A2:API key 不再建号
|
||||
|
||||
本地 `apikey create` 只对**已存在、当前启用、已完成初始化**的账号签发;迁移而来的 `legacy` 账号保留既有无密码集成 Key 兼容,但其 Key 不得作为 U3 本人恢复证明。待初始化账号、停用账号及不存在的 owner 拒绝,不执行 `EnsureUser`、不新增账号或 Key;现有 Key 不因本修订自动撤销。CLI 由当前机器/DB owner 边界执行,不能通过普通管理员 HTTP 或角色 grant 自助补领。未来新增纯集成账号须单列身份/授权方案,不能借 `apikey create` 的历史便利隐式建号。
|
||||
|
||||
Store 的旧 `CreateAPIKey` 目前被许多内部测试当建号 fixture 使用。生产调用入口先收紧;实施时应把内部 fixture 与正式签发 API 分离,并扫描所有非测试调用者,避免新调用重新打开隐式建号旁路。CLI 对不存在 owner 的返回由“创建并签发”改为明确拒绝,这是有意兼容收紧。
|
||||
|
||||
### A3:统一锁序
|
||||
|
||||
PG 账号事务统一按账号 owner 升序取得账号 advisory lock,再取得首次建号/末位管理员保护所需 bootstrap lock,然后锁用户行及后续 proposal、grant、session。SQLite 保持同等业务检查,依靠写事务串行。普通建号与首管竞争仍须保留 U7 的“空库同时入场仅一方成功”语义;不能通过改锁顺序让两方都成功。多 owner 操作按稳定排序,事务内重查 ID、版本和管理员资格。不得用死锁重试掩盖顺序倒置。
|
||||
|
||||
### A4:共享、分域且可见的游标
|
||||
|
||||
使用 256-bit CSPRNG 密钥,经共享账号数据库的 compare-and-set 在首次需要时原子持久化;保存密钥版本,绝不输出到 API、日志、任务卡或浏览器。管理搜索与领域目录以不同 HMAC 域签名,游标绑定密钥版本及 r1 原定的 actor、purpose、locator、范围、匹配字段、查询、过滤、可见目录版本。多实例从同一数据库读取同一密钥;密钥读取失败拒绝分页,旧进程本地随机游标切换时返回明确冲突并要求重新查询,不静默换页。
|
||||
|
||||
`AllCandidates` 的公共辨识变化可以使用全局公开 revision;有限候选范围的版本应由**当前可见候选集合**内的稳定 ID、有效态与获准辨识字段及领域 `ScopeVersion` 形成,不加入域外账号或未授权字段。快照读取与游标版本计算需在一致的数据库视图内完成,或在返回前复核版本并拒绝过期结果,避免版本与页面来自不同时间点。资料私密字段编辑不改变不获准字段的目录版本;当前允许披露的 `staffNo` 独立纳入版本。候选名单变化须失效旧游标。
|
||||
|
||||
若权威数据库已经实际应用 U3 v32,不能就地修改其迁移正文,必须追加新的迁移并给出旧游标废止步骤;只有证明 v32 尚未进入任何持久实例,才可在未发布候选内修订 v32。U7 `account_audit` 占 v31,U3 账号基础/恢复仍按已合并候选的 v32/v33 排序。
|
||||
|
||||
## 3. 实施与验证顺序
|
||||
|
||||
1. 固定当前主干与候选 SHA,盘点 66 条非 GET 路由、Host/runmgr 出口及账号写入者;给每条有后果 sink 指定最终有效态围栏和测试。完成 A2 生产入口及内部 fixture 分离,补“不存在/pending/disabled 均不建号或签 Key”双档测试。
|
||||
2. 按 A3 统一 PG 锁序。用两个独立连接/进程和可控屏障覆盖首管对普通建号、同 owner 建号、管理员停用对初始化/改密;验证无死锁、唯一成功与事务审计。
|
||||
3. 落 A4 密钥持久化、域分隔和范围内版本;补 SQLite 两 Store、PG 两实例跨进程翻页、字段/范围变动、域外改名、密钥不可见和故障拒绝测试;确认迁移版本前置事实。
|
||||
4. 按 A1 路由清单逐类实现最终写围栏。用暂停请求体和暂停最终 SQL 写入的确定性测试,在 SQLite、PG 双连接与 PG 两进程验证“停用先提交则无晚到写”;覆盖项目、消息、工件、设置等代表性入口及实际 RDM 限制说明。外部副作用单独验证最后检查与取消。
|
||||
5. 同步最新 main,重跑 Backend 全包、PG Store/Server、RDM 源码外组合与 Frontend 正常测试;对受影响真实浏览器路径重放。三仓正式 pin、GATE、独立 Review、阶段 7 验收仍遵守原计划的后续人工节点和受信发布前置。
|
||||
|
||||
## 4. 评审决定
|
||||
|
||||
请只裁定是否批准本修订的阶段 4–5,使 U3 阶段内可继续上述修复和隔离验证,然后**重新提交阶段 6 人工评审**。不请求现阶段批准阶段 6、阶段 7、PR 合入、受信版本 tag、真实机器/数据库账号操作、生产迁移或部署。若 A1 的全路由写围栏成本或 A2 的 CLI 兼容收紧不可接受,应在此处明确缩小验收承诺或另立增量;不得保留原 U3 §7 的完成声明同时留下已知晚到写。
|
||||
@@ -0,0 +1,139 @@
|
||||
# 最新模板驱动的两树一网、成员工作上下文与完整可读审计
|
||||
|
||||
修订:r12;更新时间:2026-10-19;需求负责人:用户;记录/准备:实施记录。
|
||||
当前阶段:**2026-10-19 按部分交付收口**(用户决定)。已交付并合入各仓 main:W2/W4a 项目结构与只读快照隔离、W4b 真人确认、W6 历史来源逐项复验、W9 审计截止水位,以及统一文档渲染器 Task 1–12 与 44 份 DHF 模板发布。未交付:W3 递归文档实例、W5 追溯网、W7 上下文提供方、W8 RDM 审计投影、W10 正式前端、W11 DHF 全量保真、W12 含真实模型的全组合验收、W13 收口,以及新增 X3/R3/F3/V3 产品链;这些另立后续大任务按 manual 逐增量评审。E1 保真判据仍未通过,正式运行验收 NOT_RUN,未部署。
|
||||
|
||||
## 目标与成功标准
|
||||
|
||||
根据最新`.templates`模板及`.tmp`材料补全RDM两树一网:细致完整的内容结构、每项目可扩展的节点与要求、随资料和进度提出调整并经人确认生效;同项目成员工作时自动使用当前权限内的项目依据;完整记录人物、时间、动作、内容、结果、依据和影响,以人可读的摘要与结构化详情展示审计。
|
||||
|
||||
成功须同时具备44份新模板的可核查接入、动态递归结构与原子版本化确认、成员真实工作上下文、完整操作留痕/追溯及可读审计。原28项及新增TT-N03/R01合计30项已确认子需求;当前目录或模板条目数量不能代替真实能力与验收。准确来源计数和差距见原对象,不缩成标题导入、只处理部分模板或仅翻译op码。
|
||||
|
||||
## 唯一当前记录与原对象
|
||||
|
||||
- [阶段1需求拆解r1原对象](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-requirements-r1.md):用户选择“确认需求,继续按阶段人工评审”;SHA256 `60fd0296840a74982ae65cc4bd1e6a810ace5109e103e8408a94d4db0573bad7`。
|
||||
- [阶段2需求评估r1及E1试验提案原对象](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage2-evaluation-r1.md):用户“批准”;SHA256 `61733945c077ae6b8f8488ee5a0e41337d7e4a019854dc647e93fecbb4b72178`。原对象保留批准前文字,当前结论在本记录更新。
|
||||
- [阶段3需求与验收条件r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage3-requirements-r1.md):28项完整范围、优先级、依赖及可判定验收,用户已确认;需求主表在Dev任务卡并逐项引用本稿。
|
||||
- [阶段4方案设计r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage4-design-r1.md):推荐路线、共享DHF合同、项目结构/版本、X1/X2扩展、完整可读审计及恢复/验证;用户已批准。SHA256 `568aa26f6b2276f786109e2298b3ae36c6c14d3be5a54e0dfc95bf1b2db4603b`。
|
||||
- [阶段5实施与测试计划r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage5-implementation-test-plan-r1.md):W0–W13跨仓分工、依赖、测试环境/费用上限和全部28项证据映射;用户已批准。SHA256 `b755ef629fae37854b8d0bc344b3f14c6933e4455be74244b9821a6d71b64ebe`。
|
||||
- [E1结果报告r1](/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/e1-20261014-091421/REPORT-r1.md):原件保全;解析路径部分可行,自动保真未通过;全部原始产物/完整SELF收据按批准范围留源码外,未发布为正式模板。
|
||||
- [来源、固定对象与完整SELF收据](../records/2026-10-14-rdm-two-trees-latest-templates/README.md):原字节保留,历史状态不冒充当前事实。
|
||||
|
||||
原对象正文只在records各维护一份;本文件维护当前目标、批准、推进与接续状态。任务卡和项目入口引用本主记录,不另维护另一套方案。
|
||||
|
||||
## 用户确认与授权
|
||||
|
||||
| 决策/阶段 | 对象与结论 | 确认人及依据 | 当前有效范围 |
|
||||
|---|---|---|---|
|
||||
| DYN-01 | 提出变更,确认后应用;已确认 | 用户;本聊天call_8724a18c54b243c5b0e6edfb0c1d50b2第0项答复 | 所有动态结构候选确认后才生效;受控文档仍遵守三权 |
|
||||
| 阶段1 | 需求拆解r1,通过 | 用户;call_22243aaf29ae4ad19c4322a1d7fd8b0f第0项答复;批准对象hash见上 | 确认目标、场景、28项子需求;继续按阶段人工评审 |
|
||||
| 工作区 | 原负责人先收尾并同步 | 用户;同一call第1项答复 | 本任务没有接管旧现场;待其完成后建立独立任务工作区 |
|
||||
| 阶段2/E1范围 | 通过/批准执行 | 用户;本聊天原话“批准”,承接阶段2r1及E1评审请求;2026-10-14,消息时间仅记录日期精度 | 按第8节运行源码外E1,试验后形成阶段3需求表;不是阶段4–7连续推进授权 |
|
||||
| E1结果/阶段3 | 通过需求及风险处理边界 | 用户;本聊天call_87e7dc7218214a27a6a6d4911a44a387第0项:“确认阶段3,进入方案设计(推荐)”;2026-10-14,日期精度 | 确认28项及原件保全/候选/未解决不发布;授权阶段4设计,不代表E1保真通过或实施获批 |
|
||||
| 阶段4 | r1通过 | 用户;本聊天call_69f62a2617e74bfd93b75a8bef7d9809第0项:“批准方案,进入实施计划(推荐)”;2026-10-14,日期精度 | 批准固定方案及剩余风险处理;授权形成阶段5计划,不授权业务实现 |
|
||||
| 阶段5 | r1通过 | 用户;本聊天call_6e90e72546514d5480737f686898f013第0项:“批准计划,进入实施(推荐)”;2026-10-14,日期精度 | 确认W0–W13、DHF U2–U6原owner续办及模型48次/300,000 tokens/人民币150元任一上限;仅隔离副本迁移演练,进入阶段6 |
|
||||
| 增补阶段4 | r1通过 | 用户;本聊天call_a6853c4232f34285a6cbae19dfbeeec5第0项:“批准方案,进入实施计划(推荐)”;2026-10-14,日期精度;固定hash见下 | 确认TT-N03/R01的X3观察/动作前风险判断、私域候选双重分享许可与HITL时序;只放行增补阶段5计划,未放行新接口代码 |
|
||||
| 增补阶段5 | r1通过 | 用户;本聊天call_497a8a4c28bd4231a2cfd63d84375f2a第0项:“批准计划,进入实施(推荐)”;2026-10-14,日期精度;固定hash见下 | 放行X3/R3/F3/V3本地实现、隔离测试和原预算内模型评测;不含真实库迁移、tag发布、部署和增量验收 |
|
||||
| 阶段6 | 增量A实施中 | W0–W4先形成可审查代码/测试;W6/W9可在独立分支并行准备 | 每增量用户确认实现产物,必要设计变化重审 |
|
||||
|
||||
本次记录时间见页首;用户确认的消息引用是审批依据,不由本地SELF命令代签人工或非作者Review。
|
||||
|
||||
## 内容范围与职责
|
||||
|
||||
1. 模板/文档内容:44份DOCX/DOC逐文件、章节/字段/表格/重复块/附件及适用性;原件与模板版本/hash、文档实例和历史版分开。E1已验证14份旧DOC可转换及结构提取,但分页/图形顺序/修订/字体等保真仍未关闭;转换稿仅候选。
|
||||
2. 两树一网:资料切片、结论、递归文档节点、项目阶段/主题/工作事项扩展、结构提案与确认、稳定ID、CAS/幂等/原子事件/重放、受控版本关系和直接/间接影响。
|
||||
3. 工作上下文:普通工作自动取得当前项目任务要求、已确认结论、授权共享资料和可读正文;固定实际依据和版本,预算内渐进读取,撤权/恢复/切换时刷新;不以手动@knowledge代替。
|
||||
4. 审计/显示:成功事件与失败尝试区分,时间/人物/操作/内容前后/来源/结果/影响及实际任务关联完整;人可读摘要、字段差异、对象路径、影响清单、筛选、完整归组/历史及权限内证据跳转。
|
||||
5. 验证:全部28项到当前对象证据;44模板对照、并发/失败/重启/撤权、两项目两成员真实模型与浏览器、精确pins/当前HEAD CI。组件局部SELF和提前独立审阅已有记录;全目标真实模型/浏览器、阶段7正式验收及当前HEAD CI仍为NOT_RUN。
|
||||
|
||||
RDM保有领域、schema/事件与业务权限;Backend仅补必要通用公开能力,Frontend/UI消费已授权的读契约和既有设计系统。新增扩展仍须四要素提案,不能导入Backend internal、改写pins内容、绕过IAM或以管理员身份取得业务正文。团队存储架构替换、线上数据操作、部署及tag发布未纳入本阶段授权。
|
||||
|
||||
## 准备及在途依赖
|
||||
|
||||
- 原共享工作区已恢复干净并包含权威origin/main;本次启动检查返回READY,完整收据由task-start原样导入。Dev R0为`add097d06137c4912a4ed9279e98ca353e4e4cf1`。
|
||||
- 独立Dev worktree:`feature/rdm-two-trees-latest-templates`;Documents候选分支同名,最初从其origin/main `a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c` 建立;本次恢复已按父仓权威pin快进至 `7bd4e17827d4c7c88647bf3c9199c495b60cb107`。保存阶段记录只代表本地候选,不表示已推送、合入、部署或业务完成。
|
||||
- 阶段2的7仓main、10相关PR快照及最新复核均保留;审计导出/水位(RDM#301/#307、Dev#488;Frontend#73已合入)和快慢通道工作来源(Backend#193、Frontend#79、Documents#95、Dev#512)按最终主干结果协调复用,不重复起另一套入口。快照不是未来准入证明。
|
||||
- 关联规划:[原两树审计集成方案](2026-10-11-rdm-two-trees-trace-audit-integration.md)、[模板与对话生成方案](2026-10-11-rdm-template-dialog-generation.md)、[系统项目与私域协作](2026-10-13-system-project-membership.md)。本目标补齐最新模板、动态结构、默认上下文与完整审计,不用旧任务完成状态代替本轮验收。
|
||||
|
||||
## 阶段与下一动作
|
||||
|
||||
| 阶段 | 状态 | 产物/出口 |
|
||||
|---|---|---|
|
||||
| 1需求拆解 | 用户通过 | 固定hash原对象及确认依据 |
|
||||
| 2需求评估 | 用户通过 | 固定r1原对象及E1范围获批 |
|
||||
| E1探索试验 | 执行结束,风险处理已获确认;保真仍未通过 | 14份转换成功,原件hash不变;59分54秒内闭合自动环节,保真判据未通过 |
|
||||
| 3需求表 | r1用户通过 | 全部28项的优先级、依赖、条件和验证方法,明确E1剩余风险 |
|
||||
| 4方案 | r1用户通过 | 方案SHA256 `568aa26f6b2276f786109e2298b3ae36c6c14d3be5a54e0dfc95bf1b2db4603b`;全部28项映射 |
|
||||
| 5实施/测试计划 | r1用户通过 | W0–W13、28项映射、44资产和模型预算;SHA256 `b755ef629fae37854b8d0bc344b3f14c6933e4455be74244b9821a6d71b64ebe`;放行阶段6本地实施与隔离测试 |
|
||||
| 6实施 | 2026-10-19 部分交付收口 | W2/W4a、W4b、W6、W9 与统一文档渲染器已合入各仓 main;W0 清单守护未经增量人审、未合入,保留在 Dev 分支历史 `9873a55`;W3/W5/W7/W8/W10–W13 及 X3/R3/F3/V3 未实施,另立后续大任务 |
|
||||
| 7正式验收 | NOT_RUN | 固定全目标候选和需求到证据映射,人审出口 |
|
||||
| 8代码Review、9合入、10收口 | 部分收口 | 本次只合入已交付部分的记录与任务卡(Documents #116、Dev #630);剩余项的 Review/合入/收口随后续任务办理 |
|
||||
|
||||
当前按已批准阶段5计划实施:W0机械来源守护代码提交 `38ef548637f426e2e36c33a50ae6b8af8c9da453`,16项SELF定向测试及44项实际目录核对通过;只证明来源身份,0项已发布。W2/W4a原并发/回滚及迁移跨实例失效已局部修复,现按已批准读隔离修订继续;`8f80e55a4d`另保留三项时间重放RED,不能用排除该用例的绿色结果宣称W4a完整通过。W6基座上下文固定候选 `d8129abe`、W9基座审计固定候选 `130ac344` 均有局部SELF及限域独立审阅;与Backend main `8e80e261` 的迁移和公开槽冲突在独立探针 `d9b00c23` 形成隔离PG全包/race/build SELF证据,尚未推送、合入或成为产品组合。DHF原工作区owner继续原任务;本任务不覆盖其脏现场。阶段6增量A形成后提交人工评审。
|
||||
|
||||
2026-10-14T15:34:17+08:00的依赖SELF快照显示:DHF U1所在RDM PR #365仍开放、未合入,head `3467a178`,原owner工作区有在途修改;目录hash `65cad94f20f31a32bee26e142004288c4e5b473a93fc0c537d5c6fef1d13ca48`,44项均为needs-review、0项published。完整命令输出已由evidence写入Dev任务卡(收据 `a770d013c48e077da35061ce52b3a309748b77abf29c9ed962d246a99afa83fc`)。W3等待唯一U1内容块合同实际合入后消费;通用结构开发无需等待44项全部发布,W11逐模板发布/生成/Word验收仍须完整满足。
|
||||
2026-10-14T16:21:32+08:00的后续SELF已核验RDM远端main及PR #365实际合入,merge SHA `57d2214feb0ac4a534fa58623fff7d02f93a860a`;唯一DHF U1合同已可消费,原owner工作树已不存在。44项目录hash与needs-review状态未变,合入合同不表示44份资产已发布。完整收据 `dc68957a407f534b79904e59bc4bcd1c7a7f5ef59267c2f9abcc075f495db3ae` 已在Dev任务卡。W2已同步该主干;W3的U1依赖解除,仍按已批准顺序在W4a读取隔离和时间修复后开始。
|
||||
|
||||
当前未决项:E1的保真差异和49字符未定位片段;44份资产逐项语义/格式人工裁定;基座X1/X2真实公开发版、旧数据兼容实测和正式模型/浏览器环境。E1结果是SELF探索证据;局部代码测试不能代替真实模型/浏览器、阶段7验收、当前HEAD CI、合入或部署,这些仍为NOT_RUN。
|
||||
|
||||
本轮修订不改阶段1/2原对象字节,不把试验执行成功记为保真通过。已在隔离工作区提交局部代码并执行测试;原DOC/DOCX、真实运行库与服务保持原状。E1临时环境和唯一成果仍保留,尚未执行清理。
|
||||
|
||||
|
||||
## 阶段4调查及恢复记录
|
||||
|
||||
- 本次恢复前评审稿未提交,首次precheck拒绝;将本任务两仓文件、patch/hash及stash保存至源码外stage4-resume-backup,再同步权威main。Documents按新pin显式快进,后续task-sync通过;新precheck READY及task-resume收据已原样导入。原稿与上游无路径内容冲突,已逐文件恢复;旧证据保持历史对象范围。
|
||||
- Dev当前设计基线main为`f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60`,任务合并后HEAD为`279ddf05b180576a70c817fed48371b72b26c089`;R0不变。仅纳入上游已合入文档/治理变化,未推进新的组件组合。
|
||||
- [阶段4源码及在途快照](../records/2026-10-14-rdm-two-trees-latest-templates/stage4-sources.json):RDM/Backend/Frontend main未变化,Documents#89与Dev#489已合入;相关审计导出、工作发现PR仍开放。DHF专项已有本地U1及E1-R1在途,详见阶段4§2,不把候选或任务叙述当发布/验收证据。
|
||||
- 方案复用DHF的TemplateAsset/ContentBlock并补齐共同合同;本专项负责项目扩展/实例/动态确认/上下文/审计,阶段5固定依赖及非重叠工作项,不接管其他工作区。
|
||||
|
||||
## 阶段5规划状态
|
||||
|
||||
- 本计划不改变阶段4已批准对象字节;DHF U1本地候选仍是40 needs-review、4 blocked、0 published。追加E1-R1四份转换稿为候选、人工格式未审核;原E1与本任务E1的输出方法不同,不能互相代签通过。
|
||||
- 2026-10-14阶段5依赖快照见[记录](../records/2026-10-14-rdm-two-trees-latest-templates/stage5-dependencies.json):Frontend#73已合入其main;其余相关导出与来源PR仍需按交付时最新状态重查。Frontend main当前快照为`5313cfad4e633d0909ed40dcdfa28a11bc1902c0`;此快照不是未来精确组合候选。
|
||||
- 阶段5计划r1已获用户批准,实施及有上限的模型评测进入其授权范围。是否实际执行、花费及产物仍以独立任务卡/收据为准;本稿不把未来结果写成已通过。
|
||||
|
||||
## 阶段6已形成的候选与依据
|
||||
|
||||
- [W0逐文件资产对照](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w0-template-ledger-r1.md):44/44原件路径、来源Git字节、DHF逻辑ID与类型候选匹配;当前目录44 needs-review、0适用性确认,内容/保真/合同仍待审核。SHA256 `6347ca86c09e00588b202e3a6f0039ac7aec426ed2d64efe5d273ca265b62235`,SELF。
|
||||
- [X1/X2公开扩展申请](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-public-extension-requests-r1.md):四要素、可信作用域和兼容/权限负例,Backend独立工作项消费;仅申请/方案记录,尚未发布接口。SHA256 `2afc37801d96d4c73099f0e2a73658b35ec37c0e6bdd793f835c5fca4a4dd137`。
|
||||
|
||||
## 本轮新增需求评估
|
||||
|
||||
- [阶段2受影响需求评估:工作信息拆解与主动风险澄清r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage2-work-observation-risk-evaluation-r1.md):用户补充要求用户发言、智能体已提交回复、实际检索及可见分析结果逐来源拆解,并在任务中及时发现歧义/风险,以对话/HITL/工作卡澄清。原`.tmp/08`已有“对话/上传/检索统一切片、切片互撞”的目标,但已批准28项未逐类验收普通工作入口、处理回执和相关动作前澄清。用户于本聊天`call_aea78d4156fe4ca89f4b9b6883b2b23f`第0项确认增补并进入需求表;评估稿SHA256 `2627342f7d6e94137d5e7418d995ce57218093f6512f67fb7b221f01067da04d`。原阶段2结论保持原范围有效,新增能力仍待阶段3–5受影响评审。
|
||||
- [阶段3工作信息拆解与主动风险澄清需求表r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage3-work-observation-risk-requirements-r1.md):只新增TT-N03(四类普通工作来源逐项处理)和TT-R01(任务内风险/矛盾及时澄清)的可判定验收条件,原28项原字节不变;总数30项。用户于本聊天`call_b517d0f07af54aa188a01ddb100485b9`第0项确认两项并进入方案设计;固定稿SHA256 `552a9fdea996bb547c185949b5072a51efafdce1339a9eaafd49537dfedd91b4`。新公开观察接口和对应产品代码仍待阶段4/5评审,原W2/W4a/时间及不受影响的W3可继续。
|
||||
- [阶段4工作来源观察与主动风险澄清方案r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage4-work-observation-risk-design-r1.md):Backend受信X3观察与动作前风险决定,RDM负责私域候选、当前权限/来源比对和既有HITL卡,确认后才成为项目有效事实。两轮限域设计复核已闭合消息/outbox的处理屏障、可见正文时序、私域片段双许可与撤权、RDM风险卡唯一owner等问题。用户于本聊天`call_a6853c4232f34285a6cbae19dfbeeec5`第0项批准方案并进入实施计划;固定稿SHA256 `c9edb25c1decbbcb31220ef0cec8703c37e4aaa87bee31eb308169000b335d8c`;原阶段4批准对象不受影响的条款继续有效。
|
||||
- [阶段5工作来源观察与主动风险澄清实施及测试计划r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage5-work-observation-risk-implementation-test-plan-r1.md):X3/R3/F3/V3的仓库owner、依赖、每路观察/风险/私域分享/恢复与浏览器验收、两项需求证据映射和原预算复用;用户于本聊天`call_497a8a4c28bd4231a2cfd63d84375f2a`第0项批准进入实施,固定SHA256 `10b91e3489ac8145eafec73759a019cb6d3b73fd50e7c74563bbbb6d18e5462c`。
|
||||
|
||||
## 阶段6受影响设计及决定
|
||||
- [W4b真人确认受影响设计修订候选r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w4b-human-confirmation-design-adjustment-r1.md):固定Backend公开Host/Request尚不能证明本次决定来自绑定确切提案修订与hash的一次性真实人响应;建议基座X3可选证明能力加RDM事务内唯一消费。候选文件SHA256 66c1bb8a1f7c1d0be3a1fe1181541b3e490c52a8a5601c3eb6410cabe2442b10;尚待阶段4受影响方案人工评审,W4b决定写入口不实施。W3可按已批递归实例合同继续,W2限域REPLAY不构成增量A验收。
|
||||
- [W4b本地实现进展](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w4b-implementation-progress-r1.md):按已接受的实施计划完成本地链路。Backend `a4d6404`、RDM `528dd0c`、Dev组合测试前的指针提交见该记录。已实现并有SELF证据;未合入、未部署。隔离PostgreSQL、真实模型与真实基座确认路径为NOT_RUN。W3 RED `TestDHFInstantiateMaterializesTemplateBlockIdentity`仍不在本次范围。
|
||||
- [领域时间持久化与历史缺项修订r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-time-contract-design-adjustment-r1.md):独立时间RED和固定源码核查发现新态与重放时间不同、ReviewCard时间丢失、CNode同版本更新覆盖原时间/主体。建议新字段显式持久化、事件schema 2及仅针对事件INSERT的最低写版本门禁;旧缺项保持历史兼容投影并明确来源。用户已于本聊天call_6ce04b5a3ca3496487ab2714ed208965第0项选择“批准修订,隔离实施验证(推荐)”;原稿保留评审前文字。授权在读取隔离固定后由原owner继续时间合同与隔离测试,真实库迁移和部署仍未放行。 固定评审对象SHA256 `d78849440e6346482fc09925d402790a7ad257ef76c85275610046a845a45f37`。
|
||||
- [X2跨成员已提交业务审计链接修订r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-audit-link-design-adjustment-r1.md):W9发现只凭会话项目会泄露私域或重归属旧操作。建议仅将可信已提交项目事件与宿主行建立不可变链接,再按当前审计/资源权限投影。公开写/读合同改变了阶段4 X2,用户已于本聊天call_bf9116ffe4ff4c5bbc4809a58ab02cbe第0项选择“批准修订,继续跨成员审计(推荐)”;W9可按修订继续实施,但安全owner局部不等于跨成员完整审计。SHA256 `385d9d7570217ddcce9fe60a60c99dc58c9a4875ad790584a724d09a210a6e52`。
|
||||
- [W2/W4实施顺序修订r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w2-w4-sequence-adjustment-r1.md):W2的并发字典修订与事务回滚在当前RDM分支保留两条RED;将已批准W4事务隔离基础W4a移到W3之前,由W2 owner在同一工作区修复,W3仍等待DHF U1合入,W4提案/真人确认W4b仍在W3后。用户于本聊天call_c6f6ccef6a5b4e92ad473d85623d4b5f第0项选择“批准修订,先实现 W4a(推荐)”;批准对象SHA256 `aaf8c091772149a3547cbec272a7f38de3a47cc41c84b7bcef05e74510efbacf`,原稿保留评审前状态。
|
||||
- [W4a项目只读快照指针隔离修订r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w4a-read-isolation-design-adjustment-r1.md):RDM固定RED证实`WorldFor`返回的Slice/Doc/Dictionary裸指针可污染同项目缓存而无事件。私有canonical、每次读独立状态图、同代共享真正sealed事件日志及发布水位/性能验证,已由用户于本聊天call_42834c379e204aa781677882d24b54c7第0项选择“批准修订,继续 W4a(推荐)”。批准对象SHA256 `3cabd9d137eaa504e50698c333f8867aec4e2f80e16ffef08fd83d513f2456d4`。旧重放时间漂移另列未决,不由复制方案冒充已修。
|
||||
- [W9 PostgreSQL审计截止水位修订r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w9-pg-audit-cutoff-adjustment-r1.md):现有序列ID可低号晚提交,固定页游标缺少已提交前缀保证;在序列CACHE 1等前提下串行化在线审计ID分配,并补迁移/回滚/离线复制检查。用户于本聊天call_22d8212219f946d8b117837d7e5ccb3f第0项选择“批准修订,实施并验证(推荐)”;批准对象SHA256 `2357b715a7c8f3451b34cc25a578d655e8a48f3f26d9cf7561ea7a13998ca857`,只放行隔离分支,真实运行库迁移仍按原边界。
|
||||
- [W6项目模型历史来源逐项复验修订r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w6-source-recheck-design-adjustment-r1.md):独立复审发现候选`resolve_goal`把完整user/judge正文写入长期回执,已有RED证实。以实际纳入的稳定来源ID/版本/hash经可选领域接口逐项重验,移除原文持久化;用户于本聊天call_751be0cc02914fe2b1fe591042d029ec第0项选择“批准修订,继续 W6(推荐)”。批准对象SHA256 `d46168392d4fd8ea9aa7f73206be039268aff6be100faef63efa052323511616`;仅放行隔离分支,真实库迁移/tag/阶段验收仍按原边界。
|
||||
- [W9全部审计写入口截止水位修订r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w9-all-writers-cutoff-adjustment-r1.md):独立复审发现并在隔离PG以测试-only RED实测显式在线低ID绕过已批r1默认函数,`committed-prefix`误报并跨页漏行。所有INSERT同事务锁/单调门禁、UPDATE/DELETE不可改、排他离线复制与只前进序列由用户于本聊天call_4f521a6ddd0542178769f8d7231916b5第0项选择“批准修订,隔离实施验证(推荐)”;批准对象SHA256 `44f6f7cd34bf95a9c1eb844bfdd70a5c2233e1b5ffc89b3091359dcb5fc3b5d8`。仅隔离分支续办,真实运行库迁移仍未放行;当前W9 `63ebc85`本身不能强报已提交前缀。
|
||||
- [Backend X1/X2与最新main组合探针r1](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-backend-combination-probe-r1.md):最新Backend main v31账号审计与W6/W9迁移重号在独立本地工作树按v31–v40重排,两个公开槽与surface合并;固定探针HEAD `d9b00c2` 的隔离PG全包/race/build SELF通过,独立限域复审未见新增高影响问题。仍非正式组件合入/CI/产品验收。
|
||||
- [W4a读取隔离P2独立限域复审](../records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage6-w4a-p2-independent-review-r1.md):固定RDM `57a8d7caedf72d9be4bdca179ae2a93e456ba009` 的独立源码副本先验证源码/精确pins,再重放最小race集合;未发现新的高影响P2问题。报告、脚本与原始收据逐字节保存在records;工具标签仍为SELF,独立身份和被测archive在报告/输出中核验,不能用外层Dev HEAD代替被测RDM SHA。原时间RED另行修复,性能成本留增量A人审;当前结论不等于W4a、W3/W4b或全目标完成。
|
||||
|
||||
## 阶段6启动记录
|
||||
|
||||
- 用户已批准阶段5r1(见上方审批表),同意DHF原工作区owner续办U2–U6及模型预算上限;这项授权不表示资产审核或基座tag发布已完成。
|
||||
- 启动时本任务Dev/Documents保留评审稿,尚无业务代码提交。独立任务从各组件权威main及各自precheck建立;W2、W6、W9可在不同工作区并行准备,共享合同/消费关系按阶段5§2处理。
|
||||
- W0初始对齐以DHF已记录的44逻辑资产/41原件hash及唯一ContentBlock候选为基础;所有资产当前仍未published,E1-R1四份仅为候选。用途/格式人工结论和单一合同版本仍须实际固定,未完成前W1/W11不放行发布。
|
||||
|
||||
## 阶段6 X2受影响方案审批
|
||||
|
||||
- 批准时间记录:2026-10-14T11:49:19.752273+08:00(本地记录时间;用户消息仅能确认2026-10-14日期精度)。批准对象为stage6-audit-link-design-adjustment-r1.md,SHA256 `385d9d7570217ddcce9fe60a60c99dc58c9a4875ad790584a724d09a210a6e52`。
|
||||
- 批准范围:已提交项目业务事实的受信宿主链接、当前audit.read与资源权限字段投影、旧无链接记录不补造;W9/W8/W10相应实现与测试恢复授权。私人会话不因项目绑定自动发布;Tag发布仍按双钥匙。
|
||||
|
||||
## 阶段6局部代码与审阅(2026-10-14T11:52:25.226437+08:00)
|
||||
|
||||
- W2 RDM局部提交与W9 Backend私域安全切片各有作者SELF测试,但独立代码审阅均发现需要修复的实质问题;负责工作区继续改进,当前不构成阶段6增量或完整W2/W9验收。W6仍在接完整普通工作链。具体分支/HEAD和缺项见Dev任务卡,结果变更后重验。
|
||||
- W9跨成员可信宿主链接的受影响设计已获用户批准;新增公共合同与消费链尚未实现/发布,旧私人会话仍保持私域。
|
||||
|
||||
## 阶段6新发现(2026-10-14T12:05:20.542456+08:00)
|
||||
|
||||
- W0新增可重跑DHF目录保护脚本与6类红绿测试;当前44份原件/逻辑身份核对通过、0已发布。F01/F02在DHF业务复核后有2项类型候选变化,仍未确认适用性或完成版本字典登记;原阶段1候选清单保留历史,不将此变化误报为原件损坏。
|
||||
- W2独立审阅的既有5项失败路径已修复,但同一World项目字典修订与资料入库同时访问仍可能竞争,需修复并补并发负例。W6/W9各自Backend分支碰到迁移v31重号,最终组合前必须按真实合入顺序重排并重验。
|
||||
@@ -0,0 +1,393 @@
|
||||
# Focused Role and Permission System Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Deliver the requested single-effective-role position model and enforce system, role, and per-project permissions from one server-side action catalog.
|
||||
|
||||
**Architecture:** Backend owns roles, the single active user binding, the permission catalog, system grants, and role defaults/caps. RDM consumes that public authority while retaining project membership, project overrides, creator ownership, and existing document duties. Frontend uses Backend role APIs for the single-role and matrix views and uses RDM only for project-scoped configuration.
|
||||
|
||||
**Tech Stack:** Go 1.27, SQLite, PostgreSQL, HTTP JSON APIs, compiled extension Host contracts, React 19, TypeScript, Vitest, Playwright.
|
||||
|
||||
**Spec:** `docs/proposals/2026-10-15-iam-focused-role-permission-spec.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- One user has at most one effective role; one role may be assigned to many users.
|
||||
- Role and user stable IDs never change when display data changes.
|
||||
- System administrators do not gain implicit access to project business content.
|
||||
- A project creator can manage only the project they created.
|
||||
- Unknown actions, missing providers, stale versions, disabled accounts, and disabled roles fail closed.
|
||||
- Role defaults never exceed role caps; project allows never exceed role or platform caps.
|
||||
- UI configuration uses a draft, preview, and atomic batch commit; hidden rows do not lose draft edits.
|
||||
- Account recovery, multi-role bindings, Agent permissions, workflow redesign, production migration, and deployment remain outside this plan.
|
||||
|
||||
## Review Focus
|
||||
|
||||
- Reassigning a user while two administrators submit concurrently must leave exactly one active binding and return one conflict.
|
||||
- Disabling a role between preview and commit must reject the commit without partial writes.
|
||||
- A project creator switching from project A to B must not retain A-derived management authority in B.
|
||||
- A filtered matrix batch must contain explicit action IDs and must not apply to hidden or newly registered actions.
|
||||
- RDM provider absence or version mismatch must deny authorization and must not fall back to the legacy local role table.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Backend action catalog and role schema
|
||||
|
||||
**Files:**
|
||||
- Create: `Agent-System-Backend/internal/authz/catalog.go`
|
||||
- Create: `Agent-System-Backend/internal/store/role_policy.go`
|
||||
- Modify: `Agent-System-Backend/internal/store/migrate.go`
|
||||
- Test: `Agent-System-Backend/internal/store/role_policy_migration_test.go`
|
||||
- Test: `Agent-System-Backend/internal/authz/catalog_test.go`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `authz.Descriptor`, `authz.DescriptorByID(string) (Descriptor, bool)`, `store.RoleRecord`, `store.RoleBinding`, and schema v35 tables.
|
||||
- Consumes: existing `users(id, owner, enabled, state_version)` and migration transaction machinery.
|
||||
|
||||
- [ ] **Step 1: Add failing catalog tests**
|
||||
|
||||
```go
|
||||
func TestCatalogRejectsUnknownAndProtectsManagementActions(t *testing.T) {
|
||||
if _, ok := DescriptorByID("invented.action"); ok { t.Fatal("unknown action registered") }
|
||||
got, ok := DescriptorByID("system.roles.manage")
|
||||
if !ok || got.Scope != ScopeSystem || !got.Protected { t.Fatalf("descriptor=%+v", got) }
|
||||
create, ok := DescriptorByID("project.create")
|
||||
if !ok || create.Scope != ScopeSystem || create.Protected { t.Fatalf("project.create=%+v", create) }
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run the focused test and confirm the missing package failure**
|
||||
|
||||
Run: `GOWORK=off go test ./internal/authz -run TestCatalogRejectsUnknownAndProtectsManagementActions -count=1`
|
||||
Expected: FAIL because `internal/authz` does not exist.
|
||||
|
||||
- [ ] **Step 3: Implement the fixed action catalog**
|
||||
|
||||
```go
|
||||
type Scope string
|
||||
const ( ScopeSystem Scope = "system"; ScopeProject Scope = "project" )
|
||||
type Descriptor struct { ActionID, Label, Description, Group string; Scope Scope; Protected bool }
|
||||
func DescriptorByID(id string) (Descriptor, bool)
|
||||
func Catalog() []Descriptor
|
||||
```
|
||||
|
||||
Register only the system and project actions listed in the spec. Return copies so callers cannot mutate the registry.
|
||||
|
||||
- [ ] **Step 4: Add schema v35 and migration tests for both dialects**
|
||||
|
||||
Create `roles`, `role_permissions`, `user_role_bindings`, `system_grants`, `authority_state`, and `policy_receipts`. Enforce one active binding per user with a unique `user_id` key; preserve inactive history through versioned replacement rows in the same transaction. Use the existing boolean representation per dialect and foreign keys to `users(id)`.
|
||||
|
||||
Run: `GOWORK=off go test ./internal/store -run 'TestRolePolicyMigration|TestMigrate' -count=1`
|
||||
Expected: PASS on SQLite; the existing PG migration suite later verifies PostgreSQL.
|
||||
|
||||
- [ ] **Step 5: Commit the schema and catalog**
|
||||
|
||||
```bash
|
||||
git add internal/authz/catalog.go internal/authz/catalog_test.go internal/store/role_policy.go internal/store/role_policy_migration_test.go internal/store/migrate.go
|
||||
git commit -m "Add the role permission catalog and schema"
|
||||
```
|
||||
|
||||
### Task 2: Atomic role, binding, and permission store
|
||||
|
||||
**Files:**
|
||||
- Modify: `Agent-System-Backend/internal/store/role_policy.go`
|
||||
- Test: `Agent-System-Backend/internal/store/role_policy_test.go`
|
||||
- Test: `Agent-System-Backend/internal/store/role_policy_pg_test.go`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `authz.DescriptorByID`, current account state, store transaction helpers.
|
||||
- Produces:
|
||||
- `CreateRole(actor string, in RoleCreate) (RoleRecord, error)`
|
||||
- `PatchRole(actor, roleID string, expected int64, patch RolePatch) (RoleRecord, error)`
|
||||
- `ReplaceRolePermissions(actor, roleID string, expected int64, changes []RolePermissionChange, key string) (PolicyReceipt, error)`
|
||||
- `AssignUserRole(actor, userID, roleID string, expectedState int64, key string) (RoleBinding, error)`
|
||||
- `RoleForUser(userID string) (RoleBindingView, error)`
|
||||
- `ReplaceSystemGrants(actor, userID string, expectedEpoch int64, actions []string, key string) (PolicyReceipt, error)`
|
||||
|
||||
- [ ] **Step 1: Write failing transaction and concurrency tests**
|
||||
|
||||
```go
|
||||
func TestAssignUserRoleKeepsOneEffectiveBinding(t *testing.T) {
|
||||
first := mustAssign(t, st, admin, userID, engineerID, 1, "assign-1")
|
||||
second := mustAssign(t, st, admin, userID, reviewerID, first.UserStateVersion, "assign-2")
|
||||
if second.RoleID != reviewerID { t.Fatalf("binding=%+v", second) }
|
||||
if got := countActiveBindings(t, st, userID); got != 1 { t.Fatalf("active=%d", got) }
|
||||
}
|
||||
```
|
||||
|
||||
Also test two concurrent replacements with the same expected state, duplicate idempotency keys, disabled users, disabled roles, unknown actions, `allowed=true/capAllowed=false`, stale role versions, a multi-change batch containing one invalid item, and rejection when a system-grant batch removes the final effective `system.permissions.manage` holder.
|
||||
|
||||
- [ ] **Step 2: Run tests and confirm missing methods fail**
|
||||
|
||||
Run: `GOWORK=off go test ./internal/store -run 'TestAssignUserRole|TestReplaceRolePermissions' -count=1`
|
||||
Expected: FAIL with undefined store methods.
|
||||
|
||||
- [ ] **Step 3: Implement transaction-scoped mutations**
|
||||
|
||||
Lock the actor, target account, role, and `authority_state` in the existing account-before-policy lock order. Validate the complete batch before any write. Increment `role_version` and `authority_epoch` once per successful transaction and persist one `policy_receipts` row per idempotency key.
|
||||
|
||||
- [ ] **Step 4: Verify SQLite and PostgreSQL behavior**
|
||||
|
||||
Run SQLite: `GOWORK=off go test ./internal/store -run 'Role|Policy|Binding' -count=1`
|
||||
Run PostgreSQL through the isolated PG harness after it creates the mode-0600 DSN file: `AGENT_SYSTEM_TEST_PG_DSN_FILE=/tmp/iam-u4-role-policy-pg-dsn GOWORK=off go test ./internal/store -run 'Role|Policy|Binding' -count=1`
|
||||
Expected: both pass with identical conflict and rollback assertions.
|
||||
|
||||
- [ ] **Step 5: Commit the store service**
|
||||
|
||||
```bash
|
||||
git add internal/store/role_policy.go internal/store/role_policy_test.go internal/store/role_policy_pg_test.go
|
||||
git commit -m "Add atomic role and binding policies"
|
||||
```
|
||||
|
||||
### Task 3: Backend authorization service and HTTP API
|
||||
|
||||
**Files:**
|
||||
- Create: `Agent-System-Backend/internal/authz/service.go`
|
||||
- Create: `Agent-System-Backend/internal/server/roles.go`
|
||||
- Modify: `Agent-System-Backend/internal/server/server.go`
|
||||
- Modify: `Agent-System-Backend/internal/server/accounts.go`
|
||||
- Test: `Agent-System-Backend/internal/server/roles_test.go`
|
||||
- Test: `Agent-System-Backend/internal/server/role_authorization_test.go`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Task 2 store methods and existing authenticated actor resolution.
|
||||
- Produces: the HTTP endpoints in the spec and `Service.AuthorizeSystem(actor, actionID string) Decision`.
|
||||
|
||||
- [ ] **Step 1: Write failing authorization and HTTP tests**
|
||||
|
||||
```go
|
||||
func TestRoleManagerCannotGrantProtectedPermission(t *testing.T) {
|
||||
cookie := loginAs(t, h, "role-manager")
|
||||
rec := do(h, "PUT", "/api/admin/roles/"+roleID+"/permissions",
|
||||
`{"expectedRoleVersion":1,"idempotencyKey":"p1","changes":[{"actionId":"system.permissions.manage","allowed":true,"capAllowed":true}]}`, cookie)
|
||||
if rec.Code != http.StatusForbidden { t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String()) }
|
||||
}
|
||||
```
|
||||
|
||||
Cover role description create/edit, exact and fuzzy role search, status/action filtering, pagination, one role assigned to two users, user reassignment, stale versions, fixed-ID batches, disabled role assignment, system-grant listing/replacement, final permission-manager protection, and account profile fields remaining outside authorization.
|
||||
|
||||
- [ ] **Step 2: Run tests and confirm routes are absent**
|
||||
|
||||
Run: `GOWORK=off go test ./internal/server -run 'Role|PermissionCatalog|UserRole' -count=1`
|
||||
Expected: FAIL with 404 or missing handlers.
|
||||
|
||||
- [ ] **Step 3: Implement service authorization and handlers**
|
||||
|
||||
Protected actions require explicit `system_grants`; `project.create` may also use the current enabled role permission. Provide `GET/PUT /api/admin/users/{userId}/system-grants` with expected epoch and idempotency key. Replace `requireAdmin` only for the new role endpoints in this task; existing unrelated admin endpoints remain unchanged until their explicit action is wired in Task 4.
|
||||
|
||||
- [ ] **Step 4: Wire account management actions without changing recovery**
|
||||
|
||||
Map account list/create/profile/state handlers to `system.users.view/create/edit/disable`. Do not touch recovery routes or credential behavior. Preserve first-admin bootstrap as the protected root recovery path.
|
||||
|
||||
- [ ] **Step 5: Run server and full Backend tests**
|
||||
|
||||
Run: `GOWORK=off go test ./internal/authz ./internal/server ./internal/store -count=1`
|
||||
Run: `GOWORK=off go test ./... -count=1`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 6: Commit the Backend API**
|
||||
|
||||
```bash
|
||||
git add internal/authz/service.go internal/server/roles.go internal/server/server.go internal/server/accounts.go internal/server/roles_test.go internal/server/role_authorization_test.go
|
||||
git commit -m "Expose role and system permission APIs"
|
||||
```
|
||||
|
||||
### Task 4: Public role provider for RDM
|
||||
|
||||
**Files:**
|
||||
- Modify: `Agent-System-Backend/pkg/extension/extension.go`
|
||||
- Modify: `Agent-System-Backend/internal/app/hostcaps.go`
|
||||
- Test: `Agent-System-Backend/internal/app/role_provider_test.go`
|
||||
- Create: `Agent-System-RDM/internal/perms/role_provider.go`
|
||||
- Modify: `Agent-System-RDM/internal/rdmapp/perms_api.go`
|
||||
- Test: `Agent-System-RDM/internal/rdmapp/role_provider_test.go`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces public `extension.RolePolicyProvider` methods `RolePolicyForActor(actor string)`, `RolePolicyForUser(userID string)`, and `CheckRoleAction(userID, actionID string)` returning versioned, non-secret snapshots.
|
||||
- Consumes the actual request actor from the trusted Host; caller-supplied actor fields never select authority.
|
||||
|
||||
- [ ] **Step 1: Add provider contract tests on both sides**
|
||||
|
||||
Backend tests verify stable user IDs, enabled state, role version, action default/cap, authority epoch, and rejection when the Host has no authenticated actor. RDM tests verify provider missing, wrong version, disabled role, and unknown action all deny without consulting the legacy tables.
|
||||
|
||||
- [ ] **Step 2: Run the contract tests red**
|
||||
|
||||
Run Backend: `GOWORK=off go test ./internal/app -run RoleProvider -count=1`
|
||||
Run RDM: `GOWORK=off go test ./internal/rdmapp -run RoleProvider -count=1`
|
||||
Expected: FAIL with missing public provider.
|
||||
|
||||
- [ ] **Step 3: Implement the public interface and RDM adapter**
|
||||
|
||||
The provider returns only role and permission metadata needed for authorization. It must not return user contact fields. RDM's evaluator must use the provider whenever a role binding exists; absence is a denial after migration readiness is enabled.
|
||||
|
||||
- [ ] **Step 4: Run both component suites**
|
||||
|
||||
Run Backend: `GOWORK=off go test ./... -count=1`
|
||||
Run RDM with the reviewed Backend module overlay during development: `GOWORK=off go test ./... -count=1`
|
||||
Expected: PASS; overlay evidence remains SELF until a trusted Backend tag is published.
|
||||
|
||||
- [ ] **Step 5: Commit each repository separately**
|
||||
|
||||
Backend commit: `Expose the role policy provider`.
|
||||
RDM commit: `Consume the Backend role authority`.
|
||||
|
||||
### Task 5: RDM migration adapter and creator-only project management
|
||||
|
||||
**Files:**
|
||||
- Create: `Agent-System-RDM/internal/perms/role_migration.go`
|
||||
- Modify: `Agent-System-RDM/internal/perms/roles.go`
|
||||
- Modify: `Agent-System-RDM/internal/rdmapp/perms_api.go`
|
||||
- Modify: `Agent-System-RDM/plugins/rdm/plugin.go`
|
||||
- Test: `Agent-System-RDM/internal/perms/role_migration_test.go`
|
||||
- Test: `Agent-System-RDM/internal/rdmapp/project_creator_permissions_test.go`
|
||||
- Test: `Agent-System-RDM/plugins/rdm/roles_test.go`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes Task 4 provider and Backend import endpoint/command.
|
||||
- Produces a versioned export manifest for existing RDM roles and a compatibility forwarding layer for `rdm.role.*` writes.
|
||||
|
||||
- [ ] **Step 1: Write migration and cross-project denial tests**
|
||||
|
||||
```go
|
||||
func TestCreatorCannotManageAnotherCreatorsProject(t *testing.T) {
|
||||
projectA := createProjectAs(t, "alice")
|
||||
projectB := createProjectAs(t, "bob")
|
||||
requireAllowed(t, setProjectPermission("alice", projectA, "carol", ActDocRead, "allow"))
|
||||
requireDenied(t, setProjectPermission("alice", projectB, "carol", ActDocRead, "allow"))
|
||||
}
|
||||
```
|
||||
|
||||
Also assert role IDs, descriptions, bindings, defaults, caps, disabled state, and counts survive export/import; once provider readiness is set, legacy local writes and fallback reads are rejected.
|
||||
|
||||
- [ ] **Step 2: Implement export and forwarding without production migration**
|
||||
|
||||
Add dry-run export and compare functions. Forward `rdm.role.create/action/assign/disable/list` to Backend through the trusted Host. Keep old tables read-only for verification; do not delete them.
|
||||
|
||||
- [ ] **Step 3: Tighten project management to immutable creator ownership**
|
||||
|
||||
For member, permission, and duty configuration, load the actual project and compare its immutable `created_by` to the authenticated actor before applying role and platform caps. Do not add delegated project-manager behavior.
|
||||
|
||||
- [ ] **Step 4: Run RDM tests**
|
||||
|
||||
Run: `GOWORK=off go test ./internal/perms ./internal/rdmapp ./plugins/rdm -count=1`
|
||||
Run: `GOWORK=off go test ./... -count=1`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 5: Commit the RDM consumer**
|
||||
|
||||
```bash
|
||||
git add internal/perms/role_migration.go internal/perms/roles.go internal/rdmapp/perms_api.go plugins/rdm/plugin.go internal/perms/role_migration_test.go internal/rdmapp/project_creator_permissions_test.go plugins/rdm/roles_test.go
|
||||
git commit -m "Move RDM role writes to the Backend authority"
|
||||
```
|
||||
|
||||
### Task 6: Frontend role API and shared draft model
|
||||
|
||||
**Files:**
|
||||
- Modify: `Agent-System-Frontend/src/api.ts`
|
||||
- Create: `Agent-System-Frontend/src/rolePermissions.ts`
|
||||
- Test: `Agent-System-Frontend/test/role-permissions.test.ts`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes Backend HTTP endpoints from Task 3.
|
||||
- Produces `RoleRecord`, `PermissionDescriptor`, `RolePermissionDraft`, `mergeRoleDraft`, `visiblePatch`, and typed API methods.
|
||||
|
||||
- [ ] **Step 1: Write failing draft-model tests**
|
||||
|
||||
Test that filtered rows retain edits, `visiblePatch` includes only explicit action IDs, single-role and matrix edits produce identical changes, stale server refresh does not replace a newer draft generation, and `allowed=true/capAllowed=false` is rejected before submit.
|
||||
|
||||
- [ ] **Step 2: Implement the typed API and pure draft helpers**
|
||||
|
||||
```ts
|
||||
export type RolePermissionValue = { allowed: boolean; capAllowed: boolean }
|
||||
export type RolePermissionDraft = Record<string, RolePermissionValue>
|
||||
export function visiblePatch(draft: RolePermissionDraft, visibleActionIds: string[]): RolePermissionChange[]
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Run tests and build**
|
||||
|
||||
Run: `npx vitest run test/role-permissions.test.ts`
|
||||
Run: `npm run build`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 4: Commit the client contract**
|
||||
|
||||
```bash
|
||||
git add src/api.ts src/rolePermissions.ts test/role-permissions.test.ts
|
||||
git commit -m "Add the role permission client model"
|
||||
```
|
||||
|
||||
### Task 7: Single-role and matrix configuration UI
|
||||
|
||||
**Files:**
|
||||
- Create: `Agent-System-Frontend/src/components/RolePermissionsPanel.tsx`
|
||||
- Modify: `Agent-System-Frontend/src/components/AdminZone.tsx`
|
||||
- Modify: `Agent-System-Frontend/src/components/AccountUsersPanel.tsx`
|
||||
- Modify: `Agent-System-Frontend/src/styles.css`
|
||||
- Test: `Agent-System-Frontend/test/role-permissions-ui.test.tsx`
|
||||
- Test: `Agent-System-Frontend/test/design-guard.test.ts`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes Task 6 API and draft helpers plus existing `@ui` components and tokens.
|
||||
- Produces the “角色与权限” system-management section and one-role assignment in user details.
|
||||
|
||||
- [ ] **Step 1: Re-read Dev `DESIGN.md` and add failing interaction tests**
|
||||
|
||||
Cover exact/fuzzy role search, state filtering, description edit, binding count, single-role edit, matrix edit, grouped paging, hidden-row draft retention, diff preview, conflict preservation, one user role replacement, system-grant editing with final-manager protection, and a late response discarded after switching roles.
|
||||
|
||||
- [ ] **Step 2: Implement the panel using existing design tokens**
|
||||
|
||||
Use `Collapsible` from `@ui`; consume `@ui/tokens.css` and `@ui/motion.css`; do not add raw colors, private keyframes, `<details>`, or inline font sizes. Keep one request sequence owner for list/detail/preview/commit results.
|
||||
|
||||
- [ ] **Step 3: Replace the RDM role admin entry**
|
||||
|
||||
Change the section label from “RDM 角色权限” to “角色与权限” and bind it to Backend APIs. Keep RDM project permission and document-duty components in project settings.
|
||||
|
||||
- [ ] **Step 4: Add the user role selector**
|
||||
|
||||
Display the current role and explicit system grants in account details. Allow role replacement only when the server advertises `system.roles.assign`; submit stable `userId`, `roleId`, expected state version, and idempotency key. Allow system-grant editing only with `system.permissions.manage`, using the server epoch and fixed action IDs.
|
||||
|
||||
- [ ] **Step 5: Run Frontend and design checks**
|
||||
|
||||
Run: `npm test`
|
||||
Run: `npm run build`
|
||||
Run paired UI: `npm test` in `Agent-System-UI`.
|
||||
Expected: all pass with no design-guard regression.
|
||||
|
||||
- [ ] **Step 6: Commit the UI**
|
||||
|
||||
```bash
|
||||
git add src/components/RolePermissionsPanel.tsx src/components/AdminZone.tsx src/components/AccountUsersPanel.tsx src/styles.css test/role-permissions-ui.test.tsx
|
||||
git commit -m "Add role and permission configuration views"
|
||||
```
|
||||
|
||||
### Task 8: Fixed-combination verification
|
||||
|
||||
**Files:**
|
||||
- Modify: `Agent-System-Dev/modules/backend`
|
||||
- Modify: `Agent-System-Dev/modules/rdm`
|
||||
- Modify: `Agent-System-Dev/modules/frontend`
|
||||
- Modify: `Agent-System-Dev/modules/ui`
|
||||
- Test evidence: `Agent-System-Dev/.task/feature-iam-u4-role-authority.md`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes reviewed component commits and trusted published tags where required.
|
||||
- Produces one fixed Dev combination and requirement-to-evidence map.
|
||||
|
||||
- [ ] **Step 1: Run component verification on exact commits**
|
||||
|
||||
Backend: full SQLite, isolated PostgreSQL, migration rollback/retry, build.
|
||||
RDM: full tests/build against the reviewed Backend public version.
|
||||
Frontend/UI: full tests/build and design guards.
|
||||
|
||||
- [ ] **Step 2: Run a real browser scenario on an isolated database**
|
||||
|
||||
Create two ordinary users, one “软件工程师” role with a description, assign both users, replace one user's role, configure `project.create`, create projects A and B under different creators, and verify A's creator cannot manage B. Verify an unassigned system administrator cannot read either project's business content. Exercise exact/fuzzy search, filters, single-role edit, matrix edit, preview, conflict, and draft retention.
|
||||
|
||||
- [ ] **Step 3: Run the Dev combination**
|
||||
|
||||
Run: `make test`
|
||||
Expected: PASS on the exact component SHAs recorded by `make evidence`.
|
||||
|
||||
- [ ] **Step 4: Record remaining boundaries**
|
||||
|
||||
Mark production migration, deployment, account recovery, multi-role, Agent permissions, and workflow changes `NOT_RUN / out of scope`. Do not claim them from component tests.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: 聚焦版角色与分层权限系统规格
|
||||
date: 2026-10-15
|
||||
type: feature
|
||||
status: approved
|
||||
approved_at: 2026-10-15
|
||||
supersedes_scope: 2026-10-13-identity-role-permission-plan.md U4-U7 中超出本文的部分
|
||||
---
|
||||
|
||||
# 聚焦版角色与分层权限系统规格
|
||||
|
||||
## 目标
|
||||
|
||||
实现用户要求的角色与权限系统,不引入账号恢复、多职位、Agent 授权或新的工作流能力。
|
||||
|
||||
首期角色等同企业职位。角色与用户分离:同一角色可分配给多个用户,每个用户同时只有一个生效角色。角色包含稳定 `roleId`、名称、可选描述、启用状态和版本。用户继续使用稳定 `userId`,姓名、电话、邮箱、工号、部门和备注均为可选资料,不参与授权主键。
|
||||
|
||||
权限分为三个配置面,但使用同一服务端动作目录和判定结果:
|
||||
|
||||
1. 系统权限控制系统设置、账号管理、角色管理、权限上限和项目创建。
|
||||
2. 角色权限描述一个职位默认可以执行的动作及其上限,例如创建项目、查看获准目录信息。
|
||||
3. 项目权限只在一个项目内生效,由该项目创建者维护;A 项目的管理权不能用于 B 项目。
|
||||
|
||||
系统管理员负责账号、角色和平台权限上限。系统管理员没有他人项目业务内容的隐式访问权,读取项目正文、原件、草稿、业务审计或导出仍需该项目的明确授权。
|
||||
|
||||
## 范围
|
||||
|
||||
### 角色与用户
|
||||
|
||||
- `Role`:`roleId`、名称、描述、状态、`roleVersion`、创建者、修改者和时间。
|
||||
- `UserRoleBinding`:`bindingId`、`userId`、`roleId`、状态、版本、任命者和任命时间。
|
||||
- 一个用户最多一条有效 binding;同一角色允许任意多个有效用户 binding。
|
||||
- 改名、编辑描述和停用角色不改变用户、项目或历史记录的稳定 ID。
|
||||
- 停用角色时保留 binding 和审计记录,但其角色授权立即失效;不回落到更宽的默认权限。
|
||||
- 任命停用角色、未知角色或停用账号均拒绝。
|
||||
|
||||
### 权限目录与三层授权
|
||||
|
||||
动作目录由受信注册表定义 `actionId`、中文名、说明、scope、分组、风险级别和是否受保护。请求不能通过动作字符串或请求体自行声明 scope。
|
||||
|
||||
首期系统动作至少包括:
|
||||
|
||||
| 分组 | 动作 |
|
||||
|---|---|
|
||||
| 系统设置 | `system.settings.read`、`system.settings.write` |
|
||||
| 用户管理 | `system.users.view`、`system.users.create`、`system.users.edit`、`system.users.disable` |
|
||||
| 角色管理 | `system.roles.view`、`system.roles.manage`、`system.roles.assign` |
|
||||
| 权限管理 | `system.permissions.view`、`system.permissions.manage` |
|
||||
| 项目入口 | `project.create` |
|
||||
|
||||
受保护的角色、权限和管理员管理动作只能来自明确系统授权,普通角色配置不能授予。`project.create` 可以来自明确系统授权或当前有效角色的允许项,但仍受平台上限约束。
|
||||
|
||||
项目动作至少包括 `project.settings`、`project.members.manage`、`project.permissions.manage`、`document.duties.assign`、`document.read`、`document.author`、`document.review`、`document.approve`。项目动作必须同时满足:账号有效、项目关系有效、当前角色有效、角色动作允许且未超过角色上限、平台未禁止、项目未明确拒绝、资源关系和文档状态允许。
|
||||
|
||||
项目创建者只获得自己项目的管理默认,且仍受平台和角色上限约束。创建者关系不授予其他项目权限,也不自动授予项目业务内容读取或代签能力。
|
||||
|
||||
### 角色权限
|
||||
|
||||
每个角色的动作配置包含 `allowed` 与 `capAllowed`:
|
||||
|
||||
- `allowed=true` 表示该角色默认允许动作。
|
||||
- `capAllowed=false` 表示该角色不能通过项目覆盖获得该动作。
|
||||
- `allowed=true && capAllowed=false` 是非法配置,服务端拒绝。
|
||||
- 未知动作和未配置动作默认拒绝。
|
||||
- 角色默认和上限不得写入超出操作者可委派范围的受保护动作。
|
||||
|
||||
首期一个用户只有一个有效角色,因此一次判定只使用该 binding,不进行跨角色动作或范围拼接。
|
||||
|
||||
### 项目权限和文档三权
|
||||
|
||||
RDM 保留项目成员、项目创建者、项目内覆盖和现有文档三权的领域权威。Backend 负责角色、binding、系统动作和平台/角色上限。
|
||||
|
||||
项目覆盖使用 `inherit | allow | deny`:`allow` 不能突破平台或角色上限,`deny` 明确阻断。项目创建者只能修改自己创建项目的成员、权限和文档三权。
|
||||
|
||||
文档编制、审核、批准继续使用现有 RDM 三权记录;分配候选必须是该项目有效成员,账号和角色有效,并具有对应动作上限。角色只提供资格,不能代替具体文档职责。
|
||||
|
||||
## 服务端接口
|
||||
|
||||
Backend 成为角色和系统权限的唯一写入权威,提供版本化接口:
|
||||
|
||||
- `GET /api/admin/permissions/catalog`
|
||||
- `GET /api/admin/roles`,支持名称精确/模糊搜索、状态和动作过滤、分页
|
||||
- `POST /api/admin/roles`
|
||||
- `GET /api/admin/roles/{roleId}`
|
||||
- `PATCH /api/admin/roles/{roleId}`,使用 `expectedRoleVersion`
|
||||
- `PUT /api/admin/roles/{roleId}/permissions`,批量提交固定 actionId 列表和 `expectedRoleVersion`
|
||||
- `PUT /api/admin/users/{userId}/role`,替换该用户唯一有效角色,使用用户状态版本和幂等键
|
||||
- `GET /api/admin/users/{userId}/role`
|
||||
- `GET /api/admin/users/{userId}/system-grants`
|
||||
- `PUT /api/admin/users/{userId}/system-grants`,批量提交明确系统动作并使用 `expectedAuthorityEpoch` 和幂等键
|
||||
- `GET /api/authz/explain`,仅解释调用者自己或其有权管理的对象
|
||||
|
||||
批量权限修改在单库事务内全部成功或全部失败;任一未知动作、越权、越上限或版本冲突不得部分写入。响应返回新版本、实际差异和审计回执标识。
|
||||
|
||||
RDM 通过公开、固定版本的 Backend 角色读取/判定契约消费角色数据。RDM 原 `rdm.role.*` 写命令在迁移期转发 Backend;切换完成后不得继续写 RDM 旧角色表。读取失败、提供者缺失或版本不兼容时拒绝权限动作。
|
||||
|
||||
## 配置界面
|
||||
|
||||
系统管理区增加“角色与权限”入口:
|
||||
|
||||
- 角色列表显示名称、描述、状态和绑定人数,支持精确搜索、模糊搜索和状态过滤。
|
||||
- 单角色视图编辑名称、描述、状态及权限。
|
||||
- 角色矩阵以角色为行、权限为列,按权限分组和分页展示。
|
||||
- 单角色视图与矩阵使用同一草稿模型和同一批量接口。
|
||||
- 过滤隐藏的单元格不丢失草稿;全选只作用于当前明确显示的固定 actionId 集合。
|
||||
- 提交前显示差异;冲突保留草稿并要求刷新,不逐格即时写库。
|
||||
|
||||
用户详情显示当前角色和明确系统授权来源,并允许有 `system.roles.assign` 权限的操作者从有效角色中选择。有 `system.permissions.manage` 权限的操作者可以编辑目标用户的系统授权,但不能撤销最后一个有效权限管理者。用户可选资料继续用于展示、搜索和辨识,不参与权限计算。
|
||||
|
||||
项目设置继续使用现有成员和权限入口,显示角色默认、角色上限、项目覆盖及最终允许/拒绝原因。项目创建者无法切换到其他项目后沿用原项目管理权。
|
||||
|
||||
## 迁移与兼容
|
||||
|
||||
1. 导出 RDM 当前角色、动作配置和账号单角色绑定,包含来源版本与摘要。
|
||||
2. 以原 `roleId` 导入 Backend;为每个账号生成一个稳定 binding。
|
||||
3. 对角色数量、绑定数量、动作默认/上限和引用逐项比对。
|
||||
4. 在迁移窗口内禁止双主写;RDM 写入口改为转发 Backend。
|
||||
5. 切换消费者后保留旧表只读,确认无回退依赖后再另行批准清理。
|
||||
|
||||
迁移失败不得启用部分角色数据;恢复时保留已撤销、停用和拒绝事实,不能复活旧权限。
|
||||
|
||||
## 验收条件
|
||||
|
||||
- 创建“软件工程师”角色并分配给两个用户,两人保留各自稳定 userId。
|
||||
- 同一用户第二次任命替换原生效角色,不产生两个同时有效的 binding。
|
||||
- 角色描述可编辑,用户可选资料全空仍合法。
|
||||
- 未知动作、默认超过上限、停用角色任命、无授权角色管理和最后系统权限管理者撤销均拒绝。
|
||||
- 普通角色可被授予 `project.create`,但不能因此修改系统设置、用户、角色或权限上限。
|
||||
- A 项目创建者管理 A 的成员、项目权限和文档三权成功;操作 B 全部拒绝。
|
||||
- 系统管理员未获项目授权时不能读取 A 或 B 的业务内容。
|
||||
- 单角色配置和角色矩阵产生等价的固定 actionId 批量 patch;过滤和分页不丢草稿。
|
||||
- SQLite 与 PostgreSQL 的版本冲突、事务回滚和迁移结果一致。
|
||||
|
||||
## 明确排除
|
||||
|
||||
本增量不实现一人多职、账号恢复、SSO/组织树、Agent 权限、工作流重建、新的文档审签流程、生产迁移或部署。现有文档三权只接入新的角色资格和项目权限判定。
|
||||
@@ -0,0 +1,368 @@
|
||||
---
|
||||
title: IAM U4 Stage 7-10 Delivery - Plan
|
||||
type: feat
|
||||
date: 2026-10-15
|
||||
artifact_contract: ce-unified-plan/v1
|
||||
product_contract_source: specialized-project-spec
|
||||
execution: code
|
||||
origin: docs/proposals/2026-10-15-iam-focused-role-permission-spec.md
|
||||
---
|
||||
|
||||
# IAM U4 Stage 7-10 Delivery - Plan
|
||||
|
||||
## Goal Capsule
|
||||
|
||||
- **Objective:** The approved IAM U4 role and permission behavior is accepted in a real browser, merged through each protected repository at reviewed commits, and closed with traceable evidence and clean workspaces.
|
||||
- **Means:** Use the repository's existing Playwright stack against an isolated RDM product composition, then deliver Backend, Frontend, Documents, RDM, and Dev in dependency order with exact-head review and CI. (KTD1–KTD5)
|
||||
- **Authority:** The focused specification approved at Documents `e9ce9a5` owns behavior; this plan owns delivery mechanics; `Agent-System-Dev/policy/delivery.md` and `policy/merge-queue.md` own stage and merge gates; the task card owns current evidence.
|
||||
- **Execution profile:** The agent prepares and performs testing, review, PRs, conflict resolution, CI checks, merges, and cleanup. The user retains stage 7 and stage 10 decisions and personally publishes any trusted tag.
|
||||
- **Stop conditions:** Stop on a changed requirement, cross-project access success, stale or mismatched candidate SHA, unresolved browser or CI failure, a conflicting merge window, a mismatched existing tag, or any request to touch production data or deployment.
|
||||
|
||||
---
|
||||
|
||||
## Product Contract
|
||||
|
||||
### Summary
|
||||
|
||||
Stage 7 proves the implemented role model and permission boundaries through the real React interface and live Backend/RDM authorization path.
|
||||
Stages 8–10 then carry the same behavior through component PRs, a trusted Backend release tag, RDM pins, the Dev fixed combination, protected-branch CI, and safe task closure.
|
||||
|
||||
### Problem Frame
|
||||
|
||||
The implementation candidate has passed SQLite, isolated PostgreSQL, RDM overlay, Frontend/UI, and Dev combination checks, but those checks do not prove browser behavior or protected-repository delivery.
|
||||
The repositories also move independently: RDM consumes a published Backend extension contract, while Dev pins Backend, Frontend, UI, and Documents but does not pin RDM.
|
||||
Delivery must preserve those dependency and evidence boundaries without turning production migration or deployment into an implied part of acceptance.
|
||||
|
||||
### Requirements
|
||||
|
||||
**Candidate identity and formal acceptance**
|
||||
|
||||
- DR1. Stage 7 starts only after each task branch is synchronized with its current `origin/main` and the tested component commits are recorded together.
|
||||
- DR2. Formal browser acceptance runs on a fresh isolated data root and random loopback ports, never on a registered or production service.
|
||||
- DR3. Browser evidence uses the existing Frontend Playwright stack against the exact Backend, RDM, Frontend, and UI sources under review.
|
||||
- DR4. Every acceptance result records the command, component SHAs, environment shape, exit code, sanitized screenshots or traces where applicable, and evidence source. Browser credentials are synthetic; artifacts use owner-restricted external storage and expire after stage 10.
|
||||
- DR5. Stage 7 requires user review of the requirement-to-evidence map before any component merge begins.
|
||||
|
||||
**Role, user, and permission behavior**
|
||||
|
||||
- DR6. The browser creates and edits a role with a description while its stable `roleId` remains unchanged. Before disabling a role, the UI names it, shows the bound-user count and authorization impact, supports cancellation without a request, and sends one versioned request only after confirmation; success preserves a usable selection, while conflict or failure preserves context for retry.
|
||||
- DR7. Two users can share one role, one user can be moved to another role, and the system never exposes two active roles for one user.
|
||||
- DR8. Name, phone, email, staff number, department, and notes remain optional and searchable without becoming authorization identifiers.
|
||||
- DR9. Exact and fuzzy role search, status and action filters, pagination, single-role editing, matrix default/cap editing, visible-page batch changes, preview, and 409 rebasing work through the rendered UI. Drafts are keyed by `roleId`: permission grouping/paging, role filters, role paging, and single/matrix switching preserve them; switching roles never transfers a draft; leaving the administration area or refreshing requires an explicit save/discard decision; a 409 rebases only the same role's draft.
|
||||
- DR10. Delegated system actions expose only their permitted user, role, or permission controls; a manager without view authority cannot replace data with an empty set. Loading, stale, empty, partial-failure, retry, and success states are distinct; destructive controls remain unavailable without authoritative data. The core flow works by keyboard with named controls, announced status changes, stable focus after save/conflict/error, and a usable narrow viewport including matrix navigation.
|
||||
- DR11. `project.create` works only through an explicit system grant or an enabled role default within its cap.
|
||||
- DR12. Project A's creator can manage A's members, overrides, and document duties, but A's creator relation and an untrusted owner label never authorize project B. A separate valid B-side membership, current role grant, cap, and project override continue to authorize only the B actions they explicitly allow.
|
||||
- DR13. System administrator identity alone cannot read another user's project business content, private conversations, originals, drafts, controlled document bodies, business audit records, or exports, and cannot create a business-content export artifact.
|
||||
- DR14. Document author, reviewer, and approver assignments require current account and role eligibility, and approval remains separate from document publication.
|
||||
- DR15. Missing providers, incompatible schemas, stale authority epochs, disabled accounts, disabled roles, unknown actions, and out-of-cap overrides fail closed. Version-conflict, unknown-action, and out-of-cap batch updates perform zero partial writes, with the same resulting state and migration outcome on SQLite and PostgreSQL.
|
||||
|
||||
**Protected delivery**
|
||||
|
||||
- DR16. Component branches merge in dependency order; a downstream pin never points to an unmerged commit or unpublished required tag.
|
||||
- DR17. Backend's trusted tag is created only by the user after the reviewed Backend PR merge commit is verified on `origin/main`; an existing tag is never rewritten.
|
||||
- DR18. RDM updates its pins only after Backend and Frontend commits are merged, then builds the product from committed Git objects or a strictly clean tracked/untracked/ignored source tree, records digests of the copied content as well as Git SHAs, and replays affected acceptance. Dirty or untracked source must fail before packaging.
|
||||
- DR19. Dev enters the manual merge queue only after all component dependencies are merged and the final gitlinks point to their authoritative commits.
|
||||
- DR20. Dev merge requires exact-head `test`, `test-pg`, and `svc-realcombo` GATE success, current Review, no conflicting main advance, and an explicit queue claim.
|
||||
- DR21. Task closure records the actual merge commits and retains every failed, skipped, and not-run result at its real evidence level. Any source, base, pin, candidate manifest, or test-definition change after stage 7 updates the manifest, replays affected evidence, and requires a renewed stage 7 conclusion before the first component merge.
|
||||
|
||||
### Actors
|
||||
|
||||
- A1. **System administrator:** manages platform accounts, roles, explicit system grants, and platform permission ceilings.
|
||||
- A2. **Delegated manager:** holds a selected subset of system actions and sees only the matching administration controls.
|
||||
- A3. **Project creator:** manages only the project identified by immutable creation metadata.
|
||||
- A4. **Project member:** receives project behavior from the current professional role, project override, resource relation, lifecycle state, and document duty.
|
||||
- A5. **Delivery agent:** executes tests, review, PRs, CI checks, merges, and cleanup within the approved scope.
|
||||
- A6. **User reviewer:** approves stage 7 evidence, personally publishes a trusted tag, and approves stage 10 cleanup.
|
||||
|
||||
### Key Decisions
|
||||
|
||||
- **One effective role remains the product model.** The delivery does not introduce multi-role assignment. Governs DR7.
|
||||
- **System administration does not grant business-content access.** Project and resource authorization remain explicit. Governs DR12–DR15.
|
||||
- **Production migration and deployment remain outside this delivery.** The migration machinery is tested only on isolated databases. Governs DR2, DR21.
|
||||
|
||||
### Key Flows
|
||||
|
||||
- F1. **Formal acceptance**
|
||||
- **Trigger:** The synchronized component candidate is fixed.
|
||||
- **Actors:** A1–A5.
|
||||
- **Steps:** Build the isolated composition; seed accounts and projects; drive role, user, system grant, project, and document flows in Chromium; capture traces and API decisions; replay SQLite, PostgreSQL, and component suites.
|
||||
- **Outcome:** DR6–DR15 have exact-candidate evidence or stage 7 stops.
|
||||
- **Covers:** DR1–DR15.
|
||||
|
||||
- F2. **Serial protected delivery**
|
||||
- **Trigger:** The user approves stage 7.
|
||||
- **Actors:** A5, A6, Gitea.
|
||||
- **Steps:** Merge Backend; publish and verify its tag; merge Frontend and Documents; update and merge RDM pins; fix the Dev gitlinks; claim the Dev queue window; pass exact-head CI; merge and verify; finish registered worktrees; close the task card through its own reviewed PR.
|
||||
- **Outcome:** Every protected branch contains the reviewed behavior and the task record identifies the actual commits.
|
||||
- **Covers:** DR16–DR21.
|
||||
|
||||
### Acceptance Examples
|
||||
|
||||
- AE1. **Shared position:** Given two enabled users and one enabled software-engineer role, assigning both users succeeds; replacing one user's role leaves one active binding for each user and the original role still has one member. Covers DR7.
|
||||
- AE2. **Fine-grained manager:** Given `system.users.view` without role or permission view, the manager opens user details without a failing role request and cannot edit roles or grants. Covers DR10.
|
||||
- AE3. **Draft conflict:** Given a local matrix draft and a concurrent role update, saving returns 409, reloads the latest role version, replays the local draft against it, and never applies role A's draft to role B. Covers DR9.
|
||||
- AE4. **Creator isolation:** Given projects A and B with different creators, A's creator can change A's members, overrides, and author/reviewer/approver duties. With no valid B-side management grant, the same actor is denied for all three mutation families in B and B remains unchanged, even if the actor is a B member or carries an untrusted owner label. A separate fixture proves that a valid B-side grant authorizes only its declared B actions. Covers DR12, DR14.
|
||||
- AE5. **Administrator privacy:** Given an administrator with no project content grant, direct authenticated requests to B's private conversations, originals, drafts, controlled bodies, business-audit list/detail, and export create/status/download routes are denied with no payload or export artifact. A separately authorized project actor supplies positive controls for the same routes. Covers DR13.
|
||||
- AE6. **Fail-closed refresh:** Given an allowed cached role snapshot, tightening the role cap changes the authority epoch; the next project or knowledge read consumes the current Backend snapshot and denies the old permission. Covers DR15.
|
||||
- AE7. **Migration rehearsal:** Given a provenance-recorded frozen v35 fixture and oracle covering active and disabled roles, inactive bindings, revoked grants, explicit denies, owner mappings, and orphan/reference failures, a trusted non-production harness invokes the real Backend/RDM stores to freeze legacy writes, stage stable IDs and full owner-to-role mappings, compare source hashes and expected results, and activate by epoch. Compare mismatch or a concurrent legacy write blocks activation; a lost success response can be retried without duplicate bindings. SQLite and PostgreSQL produce the same final state. Covers DR2, DR15, DR21.
|
||||
|
||||
### Scope Boundaries
|
||||
|
||||
Included:
|
||||
|
||||
- Repeatable UI and live-composition browser acceptance for the approved U4 requirements.
|
||||
- Test-only adjustments needed to make that acceptance deterministic and reviewable.
|
||||
- Component sync, PRs, CI, Backend tag handoff, RDM pin updates, Dev queue delivery, and task cleanup.
|
||||
|
||||
Excluded:
|
||||
|
||||
- Production schema migration, legacy-role cutover, deployment, or 8788 service changes.
|
||||
- Account recovery, password flows beyond isolated fixture setup, multi-role support, Agent permissions, organization trees, SSO, and workflow redesign.
|
||||
- Branch-protection changes, tag rewriting, runner changes, or merge-queue automation.
|
||||
|
||||
---
|
||||
|
||||
## Planning Contract
|
||||
|
||||
### Key Technical Decisions
|
||||
|
||||
- KTD1. **Use repository-native Playwright as the formal browser gate.** `Agent-System-Frontend/playwright.config.ts` and the existing `e2e/` suite already define the project's real-browser contract. `agent-browser` may add an exploratory visible smoke when installed, but its absence does not replace or invalidate the repeatable Playwright run.
|
||||
- KTD2. **Run two browser layers.** Deterministic routed tests cover UI permission combinations, pagination, draft retention, and response ordering; a live isolated RDM product covers authentication, storage, Backend policy, RDM project boundaries, and embedded Frontend behavior.
|
||||
- KTD3. **Freeze evidence by component SHA and environment.** A branch sync, pin change, test-harness change, or target-main advance invalidates only the affected results; no receipt is copied to a different object.
|
||||
- KTD4. **Deliver dependencies serially.** Backend merges and receives a trusted tag before RDM updates its Backend pin. Frontend and Documents merge before RDM fixes its product pins. Dev pins only merged component commits and enters its final queue window last.
|
||||
- KTD5. **Keep high-consequence operations dual-keyed.** The agent prepares and verifies the proposed Backend tag command; the user executes tag publication. Production migration and deployment have no execution unit in this plan.
|
||||
- KTD6. **Treat missing component CI honestly.** Backend, RDM, and Dev consume their repository workflows. Frontend and Documents use their repository verification plus downstream Dev GATE when no repository-local workflow exists; they are not labeled GATE without a real platform run.
|
||||
|
||||
### High-Level Technical Design
|
||||
|
||||
The diagrams are delivery guidance rather than implementation specifications.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
BE[Backend reviewed commit] --> BET[User-published Backend tag]
|
||||
BET --> RP[RDM Backend pin]
|
||||
FE[Frontend reviewed commit] --> RP
|
||||
UI[UI commit already on main] --> RP
|
||||
DOC[Documents plan/spec commit] --> DEV[Dev final gitlinks]
|
||||
BE --> DEV
|
||||
FE --> DEV
|
||||
UI --> DEV
|
||||
RP --> RDM[RDM protected main]
|
||||
DEV --> DCI[Dev test + test-pg + svc-realcombo]
|
||||
DCI --> DM[Dev protected main]
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Agent as Delivery agent
|
||||
participant Browser as Playwright Chromium
|
||||
participant Product as Isolated RDM product
|
||||
participant User as User reviewer
|
||||
participant Gitea as Protected repositories
|
||||
Agent->>Product: Build exact component composition
|
||||
Agent->>Browser: Run deterministic and live U4 scenarios
|
||||
Browser->>Product: Role, user, grant, project, and duty requests
|
||||
Product-->>Browser: Current policy decisions and rendered results
|
||||
Agent->>User: Stage 7 requirement-to-evidence map
|
||||
User-->>Agent: Stage 7 conclusion
|
||||
Agent->>Gitea: Review, CI, and serial component PR merges
|
||||
Agent->>User: Exact Backend merge commit and tag command
|
||||
User-->>Gitea: Publish trusted tag
|
||||
Agent->>Gitea: RDM pins, Dev queue CI, merge, and verification
|
||||
```
|
||||
|
||||
### Sequencing
|
||||
|
||||
1. Fix and accept the synchronized stage 7 candidate.
|
||||
2. Complete stage 7 browser and database evidence and obtain the user's conclusion.
|
||||
3. Re-review any files changed by acceptance work.
|
||||
4. Merge Backend, then complete the user-owned tag gate.
|
||||
5. Merge Frontend and Documents.
|
||||
6. Sync RDM, update pins, replay the product and browser gates, then merge RDM.
|
||||
7. Fix Dev gitlinks, claim the manual queue window, run exact-head CI, and merge Dev.
|
||||
8. Verify merged content, preserve receipts, clean registered worktrees, and then close the task card through its own reviewed PR after stage 10 approval.
|
||||
|
||||
### Risks and Dependencies
|
||||
|
||||
- Backend, RDM, Documents, and Dev main may advance before their windows. Each affected branch must sync once at its delivery boundary and rerun affected evidence.
|
||||
- RDM currently trails its authoritative main substantially. Conflict resolution must preserve upstream behavior and may invalidate the pre-sync RDM review.
|
||||
- Browser execution requires the repository Playwright runtime and Chromium. If the runtime cannot launch, stage 7 stops with the launch error; another browser stack is not substituted.
|
||||
- The recommended Backend version is `v0.6.0` because U4 adds public surface 2.15 and schema v36. If that remote tag exists or the release convention has changed, stop for a new user-selected version and never rewrite the ref.
|
||||
- Gitea API or Actions may fail transiently. A retry is allowed only after reading the actual PR/run state; unknown results are reconciled before resubmission.
|
||||
- The current Dev merge queue has no active window after the recorded release of the workbench visual task. This fact must be re-read immediately before U8 claims a new window.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Units
|
||||
|
||||
### U1. Record approval and fix the stage 7 candidate
|
||||
|
||||
- **Goal:** Record the user's stage 6 approval and produce one synchronized candidate manifest for formal acceptance.
|
||||
- **Requirements:** DR1, DR4, DR5.
|
||||
- **Files:** `Agent-System-Dev/.task/feature-iam-u4-role-authority.md`, `Agent-System-Documents/docs/proposals/2026-10-15-iam-u4-stage7-10-delivery-plan.md`, `Agent-System-Documents/docs/proposals/INDEX.md`.
|
||||
- **Approach:** Update the stage table with the approved component versions and date. Run the required task sync in each branch before its evidence is treated as current. Record base, head, component commits, test definitions, and browser-harness commit in one candidate manifest.
|
||||
- **Test scenarios:** A clean same-base sync leaves the candidate unchanged; a moving target updates the manifest and invalidates affected evidence; a dirty or drifting component stops the unit.
|
||||
- **Verification:** Dev precheck/task-resume receipt, `make task-sync` evidence, recursive worktree verification, and Documents `git diff --check`.
|
||||
- **Dependencies:** None.
|
||||
|
||||
### U2. Add the repeatable IAM browser acceptance slice
|
||||
|
||||
- **Goal:** Make DR6–DR15 reproducible in the existing browser-test stack without production services.
|
||||
- **Requirements:** DR2–DR4, DR6–DR15.
|
||||
- **Files:** `Agent-System-Frontend/e2e/iam-role-authority.playwright.ts`, `Agent-System-RDM/scripts/iam-u4-role-acceptance.sh`, and only the smallest supporting test fixtures required by those files.
|
||||
- **Approach:** Add deterministic route-driven cases for fine-grained navigation, filters, matrix edits, role-scoped draft lifetime, 409 rebasing, pagination, late-response rejection, role-disable impact confirmation, and independently loading role/permission data. Cover keyboard operation, focus, accessible names and announcements, and a narrow viewport with horizontal matrix navigation. Add a live harness that materializes exact committed candidate sources into a temporary build root, builds the embedded RDM product, initializes a fresh SQLite database, starts on loopback random ports, and runs the same Playwright file in live mode. Synthetic credentials and activation material remain in the temporary root and are deleted on exit; traces and screenshots are sanitized before owner-restricted retention.
|
||||
- **Execution note:** Add failure-first cases for the previously reviewed permission combinations and race paths before changing the harness or UI assertions.
|
||||
- **Test scenarios:** Roles-only viewer; users-only viewer; permissions viewer without manager; permissions manager without view; shared-role assignment and reassignment; exact/fuzzy/action/status filters; multi-page role selection; matrix default/cap and visible-page batch edits; draft-preserving and explicit-discard transitions; concurrent 409 rebase; stale response after role switch; role-disable cancel/success/conflict/failure; initial loading; filtered and catalog-empty states; independent role-list and permission-catalog failure; failed create/save retry; keyboard-only core flow; narrow viewport; current epoch denial; isolated service startup failure and cleanup.
|
||||
- **Verification:** Focused Playwright run with trace retention, Frontend unit tests/build/design guard, harness shell check, and a clean-process check after success and failure.
|
||||
- **Dependencies:** U1.
|
||||
|
||||
### U3. Execute stage 7 formal acceptance
|
||||
|
||||
- **Goal:** Produce the requirement-to-evidence map the user can approve without reading implementation details.
|
||||
- **Requirements:** DR2–DR15.
|
||||
- **Files:** `Agent-System-Dev/.task/feature-iam-u4-role-authority.md`; screenshots, traces, and receipts remain outside source and are linked by digest or durable run URL.
|
||||
- **Approach:** Run deterministic Playwright and the live isolated product. Replay Backend SQLite and isolated PostgreSQL role-policy tests, RDM full tests against the fixed Backend, Frontend/UI suites, and Dev combination tests. Exercise migration through an isolated cross-component harness that calls the real trusted Backend/RDM store path for freeze, stage, compare, activate, failure, and retry against the frozen v35 fixture and oracle. Record each DR-ID as PASS, FAIL, SKIP, or NOT_RUN against the exact candidate.
|
||||
- **Test scenarios:** AE1–AE7 plus missing provider, incompatible schema, disabled account/role, final permission-manager protection, project-override cap, document-duty cap, administrator audit/export denial, dirty product-source rejection, and SQLite/PostgreSQL batch failures for version conflict, unknown action, and out-of-cap change with zero partial writes.
|
||||
- **Verification:** Evidence receipts and browser artifacts match the candidate manifest; an independent replay covers the minimum critical set; the user records the stage 7 conclusion in the task card.
|
||||
- **Dependencies:** U2.
|
||||
|
||||
### U4. Re-review and prepare component PRs
|
||||
|
||||
- **Goal:** Turn the stage 7 candidate into current, reviewable component branches without changing accepted behavior.
|
||||
- **Requirements:** DR4, DR16, DR21.
|
||||
- **Files:** Component diffs and task records in Backend, Frontend, Documents, and RDM.
|
||||
- **Approach:** Sync each component with its current main at its own delivery boundary. Resolve conflicts without weakening authorization. If source, base, dependency pin, candidate manifest, or test definition changes, update the manifest, rerun the affected U2/U3 evidence, and obtain a renewed stage 7 conclusion before any component merge. Then simplify only changed code, conduct independent code review, push the branch, and create a draft PR with the final behavior and evidence.
|
||||
- **Test scenarios:** Clean sync; source conflict; changed public surface; changed Frontend API type; changed RDM provider contract; target advance after review.
|
||||
- **Verification:** Each PR identifies base/head, component dependencies, review findings and closure, and current applicable CI or explicit absence of repository-local CI.
|
||||
- **Dependencies:** U3 and stage 7 user approval.
|
||||
|
||||
### U5. Merge Backend and publish its trusted tag
|
||||
|
||||
- **Goal:** Establish the authoritative public role-policy contract RDM can consume.
|
||||
- **Requirements:** DR16, DR17.
|
||||
- **Files:** Backend PR and release tag; no production service files.
|
||||
- **Approach:** Confirm Backend PR HEAD contains current main, public surface 2.15, schema v36, staged migration, and the reviewed tests. Require the `vet-and-test` GATE on that exact HEAD, complete agent Review, merge without force, and verify the merge commit on `origin/main`. Prepare an annotated `v0.6.0` command bound to that merge commit; the user executes it. Read the remote peeled tag before proceeding.
|
||||
- **Test scenarios:** CI failure; main advance; merge conflict; tag absent; tag already exists at the same commit; tag exists at another commit; push result unknown.
|
||||
- **Verification:** PR merge URL, exact merge SHA, successful exact-head CI, remote annotated tag and peeled commit equality.
|
||||
- **Dependencies:** U4. The user-owned tag action is an internal completion gate after the Backend merge.
|
||||
|
||||
### U6. Merge Frontend and Documents
|
||||
|
||||
- **Goal:** Land the accepted administration UI and its authoritative records before RDM fixes product pins.
|
||||
- **Requirements:** DR3, DR6–DR10, DR16, DR21.
|
||||
- **Files:** Frontend PR, Documents PR, `Agent-System-Documents/docs/proposals/INDEX.md`.
|
||||
- **Approach:** Sync and revalidate Frontend, including the IAM Playwright slice, then merge the reviewed PR. Sync Documents, verify links and claims, and merge its PR. UI requires no U4 PR when `e295cae` remains on authoritative main.
|
||||
- **Test scenarios:** Frontend main changes affecting AdminZone, styles, API types, or test harness; Documents link drift; UI main no longer contains the expected token commit.
|
||||
- **Verification:** Frontend tests/build/Playwright and platform status, Documents `git diff --check`, merged commits on each main, and UI ancestry check.
|
||||
- **Dependencies:** U4; Backend may merge before or during this unit, but RDM pinning waits for both U5 and U6.
|
||||
|
||||
### U7. Update and merge the RDM composition
|
||||
|
||||
- **Goal:** Replace the development overlay with authoritative merged pins and prove the real product composition.
|
||||
- **Requirements:** DR12–DR18, DR21.
|
||||
- **Files:** `Agent-System-RDM/pins/agent-system-backend`, `pins/agent-system-frontend`, `pins/agent-system-ui`, public-contract references, product manifest, and RDM task evidence.
|
||||
- **Approach:** Sync the RDM branch with current main and resolve its known divergence. Pin Backend to the verified tagged merge commit, Frontend to its merged commit, and UI to current authoritative main. Remove reliance on the temporary `go.work` overlay. Harden product assembly so it materializes committed Git objects, or rejects any tracked, untracked, or relevant ignored drift before copying, and records copied-content digests in addition to Git SHAs. Run the full RDM suite, product build, product smoke, migration rehearsal, and live IAM Playwright acceptance; review the resulting pin diff and merge the RDM PR after `build-and-test` succeeds.
|
||||
- **Test scenarios:** Pin mismatch; tag/commit mismatch; tracked, untracked, or ignored source drift; copied-content digest mismatch; missing embedded assets; migration staging failure; source-hash mismatch; provider schema mismatch; browser regression after real pins.
|
||||
- **Verification:** `PRODUCT_MANIFEST.json` matches the three gitlinks, RDM HEAD, and actual copied-content digests; a dirty-source negative test fails before packaging; full local receipts and exact-head RDM CI pass; merged RDM main contains the reviewed pins.
|
||||
- **Dependencies:** U5, U6.
|
||||
|
||||
### U8. Deliver the final Dev combination through the manual queue
|
||||
|
||||
- **Goal:** Merge one Dev candidate that pins only authoritative component commits and carries current evidence.
|
||||
- **Requirements:** DR16, DR19, DR20, DR21.
|
||||
- **Files:** `Agent-System-Dev/modules/backend`, `modules/frontend`, `modules/ui`, `modules/documents`, task card, PR, and merge-queue issue #518.
|
||||
- **Approach:** Re-read #518 and claim the only Dev main window. Run `make task-sync`, update gitlinks to merged component commits, fix the candidate, and store final receipts outside source. Run local `make test` and `make build`, complete final independent Review, push the Dev branch, and require `test`, `test-pg`, and `svc-realcombo` on the exact PR HEAD. Recheck main/head immediately before a non-force PR merge, then read back main and the component tree.
|
||||
- **Test scenarios:** Active competing window; main advance after CI; component SHA drift; CI transient failure within retry budget; repeated failure; unknown merge response; merged main content mismatch.
|
||||
- **Verification:** Queue claim/release entries, current base/head, three successful GATE jobs, review receipt, PR merge URL, final main SHA, and exact `git ls-tree` component values.
|
||||
- **Dependencies:** U7 and merged component records from U5–U6.
|
||||
|
||||
### U9. Verify, close, and clean the task
|
||||
|
||||
- **Goal:** Leave authoritative records and no abandoned IAM workspaces or branches.
|
||||
- **Requirements:** DR21.
|
||||
- **Files:** Dev task card and archive entry; component task records where applicable.
|
||||
- **Approach:** Verify actual merged contents and component ancestry. Record browser, SQLite, PostgreSQL, component CI, Dev CI, tag, PR, and merge evidence with their real source levels, then request stage 10 approval. Preserve cleanup receipts outside the worktree; after all writers have exited, run `TASK_WRITERS_STOPPED=1 make task-finish` from the registered task worktree. Then run `make task-close` from clean main and deliver its card-close PR through the applicable queue, Review, CI, merge, and readback path. Never force-delete a refused cleanup.
|
||||
- **Test scenarios:** Uncommitted or untracked file; live writer; unmerged local or remote commit; missing task-card PR link; cleanup refusal; post-merge content mismatch.
|
||||
- **Verification:** Stage 10 conclusion, archived task card on main, clean recursive state, merged ancestry, removed task worktrees, and preserved external receipts.
|
||||
- **Dependencies:** U8. Stage 10 approval is an internal gate before cleanup.
|
||||
|
||||
---
|
||||
|
||||
## Verification Contract
|
||||
|
||||
| Gate | Command or platform check | Applies to | Done signal |
|
||||
|---|---|---|---|
|
||||
| Backend SQLite | `GOWORK=off go test ./... -count=1` | U3, U5 | All packages pass at the recorded Backend HEAD |
|
||||
| Backend PostgreSQL | Isolated PostgreSQL 16 with `AGENT_PG_TEST_DSN`, then role, migration, delegation, and lock-order store tests | U3, U5 | No skips in the selected PG set; container removed |
|
||||
| Cross-database atomicity | Force version-conflict, unknown-action, and out-of-cap batch failures against SQLite and isolated PostgreSQL | U3 | Both stores retain identical pre-request state with zero partial writes |
|
||||
| Migration oracle | Trusted isolated Backend/RDM store harness against the frozen v35 fixture and expected oracle | U3, U7 | Freeze/stage/compare/activate/failure/retry results match on SQLite and PostgreSQL; mismatches block activation |
|
||||
| Frontend unit/build | `npm test && npm run build && node scripts/check-knip.mjs` | U2, U3, U6 | Tests pass, build succeeds, knip stays within baseline |
|
||||
| UI | `npm test` plus the design guard through the Frontend/Dev suite | U3, U6 | UI tests and design guard pass at the fixed UI commit |
|
||||
| Browser deterministic | `npm run e2e -- e2e/iam-role-authority.playwright.ts` with isolated preview | U2, U3, U6 | Required scenarios pass; failure traces retained |
|
||||
| Browser live product | `scripts/iam-u4-role-acceptance.sh` with exact source SHAs | U3, U7 | Embedded product scenarios pass on a fresh data root; screenshot and manifest digests recorded |
|
||||
| RDM overlay | `GOWORK=<fixed overlay> go test ./... -count=1` | U3 | Development contract passes before authoritative pins exist |
|
||||
| RDM pinned product | Dirty-source negative test, then `make test`, `make product`, and `make product-smoke` from committed sources | U7 | Drift is rejected; full suite, embedded product, copied-content digests, and manifest smoke pass without overlay |
|
||||
| Documents | `git diff --check` plus link and version review | U1, U6 | No malformed diff or stale reference |
|
||||
| Dev local combination | `make test && make build` after `make task-sync` | U3, U8 | Exact fixed combination passes and builds |
|
||||
| Component CI | Backend `vet-and-test`; RDM `build-and-test`; current platform-required Frontend/Documents checks when present | U5–U7 | Each available GATE is successful on the merged candidate HEAD |
|
||||
| Dev CI | Gitea `test`, `test-pg`, `svc-realcombo` | U8 | All three jobs succeed on the same final PR HEAD |
|
||||
| Merge integrity | PR head/base readback, non-force merge, `origin/main` and component tree readback | U5–U8 | Actual protected main matches the reviewed candidate |
|
||||
| Cleanup | External receipt preservation; guarded `task-finish`; then `task-close` PR Review/CI/merge/readback | U9 | No writer, unique file, unmerged commit, active lock, or cleanup result is lost |
|
||||
|
||||
Evidence rules:
|
||||
|
||||
- Local commands remain `SELF` unless an independent reviewer replays them.
|
||||
- Gitea Actions counts as `GATE` only when the run identity, job, exact SHA, and result are recorded.
|
||||
- A Playwright screenshot or trace proves only the scenario and build identified by its receipt.
|
||||
- `SKIP` and `NOT_RUN` remain visible; they are never converted to PASS by another layer's test.
|
||||
- Any source, base, pin, manifest, or test-definition change updates the named candidate and reruns the gates it affects. A post-stage-7 change also requires a renewed stage 7 conclusion before component merge; a final Dev HEAD change invalidates its three required CI jobs.
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
Global completion requires all of the following:
|
||||
|
||||
- DR1–DR21 all have PASS evidence. These delivery requirements are mandatory; SKIP, NOT_RUN, and exclusions block completion.
|
||||
- The user has approved stage 7 and stage 10 on named candidate versions.
|
||||
- Independent final Review has no unresolved Critical or Important finding.
|
||||
- Backend, Frontend, Documents, RDM, and Dev PRs are merged in dependency order at the recorded commits.
|
||||
- The trusted Backend tag exists remotely and peels to the reviewed Backend merge commit.
|
||||
- RDM's product manifest uses authoritative merged pins and no development overlay.
|
||||
- Dev's final PR HEAD has successful `test`, `test-pg`, and `svc-realcombo` jobs.
|
||||
- Actual protected main branches and Dev gitlinks match the reviewed candidates.
|
||||
- Production migration and deployment remain NOT_RUN unless separately authorized.
|
||||
- Failed experiments, temporary build roots, credentials, processes, branches, and worktrees are removed or retained with an explicit reason; no abandoned attempt code remains in the diffs.
|
||||
- Task cards are archived through the guarded workflow and external receipts remain available.
|
||||
|
||||
Per-unit completion:
|
||||
|
||||
| Unit | Completion signal |
|
||||
|---|---|
|
||||
| U1 | Stage 6 approval and synchronized candidate manifest are recorded |
|
||||
| U2 | Repeatable deterministic and live IAM browser slices exist and pass locally |
|
||||
| U3 | User approves the exact stage 7 requirement-to-evidence map |
|
||||
| U4 | Current component PR candidates have valid review and applicable checks |
|
||||
| U5 | Backend is merged and the user-published tag is verified |
|
||||
| U6 | Frontend and Documents are merged; UI ancestry remains valid |
|
||||
| U7 | RDM is merged with authoritative pins and a matching product manifest |
|
||||
| U8 | Dev is merged through an exclusive queue window with three exact-head GATE jobs |
|
||||
| U9 | Stage 10 is approved, records are archived, and guarded cleanup succeeds |
|
||||
|
||||
---
|
||||
|
||||
## Appendix
|
||||
|
||||
### Sources
|
||||
|
||||
- `docs/proposals/2026-10-15-iam-focused-role-permission-spec.md`
|
||||
- `docs/proposals/2026-10-15-iam-focused-role-permission-implementation-plan.md`
|
||||
- `Agent-System-Dev/.task/feature-iam-u4-role-authority.md`
|
||||
- `Agent-System-Dev/policy/delivery.md`
|
||||
- `Agent-System-Dev/policy/merge-queue.md`
|
||||
- `Agent-System-Dev/.gitea/workflows/ci.yaml`
|
||||
- `Agent-System-Backend/.gitea/workflows/ci.yml`
|
||||
- `Agent-System-RDM/.gitea/workflows/ci.yml`
|
||||
- `Agent-System-RDM/scripts/build-product.sh`
|
||||
- `Agent-System-Frontend/playwright.config.ts`
|
||||
- `Agent-System-Frontend/e2e/rdm-duties.playwright.ts`
|
||||
@@ -0,0 +1,108 @@
|
||||
# 分层 Python 环境方案 r1
|
||||
|
||||
状态:待评审(收录不是批准)。编制:2026-10-15。
|
||||
触发:dev 8788 会话 `cnv_7936c0a799ff` 中,智能体无法把已有 Markdown 摘要渲染成 docx,并向用户报告「没有 Python 对应的包」。
|
||||
|
||||
## 1. 已核实的故障(不是「缺包」本身)
|
||||
|
||||
8788 的 `run_python` / `run_shell` 跑在 bwrap 沙箱里(只读根、`--tmpfs /home`、`--unshare-net`)。同一台宿主机的 `~/.local` 里其实已经有 python-docx、lxml、openpyxl、python-pptx。失败来自四件事叠在一起:
|
||||
|
||||
1. **依赖层没有接线。** 代码已有 `--exec-deps-dir`(F3),但 `scripts/svc.sh` 与 8788 的启动参数都没有传入它。沙箱把 `/home` 遮掉之后,`~/.local` 不可见。
|
||||
2. **解释器解析到会被遮掉的路径。** 服务进程的 `PATH` 里 linuxbrew 在 `/usr/bin` 之前,`python3` 被解析成 `/home/linuxbrew/.linuxbrew/bin/python3`。沙箱里这条路径不存在,`run_python` 得到 `exit=127`。
|
||||
3. **工具说明指向一条走不通的安装路径。** `run_python` 描述和 `base.deliverables` 都写「缺库先 `pip install --user`」。沙箱断网、根只读、家目录是空 tmpfs,这条命令必然失败。
|
||||
4. **没有向系统申请包的通道。** 智能体只能探测、报错、让用户选择,再派一个后台任务去轮询一个永远不会出现的依赖。
|
||||
|
||||
同一次会话里还有多次模型网关 `401 invalid_api_key`。那是密钥问题,不在本方案范围内。
|
||||
|
||||
## 2. 目标
|
||||
|
||||
每个工作区和沙箱都能直接使用系统提供的 Python 能力(解释器 + 办公与数据处理基础包),不必各自新建虚拟环境。某个工作区需要额外的包时,向系统申请;系统决定装不装,并只把结果挂给这个工作区。
|
||||
|
||||
成功标准:
|
||||
|
||||
- 沙箱内 `import docx, openpyxl, pptx` 成功,`python3 -m housestyle.build` 能产出通过结构自检的 docx。
|
||||
- 两个工作区要同一包的不同版本时,互不影响,基础层版本不变。
|
||||
- 沙箱仍然断网。安装只发生在宿主侧的构建器里,并且只接受带哈希的预编译 wheel。
|
||||
- 白名单内的包自动批准;白名单外、要改基础层版本、体积超限、用户上传的 wheel,弹审批卡。sdist 与黑名单直接拒绝。
|
||||
|
||||
## 3. 不采用的两条路
|
||||
|
||||
- **每个工作区一个 venv。** 贵的是重复下载、解析和安装,不是 venv 目录本身。同样的包会被装很多遍。
|
||||
- **所有包装进一个可变的系统环境。** 一个工作区的需求会改变所有工作区的行为,版本冲突无法隔离,也无法复现「当时用的是哪一套包」。
|
||||
|
||||
## 4. 采用的结构
|
||||
|
||||
所有环境层不可变,按内容哈希命名,按会话挂载。系统只新增层,不改已经发出去的层。
|
||||
|
||||
```text
|
||||
<envroot>/ 默认 runtime/envs/,各服务实例共享
|
||||
python/cpython-<ver>/ 系统托管的 CPython(只读)
|
||||
python/current -> 上述目录
|
||||
layers/base-<hash>/site-packages
|
||||
layers/x-<hash>/site-packages 扩展层:相对基础层的增量闭包
|
||||
layers/iso-<hash>/site-packages 完整隔离层:仅在审批通过「覆盖基础层版本」时使用
|
||||
wheelhouse/ 按 sha256 去重的 wheel
|
||||
locks/<hash>.json
|
||||
catalog.json 白名单、黑名单、单包体积上限
|
||||
current -> layers/base-<hash>
|
||||
bin/pip 垫片:提示改用 python_env,不以安装成功退出
|
||||
```
|
||||
|
||||
层键 = 锁文件内容 + Python 标签 + 平台的哈希。同一份需求在任何工作区都命中同一层。
|
||||
|
||||
基础层由系统策划,首批为:python-docx、openpyxl、python-pptx、lxml、Pillow、numpy、matplotlib、pypdf、reportlab、markdown、pdfplumber,以及它们的传递依赖。名单可以在评审时增减;锁文件在第一次 `env ensure` 时生成并应入库,之后构建按锁复现。
|
||||
|
||||
解释器优先使用托管前缀(python-build-standalone 的 install_only 包)。下载失败时,退化为用系统 `python3 -m venv` 做一份唯一的托管前缀,并在 `python/SOURCE` 里写明这是退化,不是每个工作区各做一份。沙箱里的 `python3` 永远是这个前缀的绝对路径;找不到托管前缀时才用 `/usr/bin/python3`,不再走会落到 `/home` 下的 `PATH` 查找。
|
||||
|
||||
## 5. 一次执行如何看到这些包
|
||||
|
||||
沙箱参数在 `--tmpfs /home` 之后,只读挂载:托管解释器前缀(如果它位于会被 tmpfs 遮住的路径上)、基础层、该会话绑定的扩展层。`PATH` 固定为 `<托管 bin>:<envroot>/bin:/usr/local/bin:/usr/bin:/bin`,不再继承宿主 `PATH`。`PYTHONPATH` 是这些层再加上 house-style。`PIP_NO_INDEX=1`。
|
||||
|
||||
扩展层与基础层来自同一次以基础层为约束的解析,每个发行名只有一个版本,所以叠放顺序不影响导入。隔离层例外:它替换基础层,而不是叠在上面,用来满足「这个工作区必须要 numpy<2」这类与基础层冲突的需求。
|
||||
|
||||
## 6. 申请(工具 `python_env`)
|
||||
|
||||
动作:`status`、`request`、`wait`。
|
||||
|
||||
- `status` 返回基础层包清单、本会话已绑定的层、未完成的申请。
|
||||
- `request` 带包规格或工作区内的 `.whl`。解析以基础层锁为约束(等价于带 constraints 的 `pip install --dry-run --report`)。分级:
|
||||
- 全部在白名单内、纯 wheel、未超体积:自动批准并构建。命中已有层时只是多挂一个目录。
|
||||
- 白名单外、要覆盖基础层已固定的版本、超体积、用户上传的 wheel:写入 `exec_env_requests`,发一张选择卡(批准 / 拒绝;覆盖基础层版本时多一个「建隔离层」)。系统管理员或该会话的属主可以批。决定写入 `audit_events`。
|
||||
- 只有 sdist、命中黑名单、解析失败、哈希不符:拒绝,并说明原因。
|
||||
- 构建在宿主侧进行:`--only-binary=:all:`,校验 sha256,只用解包 wheel,不执行 setup.py。这是唯一有网络的步骤,并且不在沙箱里。
|
||||
- 构建完成后把层 ID 写进 `exec_env_bindings`。下一次 `run_python` / `run_shell` 挂上这些层。`wait` 在短超时内轮询申请状态。
|
||||
|
||||
## 7. 三个顾虑如何被挡住
|
||||
|
||||
- **成本。** 基础层覆盖常见办公和数据场景。wheel 与层按哈希缓存,第二个工作区要同一套包时不再下载、不再解析。
|
||||
- **冲突。** 不存在共享的可变环境。冲突需求要么被拒绝并说明卡在基础层的哪一个版本,要么经审批得到一份只属于该会话的隔离层。基础层哈希不变。
|
||||
- **包都堆进系统环境。** 基础层只放策划过的包。扩展层按会话绑定,其他会话看不见。升级基础层生成新的 `base-<hash>` 并移动 `current`;已经绑定旧基础层的会话保持不动,直到显式 rebase。
|
||||
|
||||
## 8. 安全
|
||||
|
||||
- 沙箱断网、根只读、家目录遮蔽,这些都不放宽。
|
||||
- 不在宿主上执行第三方构建脚本。
|
||||
- 只挂当前会话绑定的层。
|
||||
- 申请记录含会话、包、wheel 哈希、批准人。
|
||||
- 任务封存时应能读到基础层哈希与层 ID(绑定表就是这份清单)。
|
||||
|
||||
## 9. 实施切片
|
||||
|
||||
- **P0** 解释器与 `PATH` 不再指向会被沙箱遮住的 linuxbrew;`svc.sh` 在环境根存在时传入 `AGENT_SYSTEM_EXEC_ENV_ROOT` 与基础层 `AGENT_SYSTEM_EXEC_DEPS_DIR`;工具说明与提示词改为 `python_env`,去掉 `pip install --user`;配置了依赖层时启动做真实导入探针。
|
||||
- **P1** 环境根、锁、层、wheelhouse、托管解释器,以及 `agent-system env ensure|lock|gc|doctor|rebase|python`。
|
||||
- **P2** 表 `exec_env_requests`、`exec_env_bindings`,工具 `python_env`,分级审批,pip 垫片,按会话挂载。
|
||||
- **P3** 管理区「Python 环境」页(层、申请、批准/拒绝、rebase、gc、上传 wheel)。
|
||||
|
||||
## 10. 验收
|
||||
|
||||
- `sandboxArgv` 覆盖多层只读挂载、固定 `PATH`、`PIP_NO_INDEX`。
|
||||
- 离线解析夹具:冲突、白名单、sdist 拒绝、哈希不符。
|
||||
- 有 bwrap 时:沙箱内能导入层里的模块,`pip` 垫片给出申请指引,外网不可达。
|
||||
- 两个会话分别要 `foo==1` 与 `foo==2`,各得一层,基础层哈希不变。
|
||||
- 在基础层可用时,`housestyle.build` 产出的 docx 通过既有 OOXML 结构自检。
|
||||
|
||||
## 11. 已定与未定
|
||||
|
||||
已定(2026-10-15 对话):白名单内自动批准,其余弹审批卡;解释器由系统托管,而不是长期绑死宿主 `/usr/bin/python3`。
|
||||
|
||||
未定,留在评审:基础层最终包名单是否增减;审批人除系统管理员和会话属主外,是否还要接项目角色。本实施先只认系统管理员与会话属主,避免在基座里发明第二套项目角色判断。
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: 文档职责矩阵整改
|
||||
date: 2026-10-15
|
||||
type: feature
|
||||
execution: code
|
||||
artifact_contract: rdm-duty-matrix/v1
|
||||
product_contract_source: legacy-requirements
|
||||
---
|
||||
|
||||
# 文档职责矩阵整改 r2
|
||||
|
||||
负责人:weichen;编制日期:2026-10-15。
|
||||
本记录是文档职责整改的唯一主记录。它取代
|
||||
[r1 增量方案](2026-10-13-rdm-settings-members-duties-perms-increment.md)
|
||||
第四节,以及该方案 P5、P7 中“文档职责页”的交互;r1 的设置归属、成员、权限矩阵与其余工作包继续有效。
|
||||
|
||||
候选分支 `feature/rdm-settings-completion` 里的文档职责界面暂停合入。系统设置、成员选择、权限矩阵和已落地的后端安全能力不在本暂停范围内。本任务从当时的 `origin/main` 另起兄弟分支 `feature/rdm-duty-matrix`,不把该候选当作父分支。
|
||||
|
||||
## 四项领域裁定
|
||||
|
||||
1. 职责只到文档级。项目设置不再新增章节级职责;历史章节审签只读保留。
|
||||
2. 项目设置只分配已有受控文档的编制、审核、批准职责。不创建文档、不从模板生成、不提交审核、不审核通过、不驳回、不终批。
|
||||
3. 每份文档恰好一名编制、至少一名审核、恰好一名批准。同一人在同一文档上只担一个职责。审核可以有多人。
|
||||
4. 与文档职责完全一致的旧章节覆盖可以归并为文档级。同一文档下章节人员不一致的,列出清单,由项目负责人逐文档确认,不自动覆盖。
|
||||
|
||||
项目负责人可以分配职责,但不因负责人身份自动成为编制、审核或批准人。当前职责与已冻结的审签名单分开保存;修改当前职责不改写已批准版本和历史名单。
|
||||
|
||||
姓名来源仍按 r1 评审补充第 3 条待证。本页用账号标识展示,不把未证实的姓名字段写进契约。
|
||||
|
||||
## 契约
|
||||
|
||||
读:`rdm.duty.matrix`。`view` 为 `member`、`document` 或 `matrix`。筛选在分页之前。文档页上限 20。响应给出文档完整性、`dutyVersion`、章节覆盖数、在途轮次、成员资格、单元格 `none|author|reviewer|approver`,以及当前操作人是否可分配。单元格只投影当前文档级职责。没有 `duty.assign` 的调用直接拒绝,避免矩阵列头泄露不可见文档。
|
||||
|
||||
写:唯一入口仍是每份文档的完整目标,`rdm.review.assign.doc` 与 `rdm.review.assign.doc.batch`(1–20 项,整批原子)。带 `expectedDutyVersion` 与 `confirmInvalidation`。`rdm.review.assign` 只返回“章节级职责已停用,请在文档级设置”。
|
||||
|
||||
预览:`rdm.duty.preview` 与写载荷相同,只读返回替换对象、在途失效和缺人原因,不写数据。保存时服务端重新校验。
|
||||
|
||||
迁移:`rdm.duty.legacy.scan` 只读;`rdm.duty.legacy.apply` 只清除与文档职责完全一致的章节覆盖。
|
||||
|
||||
## 三视图
|
||||
|
||||
按人员、按文档、成员×文档矩阵共享同一份服务端数据和同一份未保存草稿。单元格由文档三权反推。把唯一编制或批准改成其他值可以继续编辑,但在指定接替人前不能保存。替换已有编制或批准时提示“将替换某某”,保存时一次替换。窄屏不压缩整张矩阵,改走前两个视图。一次保存最多 20 份文档。请求带递增序号,过期响应丢弃。写入结果未知时重读,不自动重放。
|
||||
|
||||
页面顶部写明:本页只分配已有文档的职责,不创建或生成文档。
|
||||
|
||||
## 验收
|
||||
|
||||
单文档三权恰好、多审核人、一人一责、三视图草稿一致、替换提示与原子替换、缺人禁止保存、成员失效保存被拒、版本冲突、批量整批失败不写、影响预览与历史不变、无私密文档列头泄露、无创建/生成/审签按钮、迟到响应不覆盖、design-guard、`make test` 与 `make build`。部署和真实账号浏览器验收另行授权。
|
||||
@@ -0,0 +1,88 @@
|
||||
# 分层分支交付与规范精简 r1
|
||||
|
||||
- 状态:已批准实施(2026-10-18 用户指示按计划实施);推进中
|
||||
- 负责人:weichen(需求与批准)
|
||||
- 实施:Dev 治理大任务 `feature/delivery-model-v3`
|
||||
- 适用范围:Agent-System-Dev 开发流程与规范
|
||||
- 更新时间:2026-10-18
|
||||
|
||||
## 1. 背景
|
||||
|
||||
用户提出的需求:
|
||||
|
||||
- 减少合入 Dev main 的次数,让其他分支不必反复同步、反复跑 CI。
|
||||
- L2 合入 L1 要轻;按任务类别分别处理,修复优先。
|
||||
- 测试、验收、审批放在合适的层级,不在每一层重复。
|
||||
- 去掉 Agent 的长时间 sleep 等待;精简膨胀的规范。
|
||||
|
||||
2026-10-18 只读基线(均为 **SELF** 观察):
|
||||
|
||||
- main 推进:14 天共 410 次(first-parent),峰值 85 次/天。按 PR 标题粗分,闭合任务卡约 40%、功能约 30%、组件 pin 约 20%、修复约 6%。
|
||||
10-14 启用合入窗口后仍约 17 次/天,闭合 PR 仍占约 40%。
|
||||
- 分层使用:近期 291 个已合入 PR 中 288 个 base 为 main,initiative/child 模型只用过一次。
|
||||
- CI:3.3 天跑了 200 次,单次中位 8.3 分钟;闭合相关运行约占 31% 机时;main 的 push CI 有 95% 在复测与 PR head 完全相同的树;每个 PR 平均 2.4 次 CI。
|
||||
- 等待:Git 远端往返约 0.35 秒。长等待来自 Agent 手写 `sleep N; curl` 轮询 CI,以及串行克隆 105 个嵌套子模块(实际只有 13 个不同仓;并行 `--jobs 8` 实测约 26 秒)。
|
||||
- 规范体量:日常必读规范约 4.6 万字符;同一段 Agent 路由规则写了 7 处;归档任务卡中位 113 KB,原因是证据工具把完整 JSON 收据写进了卡。
|
||||
|
||||
结论:频繁触发的主因不是层级不够,而是记账类改动也在推进 main,加上每一层都执行同样重的门禁。
|
||||
|
||||
## 2. 目标与成功标准
|
||||
|
||||
- 任务卡在合入前随 PR 折叠闭合,不再单独开闭合 PR。
|
||||
- 统一一个阻塞式的 CI 等待入口,按精确 SHA 等待结果。
|
||||
- 完整门禁只在进入 main 时执行;L2 合入 L1 只做轻量检查。
|
||||
- 任务分通道:修复直接进 main 并优先;其他类别按主题聚合进 L1。
|
||||
- 规范单一权威、更精简;任务卡变小。
|
||||
|
||||
成功标准:采纳两周后按本次基线复测。main 推进次数、CI 次数与机时、每 PR 平均 CI 次数均下降;闭合 PR 数降到零(存量清理除外)。
|
||||
|
||||
## 3. 方案要点
|
||||
|
||||
### 3.1 固定两级分支
|
||||
|
||||
- L1 大任务:从 main 切出,最终一次合入 main。L2 子任务:从 L1 切出,合入 L1。
|
||||
- L2 内部用 agent-exec 单元控制上下文长度,单元不开 PR,是最轻的一层。
|
||||
- 不再加深层级:main 的推进次数只取决于根层交付次数;每多一层就多一条同步链,集成也被推迟;现行 Guidelines 与工具只定义了两级。
|
||||
- 太大时横向拆:L1 超过约 2 周或 6–8 个子任务时拆成多个并列 L1;L2 太大就拆成兄弟 L2 或更多单元。
|
||||
|
||||
### 3.2 L1 章程
|
||||
|
||||
- 章程写在 L1 任务卡顶部:用途与目标、接纳范围与非目标、方案和计划链接、子任务登记、分级测试策略、验收条件、追加的领域规则、生命周期。
|
||||
- 建 L1 时立即开一个 base 为 main 的 [WIP] PR,用于分流发现,评论区同时作为仓外调度记录。
|
||||
- L1 不追 main,只在三种情况下合入最新 main:最终交付窗口;需要 main 上的某个修复;长周期 L1 到达里程碑或每周一次。
|
||||
|
||||
### 3.3 任务通道
|
||||
|
||||
- 修复:`fix/` 直接进 main 并优先排队;P0 用 `hotfix/`。
|
||||
- 完善:按领域放进“完善列车” L1。
|
||||
- 扩展:加入(JOIN)同主题的在途 L1。
|
||||
- 新增:新建 L1 并写章程。
|
||||
- 治理与规范:集中在一个治理 L1 中。
|
||||
- 记录类改动不单独推进 main;组件 pin 跟随用到它的 L1 一起推进。
|
||||
|
||||
### 3.4 按层级分配门禁
|
||||
|
||||
- 单元合入 L2:worker 自检,host 做最小直接检查。
|
||||
- L2 合入 L1:先同步 L1 头,跑受影响模块的测试,由一个全新会话做独立 Review,轻量 CI 作为 GATE。
|
||||
不排合入窗口,不需要分流收据、三段证据和人工审批。
|
||||
- L1 的 WIP PR:完整 CI 照常运行,作为不阻塞任何人的提前预警。
|
||||
- L1 或修复合入 main:合入窗口、完整 CI、整体 Review、三段证据,以及一次用户专属验收。
|
||||
- 人工审批只保留三处:L1 章程确认、L1 最终的用户专属验收、高后果双钥匙操作。
|
||||
|
||||
## 4. 阶段与关联任务
|
||||
|
||||
| 阶段 | 内容 | 状态 |
|
||||
|---|---|---|
|
||||
| R | 本主记录、PROJECT.md 链接、治理 L1 及其 WIP PR | 推进中 |
|
||||
| P1 | 合入前折叠闭合并清理存量卡;`make ci-wait` 与等待规则;子模块并行物化 | 待实施 |
|
||||
| P2 | CI 按 PR base 区分完整与轻量;L2 免分流、免合入窗口、免三段证据;三种卡模板;通道写入 delivery.md | 待实施 |
|
||||
| P3 | 规范精简:AGENTS.md 改为入口;delivery.md 作为单一权威并并入 merge-queue;矩阵与采纳记录改为引用;证据摘要入卡、完整收据出卡 | 待实施 |
|
||||
| M | 采纳两周后按本次基线复测 | 待执行 |
|
||||
|
||||
实时进度以 Dev 治理大任务的任务卡和 PR 为准;本记录只在阶段完成时更新。
|
||||
|
||||
## 5. 未纳入与限制
|
||||
|
||||
- 分支保护等平台设置不在本方案范围内;如需变更,由用户按双钥匙规则亲手执行。
|
||||
- 不引入自动合入队列、合入列车或调度服务。
|
||||
- 基线数字按 PR 标题粗分,只用于判断方向;实际效果以复测结果为准。
|
||||
@@ -0,0 +1,276 @@
|
||||
# EXT-20:共享法规检索与网络证据扩展点
|
||||
|
||||
状态:**已获用户授权(2026-10-18)**;owner:weichen;主任务:Dev 仓 initiative `feature/regulations-kb`。
|
||||
来源计划:Dev 仓 `docs/superpowers/plans/2026-10-18-regulations-knowledge-base-plan.md` 的 KTD1、KTD14 与 U9(本文是 U9 的基座公开契约)。
|
||||
规范依据:[扩展面兼容与演进](2026-10-01-extension-compat-policy.md)(§6 扩展点申请模板);同类先例:EXT-19 账号目录(受信插件注册、Host 可选接口消费)。
|
||||
实现位置:Backend 分支 `feature/regulations-kb-ext20`(`pkg/extension/regulations.go`、`internal/app/regulations.go`、`internal/app/compiled.go`;本文核对的提交为 `499ad47`,SELF·源码级)。
|
||||
撰写日期:2026-10-18。
|
||||
|
||||
## 1. 申请四要素(compat-policy §6)
|
||||
|
||||
- **场景**:Agent-System-RDM 处理涉及法规、标准或审评指导原则的问题时,必须同时查询受控法规语料库和真实网络搜索(双源核验),
|
||||
并把每条法规结论绑定到固定语料修订、法规版本、条款节点与原文片段。当前两条腿都走不通:
|
||||
共享法规库没有公开检索入口;RDM 现有网络腿由模型提出 URL 和摘录后再抓取比对,无法证明真实搜索发生过,基座也没有搜索能力。
|
||||
- **希望符号**:`pkg/extension` 新增可选能力 `RegulationsHost`(分发 Host 侧消费)、`RegulationsRegistrar`(进程内 Registry 侧注册)、
|
||||
提供方接口 `RegulationsProvider`、请求/结果 DTO、状态常量、`RegulationsSchemaVersion` 与 `ErrRegulationsUnavailable`。
|
||||
`Host` 接口本身不加方法。
|
||||
- **为何现有注册点组合不出来**:见第 2 节。
|
||||
- **兼容**:纯加法的可选能力;`SurfaceVersion` 由 `2.14.0-experimental` 升为 `2.15.0-experimental`,见第 5 节。
|
||||
|
||||
## 2. 为何现有扩展点组合不出来
|
||||
|
||||
| 现有扩展点 | 不能承载的原因 |
|
||||
|---|---|
|
||||
| `Host.KnowledgeSearch` / `KnowledgeWrite` | owner 作用域的项目知识检索,返回 `core.RetrievalHit`。共享法规不属于任何 owner:写进每个 owner 的知识库会复制语料、失去修订不可变性;其返回类型没有语料修订、法规/版本/节点稳定 ID、原文哈希、定位与披露状态,加字段也改变不了 owner 隔离语义。计划 KTD14 明确禁止经它承载共享法规 |
|
||||
| 项目作用域知识(`projectID` 参数、项目授权) | 共享法规访问不应随项目扩大或缩小;借项目 ID 访问会让项目成员关系变成法规访问面,也让同一条款在不同项目下出现不同可见性 |
|
||||
| `AccountDirectoryRegistrar` | 机制相同(受信插件注册、Host 可选接口消费),但语义专用于账号目录候选判定,不能复用为法规检索 |
|
||||
| 通用工具 / 命令总线 / KV / 后台任务 / 审计 | 都不能让一个插件把只读能力安全地提供给另一个插件:没有可归属的真实搜索记录,也不在发往外网前做查询最小化;证据无法钉住语料修订;任何插件都可以注册同名命令冒充提供方,不存在“单一受信提供方” |
|
||||
| 下游直接导入法规仓 | 绕过基座的调用方身份、查询最小化与审计边界,违反 RDM“只经基座公开扩展”的约束 |
|
||||
|
||||
因此需要一个新扩展点同时满足四点:共享的非项目语料;可归属、做过查询最小化的真实网络搜索;钉住语料修订的不可变证据;单一受信提供方。
|
||||
|
||||
## 3. 公开符号(`pkg/extension/regulations.go`)
|
||||
|
||||
### 3.1 常量与错误
|
||||
|
||||
- `RegulationsSchemaVersion = 1`:基座唯一接受的请求 schema;其他值在到达提供方前被拒绝。
|
||||
- 法规检索状态:`RegulationsStateOK = "ok"`、`RegulationsStateEmpty = "empty"`、`RegulationsStateDegraded = "degraded"`、`RegulationsStateUnavailable = "unavailable"`。
|
||||
- 法规披露级别:`RegulationDisclosureFull = "full"`、`RegulationDisclosureExcerpt = "excerpt"`、`RegulationDisclosureMetadataOnly = "metadata_only"`、`RegulationDisclosureWithheld = "withheld"`。
|
||||
- 网络搜索状态:`WebSearchStateOK = "ok"`、`WebSearchStateEmpty = "empty"`、`WebSearchStateUnavailable = "unavailable"`、`WebSearchStateRateLimited = "rate_limited"`、`WebSearchStateRejected = "rejected"`、`WebSearchStateError = "error"`。
|
||||
- 网页抓取状态:`WebCaptureStateCaptured = "captured"`、`WebCaptureStateRejected = "rejected"`、`WebCaptureStateFailed = "failed"`。
|
||||
- 网页留存级别:`WebRetentionFull = "full"`、`WebRetentionExcerpt = "excerpt"`、`WebRetentionMetadataOnly = "metadata_only"`。
|
||||
- `ErrRegulationsUnavailable`(`"extension: regulations provider unavailable"`):能力不可用。调用方不得回退到 `KnowledgeSearch`。
|
||||
|
||||
### 3.2 接口
|
||||
|
||||
```go
|
||||
// 由受信的法规知识插件(插件 ID "kbreg")实现并注册;基座不内置实现。
|
||||
type RegulationsProvider interface {
|
||||
SearchRegulations(context.Context, RegulationsCaller, RegulationsSearchRequest) (RegulationsSearchResult, error)
|
||||
ResolveRegulationEvidence(context.Context, RegulationsCaller, RegulationEvidenceRequest) (RegulationEvidence, error)
|
||||
SearchWeb(context.Context, RegulationsCaller, WebSearchRequest) (WebSearchResult, error)
|
||||
CaptureWeb(context.Context, RegulationsCaller, WebCaptureRequest) (WebCapture, error)
|
||||
}
|
||||
|
||||
// 编译进程内 Registry 的可选能力;只有插件 ID "kbreg" 可注册,且只能注册一次。
|
||||
type RegulationsRegistrar interface {
|
||||
RegisterRegulationsProvider(RegulationsProvider) error
|
||||
}
|
||||
|
||||
// 分发 Host 句柄的可选能力(类型断言获取);缺失即不可用,调用方不得回退到 KnowledgeSearch。
|
||||
type RegulationsHost interface {
|
||||
SearchRegulations(context.Context, RegulationsSearchRequest) (RegulationsSearchResult, error)
|
||||
ResolveRegulationEvidence(context.Context, RegulationEvidenceRequest) (RegulationEvidence, error)
|
||||
SearchWeb(context.Context, WebSearchRequest) (WebSearchResult, error)
|
||||
CaptureWeb(context.Context, WebCaptureRequest) (WebCapture, error)
|
||||
}
|
||||
```
|
||||
|
||||
`RegulationsHost` 与 `RegulationsProvider` 方法一一对应,区别只在 Host 侧没有 `RegulationsCaller` 参数:调用方身份由基座填写,调用方无法注入。
|
||||
|
||||
### 3.3 DTO 字段
|
||||
|
||||
JSON 名为 camelCase。下表“必出”指没有 `omitempty`、零值也会序列化的字段,其余字段均为 `omitempty`。
|
||||
最小 `WebSearchRequest{SchemaVersion: 1, Query: "q"}` 序列化为 `{"schemaVersion":1,"query":"q"}`。
|
||||
|
||||
**`RegulationsCaller`**(基座从可信分发上下文填写)
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `PluginID` | `pluginId`(必出) | 发起调用的插件 ID(消费方,例如 `rdm`),不是提供方 ID |
|
||||
| `Actor` | `actor` | 本次分发的操作主体 |
|
||||
| `Owner` | `owner`(必出) | 本次分发的 owner |
|
||||
|
||||
刻意不含项目 ID:共享法规访问既不随项目扩大,也不随项目缩小。
|
||||
|
||||
**`RegulationsSearchRequest`**
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `SchemaVersion` | `schemaVersion`(必出) | 必须等于 `RegulationsSchemaVersion` |
|
||||
| `Query` | `query`(必出) | 检索文本 |
|
||||
| `CorpusRevision` | `corpusRevision` | 要检索的语料修订;空表示当前已发布修订,结果回显实际检索的修订 |
|
||||
| `Kinds` | `kinds` | 文献类别过滤(法规、标准、指导原则等,取值由提供方定义) |
|
||||
| `CurrentOnly` | `currentOnly` | 只返回现行版本 |
|
||||
| `DocNo` | `docNo` | 按文号过滤 |
|
||||
| `ClauseNo` | `clauseNo` | 按条款号过滤 |
|
||||
| `Limit` | `limit` | 结果数上限,由提供方解释 |
|
||||
|
||||
**`RegulationsSearchResult`**
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `CorpusRevision` | `corpusRevision`(必出) | 实际检索的语料修订 |
|
||||
| `State` | `state`(必出) | `ok` / `empty` / `degraded` / `unavailable` |
|
||||
| `DegradedReasons` | `degradedReasons` | 降级原因(例如向量索引不可用) |
|
||||
| `Hits` | `hits`(必出) | 命中列表 `[]RegulationHit` |
|
||||
|
||||
**`RegulationHit`**
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `RegulationID` / `EditionID` / `NodeID` | `regulationId` / `editionId` / `nodeId`(必出) | 法规、版本、条款节点的稳定 ID,重新建索引后不变 |
|
||||
| `DocNo` / `Title` | `docNo` / `title` | 文号与标题 |
|
||||
| `EditionLabel` / `LegalStatus` | `editionLabel` / `legalStatus` | 版本标签与法律效力状态(现行、废止等) |
|
||||
| `ClauseNo` / `HeadingPath` | `clauseNo` / `headingPath` | 条款号与章节标题路径 |
|
||||
| `Excerpt` / `ExcerptStart` / `ExcerptEnd` | `excerpt` / `excerptStart` / `excerptEnd` | 按披露级别允许返回的原文片段及其偏移 |
|
||||
| `NodeSHA256` / `SourceAssetSHA256` | `nodeSha256` / `sourceAssetSha256` | 节点文本哈希与来源资产(原件)哈希 |
|
||||
| `PageStart` / `PageEnd` | `pageStart` / `pageEnd` | 原件页码定位 |
|
||||
| `Disclosure` | `disclosure`(必出) | `full` / `excerpt` / `metadata_only` / `withheld` |
|
||||
| `WithheldReason` | `withheldReason` | 不披露原文的原因(例如来源权利限制) |
|
||||
| `IsSummary` | `isSummary` | 命中的是摘要而不是原文 |
|
||||
| `MatchKinds` | `matchKinds` | 命中方式(全文、向量、编号等,取值由提供方定义) |
|
||||
| `Score` | `score` | 相关度分数 |
|
||||
|
||||
**`RegulationEvidenceRequest`**(取回钉住修订的节点原文片段)
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `SchemaVersion` | `schemaVersion`(必出) | 必须等于 `RegulationsSchemaVersion` |
|
||||
| `CorpusRevision` | `corpusRevision`(必出) | 证据所钉住的语料修订 |
|
||||
| `NodeID` | `nodeId`(必出) | 条款节点 ID |
|
||||
| `Start` / `End` | `start` / `end` | 可选的片段偏移 |
|
||||
|
||||
**`RegulationEvidence`**
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `CorpusRevision` | `corpusRevision`(必出) | 证据所属修订 |
|
||||
| `RegulationID` / `EditionID` | `regulationId` / `editionId` | 法规与版本 ID |
|
||||
| `NodeID` | `nodeId`(必出) | 条款节点 ID |
|
||||
| `ClauseNo` | `clauseNo` | 条款号 |
|
||||
| `Excerpt` / `Start` / `End` | `excerpt` / `start` / `end` | 原文片段与偏移 |
|
||||
| `NodeSHA256` / `SourceAssetSHA256` | `nodeSha256` / `sourceAssetSha256` | 节点文本哈希与来源资产哈希 |
|
||||
| `PageStart` / `PageEnd` | `pageStart` / `pageEnd` | 页码定位 |
|
||||
| `Disclosure` | `disclosure`(必出) | 同 `RegulationHit.Disclosure` |
|
||||
| `WithheldReason` | `withheldReason` | 不披露原因 |
|
||||
| `HashVerified` | `hashVerified`(必出) | 提供方报告的哈希校验结果;基座原样透传,不自行校验 |
|
||||
|
||||
**`WebSearchRequest`**(真实网络搜索)
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `SchemaVersion` | `schemaVersion`(必出) | 必须等于 `RegulationsSchemaVersion` |
|
||||
| `Query` | `query`(必出) | 发往外网的搜索词;基座先去首尾空白再校验 |
|
||||
| `Exclusions` | `exclusions` | 调用方声明的机密词(项目名、编号、人员等);查询含任一词即由基座拒绝 |
|
||||
| `PreferOfficial` | `preferOfficial` | 优先官方来源 |
|
||||
| `Limit` | `limit` | 结果数上限,由提供方解释 |
|
||||
|
||||
**`WebSearchResult`**
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `Provider` | `provider` | 实际使用的搜索提供方 |
|
||||
| `SentQuery` | `sentQuery` | 实际发往外网的查询 |
|
||||
| `SearchedAt` | `searchedAt`(必出) | 搜索时间 |
|
||||
| `State` | `state`(必出) | `ok` / `empty` / `unavailable` / `rate_limited` / `rejected` / `error` |
|
||||
| `Reason` | `reason` | 非 `ok` 状态的原因 |
|
||||
| `Results` | `results` | 排序结果 `[]WebSearchHit` |
|
||||
|
||||
**`WebSearchHit`**:`Rank`(`rank`,必出,排名)、`URL`(`url`,必出)、`Title`(`title`)、`Snippet`(`snippet`,搜索摘要,不是已核验证据)、`Publisher`(`publisher`,发布机构)、`Official`(`official`,是否被提供方判定为官方来源)。
|
||||
|
||||
**`WebCaptureRequest`**(抓取先前 `SearchWeb` 找到的页面)
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `SchemaVersion` | `schemaVersion`(必出) | 必须等于 `RegulationsSchemaVersion` |
|
||||
| `URL` | `url`(必出) | 要抓取的地址 |
|
||||
| `SearchProvider` / `SearchQuery` / `SearchRank` | `searchProvider` / `searchQuery` / `searchRank` | 关联的来源搜索(提供方、查询与排名),用于证据溯源 |
|
||||
|
||||
**`WebCapture`**
|
||||
|
||||
| 字段 | JSON | 含义 |
|
||||
|---|---|---|
|
||||
| `CaptureID` | `captureId` | 抓取记录 ID |
|
||||
| `FinalURL` | `finalUrl` | 跟随重定向后的最终地址 |
|
||||
| `FetchedAt` | `fetchedAt`(必出) | 抓取时间 |
|
||||
| `ContentType` / `ByteSize` / `SHA256` | `contentType` / `byteSize` / `sha256` | 内容类型、字节数与内容哈希 |
|
||||
| `Retention` | `retention` | `full` / `excerpt` / `metadata_only` |
|
||||
| `Text` | `text` | 页面全文,仅当来源权利允许全文留存时出现 |
|
||||
| `Candidates` | `candidates` | 从页面解析出的条款候选 `[]WebClauseCandidate` |
|
||||
| `State` | `state`(必出) | `captured` / `rejected` / `failed` |
|
||||
| `Reason` | `reason` | 非 `captured` 状态的原因 |
|
||||
|
||||
**`WebClauseCandidate`**:`ClauseNo`(`clauseNo`)、`Excerpt`(`excerpt`,必出)、`Start` / `End`(`start` / `end`,必出,片段在抓取文本中的偏移)。
|
||||
|
||||
## 4. 基座强制行为(`internal/app/regulations.go`、`compiled.go`)
|
||||
|
||||
### 4.1 注册
|
||||
|
||||
1. 只有插件 ID 为 `kbreg` 的编译进程内插件可注册提供方;其他插件 ID 或 `nil` 提供方返回错误。
|
||||
2. 只能注册一次:重复注册返回错误,已注册的第一个提供方保持不变。
|
||||
3. 声明式 Registry(`compiledRegistry`)一律拒绝 `RegisterRegulationsProvider`。
|
||||
4. 宿主未装配提供方槽时,注册返回“registration unavailable”错误;带清单记录的包装 Registry(`recordRegistry`)只把注册转发给内层 `RegulationsRegistrar`。
|
||||
|
||||
### 4.2 每次 Host 调用
|
||||
|
||||
按以下顺序执行,四个方法一致:
|
||||
|
||||
1. 先做账号有效性守卫(`requireEffective`);停用等无效账号直接返回守卫错误,提供方不会被调用。
|
||||
2. 没有已注册提供方或没有审计存储时返回 `ErrRegulationsUnavailable`。调用绝不在无审计的情况下执行;这类不可用调用不写审计。
|
||||
3. `RegulationsCaller` 由基座填写为 `{PluginID: 调用插件, Actor: 分发主体, Owner: 分发 owner}`,不含项目 ID。
|
||||
4. `SchemaVersion != RegulationsSchemaVersion` 时拒绝并返回错误,提供方不会被调用;写一条 `state=invalid` 的审计。
|
||||
5. 只有 `SearchWeb` 做查询最小化校验:
|
||||
- 先去掉 `Query` 首尾空白,提供方收到的是去空白后的查询;
|
||||
- 去空白后为空、不是合法 UTF-8 或超过 256 个 rune 时返回错误(`1-256` 按 rune 计,不按字节计),写 `state=invalid` 审计;
|
||||
- 查询包含任一 `Exclusions` 词时(每个词先去首尾空白,空词忽略,按小写子串匹配,大小写不敏感),基座直接返回
|
||||
`WebSearchResult{State: "rejected", Reason: "query contains an excluded term"}` 且 error 为 nil,提供方不会收到该查询,审计记 `state=rejected`。
|
||||
6. 提供方返回的 `State`、`Disclosure`、`Retention`、`DegradedReasons`、`HashVerified` 等全部字段原样透传;基座不把 `degraded`、`withheld`、`rejected`、`rate_limited` 或失败包装成成功,提供方返回的 error 原样返回。
|
||||
7. `CaptureWeb` 在基座侧不校验 URL:抓取安全控制(私有/保留地址、重定向、大小、权利留存)属于提供方职责(计划 U5)。
|
||||
|
||||
### 4.3 审计
|
||||
|
||||
每次到达 schema 校验的调用恰好写一条基座审计事件:owner 为分发 owner,Actor 为 `plugin:<调用插件>`,Target 为 `kbreg`。
|
||||
|
||||
| 方法 | 动作 | `revision` | `count` | `state` | `querySha256` |
|
||||
|---|---|---|---|---|---|
|
||||
| `SearchRegulations` | `regulations.search` | 成功时为结果修订,否则为请求修订 | `len(Hits)` | 提供方 `State` | `Query` 原文的 SHA-256 |
|
||||
| `ResolveRegulationEvidence` | `regulations.evidence` | 结果修订非空时取结果,否则为请求修订 | 成功为 1 | 成功为 `ok` | 不记 |
|
||||
| `SearchWeb` | `web.search` | 不记 | `len(Results)` | 提供方 `State`,或基座的 `rejected` | 去空白后查询的 SHA-256 |
|
||||
| `CaptureWeb` | `web.capture` | 不记 | `len(Candidates)` | 提供方 `State` | 去空白后 `SearchQuery` 的 SHA-256 |
|
||||
|
||||
- 审计证据 JSON 只有 `revision`、`count`、`state`、`querySha256` 四个字段(`revision` 与 `querySha256` 为空时省略);查询明文、法规片段、搜索摘要与网页全文都不进审计。
|
||||
- 失败时 `state` 取 `invalid`(schema 或查询校验失败)或 `error`(提供方返回 error),`count` 为 0。
|
||||
- 提供方 error 优先返回;调用成功但审计写入失败时,结果被扣留并返回审计错误。
|
||||
|
||||
## 5. 兼容
|
||||
|
||||
- **可选能力**:`RegulationsHost` 与 `RegulationsRegistrar` 都经类型断言获取,`Host` 与 `Registry` 接口没有新增方法;旧插件、第三方 fake Host 与旧 Registry 实现照常编译。断言失败即能力不可用。
|
||||
- **纯加法**:新增 3 个接口、12 个 DTO、20 个状态常量、`RegulationsSchemaVersion` 与 `ErrRegulationsUnavailable`;`surface.txt` 快照同步增加这些顶层名与接口方法。按 compat-policy“每次加法升次版本号”,`SurfaceVersion` 由 `2.14.0-experimental` 升为 `2.15.0-experimental`。
|
||||
- **不改 `KnowledgeSearch`**:owner 作用域项目知识检索的签名与语义不变;法规能力缺失时调用方不得回退到它。
|
||||
- **组合方式**:法规插件以编译进程内插件注册(`extension.RegisterCompiled`,插件 ID `kbreg`),与 RDM 同二进制组合。当前只有进程内 `inprocHost` 实现 `RegulationsHost`;sidecar `/host/v1` HTTP 路由不在本扩展范围,出现真实需求再申请。
|
||||
- **请求演进**:请求 schema 以 `RegulationsSchemaVersion` 显式版本化;新增可选字段一律带 `omitempty`,不兼容的请求变更须升 schema 版本并另行申请。
|
||||
|
||||
## 6. 验收(对应 Backend 测试)
|
||||
|
||||
| 验收条件 | 测试 |
|
||||
|---|---|
|
||||
| 能力可选:空 Host/Registry 不暴露能力;schema 版本为 1;错误值已定义;下游仅凭 `pkg/extension` 即可实现提供方 | `pkg/extension` `TestRegulationsContractIsOptional` |
|
||||
| 状态常量的线上取值固定;可选字段省略;`RegulationsCaller` 序列化不含 project | `pkg/extension` `TestRegulationsWireNames` |
|
||||
| 无提供方或无提供方槽时四个方法都返回 `ErrRegulationsUnavailable`,且不写审计 | `internal/app` `TestRegulationsUnavailableWithoutProvider` |
|
||||
| 只有 `kbreg` 可注册;`nil` 被拒;重复注册被拒且不替换;无槽时注册被拒 | `TestRegulationsRegistrationOnlyTrustedKbregOnce` |
|
||||
| 声明式 Registry 拒绝注册;记录型包装 Registry 转发 `kbreg` 注册 | `TestRegulationsDeclarativeRegistrationRejected` |
|
||||
| 提供方收到的 Caller 由分发上下文填写 | `TestRegulationsCallerFilledFromDispatchContext` |
|
||||
| schema 版本 0 与 2 被拒,提供方不被调用 | `TestRegulationsRejectsOtherSchemaVersions` |
|
||||
| 空查询、纯空白查询、257 rune 查询被拒;256 rune 查询通过且提供方收到去空白后的查询 | `TestRegulationsWebQueryBounds` |
|
||||
| 含排除词(大小写不敏感)的查询返回 `rejected`、提供方不被调用、审计不含该词;空排除词不拦截 | `TestRegulationsExclusionRejectedBeforeProvider` |
|
||||
| 提供方的 `degraded`、`withheld`、`metadata_only`、`rate_limited`、`rejected` 与 error 原样透传 | `TestRegulationsProviderStatesPassThroughUnchanged` |
|
||||
| 每次调用一条审计,只含 revision、count、state、querySha256,不含查询明文、片段或网页文本 | `TestRegulationsAuditEvidenceOmitsQueryAndText` |
|
||||
| 账号无效时四个方法返回守卫错误,提供方不被调用 | `TestRegulationsRequireEffectiveAccount` |
|
||||
| 只用 `pkg/extension` 的测试插件以 `kbreg` 经编译插件路径注册,冒充插件注册失败,另一编译插件经 Host 断言调用成功并留下基座审计 | `TestRegulationsCompiledPluginCompatibility` |
|
||||
| 未编入提供方时消费方命令不会提交成功 | `TestRegulationsCompiledConsumerWithoutProvider` |
|
||||
|
||||
另需 `pkg/extension` 的 surface 快照测试通过(`surface.txt` 与导出面一致)。
|
||||
|
||||
## 7. 分工
|
||||
|
||||
- **Backend(本扩展,计划 U9)**:只负责公开契约、基座强制行为与兼容测试;不内置提供方、不实现搜索或抓取、不实现 RDM 适配器。
|
||||
- **`Agent-System-KB-Regulations`(计划 U2–U5)**:实现并以插件 ID `kbreg` 注册 `RegulationsProvider`,负责语料修订、检索、披露级别、真实搜索提供方适配、网页抓取安全控制与权利留存。
|
||||
- **Agent-System-RDM(计划 U6/U7)**:经 `RegulationsHost` 消费本能力,把语料检索与网络搜索作为两条独立证据腿做双源核验;负责项目授权、引用渲染与业务审计投影。能力不可用时必须显式降级,不得回退到 `KnowledgeSearch`,也不得宣称完成双源核验。
|
||||
- **Dev(计划 U8)**:组合 pin 与组合验证。
|
||||
|
||||
## 8. 不在本文范围
|
||||
|
||||
- sidecar `/host/v1` HTTP 路由与远程提供方形态。
|
||||
- 搜索提供方选择、实网联调与费用(需用户另行确认提供方与凭据)。
|
||||
- RDM 证据批次模型、引用展示与篡改检测记录(计划 U6/U7)。
|
||||
+30
-2
@@ -4,10 +4,28 @@
|
||||
本索引负责导航与差异提示,规划正文、批准范围和验收条件仍以链接的主记录及其批准版本为准。
|
||||
合入授权不批准新方向、不调整里程碑范围、不启动新的业务任务。
|
||||
|
||||
待评审(收录不是批准):[svc 插件组合部署(--with)方案 r1](2026-10-14-svc-plugin-compose-deploy.md)。
|
||||
[分层分支交付与规范精简 r1](2026-10-18-delivery-model-v3.md):2026-10-18 经用户批准实施;
|
||||
由 Dev 治理大任务 `feature/delivery-model-v3` 推进,实时进度见该任务卡与 PR。
|
||||
|
||||
[EXT-20 共享法规检索与网络证据扩展点](2026-10-18-ext-20-regulations-provider.md):法规知识库计划 U9 的基座公开契约;
|
||||
2026-10-18 经用户授权,由 Dev initiative `feature/regulations-kb` 推进,实时进度见该任务卡与 PR。
|
||||
|
||||
待评审(收录不是批准):[svc 插件组合部署(--with)方案 r1](2026-10-14-svc-plugin-compose-deploy.md);
|
||||
[分层 Python 环境方案 r1](2026-10-15-layered-python-env.md)(8788 无法生成 docx 的环境层;白名单自动批准,其余审批)。
|
||||
|
||||
## 先看哪一份
|
||||
|
||||
- [IAM U4 阶段 7–10 验收与交付计划](2026-10-15-iam-u4-stage7-10-delivery-plan.md):
|
||||
基于已批准的聚焦角色权限实现,安排真实浏览器验收、跨仓 Review/PR/CI、Backend 受信 tag、RDM 权威 pin、Dev 手工合入窗口及安全收口。
|
||||
生产迁移、部署、多角色、账号恢复、Agent 权限和工作流改造不在本计划内。
|
||||
|
||||
- [IAM U3 账号资料、有效态、受控目录与本人恢复 r1](2026-10-14-iam-u3-account-contract-and-plan.md):
|
||||
2026-10-14 用户批准 U3 r1 阶段 4–5;[阶段 6 审阅后修订 r1(A1–A4)](2026-10-14-iam-u3-stage6-review-amendment.md)与[委托投影真实操作者修订](2026-10-14-iam-u3-delegated-projection-actor-amendment.md)均于 2026-10-14 经用户就受影响的阶段 4–5 批准。
|
||||
实施已合入:Backend PR #198 于 2026-10-14 合入(`2716b9e`,发布为 v0.5.0);Frontend PR #86(`6db528d`)、RDM PR #380(`7c968d9`)与 Dev 组合 PR #626(`7716b28`)于 2026-10-19 合入。
|
||||
用户在部署环境上的业务验收待完成;生产部署不在本条目范围内。
|
||||
|
||||
- [最新模板驱动的两树一网、成员上下文与完整可读审计 r12](2026-10-14-rdm-two-trees-latest-templates.md):2026-10-19 按部分交付收口。已合入各仓 main:W2/W4a 项目结构与只读隔离、W4b 真人确认、W6 历史来源复验、W9 审计截止水位,以及统一文档渲染器(44 份 DHF 模板发布)。剩余 W3/W5/W7/W8/W10–W13 另立后续大任务,E1 保真未通过、正式运行验收 NOT_RUN。
|
||||
|
||||
- [IAM I1 权限边界与公开扩展合同 r1](2026-10-13-iam-i1-permission-contract.md):
|
||||
依据已批准的[用户、职位角色与分层权限统一方案 r1](2026-10-13-identity-role-permission-plan.md)
|
||||
(Documents `a088809`)冻结系统/项目/资源边界、管理员无业务 bypass、创建者 cap、独立 `audit.read` 与公开扩展四要素。
|
||||
@@ -18,6 +36,12 @@
|
||||
运行卡呈现状态、已完成工作、当前发现与剩余项;四层阅读、阶段成果、来源、异常恢复及 U1–U4。
|
||||
2026-10-12 方案设计已批准(阶段 1–4);首批仅 U1;[U1 实施计划 r1](2026-10-12-fast-slow-channel-display-u1-plan.md) 待阶段 5 批准;业务实施和运行验收 NOT_RUN。
|
||||
|
||||
- [快慢通道 U2/U3 实施计划 r0.1](2026-10-13-fast-slow-u2-u3-plan.md):部分收口:阶段 5 已批准,零付费机制(含 r0.6)已合入;真实模型质量未解决(r0.4 A01 FAIL,r0.5/r0.6 A01 NOT_RUN),未部署。详见[核验报告](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。
|
||||
- [U3 r0.5 安全终态证据与可信快通道反馈设计](2026-10-14-fast-slow-u3-r05-terminal-evidence-and-fast-feedback-design.md):书面设计、[详细实施计划](2026-10-14-fast-slow-u3-r05-terminal-evidence-and-fast-feedback-implementation-plan.md)及零付费阶段 6 已获批准;唯一另行授权的短工具流探针返回 513 Usage、`clean_eof`、缺 `[DONE]`,工具零执行且授权已用尽。A01 质量仍 NOT_RUN,详见[核验记录](../reports/2026-10-13-fast-slow-u2-u3-validation.md)。
|
||||
- [U3 r0.6 当前路由的传输完成性证据设计](2026-10-14-fast-slow-u3-r06-transport-completeness-design.md):书面设计与[详细实施计划](2026-10-14-fast-slow-u3-r06-transport-evidence-implementation-plan.md)已获批准,零付费实施通过阶段 6 并合入;唯一获批的一次性传输边界探针(472 Usage、HTTP/2 干净 EOF、缺 `[DONE]`、工具零执行)判定 INCONCLUSIVE,A01 不具备资格,未部署。
|
||||
- [U3 质量修订设计 r0.2](2026-10-13-fast-slow-u3-quality-revision.md):三处修订方向和书面设计均已批准,实施计划待人工评审;原样本质量及停止边界仍 FAIL,无新付费样本授权。
|
||||
- [U3 质量修订实施计划 r0.2](2026-10-13-fast-slow-u3-quality-implementation-plan.md):书面设计已批准,阶段 5 计划待人工评审;Task 1–5 为零付费实施与验证,Task 6 的真实模型样本另需明确资源授权。
|
||||
|
||||
Generative UI 方向已收口(U1–U7 全部落地,2026-10-12):[使用说明与评测记录](2026-10-12-generative-ui-usage-and-evaluation.md)(final);
|
||||
主记录 [r2](2026-10-10-generative-ui-plugin.md) 与 [U5 动作范围 r2](2026-10-11-generative-ui-u5-action-scope.md) 保留为过程权威。
|
||||
|
||||
@@ -182,7 +206,11 @@ RDM 总案把库分期作为支撑与依赖,不覆盖库分期的原始范围
|
||||
|
||||
- [最终验证与合入调度实施计划 r1](2026-10-13-merge-queue-implementation-plan.md):阶段 5 已于 2026-10-13 经用户「批准」确认,原生逐项实施;U1–U3 源码与自检在 Dev 任务分支推进,U4 待启用记录及规则已准备,U5 平台所有者操作与 U6 真实三任务 CI 试行仍 NOT_RUN。实际对象、证据和进度回链 Dev 任务卡,不把本索引当第二进度权威。
|
||||
|
||||
- [RDM 设置归属、成员、文档职责与权限矩阵完善增量方案 r1](2026-10-13-rdm-settings-members-duties-perms-increment.md):承接总案 U3/U4/U6(衔接 U5)的完整增量——设置作用域与受管项、可搜索人员选择器、文档清单+职责分配、单成员/多人权限矩阵与三态项目覆盖;含服务端一致性修复(职责目标成员校验推翻 G1-5 旧裁定、职责变更与审签失效原子化)与 P1–P8 工作包。**2026-10-13 用户评审通过并授权实施**(两批推进;正式验收与清理回收保留人工节点);P1 契约随本稿固定,P2 基座契约扩展按总案发版顺序排队。
|
||||
- [RDM 设置归属、成员、文档职责与权限矩阵完善增量方案 r1](2026-10-13-rdm-settings-members-duties-perms-increment.md):承接总案 U3/U4/U6(衔接 U5)的完整增量——设置作用域与受管项、可搜索人员选择器、单成员/多人权限矩阵与三态项目覆盖;含服务端一致性修复。**2026-10-13 用户评审通过并授权实施**。第四节及 P5/P7 的文档职责页交互已被下方 r2 取代,其余部分继续有效。
|
||||
|
||||
## 2026-10-15 规划补充
|
||||
|
||||
- [文档职责矩阵整改 r2](2026-10-15-rdm-duty-matrix-rework.md):项目设置只分配已有文档的编制、审核、批准;按人员、按文档、成员×文档三视图共享一份草稿。章节级新指派停用,有歧义的旧章节职责逐文档确认。2026-10-15 按实施方案执行;部署与真实账号验收未授权。收录不把其余未完成增量自动标成已验收。
|
||||
|
||||
## 2026-10-12 规划补充
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# 两树一网本轮来源与原始评审对象
|
||||
|
||||
当前推进状态只在 [方案主记录](../../proposals/2026-10-14-rdm-two-trees-latest-templates.md) 维护。
|
||||
|
||||
本目录按原字节保存阶段1/2原对象、源调查及SELF收据;用户已批准阶段2及E1范围,当前结论在主记录更新,原对象保留批准前文字。对象中的旧工作区状态、绝对路径和/tmp引用是历史执行环境,不代表当前工作区准入状态。初次保存收据的完整副本在evidence目录,摘要在preservation-manifest.json;不改写已批准对象去覆盖历史。
|
||||
|
||||
- [阶段1原对象](rdm-two-trees-requirements-r1.md)
|
||||
- [阶段2原对象与E1试验范围](rdm-two-trees-stage2-evaluation-r1.md)
|
||||
- [工作信息拆解与主动风险澄清的阶段2受影响评估r1](rdm-two-trees-stage2-work-observation-risk-evaluation-r1.md):用户已确认增补并要求进入阶段3;原稿字节保留,不改变原阶段2已批准对象。
|
||||
- [阶段3工作信息拆解与主动风险澄清需求表r1](rdm-two-trees-stage3-work-observation-risk-requirements-r1.md):用户已确认TT-N03、TT-R01新增条件;原28项仍按原批准对象,原稿字节保留。
|
||||
- [阶段4工作来源观察与主动风险澄清方案r1](rdm-two-trees-stage4-work-observation-risk-design-r1.md):受影响公开接口、候选/HITL/卡片、权限和恢复方案,用户已批准固定版本。
|
||||
- [阶段5工作来源观察与主动风险澄清实施及测试计划r1](rdm-two-trees-stage5-work-observation-risk-implementation-test-plan-r1.md):TT-N03/R01 的代码 owner、依赖、隔离测试、全链路验收与原预算复用,用户已批准固定版本。
|
||||
- [阶段6 W4b 真人确认受影响设计修订候选r1](rdm-two-trees-stage6-w4b-human-confirmation-design-adjustment-r1.md):固定公开 Host 缺可信一次性人工证明的合同差距、候选 X3 能力和 RDM 原子消费/恢复/测试边界;待阶段4受影响方案人工评审,确认写入暂不实施。
|
||||
- [阶段3需求与验收条件r1原对象](rdm-two-trees-stage3-requirements-r1.md):已获用户确认,原字节保留。
|
||||
- [阶段4方案设计r1](rdm-two-trees-stage4-design-r1.md):用户已批准,原字节保留。
|
||||
- [阶段5实施与测试计划r1](rdm-two-trees-stage5-implementation-test-plan-r1.md)
|
||||
- [阶段5依赖状态快照](stage5-dependencies.json)
|
||||
- [W0逐文件模板/目录对照r1](rdm-two-trees-stage6-w0-template-ledger-r1.md)
|
||||
- [X1/X2基座公开扩展申请r1](rdm-two-trees-stage6-public-extension-requests-r1.md)
|
||||
- [X2跨成员审计可信链接设计修订r1](rdm-two-trees-stage6-audit-link-design-adjustment-r1.md):用户已批准受影响公开合同,原对象保留评审前状态。
|
||||
- [W2/W4关键依赖顺序修订r1](rdm-two-trees-stage6-w2-w4-sequence-adjustment-r1.md):用户已批准W4a先行,原对象保留评审前状态。
|
||||
- [W4a项目只读快照指针隔离修订r1](rdm-two-trees-stage6-w4a-read-isolation-design-adjustment-r1.md):同项目缓存污染RED后的受影响读合同已获用户批准,原对象保留评审前状态;W4a继续隔离实现/验证。
|
||||
- [领域时间持久化与历史缺项修订r1](rdm-two-trees-stage6-time-contract-design-adjustment-r1.md):固定时间RED后的数据合同已获用户批准(call_6ce04b5a3ca3496487ab2714ed208965);原稿字节保留,旧历史不补造,仅隔离实施/测试。
|
||||
- [W9 PostgreSQL审计截止水位修订r1](rdm-two-trees-stage6-w9-pg-audit-cutoff-adjustment-r1.md):用户已批准隔离分支实现/验证;真实运行库迁移未获放行,原对象保留评审前状态。
|
||||
- [W6项目模型历史来源逐项复验修订r1](rdm-two-trees-stage6-w6-source-recheck-design-adjustment-r1.md):长期回执原文RED后的X1受影响公开合同已获用户批准;原对象保留评审前状态,W6仅隔离分支续办。
|
||||
- [W9全部审计写入口截止水位修订r1](rdm-two-trees-stage6-w9-all-writers-cutoff-adjustment-r1.md):显式在线ID绕过后的DB门禁与排他复制修订已获用户批准,原对象保留评审前状态;强coverage仍待修复和验证。
|
||||
- [W9隔离PG显式低ID跨页RED原始SELF收据](evidence/backend-w9-explicit-low-red-20261014-01.json):从Backend独立工作树源码外收据逐字节复制,副本与原件SHA256均为`21999df9ca7304288df42a5a0ac62687870636291bc61a8b1340fd92729bfd96`;退出码1是预期的失败用例,不是代码已修复或验收通过。
|
||||
- [Backend X1/X2与最新main组合探针r1](rdm-two-trees-stage6-backend-combination-probe-r1.md):仅本地合并/测试证据,未推送或合入组件。
|
||||
- [W4a读取隔离P2独立限域复审](rdm-two-trees-stage6-w4a-p2-independent-review-r1.md)、[完整原始收据](evidence/rdm-p2-review-57a8d7ca-replay-20261014-01.json)及[重放脚本](evidence/rdm-p2-review-57a8d7ca-replay.sh):逐字节保留审阅者原件。RDM固定对象57a8d7ca与外层Dev收据对象不同,输出已核验archive及pins;旧时间RED与性能人审未由本结论代替。
|
||||
- [阶段4源码与在途依赖快照](stage4-sources.json)
|
||||
- [模板与会议来源台账](rdm-two-trees-source-inventory.json)
|
||||
- [旧DOC源码补充](rdm-two-trees-legacy-source-addendum.md)
|
||||
- [固定main及PR快照](stage2-sources/remote-snapshot.json)
|
||||
- [相关PR变更文件](stage2-sources/overlap-snapshot.json)
|
||||
- [额外源码哈希](stage2-sources/extra-source-snapshot.json)
|
||||
|
||||
JSON的localCopy字段记录调查时源码外缓存的位置;仓内保留源码commit/path/hash和远端链接,不在Documents复制另一套业务源码。公开依赖仍以各仓真实源码及当前pin为准。所有本地执行收据均为SELF,不能替代CI、独立重放或人工批准。
|
||||
|
||||
E1已按批准范围执行,全部原始产物及完整收据留源码外:[报告与逐文件结果](/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/e1-20261014-091421/REPORT-r1.md)。14份转换成功,完整保真未通过;原件未改变。组件本地实现及隔离自检已开展,真实模型/浏览器、正式验收和部署仍未执行;各项当前结论见主记录。此机器绝对路径只定位当前保存材料,不表示已在远端发布或可在其他机器直接取得。
|
||||
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
repo=/home/weichen/projects/Agent-System-RDM-wt-feature-rdm-two-trees-project-dictionary
|
||||
snapshot=/tmp/rdm-p2-review-8shrap
|
||||
source_sha=57a8d7caedf72d9be4bdca179ae2a93e456ba009
|
||||
verify_dir=$(mktemp -d /tmp/rdm-p2-receipt-verify-XXXXXX)
|
||||
git -C "$repo" archive "$source_sha" | tar -x -C "$verify_dir"
|
||||
diff -qr -x pins "$verify_dir" "$snapshot"
|
||||
printf 'SOURCE_SHA=%s SOURCE_TREE=IDENTICAL_TO_GIT_ARCHIVE\n' "$source_sha"
|
||||
for pin in agent-system-backend agent-system-core agent-system-frontend agent-system-ui; do
|
||||
expected=$(git -C "$repo" ls-tree "$source_sha:pins" "$pin" | awk '{print $3}')
|
||||
actual=$(git -C "$repo/pins/$pin" rev-parse HEAD)
|
||||
test "$actual" = "$expected"
|
||||
test -z "$(git -C "$repo/pins/$pin" status --porcelain=v1)"
|
||||
printf 'PIN_%s=%s MATCHES_GITLINK CLEAN\n' "$pin" "$actual"
|
||||
done
|
||||
diff -qr -x .git "$repo/pins" "$snapshot/pins"
|
||||
printf 'PIN_SOURCE=IDENTICAL_TO_VERIFIED_PIN_CHECKOUTS\n'
|
||||
printf 'SNAPSHOT_PATH=%s\n' "$snapshot"
|
||||
cd "$snapshot"
|
||||
GOWORK=off go test -race -v ./internal/domain ./internal/rdmapp -run 'TestFrozenWorldCopySeparatesNestedStateAndSharesOnlySealedLog|TestEventLogDoesNotAliasEventInputsOrOutputs|TestEventLogCloseSealsSettersRestoresAndTransactionClosures|TestPublishedReadPointersCannotPolluteOtherReaders|TestRuntimePrivateSeedSurvivesPublicDictionaryMutationBeforeFirstProjectRead|TestRuntimePublicDictionaryCannotPoisonProjectOrHistoricalReaders|TestRetainedTransactionWorldCannotPoisonCommittedCanonical|TestWorldForSharesOnlySealedLogWithinRevision|TestSameRevisionCanonicalCannotBeReplacedByAnotherProjection|TestLaterInstanceCommitRejectsOlderPendingCanonical|TestReaderWaitsForLocalCommitPublication|TestProjectTransactionPublishesOnlyAfterCommit|TestProjectTransactionSQLiteTwoInstanceCAS|TestLegacyAttributionRefreshesOtherRuntimeSQLite|TestCancelInFlightUpdatesCardSameSource' -count=1 -timeout 90s
|
||||
|
||||
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
+34
File diff suppressed because one or more lines are too long
@@ -0,0 +1,117 @@
|
||||
[
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/rdm-two-trees-requirements-r1.md",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-requirements-r1.md",
|
||||
"sha256": "60fd0296840a74982ae65cc4bd1e6a810ace5109e103e8408a94d4db0573bad7"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/rdm-two-trees-stage2-evaluation-r1.md",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage2-evaluation-r1.md",
|
||||
"sha256": "61733945c077ae6b8f8488ee5a0e41337d7e4a019854dc647e93fecbb4b72178"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/rdm-two-trees-legacy-source-addendum.md",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-legacy-source-addendum.md",
|
||||
"sha256": "4157703086f11f06b367927824f0f0345ff0f1108eade8ee5926c9608a7f2784"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/rdm-two-trees-source-inventory.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-source-inventory.json",
|
||||
"sha256": "7f55ac6fbd6088727855b49395e130bf81c8f3cb4e835bb2bdeb9bb3e3087bcd"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/remote-snapshot.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/stage2-sources/remote-snapshot.json",
|
||||
"sha256": "3e61710ebc9c51af7ed7d530484b4b9c53eeb7efd4aadf45b6dccb1671a29956"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/overlap-snapshot.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/stage2-sources/overlap-snapshot.json",
|
||||
"sha256": "e3b4f07086145cc4b2bd48d91a9dba6ca78e3ce4a2b512bd5257d2b122e6921f"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/extra-source-snapshot.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/stage2-sources/extra-source-snapshot.json",
|
||||
"sha256": "60576c5fc8163c9981c4a7147102993be0fe8e6b84616df9f9d7860d780bd494"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-01a13639-artifact-check.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-01a13639-artifact-check.json",
|
||||
"sha256": "d433ea42b7ad4d13e5d0889b4c1a289708b86090f857cf05310f7939bbfbff61"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-01a13639-legacy-source-receipt.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-01a13639-legacy-source-receipt.json",
|
||||
"sha256": "39012119226daf018c09677384558ba78e400afd0f53b525c41ede95957a18a5"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-01a13639-meeting-inventory-v2.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-01a13639-meeting-inventory-v2.json",
|
||||
"sha256": "3cb936c388deddcc07e0cfaab4f72e954656bc3d42d245d43daf74956f314784"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-01a13639-meeting-inventory.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-01a13639-meeting-inventory.json",
|
||||
"sha256": "b6021e9adb656a48d5e01e6d1cdbf8fd7e413e4131008f495783bb0848f32c87"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-01a13639-template-inventory-v2.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-01a13639-template-inventory-v2.json",
|
||||
"sha256": "1ccb9e2f1c1bfc21f68066c9700d0db4c9239405640879f159f909250f39a0cd"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-01a13639-template-inventory.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-01a13639-template-inventory.json",
|
||||
"sha256": "9ed0ea32c52436b4d17157a29ba4d8d85879b11d9bba1b3a4bb96aadab80a2f2"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-20261014-01a13639-start.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-20261014-01a13639-start.json",
|
||||
"sha256": "833f2f4a4c8f8d327520be31fe7ee33d582a8864537beb5a4adbf6587eaee0a4"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-stage2-check-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-stage2-check-01a13639.json",
|
||||
"sha256": "19e47e7f1050cbb370dd93f1aa01c2a2cabf2eb283b84278733cf41b05c5bd06"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-stage2-extra-sources-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-stage2-extra-sources-01a13639.json",
|
||||
"sha256": "ee94eebd5e0ac20eb45d0eb535c73c9aa23c493b854d1accda948b0a46af3cc2"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-stage2-gitea-token-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-stage2-gitea-token-01a13639.json",
|
||||
"sha256": "2b9901681248b74f0c467f8fffd508153a94ce1add9dec5a07a90a6a7577eeb5"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-stage2-gitea-version-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-stage2-gitea-version-01a13639.json",
|
||||
"sha256": "c5647906354f86438559c5f4206044223e28501ec7605e3c96086c5d6cf482e0"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-stage2-overlap-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-stage2-overlap-01a13639.json",
|
||||
"sha256": "123ffcfcbd414a80531e9262581dc45689e5dc37e8ca365c02b879dd3b50b5f7"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-stage2-refresh-20261014-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-stage2-refresh-20261014-01a13639.json",
|
||||
"sha256": "f90188e833699834df7476696d37e7ee9822eeea8deb98797664019d4b13d89d"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/evidence/rdm-two-trees-stage2-remote-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-stage2-remote-01a13639.json",
|
||||
"sha256": "ce2eaf499e3fe62e8f91e47abb578fb57d83dbb52d00366e89e4e1c05acc5492"
|
||||
},
|
||||
{
|
||||
"source": "/tmp/rdm-two-trees-recheck-20261014-084650-01a13639.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/evidence/rdm-two-trees-recheck-20261014-084650-01a13639.json",
|
||||
"sha256": "fcae2cb5e4dd7755b8dad093ca1cc7ff83403a5d81e119aea77fdcbdcf2e870a"
|
||||
},
|
||||
{
|
||||
"source": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-refresh-20261014-084314/snapshot.json",
|
||||
"saved": "docs/records/2026-10-14-rdm-two-trees-latest-templates/stage2-refresh-20261014-084314/snapshot.json",
|
||||
"sha256": "b241e0e4f7eb3c48c9bc04f3105af4ef14df125e96b01f0a21d098d568cea5ce"
|
||||
}
|
||||
]
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
# 两树一网来源核对补充:旧 DOC 模板接入
|
||||
|
||||
更新时间:2026-10-14T01:25:29+08:00。状态:SELF 只读源码证据;阶段1需求范围及后续阶段仍待用户评审。
|
||||
|
||||
本补充不修改已提交评审的 [需求拆解 r1](rdm-two-trees-requirements-r1.md),r1 SHA256 为 `60fd0296840a74982ae65cc4bd1e6a810ace5109e103e8408a94d4db0573bad7`。
|
||||
|
||||
本轮44份模板中的14份 `.doc` 文件均为实际 OLE Word 容器,文件头与来源哈希逐份核对;两份内嵌ZIP对象的DOC也仍是旧Word文件。
|
||||
|
||||
Backend 当前源码 `5d5fc9891c0eb8994545ccb8b740535d9b99fb0e` 的 [解析入口](/home/weichen/projects/Agent-System-Dev/modules/backend/internal/ingest/ingest.go:85) 明确对 `doc/xls/ppt` 返回“不解析,请转存后重传”的提示。RDM实际pin中的对应源码与之逐字节相同。故14份旧DOC不能通过现有内置解析器直接得到完整模板章节/表格/样式。当前源码调查没有运行解析器、模板渲染或转换工具,不宣称运行验证。
|
||||
|
||||
这使 TT-T01(全部模板接入)和 TT-T02(细粒度内容完整)的后续方案必须明确旧DOC的正式转换或解析路径及其核验:原资产保持不变,转换/解析产物绑定来源哈希;章节、表格、示例/固定文本、图片和排版不能默默丢失。具体实现路线待对应设计阶段确认;不能将这些模板标为空、跳过后声称44份完整覆盖。
|
||||
|
||||
源码外全文提取只能支持需求调查,不能当作产品模板导入能力。完整命令输出由 evidence 工具保存到 `/tmp/rdm-two-trees-01a13639-legacy-source-receipt.json`,复制后保存于本目录 `evidence/`。
|
||||
|
||||
当前共享Dev仍有Documents及Guidelines两个gitlink漂移,未接管、未同步、未创建任务worktree。当前没有本任务阶段1需求评审结论或连续推进授权;动态方式DYN-01已确认且不重问。待用户回复此前两个问题后,按照确认范围从最早未满足的节点继续。
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
# RDM 两树一网最新模板需求拆解与来源核对 r1
|
||||
|
||||
状态:阶段 1 需求拆解,待用户评审;整体实现目标仍未完成。
|
||||
记录人:Codex;负责人:用户;更新时间:2026-10-14T01:21:03+08:00。
|
||||
本记录暂存于源码外,因为启动检查返回 `SHARED_WORKSPACE_BUSY`;没有创建任务 worktree、修改项目代码、迁移数据、部署或更改其他任务现场。恢复准入后须导入 Documents 主记录和本任务卡,不能把此暂存物当作仓内已交付方案。
|
||||
|
||||
## 1. 用户目标及已确认决定
|
||||
|
||||
依据当前用户原始请求:用 `.templates` 的最新模板和 `.tmp` 的项目材料补全两树一网,结构细致完整,允许不同项目按内容与进度动态扩充;同项目成员工作时将其作为上下文和依据;各种操作须完整留痕,追溯审计以人可读的结构化方式显示。
|
||||
|
||||
已确认决定 DYN-01:用户本轮选择“提出变更,确认后应用”。这只确认动态变更方式,不等于需求表、方案、实施计划或连续实施授权已经通过。
|
||||
|
||||
需求优先口径:当前用户要求及本轮决定;当前项目有效需求与 IAM 合同;最新模板中的内容要求;已裁定的历史会议。历史讨论保留来源,但被后续裁决替代的条款不恢复生效。模板中某个产品的示例、数值、姓名、企业信息和测试结果不成为其他项目的事实;模板列出的法规版本也不构成当前法规适用性证明。
|
||||
|
||||
## 2. 本轮已核对的材料与证据边界
|
||||
|
||||
- `.templates/DHF 文件模板` 实际含 **44 份 Word 模板:30 DOCX、14 DOC**,覆盖目录 0–6 七个阶段。`.DS_Store` 排除。44 份文字已提取;30 DOCX 提取表格行/单元格结构。14 DOC 目前为二进制主文字提取,**表格层级、样式、图片及最终排版未验证**;自动识别的 heading 只是候选,不能直接当已批准章节。
|
||||
- `.tmp/Discussion-Meetings` 及根目录的 16 份原始 DOCX 已提取并登记哈希;会议输出与 `further-objective` 共 56 份 Markdown 建立来源索引。重点复核《08 核心数据模型》《13 架构与知识树讨论纪要》及权限、需求、设计的相关条款;索引不表示每份全文已作独立审阅。
|
||||
- 当前本地 RDM 源码快照:`f3ed2d3b762a8f7f6d136d9b77808c2279825de8`。Dev 及 Backend、Frontend、Documents、Guidelines、RDM pins 的实际 SHA 和源码文件哈希见 [来源台账](rdm-two-trees-source-inventory.json)。此为本地源码调查 **SELF**,不是部署环境或最新远端准入证明。
|
||||
- 新模板有四份阶段评审文件字节完全相同:输出、验证、转移、确认评审。应复用资产解析,但保留各自逻辑用途和阶段绑定。输入与转换两个风险报告也应分别绑定,不能用相同名称覆盖实例。
|
||||
- 启动检查原始收据:[启动检查](/tmp/rdm-two-trees-20261014-01a13639-start.json)。当时 Dev `feature/rdm-increment-acceptance-note`,HEAD `648d6ee12c99b326a854a760db135f0b13106c10`,工作树显示 Documents/Guidelines 两个 gitlink 漂移,落后本次 fetch 的主干 30 提交。后续检查两个子仓本身 clean,但其检出不归本任务;不能自行切换或丢弃其现场。
|
||||
- 模板首次提取两项失败的收据保留;根因为旧 DOC 中内嵌 ZIP 被错误判断成 DOCX。改以文件头识别后 44 份文字提取成功:[修正后完整收据](/tmp/rdm-two-trees-01a13639-template-inventory-v2.json)。抽取成功不代表模板内容、样式或业务验收通过。
|
||||
- 业务单测、组合 test/build、浏览器、真实模型对照、CI、运行验收、迁移和部署均 **NOT_RUN**。本轮不引用旧任务测试作为此次实现通过的依据。
|
||||
|
||||
## 3. 当前能力与本次需求差距(源码事实)
|
||||
|
||||
| 范围 | 本轮源码可确认 | 本次需要补齐 |
|
||||
|---|---|---|
|
||||
| 两树与追溯网 | 已有 `NoteTree`、`DocTree`、一般追溯边、15 类受控节点/11 类合规边、结论、事件重放、项目分片 | 细粒度内容契约、项目可扩展结构与确认后的结构变更链路 |
|
||||
| 模板 | 字典 69 文档类型;注册表 73 条,其中 69 为生成骨架 | 多数骨架含“章节名待补/内容要求待补”,不能代替本轮44份标准模板;须逐文件、逐章节、逐表格绑定 |
|
||||
| 字典 | 14 阶段、69 类型、9 主题,随包内嵌种子;标签校验只接受受控值 | 同一项目版本化扩展阶段、主题、工作事项、专业/产品维度;不能绕过权限或污染其他项目 |
|
||||
| 文档结构 | `structure.go` 按类型+标题、章节标题幂等补缺;`Section` 没有父章节/内容块字段;自举 YAML 定义 10 文档/22要求 | 稳定节点 ID、嵌套章节、字段/表格/重复块;重命名、移动、调整内容要求、废止、模板升级不能靠标题识别 |
|
||||
| 笔记结构 | 支持骨架新增、切片多挂载;已有标签与软删除事件 | 正式的项目结构提案/确认/拒绝、层级调整、用户入口与版本冲突处理 |
|
||||
| 工作上下文 | 已发布知识具备台账和资源授权;起草 Compose 通过章节条件取素材;普通对话初始知识注入由 `@knowledge` 触发;自动 Memory 适配器读 owner 的 `memory_entries` | 普通工作自动取得当前项目结构/阶段/结论/任务要求及相关已发布知识;不能把个人记忆或“检索工具存在”当作所有工作已使用两树一网 |
|
||||
| 审计记录 | 事件有时间、actor、op、target、detail、operationId;审计列表归组并分页,DTO不返回原始重放 payload | 完整人物/来源、内容变更、前后版本、原因、结果、影响与实际上下文依据;覆盖失败/拒绝/后台/宿主动作并保持不同事实语义 |
|
||||
| 审计页面 | `RdmAuditWorkspace.tsx` 已有四入口;事件行直接显示 `ev.op`、actor ID、截断 detail;关系行显示英文 layer/state 和对象 ID | 中文业务动作、人物名称、对象路径、结构化差异、影响列表、权限内证据跳转;人可读的筛选与分组 |
|
||||
| 授权 | 当前 IAM 要求独立 `audit.read` grant;创建者/管理员身份不自动赋予业务审计 | 成员日常上下文与业务审计分动作;审计权限不替代文档三权/当前正文权限,权限变更和跨项目均服务端执行 |
|
||||
|
||||
以上仅是需求调查;没有声明所有现有写路径已完成完整性或并发审计。
|
||||
|
||||
## 4. 用户场景与成功标准
|
||||
|
||||
1. 新建软件项目或含软硬件/无菌的项目后,以适用模板建立初始内容清单;软件项目可对不适用的材料/灭菌事项标“不适用+依据”,记录仍保留。项目差异不靠复制固定树硬编码。
|
||||
2. 上传或整理资料后,成员先得到来源明确的知识切片、相关节点和缺项;系统提出增加主题/章节/需求/关系或调整挂载的提案,展示理由与影响,用户确认后才改变有效结构。
|
||||
3. 两名成员在同项目的个人会话中做不同任务时,均自动使用各自可访问的共同项目知识、当前要求与已确认结论,输出可回指实际使用的节点及版本;原始会话、个人草稿、原件不因成员身份自动共享。
|
||||
4. 对某一需求、章节、风险控制或测试结果查看追溯时,能分辨“有来源”“已确认”“待复核”“缺少验证”,可定位确切版本、相关资料和受影响文档。
|
||||
5. 在审计页查看一次结构调整或文档更新,能读出谁、何时、为何、从什么改成什么、谁确认、成功或失败、直接/间接影响;分页不拆散一次操作、不丢事件,不显示机器 payload 作为业务记录。
|
||||
6. 重启、并发修改、后台任务恢复、撤销成员/职责、切换项目/账号后,上述结构、权限、历史与上下文仍一致;未知历史信息明确“当时未记录”,不补写假事实。
|
||||
|
||||
## 5. 两树一网的内容分工与细粒度要求
|
||||
|
||||
### 5.1 笔记树:项目知道什么、依据是什么
|
||||
|
||||
浏览骨架可按项目阶段、工作事项、子系统和主题组织;知识本体允许多处挂载,保持唯一 ID。需要覆盖:项目目标/范围、用户场景、原始资料切片、会议决议、已确认结论、需求与约束、技术方案、风险与控制、验证证据、转换/确认资料。问题、冲突、假设和缺项在登记册维护并关联相应树节点;不能塞入正式正文假装内容完成。
|
||||
|
||||
每条知识至少可定位:类型/标题/摘要、原文或证据引用、来源主体与上传/产生/确认者、原始文件或对话发言锚点、页/章节/表格/段落、归属项目/阶段/工作事项/主题、适用范围、有效/待确认/取代/废止状态、版本、时间、取代链、确认及共享状态。扩展属性需有字段语义和来源,不能用无约束 JSON 代替可验证的业务结构。
|
||||
|
||||
### 5.2 文档树:需要交付什么、每一处应写什么
|
||||
|
||||
实例层级允许“阶段 → 文档 → 多级章节 → 段落/字段/表格/重复项/附件引用”。模板定义、项目文档实例和历史版本分别记录。通用字段包括稳定 ID、父节点、排序、节点种类、内容要求、输入/证据条件、必填/可选/条件适用、填写说明/示例区分、字段类型/单位/验证方法、表格列和重复规则、负责人/三权、当前内容版本、进度及缺项。
|
||||
|
||||
进度不能只用有无文字:应区分未开始、素材不足、草稿、待确认、评审中、已批准、依据变更待复核、不适用。数量统计须说明范围与截止版本;“不适用”保留理由及确认记录,不物理删除必需项。蓝字/斜体示例与固定文本的含义要从原模板解析,不能按整段正文无差别复制。
|
||||
|
||||
项目建议书最新模板至少要求:项目内容/定位/竞品差异/目标/意义;立项依据/行业/客户/技术基础;产品型号/组成/性能;人员/场地设备/经济预算;其他说明;修订历史和编制/审核/批准元信息。
|
||||
|
||||
最新用户需求模板包含 **12 组**内容:临床与用途、用户与场景、功能与性能、安全风险、生物化学安全、可用性、兼容接口、灭菌感染控制、包装运输储存、软件数据、标识信息、法规合规。既有会议的六维分类仍保留为分类维度,不能据此裁掉本轮模板中的具体组项。
|
||||
|
||||
系统需求与设计输入要求保留 UN/SR/DI 的编号、来源、条件/行为/约束、子系统与可验证方法;各类测试保留用例、需求引用、环境/被测版本、预期/实际结果、执行者与证据。软件配置计划、配置报告、维护计划,软件详细设计、集成测试、追溯报告,以及设计验证/确认记录、试产总结等须分别建模其用途。
|
||||
|
||||
### 5.3 追溯网:事实出处、实现与证据链、变化影响
|
||||
|
||||
保留一般来源/操作关系与受控合规关系两套现有语义,经统一读取展示。至少能表达资料→结论、模板要求→章节、UN→SR→DI→设计实现→验证、风险→控制措施→需求/实现/验证、软件需求→架构/详细设计→单元/集成/系统测试→结果,及设计输出→转换/确认。
|
||||
|
||||
受控关系绑定端点的确切版本;候选关系经确认才生效;端点升版后显示待复核,不能自动把旧测试宣称为新版验证。影响范围同时展示直接对象和可追踪的间接对象,区分“本次操作当时记录的影响”与“按当前版本重新分析的影响”。资料来源、法规条款、模板、会议发言等作为证据可回查,不能把操作日志数量当作合规覆盖率。新增受控类型和 DI 与当前15类节点的绑定方式留待方案设计明确。
|
||||
|
||||
### 5.4 项目动态扩展(已选方式)
|
||||
|
||||
触发包括新资料、新需求、阶段推进、发现缺项、模板升级或成员主动整理。提案须说明新增/重命名/移动/调整要求/取代/废止的对象、具体差异、证据、理由、直接/间接影响、适用范围和风险;允许接受、修改后接受或拒绝。
|
||||
|
||||
确认时重验当前用户权限、当前节点/结构版本、模板版本及受控状态;发生并发冲突返回可读差异,不覆盖他人修改。修改结构及关联事件整批原子保存,幂等重试不重复生成节点,失败不出现半棵树。受控正文/已批准内容的实质变更仍遵守既有三权与重审规则;新增普通结构节点的确认不代替文档批准。
|
||||
|
||||
## 6. 成员工作上下文的必需内容
|
||||
|
||||
每次工作根据可信项目身份与当前主体获取:项目概况/范围/阶段,任务对象与内容要求,相关已确认结论,相关当前文档内容(按权限),来源知识、未决冲突/缺项和本次依据版本。先提供短摘要与稳定引用,按任务相关性拉取细节,并有预算与截断说明;无需每轮读取所有文档,也无需用户输入 `@knowledge` 才得到项目依据。
|
||||
|
||||
上下文在新任务、项目/任务切换和相关有效变更后刷新;后台恢复与执行前重验权限及版本,历史对话里的已撤权正文不能继续作为授权读取入口。模板只用于约束任务,原始资料中的指令视为数据。记录实际向模型提供的对象、版本、检索范围、有效水位、摘要/裁剪及来源;“系统预期会使用”不算实际使用证据。
|
||||
|
||||
共享的是经确认/发布且当前有权限使用的项目知识;审计读取、结构元信息、受控正文、原件和个人对话分别按现行 IAM 授权。同项目成员能使用工作依据不意味着自动获得全员原始对话、草稿或审计全量权限。撤销/废止后新工作排除相应依据;仍相关的冲突必须作为冲突显示,不能靠“最新内容优先”悄然裁决。
|
||||
|
||||
## 7. 完整记录与可读审计
|
||||
|
||||
### 7.1 操作覆盖矩阵
|
||||
|
||||
| 对象 | 需记录的操作 | 必须解释的影响 |
|
||||
|---|---|---|
|
||||
| 模板与项目结构 | 导入、解析、版本绑定、初始化、增加、重命名、移动、排序、修改要求、废止、升级、提案/确认/拒绝 | 哪些实例/章节/资料挂载/职责/缺项/后续任务受影响 |
|
||||
| 知识与资料 | 上传、相关性判定、确认/拒绝、解析、切片、标签变更、挂载/摘挂、发布/撤销、结论确认/修订 | 来源、共享范围、引用它的章节/需求、索引及依据有效性 |
|
||||
| 文档 | 起草、提案、采纳/拒绝、编辑、版本化、提交、批注、审核、驳回、批准、撤回、导出 | 正文/版本/审签状态及受影响引用,原件和输出证据 |
|
||||
| 需求/风险/测试/追溯 | 条目增改、分解、候选边、确认/废止、端点升版、风险控制、测试执行/结果登记、基线快照 | 直接/间接影响、失效关系、验证缺口与待复核范围 |
|
||||
| 权限与成员 | 成员加入/移除、角色/职责/权限变更、拒绝访问、授权后的查看/下载/导出 | 当前与原有效权限/职责、受影响工作与可读范围,隐藏未授权正文 |
|
||||
| 智能体与后台工作 | 任务发起、模型/工具执行、获取上下文、确认等待、恢复、取消、重试、失败、完成、投递 | 发起人/执行主体、实际输入依据、输出对象、结果、错误与未完成项 |
|
||||
|
||||
这里只定义与本项目工作有关的操作覆盖,不把每次鼠标 hover 等 UI 噪声当业务操作;同一次后台重试保留尝试信息但不重复宣称业务生效。
|
||||
|
||||
### 7.2 记录字段与事实语义
|
||||
|
||||
- 时间:发生、开始/结束、提交/生效、确认与失败时间(适用时),统一保存明确时区/精度,页面按用户时区展示;未知值写未记录。
|
||||
- 人物:稳定用户 ID、当时显示名/角色/职责、发起人与执行主体、智能体/任务/run、确认/审核/批准者;账号改名后历史身份仍可辨认,系统动作和人工动作可区分。
|
||||
- 定位与操作:项目、请求/操作/批次/关联任务/会话的受控引用,动作类型、对象类型/ID/标题/路径、作用范围、预期版本、实际前后版本、幂等键/因果链。
|
||||
- 内容与依据:操作前后字段或结构差异、不可变原文/版本引用及哈希、原因与用户意见、模板ID/版本/hash、知识/文件/章节/表格锚点;网络来源保留URL、查询词、检索时间和具体引用;模型相关动作保存可用的模型/工具与输入依据引用。
|
||||
- 结果与影响:成功/失败/拒绝/取消/待确认/部分完成的真实状态,错误类别、实际已发生效果、直接/间接影响对象、需要重审/重做/补证的条目及影响分析的版本/范围。
|
||||
- 记录完整性:schemaVersion、完整操作批次、seq/commit水位、可信执行来源及缺项。历史没记录的字段不靠当前值或模型补造。
|
||||
|
||||
成功结构变更与相应事件必须一致提交;失败/拒绝/取消属于操作尝试,不能插入“已生效”的结构事件去伪造结果。跨库/跨宿主记录要保留真实投递状态和恢复链路,具体事务与尝试日志实现由方案阶段确认。公开 DTO 与内部重放 payload 分开,敏感值、凭据、未授权原文不随审计摘要泄漏。
|
||||
|
||||
### 7.3 页面可读结果(示例,非真实审计记录)
|
||||
|
||||
> **某成员于 10:42 调整了“设计输入 / 用户需求 / 使用环境”**
|
||||
> 操作:将“门诊场景”移至“医院使用场景”;依据:已确认会议结论与用户需求模板。
|
||||
> 变更:父节点从“补充资料”变为“医院使用场景”,知识正文保持同一不可变来源。
|
||||
> 确认:另一名具备该动作权限的成员确认,结构版本 8 → 9,结果“已生效”。
|
||||
> 影响:2 份相关文档、3 个需求条目需要复核;其中 1 个已批准章节的依据发生变化。
|
||||
> 展开:前后差异 / 来源依据 / 当时影响 / 当前关联 / 有权限的对象详情。
|
||||
|
||||
默认以一次业务操作展示一张摘要或一行时间线,中文动作、人名、对象名称/路径、时间和结果直接可读。展开为可比较的前后字段、原因、确认链、内容引用与影响对象列表;需要更多证据时再打开现有唯一文件预览。技术操作码、原始 JSON/base64 payload、数据库记录不作为页面的业务记录展示,也不能用通用 AI 生成未经证实的审计解释。
|
||||
|
||||
按时间、人物、业务动作、对象、结果和任务筛选;重试/批次按一次操作归组,操作跨页时仍可完整展开。新旧项目、账号或历史水位切换必须丢弃迟到响应。历史模式提供可读时间/正式版本选择,完整批次截止语义仍保留。已废止对象可审计,但是否能看历史正文仍取决于当前权限。页面只消费 `DESIGN.md` 的令牌、MotionKit、Collapsible,沿用现有四入口、三栏与唯一预览。
|
||||
|
||||
## 8. 候选子需求清单(供阶段1评审;不是已批准需求表)
|
||||
|
||||
| ID | 需求 | 可判定成功条件 | 来源 |
|
||||
|---|---|---|---|
|
||||
| TT-T01 | 完整登记44份最新Word模板,保留原文件/哈希/格式与阶段用途 | 44份均有解析结果或明确阻塞,不以占位骨架计为标准模板完成 | 当前请求、.templates |
|
||||
| TT-T02 | 内容要求覆盖多级章节、表格字段、重复块、附件与填写约束 | 逐模板对照不丢必需项,示例不进入项目事实 | 模板、《08》§三、C-08 |
|
||||
| TT-T03 | 按产品/项目适用性选择并确认内容 | 软件/硬件/无菌等不同项目的必需/可选/不适用项目可解释、可追溯 | 当前请求、模板说明 |
|
||||
| TT-T04 | 模板定义、实例、文档版分别绑定版本 | 升级预览差异,确认后应用;旧实例可回查原模板hash | 模板、既有模板方案 |
|
||||
| TT-N01 | 项目知识、来源、结论与问题完整组织 | 知识唯一ID、多挂载、来源可定位,结论取代与软删除可回放 | 《08》§二、§十、R1–R5 |
|
||||
| TT-N02 | 项目自有阶段/主题/工作事项/类型扩展 | A项目扩展不污染B项目,两个树的标签语义一致且有版本 | 当前请求、《08》§四 |
|
||||
| TT-D01 | 文档树支持稳定ID与递归内容结构 | 移动/重命名后ID及引用保持,重复表格与附件可表达 | 当前请求、44份模板 |
|
||||
| TT-D02 | 动态结构提案、差异、确认/拒绝 | 确认前有效树不变;接受/拒绝可审计且重启后保存 | 本轮 DYN-01 |
|
||||
| TT-D03 | 并发、原子保存、幂等、故障恢复 | 旧版本写入拒绝;事件中途失败零部分结构;重复确认不生成双份 | 《08》§十五、既有U2合同 |
|
||||
| TT-D04 | 受控正文与结构变更不绕过审签 | 已批准正文需既有重审;普通结构确认不自动批准文档 | 现行三权、J-04 |
|
||||
| TT-G01 | 一般来源与受控合规链均可追溯 | UN/SR/DI/设计/测试及风险/软件链可按版本查看,候选/缺项明确 | 最新模板、《08》§十六 |
|
||||
| TT-G02 | 端点升版与关系影响可复核 | 旧关系不宣称新版有效,直接/间接影响及分析水位可辨认 | 《08》、C-01 |
|
||||
| TT-G03 | 来源主体与证据锚点完整 | 人工/规则/模型、模板、网络、知识引用分别可定位 | 《08》§十、SR-D6 |
|
||||
| TT-C01 | 日常工作自动获得项目结构与依据 | 普通成员无需@knowledge;实际模型输入含当前项目任务相关依据 | 当前请求、SR-G10/G11 |
|
||||
| TT-C02 | 任务相关检索与渐进上下文 | 不全量读全部文档;素材、模板要求、冲突、缺项和截断有说明 | C-08/C-09、J-07 |
|
||||
| TT-C03 | 共享与私域及当前权限闭环 | 跨成员只取已授权共享/职责正文;跨项目/撤权后不泄漏 | 现行 IAM、私域合同 |
|
||||
| TT-C04 | 上下文依据与版本可审计,恢复时刷新 | 记录实际输入ID/版本/水位;恢复不继续用撤权或失效依据 | 当前请求、行为面验证要求 |
|
||||
| TT-A01 | 覆盖结构/内容/关系/权限/智能体各类操作 | 操作覆盖矩阵每格有记录或明确不适用,不虚报全量 | 当前请求、SR-G3 |
|
||||
| TT-A02 | 时间、人物、操作、内容、影响完整 | 具备§7.2字段及缺项标识,能定位前后版本与确认链 | 当前请求、《08》§八/十/十四 |
|
||||
| TT-A03 | 成功和失败/拒绝/取消语义准确 | 失败保留尝试及实际副作用,不能成为已生效事件 | 当前请求、R4/R5 |
|
||||
| TT-A04 | 宿主/后台关联及历史诚实出口 | 真正关联操作/run,无法取得的面标明未覆盖,旧信息不补造 | 现有inspection coverage |
|
||||
| TT-U01 | 审计自然语言摘要与结构化详情 | 无内部op码/原始payload冒充业务记录,用户可读前后差异与影响 | 当前请求、DESIGN.md |
|
||||
| TT-U02 | 来源/影响对象和证据可读可跳转 | 人可识别标题/路径/关系含义,进入权限内详情及唯一文件预览 | 旧追溯方案、《08》 |
|
||||
| TT-U03 | 可读筛选、完整归组、分页及历史查看 | 时间/人物/动作/对象/结果可筛,跨页操作不拆失,迟到响应丢弃 | 当前请求、异步/seq规则 |
|
||||
| TT-U04 | 审计动作与正文权限分离 | metadata/差异/历史/导出统一披露规则,audit.read不自动赋予正文权 | 当前 IAM、隐私合同 |
|
||||
| TT-V01 | 模板/结构/重放与故障有需求到证据映射 | 固定候选和精确pins;正常、并发、失败、重启场景可重放 | 根AGENTS、verification |
|
||||
| TT-V02 | 真实模型任务级前后对照 | 同项目成员普通工作展示实际依据使用、召回/错误引用/失效处理结果 | policy/delivery.md 行为面验证 |
|
||||
| TT-V03 | 真实浏览器和当前HEAD CI验收 | 两项目两成员流程、审计可读性、动态提案确认与权限回归验证 | 用户目标、交付门禁 |
|
||||
|
||||
## 9. 边界、尚待确认事项与接续
|
||||
|
||||
本次增量围绕标准模板接入、动态两树一网、成员工作上下文与完整可读审计;复用既有项目/IAM、知识发布、受控合规图、审签与审计入口。团队存储架构替换、平台身份重构、飞书发布、法规定版和线上服务变更不由此次请求自动扩展授权。
|
||||
|
||||
仍需后续设计明确:新模板七阶段与现有14阶段的映射;44个资产与69既有类型及新细分类的绑定;示例/固定文本及DOC样式解析;现有项目的升级预览和历史资料适用性;普通成员工作读取面与audit.read差异;默认上下文预算及相关性排序;宿主/失败尝试审计的公开扩展能力。明确待核实,不预写“已就位”。
|
||||
|
||||
按 `policy/delivery.md`,目前仅阶段1需求拆解产物可评审,阶段2–7及10没有本任务人工结论。本轮动态方式已确认。用户可按阶段评审;若明确授权连续推进,须记录对应阶段、允许动作、终点与停止条件。无法取得当前HEAD CI/独立平台批准、基座发版tag必须由用户执行、出现模板或数据身份冲突、需要线上迁移/部署时,按实际边界停止受影响工作。
|
||||
|
||||
建议接续顺序仅用于解释依赖,不构成实施计划已批准:先完成源材料和内容绑定;再明确项目扩展/结构提案与版本合同;随后将工作上下文、写操作审计和可读展示沿真实链路串通;最后固定组合完成模板对照、故障重放、真实模型/浏览器及当前HEAD CI。远端在途任务重叠尚未重新核验,阶段2须核对,不能重复实施已经交付或在途的范围。
|
||||
|
||||
写入准入前需要工作区owner保存并处理现有gitlink漂移/分支现场,再使用新唯一收据重跑启动检查至READY并从origin/main建立登记任务工作区。本任务不代替owner声明“所有写者已退出”。源码外主记录/台账届时导入 `modules/documents/docs/proposals/` 并在 PROJECT.md 及任务卡引用;本记录不声称已完成仓内留存。
|
||||
|
||||
## 附录A. 44份模板逐文件候选绑定
|
||||
|
||||
此表是需求调查候选,所有新类型名称与阶段映射尚未批准;现有类型不存在时显式标出,不以类似名称假装已覆盖。未提供标准模板的既有69类条目保留并标缺项,不以44份替换后声称全部模板完成。
|
||||
|
||||
| # | 来源文件(均在`.templates/DHF 文件模板/`) | 阶段目录 | 候选docType | 注意事项 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 0.1初始要求申请表.docx | 0. 商务阶段 | `bd_intake` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 2 | 1.1、731QCP29-F01 项目建议书 02.docx | 1. 策划阶段 | `rd_proposal` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 3 | 1.2、731QCP29-F02 设计开发计划任务书 02.docx | 1. 策划阶段 | `rd_design_plan` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 4 | 1.3、731QCP29-F07 设计开发(策划)评审记录 02.docx | 1. 策划阶段 | `rd_planning_review` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 5 | 2.10.1、731QCP29-F13 配置管理计划 02.docx | 2. 设计输入阶段 | `rd_sw_config` | 现有类型合并配置与维护,计划/报告不得混用 |
|
||||
| 6 | 2.10.2、软件维护计划模板.docx | 2. 设计输入阶段 | `rd_sw_maintenance_plan` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 7 | 2.11.1、731QCP29-F16设计输入规格书模版.docx | 2. 设计输入阶段 | `rd_design_input_spec` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 8 | 2.12、731QCP29-F05 设计开发输入清单 02.docx | 2. 设计输入阶段 | `rd_design_input_list` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 9 | 2.13、RDDHF0213-xxxx产品系统设计方案.doc | 2. 设计输入阶段 | `rd_system_design` | DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 10 | 2.14、731QCP29-F07 设计输入评审记录.docx | 2. 设计输入阶段 | `rd_input_phase_review` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 11 | 2.1、731QCP29-F14 用户需求模板.doc | 2. 设计输入阶段 | `rd_user_needs` | DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 12 | 2.2、RDDHF0202-xxxx 医疗器械法规和标准清单.docx | 2. 设计输入阶段 | `rd_regs_stds` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 13 | 2.3、RDDHF0203-xxxx 同类产品不良事件信息.docx | 2. 设计输入阶段 | `rd_adverse_events` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 14 | 2.4、731QCP29-F15 系统需求规格书模板.doc | 2. 设计输入阶段 | `rd_system_reqs` | 与 pm_system_reqs 的边界需明确,不能默认按 YAML 顺序选取;DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 15 | 2.5、731QCP29-F07 需求评审记录表.docx | 2. 设计输入阶段 | `rd_req_review` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 16 | 2.6、731QCP29-F03 风险管理计划 02.docx | 2. 设计输入阶段 | `rd_risk_plan` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 17 | 2.7.3、731QCP29-F04 风险管理报告 02.docx | 2. 设计输入阶段 | `rd_risk_report` | 新模板属输入阶段;现有类型归输出阶段,阶段口径需确认 |
|
||||
| 18 | 2.8、731QCP29-Fxx 软件开发计划-模板.doc | 2. 设计输入阶段 | `rd_sw_plan` | DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 19 | 2.9、软件需求规格书模板.docx | 2. 设计输入阶段 | `rd_sw_reqs` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 20 | 3.12、原材料进货检验规范-模版.docx | 3. 设计输出阶段 | `rd_incoming_iqc` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 21 | 3.15、产品技术要求.doc | 3. 设计输出阶段 | `rd_tech_req` | DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 22 | 3.17、731QCP29-F06 设计开发输出清单 02.docx | 3. 设计输出阶段 | `rd_design_output_list` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 23 | 3.18、731QCP29-F07 设计输出评审记录.docx | 3. 设计输出阶段 | `rd_output_review` | 四份阶段评审模板字节相同;保留阶段独立用途 |
|
||||
| 24 | 3.6.2、软件详细设计模板.docx | 3. 设计输出阶段 | `rd_sw_detail_design` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 25 | 3.8、RDDHF0213-xxx采购技术说明-结构&硬件.doc | 3. 设计输出阶段 | `rd_purchase_spec` | DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 26 | 3.9.1、731QCP29-Fxx 工艺流程图模板.doc | 3. 设计输出阶段 | `rd_process_flow` | DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 27 | 3.9.2、RDSOP00xx-00xx xxx作业指导书.docx | 3. 设计输出阶段 | `rd_work_instruction` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 28 | 731QCP33-F01 软件可追溯性分析报告 02.docx | 3. 设计输出阶段 | `rd_sw_trace_report` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 29 | 24.产品有效期验证.doc | 4. 设计验证阶段 | `rd_lifetime` | 使用期限与货架寿命须按正文及适用范围确认;DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 30 | 41.软件单元测试用例-模板.doc | 4. 设计验证阶段 | `rd_sw_unit_test` | 测试用例与测试结果分实体,报告绑定用例及被测版本;DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 31 | 42.软件集成测试用例-模板.doc | 4. 设计验证阶段 | `rd_sw_integration_test` | 现有类型未区分;需新增或评审 subtype;DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 32 | 43.软件系统测试用例-模板.doc | 4. 设计验证阶段 | `rd_sw_sys_test` | 测试用例与测试结果分实体,报告绑定用例及被测版本;DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 33 | 49. 软件配置管理报告-模板.doc | 4. 设计验证阶段 | `rd_sw_config_report` | 现有类型未区分;需新增或评审 subtype;DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 34 | 731QCP29-F07 设计验证评审记录.docx | 4. 设计验证阶段 | `rd_verification_review` | 四份阶段评审模板字节相同;保留阶段独立用途 |
|
||||
| 35 | 731QCP29-F08 设计开发验证记录 02.docx | 4. 设计验证阶段 | `rd_verification_record` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 36 | 756QCP26-F02 验证确认报告 V03-.docx | 4. 设计验证阶段 | `rd_verification_validation_report` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 37 | 731QCP29-F04 风险管理报告 02.docx | 5. 设计转换阶段 | `rd_risk_report_t` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
| 38 | 731QCP29-F07 设计转移评审记录.docx | 5. 设计转换阶段 | `rd_transfer_review` | 四份阶段评审模板字节相同;保留阶段独立用途 |
|
||||
| 39 | 731QCP29-F09+试产总结报告+03-20250730.docx | 5. 设计转换阶段 | `rd_trial_production_report` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 40 | 53. 使用错误评估报告-模板zlx.doc | 6. 设计确认阶段 | `rd_use_error` | DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 41 | 731QCP29-F07 设计确认评审记录.docx | 6. 设计确认阶段 | `rd_confirmation_review` | 现有类型未区分;需新增或评审 subtype;四份阶段评审模板字节相同;保留阶段独立用途 |
|
||||
| 42 | 731QCP29-F11 设计开发确认记录 02.docx | 6. 设计确认阶段 | `rd_confirmation_record` | 现有类型未区分;需新增或评审 subtype |
|
||||
| 43 | 756QCP20-F01 计算机软件确认报告 02.doc | 6. 设计确认阶段 | `rd_sw_validation_report` | 现有类型未区分;需新增或评审 subtype;DOC 已提取主文字;表格层级、样式、图片仍需正式解析核验 |
|
||||
| 44 | 756QCP26-F01 验证确认方案 V03-.docx | 6. 设计确认阶段 | `rd_validation_plan` | 已有类型候选;内容要求与格式仍需逐项批准 |
|
||||
|
||||
## 附录B. 重点可复核源码与来源
|
||||
|
||||
- RDM:`internal/domain/{notetree,doctree,labels,eventlog,tracenet,compliance,conclusion}.go`、`internal/rdmapp/{templates,templates_gen,structure,inspection,inspection_visibility,compose,knowledge_publication,runtime}.go`、`plugins/rdm/plugin.go`。
|
||||
- Dev 固定实际检出:`modules/backend/internal/runtime/llm.go`、`modules/backend/internal/runmgr/memory.go`、`modules/backend/internal/ctxasm/ctxasm.go`、`modules/backend/internal/app/app.go`、`modules/frontend/src/components/RdmAuditWorkspace.tsx`;RDM实际 pins 中已核对初始知识注入入口相同。
|
||||
- 会议重点:`.tmp/Discussion-Meetings/2026-10-08_19-36/Outputs/{01,03,08,10,11,13}*.md`;旧期输出用于保留来源及裁定次序;ASR含转写噪声,不以未核实人名与数字建立正式业务事实。
|
||||
- 关联有效主记录:`modules/documents/docs/proposals/2026-10-11-rdm-two-trees-trace-audit-integration.md`、`2026-10-11-rdm-template-dialog-generation.md`、`2026-10-11-rdm-final-target-completion.md`、`2026-10-13-system-project-membership.md`;原U1–U5已有实施记录,本次是新增内容与能力补齐,旧报告不能替代本轮源核对。
|
||||
|
||||
后续评审与实现只在同一主记录续办,确认DYN-01不重问;其他未完成阶段、当前源码SHA、准入收据、模板绑定候选及NOT_RUN缺项一并保留。
|
||||
+1617
File diff suppressed because it is too large
Load Diff
+152
@@ -0,0 +1,152 @@
|
||||
# 两树一网阶段 2:需求评估 r1
|
||||
|
||||
状态:阶段 1 已获用户确认;本阶段 2 评估待人工评审。整体实现目标尚未完成。
|
||||
记录人:Codex;评审人/需求负责人:用户;记录时间:2026-10-14T03:54:21+08:00。
|
||||
授权方式:manual(按阶段人工评审)。共享Dev工作区由原负责人收尾并同步;本任务继续只读调查及源码外记录,没有接管、同步、创建任务worktree、修改业务代码、迁移或部署。
|
||||
|
||||
## 1. 已确认范围与本次评估对象
|
||||
|
||||
阶段1评审对象:[需求拆解 r1](rdm-two-trees-requirements-r1.md),SHA256:`60fd0296840a74982ae65cc4bd1e6a810ace5109e103e8408a94d4db0573bad7`。用户回复原话:**“确认需求,继续按阶段人工评审”**;现场处置原话:**“由原工作区负责人先收尾并同步”**。来源为本聊天 `request_user_input_async / call_22243aaf29ae4ad19c4322a1d7fd8b0f` 的第0、1项回复。确认的是阶段1需求拆解及后续流程,不是阶段2–7产物已批准。
|
||||
|
||||
已确认动态方式DYN-01:智能体提出结构变更,成员确认后应用。保持28个TT需求及44份新模板逐文件范围,不重新缩成固定三层树、部分模板、手动知识查询或仅审计文案翻译。未提供新标准模板的既有类型保留并明确缺项;不声称最新44个资产覆盖全部69个既有类型。
|
||||
|
||||
本阶段评估价值、可行性、工程和评审成本、风险、依赖、在途任务重叠及模块/公开契约符合度;不冻结新API、数据库迁移方案或实施计划。下一阶段仍须人工评审。
|
||||
|
||||
## 2. 评估结论与推荐取舍
|
||||
|
||||
**整体可行,建议在既有RDM领域能力上补齐完整链路;工程量高。** 现有两树、一般网/受控合规图、原子事件、重放、文档审签、发布授权及四入口审计工作区可复用。主要工作是细粒度模板/节点契约、项目扩展与结构提案、默认项目工作上下文、审计写入信息与读投影,而不是只增加树的显示。
|
||||
|
||||
建议保留全部已确认需求,按可验证增量实施,完整目标不因分批而缩小。先解决模板完整接入和结构/版本依赖,再将成员上下文、操作审计及人可读展示接成真实流程;既有权威数据和权限边界保留。准确顺序、实施单元、接口和测试环境在阶段4–5定稿,本阶段只评估依赖。
|
||||
|
||||
| 路线 | 对目标的满足程度 | 成本/风险 | 推荐结论 |
|
||||
|---|---|---|---|
|
||||
| 复用现有RDM结构、事件、发布和审签;补细粒度契约及必要公开扩展 | 能覆盖44模板、项目动态扩充、成员工作依据及完整可读审计 | 局部领域数据演进、基座扩展/发版依赖、真实模型与组合验收成本较高 | 推荐,进入后续需求表与设计 |
|
||||
| 只导入标题和若干表格,再翻译审计op码 | 无法覆盖多级内容、动态确认、实际上下文和完整操作影响 | 代码量低,但留下用户明确提出的主要缺口 | 不作为本目标交付路线 |
|
||||
| 重写两树/图存储和项目/权限体系 | 可重新建模,但与已交付能力大量重叠 | 迁移和历史保真风险最大,会拖入无关体系替换 | 当前无证据需要全面重写,不推荐 |
|
||||
|
||||
## 3. 当前主干事实、基线与证据等级
|
||||
|
||||
本次使用已验证的Gitea只读API,按完整main SHA读取不可变文件。七仓开放PR清单已分页读取,十个相关PR进一步核对了变更文件并在读取前后核验head一致。清单和源码复制为 **SELF** 调查证据,不是CI/GATE或独立代码Review通过。
|
||||
|
||||
| 仓库 | 本次API核验的main SHA | 当前开放PR数 |
|
||||
|---|---|---|
|
||||
| Agent-System-Backend | `5d5fc9891c0eb8994545ccb8b740535d9b99fb0e` | 3 |
|
||||
| Agent-System-Dev | `add097d06137c4912a4ed9279e98ca353e4e4cf1` | 6 |
|
||||
| Agent-System-Documents | `a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c` | 2 |
|
||||
| Agent-System-Frontend | `eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b` | 2 |
|
||||
| Agent-System-RDM | `6fcb256205c2384abed35d3b6ab96ca7216e9297` | 2 |
|
||||
| Agent-System-UI | `2c4322ef56df64ad72f65907d25b048a74bb5ffc` | 1 |
|
||||
| Development-Guidelines | `2f5b19872be2a4597838a4131ad75d1be089ee5e` | 0 |
|
||||
|
||||
来源:[主干与PR快照](stage2-sources/remote-snapshot.json)、[相关PR变更文件快照](stage2-sources/overlap-snapshot.json)、[额外固定源码](stage2-sources/extra-source-snapshot.json)。核验时间以各快照 `checkedAt` 为准;正式启动/验收时必须再获取权威目标,不能把此快照当未来main。
|
||||
|
||||
复核的RDM/Backend/Frontend主要业务文件与本地实际检出逐字节相同;Dev PROJECT/delivery及Documents索引存在差异,当前共享检出仍停留在旧任务分支。远端和当前检出的delivery规则都保留阶段1–7人工评审;本轮按用户给定AGENTS与已确认manual授权执行,不擅自切换规范。
|
||||
|
||||
**对阶段1源码判断的补充**:运行时字典已有持久化加载,优先读库内最新字典、缺失时才读种子;Runtime仍持有一个 `Dict` 并交给各项目World。故不能把“有持久化字典”当作“已有每项目独立扩展”。文件种子69类型/14阶段/9主题的数量,只证明该种子资产,不代表当前运行库实际词条数;本阶段没有读运行数据库。
|
||||
|
||||
内置解析器对旧DOC明确“不解析”,本轮14份DOC仍需要正式转换/解析路径。Microsoft提供独立的DOC二进制格式规范,因此将DOC当XML或仅提取可见文本不能证明表格/样式完整。[Microsoft MS-DOC规范](https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-doc/ccd7b486-7881-484c-a137-51170af7cc22)。这影响TT-T01/T02的可行性验证,不能跳过。
|
||||
|
||||
## 4. 28项需求的价值、可行性与符合度
|
||||
|
||||
工作量为相对评估,**不是工期或成本承诺**。高=同时涉及数据、写路径/恢复、权限或公开扩展;中=可局部复用但仍需明确契约和真实验证。当前实现缺口与要求符合度分别记录,源码存在不代表运行可用。
|
||||
|
||||
| 需求组及全部ID | 价值与现有基础 | 可行性/主要缺口 | 符合度 | 相对工作量 |
|
||||
|---|---|---|---|---|
|
||||
| TT-T01、TT-T02、TT-T03、TT-T04 | 用真实模板约束内容与格式;已有注册表和目录资产 | 44份资产逐块解析、适用性、固定版本/hash、实例绑定;14DOC完整性未验证,生成骨架不能算标准模板 | 需调整后符合;DOC路径待验证 | 高 |
|
||||
| TT-N01、TT-N02 | 将资料、结论与依据组织为共同项目知识;已有切片、多挂载、结论/取代 | 现有共用Dict改为具有明确项目作用域的扩展合同;阶段/工作事项/主题有版本和审计,旧数据保真 | 需调整后符合 | 中–高 |
|
||||
| TT-D01、TT-D02、TT-D03、TT-D04 | 不同项目按进展调整,且人确认后才生效;已有DocTree、状态机、TxProject | 递归内容块、稳定ID、结构提案/CAS/幂等、移动/更名/废止、审签影响;不能按标题当身份 | 需调整后符合 | 高 |
|
||||
| TT-G01、TT-G02、TT-G03 | 能回答事实来源、合规证据链及影响;已有一般网与受控版本网 | 最新UN/SR/DI/设计/测试模板字段与现有15类受控节点映射;版本端点、直接/间接影响、来源主体与锚点 | 符合领域定位;映射需调整后符合 | 中–高 |
|
||||
| TT-C01、TT-C02、TT-C03、TT-C04 | 让每个成员的日常工作基于项目最新有效依据;已有发布台账、检索/资源授权与Compose | 普通对话的自动项目依据入口、上下文预算/版本manifest、恢复/撤权刷新;个人Memory与@knowledge不能替代 | 需调整后符合;公开入口需核对/申请 | 高 |
|
||||
| TT-A01、TT-A02、TT-A03、TT-A04 | 完整记录时间、人物、操作、内容、结果和影响;已有结构事件、操作ID/outbox、宿主命令审计 | 成功事件与失败尝试分语义、前后值/来源/当时影响、人物/任务关联、宿主项目级读面及披露、历史缺项诚实显示 | 需调整后符合;宿主读面待设计 | 高 |
|
||||
| TT-U01、TT-U02、TT-U03、TT-U04 | 无需理解数据库或内部代码即可取证;已有四入口和唯一文件预览 | 业务操作摘要/结构化差异/对象名称/影响、可读筛选/历史、完整归组和按字段授权;不新增独立管理屏 | 符合DESIGN布局;读契约需调整后符合 | 中,受上游数据契约制约 |
|
||||
| TT-V01、TT-V02、TT-V03 | 防止模板数量、mock和页面存在被误当用户目标已完成 | 44份对照、并发/失败/重启/撤权;两项目两成员真实模型与浏览器;精确pins及当前HEAD CI | 符合交付规则;本次业务验证NOT_RUN | 高 |
|
||||
|
||||
上述组覆盖28项已确认子需求,没有把高成本项移出本目标。最终优先级与处理结论在阶段3需求表确认,不由本阶段表格自动批准实施。
|
||||
|
||||
## 5. 成本、依赖与模块归属
|
||||
|
||||
### 5.1 成本依据
|
||||
|
||||
- 模板资产:44份逐文件内容核对,候选绑定涉及32个既有类型和12个新增/细分用途;这不是12个类型已经决定新增。其余37个既有类型本次没有对应的新标准资产,须保留兼容或缺项状态。
|
||||
- 文档结构:仅30份DOCX就有 **199个表格对象、1504行、5731个含文字段落、809个标题候选**。计数包括封面、签署、目录、示例与重复内容,不等于正式要求数量;说明不能按几个H2批量生成替代语义核对。14份DOC的正式表格/格式规模尚未计入。
|
||||
- 数据与恢复:涉及项目字典作用域、结构/内容版本、提案与确认、事件schema、重放、历史/导出截止和旧对象绑定。需要迁移/兼容与故障验证,不能按“只增加几个字段”估计。
|
||||
- 公共链路:至少要评估自动项目工作上下文与宿主项目审计读取两个通用能力接缝,必要时还包括可信人物显示信息。下游不能直接读取Backend internal表,也不能给审计用户广泛账号管理权限。
|
||||
- 真实验收:多人多项目、不同文档职责、撤权、恢复与模型实际依据使用都需要准备真实场景和可核查记录。模型样本数量、预算及正式测试环境在阶段5由用户批准;当前没有调用付费模型。
|
||||
|
||||
成本控制采用现有域模型/事务/读面、沿用四入口与唯一预览、复用在途导出/工作摘要、给模型短摘要后按相关性展开;不会通过取消递归结构、只处理少量模板或让用户手动@knowledge来降低成本。
|
||||
|
||||
### 5.2 依赖与归属
|
||||
|
||||
| 能力/接缝 | 主归属 | 现有可复用点 | 必须完成的评估/设计条件 |
|
||||
|---|---|---|---|
|
||||
| 标准模板语义、适用性、schema、发布和实例绑定 | RDM;原始材料来自Dev `.templates` | `templates.go/templates_gen.go`、DocTree、版本/审签 | 先保全原件与hash;发布结构须可审,不凭文件名替换现有docType |
|
||||
| 项目字典、递归结构、结构提案和影响 | RDM领域与应用层 | `WorldFor`、一般/受控图、`TxProjectOp`及事件重放 | 同项目生效版本唯一;跨项目互不污染;固定对象与受控状态重新鉴权 |
|
||||
| 普通工作自动取得项目依据 | RDM提供领域摘要/引用/权限,Backend负责通用注入/恢复/预算 | `Host.KnowledgeSearch`、已发布台账、检索资源授权、ctxasm/运行记忆端口 | 先确认现有注册组合能否满足;不足则在Dev申请可选公开能力,不能导入internal或直接改个人记忆表 |
|
||||
| 结构审计、前后变化、影响与人可读投影 | RDM | 事件日志、operationId、inspection读服务 | 公共DTO与重放payload分离;成功与失败尝试区分;历史不补造字段 |
|
||||
| 宿主命令/后台动作与项目审计关联 | Backend通用能力 + RDM领域读适配 | owner作用域命令审计、Host.Audit、outbox | 需要受信项目/主体/资源及字段披露合同,不能拿全owner审计列表当项目审计 |
|
||||
| 审计与成员工作界面 | Frontend消费确定读契约;UI消费既有原语 | RdmAuditWorkspace、三栏、现有文件预览、tokens/MotionKit/Collapsible | 显示中文动作、人名/可辨账号、对象路径、差异/影响;不向客户端下发受限正文后再隐藏 |
|
||||
| 公共扩展、tag与组合交付 | Dev/Backend/Frontend及RDM按各仓规则 | `pkg/extension`、可选接口惯例、pins/checks | 扩展申请四要素、兼容/隔离;基座tag发布仍由用户亲手执行;不能让RDM合入main时长期依赖未发布本地分支 |
|
||||
|
||||
本轮不会把项目/IAM、任务系统或通用数据存储整体替换。在本次复核的公开面中未找到项目上下文Provider和项目级宿主审计查询;具体符号或路径仍是阶段4设计问题,尚未批准新API。
|
||||
|
||||
## 6. 在途任务与重叠处理
|
||||
|
||||
以下是本次API读取时的真实开放状态,均 `merged=false`;不是“已经合入”。读取的PR head在文件清单核对前后保持一致。仅作依赖/重叠评估,不把PR说明、审批或CI声明当现行主干能力。
|
||||
|
||||
| 在途范围 | 已核验的PR与主要文件 | 与本目标关系及处理建议 |
|
||||
|---|---|---|
|
||||
| 审计导出/水位固定 | RDM #301:persist、export_artifact/report、cgraph_export、xlsx、plugin;Frontend #73:RdmAuditWorkspace/store/styles/workspaces;RDM #307、Dev #488负责pin消费 | 与TT-A/U/G历史取证、DTO、分页/导出语义耦合;优先复用该候选最终主干结果,设计阶段保留同一水位与授权模型,不能重复起另一套导出入口 |
|
||||
| 快慢通道有依据的工作判断/来源 | Backend #193、Frontend #79、Documents #95、Dev #512:runtime/runmgr/上下文相关执行、任务来源、卡片/预览/contract | 与TT-C/A/U的任务依据、来源manifest、进度和显示重叠;复用其可信来源与同一任务卡,不能把未确认发现自动变成已确认项目知识;本次结构确认仍单独持久化 |
|
||||
| 历史方案/交付状态回填 | Documents #89、Dev #489:原两树方案及恢复/账号方案状态 | 主要是文档状态重叠;本轮新需求记录与原方案的状态更新须协调,不能用旧正文或索引表示本目标已完成 |
|
||||
| 账户事务与活动实例保护 | Backend #185、Dev #486/#482 | 对真实身份/审计/验收环境有依赖影响;不会重复实施账户事务、替换当前身份或操作运行实例 |
|
||||
|
||||
- [Agent-System-Backend #193](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193):`5f834544b0b808cb16214a36725f2ae3cb90bfd4`
|
||||
- [Agent-System-Dev #488](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488):`334d2e2375095f3b4160ab232296f9c92065c565`
|
||||
- [Agent-System-Dev #489](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489):`3e7f0360087b126f41fa9ce18dbd1e53d0a8f067`
|
||||
- [Agent-System-Dev #512](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512):`e31443a8ff1f099f9b2ef320c295b0ddcdaf503d`
|
||||
- [Agent-System-Documents #89](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89):`b8df6f3c2a3180b06c61d2303bbfea9a3914f186`
|
||||
- [Agent-System-Documents #95](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95):`c7cb2d8d89aaef0329c9a8a2045fcd42abb36e39`
|
||||
- [Agent-System-Frontend #73](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73):`d9bb780384b16f661d71a5e6ad288a77426d9d98`
|
||||
- [Agent-System-Frontend #79](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79):`006c81567546deb1cbd95abbb7ca6a36f99241b2`
|
||||
- [Agent-System-RDM #301](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301):`6252f62524ef34360fdcdf8844d7e729378ffbfb`
|
||||
- [Agent-System-RDM #307](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307):`8ae52a6d9a4d8b60e875f9c56862f34dffed7705`
|
||||
|
||||
补充源码核对:Frontend #73候选主要新增概览导出,但其 `EventRow` 仍显示 `ev.op`、actor及截断detail;所以该在途工作并不覆盖本次“详细可读操作记录”。Documents #95候选设计将模型发现与可信依据/待确认判断分开;这是相关约束,不能将其“已批准设计”叙述升级为本轮模型验证或主干已交付能力。
|
||||
|
||||
没有看到上述开放清单中直接实现“44个新标准资产、项目字典独立扩展、递归结构提案、默认两树一网上下文、完整审计投影”的PR。此结论限于已核验的开放PR标题、变更文件与两份候选源码,不代表所有未推送工作都不存在;阶段5启动仍须与当前任务和新main重验。
|
||||
|
||||
## 7. 风险与处理边界
|
||||
|
||||
| 风险 | 影响 | 建议处理 | 当前状态 |
|
||||
|---|---|---|---|
|
||||
| 旧DOC转换只保留文字,丢表格、图片、样式及蓝字示例含义 | 44份标准模板完整性无法成立 | 先做E1受控解析/转换试验;每份有可核查差异台账,缺项不计完成 | 重大未知,E1待批准、NOT_RUN |
|
||||
| 目录7阶段、既有14阶段及12个细分用途语义冲突 | 权限阶段被误映射、计划/报告或验证/确认混用 | 阶段3列逐项适配;阶段4冻结stage/type用途映射与版本 | 待设计;不凭目录名批量覆盖 |
|
||||
| 全局库字典与各项目自由扩展混用 | A项目新增词条改变B项目或旧历史读取 | 项目作用域与版本权威、旧字典兼容/回放必须明确 | 源码缺口已确认 |
|
||||
| 结构/正文确认同名不同版或并发修改覆盖 | 丢资料、半次操作、审签与影响错位 | 预期版本、整批事务、幂等、失败恢复及重放;基线正文仍受审签 | 机制可复用;新操作未实现 |
|
||||
| 所有成员上下文走audit接口,或共享结构顺带读他人私域 | 普通工作被多余审计权限阻塞,或发生越权 | 工作读面/审计/正文/原件分别服务端授权;历史及恢复按当前权限 | 需补新读合同,不能放宽audit/read为捷径 |
|
||||
| 自然语言审计只是前端翻译或模型自由重述 | 人物、内容、影响不完整或凭空产生结论 | 以持久业务事实产生确定摘要/结构化详情,未知显式未记录,候选与生效分开 | 当前DTO字段不足 |
|
||||
| 已有项目升级直接重生成或自动替换模板 | 历史ID/内容/审批依据丢失 | 预览+显式确认,保全原版本、原件及取代关系;不能线上自动迁移 | 本轮迁移NOT_RUN |
|
||||
| 在途PR/main或tag前进,使证据/组合失效 | 新候选错用旧CI,或RDM消费未发布基座 | 当前HEAD、来源和pins重验;tag双钥匙,实施/部署授权分别记录 | 阶段5–9门禁,不在本轮执行 |
|
||||
|
||||
## 8. E1受控试验提案(本次只写计划,未执行)
|
||||
|
||||
目的:回答“能否完整解析/转换本轮14份DOC的内容结构与关键格式,从而为44份新模板建立可靠内容契约”。此试验不实现产品功能,也不批准业务代码、共享现场写入、数据迁移或部署。
|
||||
|
||||
- **对象**:来源台账中固定hash的14份DOC;30份DOCX只作结构/样式对照,原件只读。先用用户需求、软件测试用例、采购技术说明三种复杂度不同的样本判断方法,再覆盖全部14份;样本成功不计整体通过。
|
||||
- **环境**:独立临时目录和独立转换器profile,原件只读挂载,输出留在源码外,禁止运行文档宏和访问外部文档链接;转换进程不获得仓库/用户secret/运行库的写入或读取权限。试验所需软件优先使用已有可用能力;如确需获取,限可核验来源的隔离临时运行环境,不全局安装或修改服务。未能建立此环境则停止并报告缺项。
|
||||
- **候选方法及依据**:优先验证LibreOffice headless导入DOC、导出DOCX,然后用OOXML提取章节/表格/样式/图片/页眉页脚/编号。其官方文档列出无界面转换、独立profile以及Word97–2003与DOCX过滤器;这是方法可行性依据,不证明本轮模板保真。[命令参数](https://help.libreoffice.org/latest/en-US/text/shared/guide/start_parameters.html)、[格式过滤器](https://help.libreoffice.org/latest/en-US/text/shared/guide/convertfilters.html)。当前PATH未找到LibreOffice,不能预写工具已就绪或依赖版本。
|
||||
- **判据**:全部14份都有原件hash→转换器版本/参数→产物hash→内容/表格/合并关系/示例与固定文本/图片/关键格式核对结果;关键要求、表格列/合并和示例语义零静默丢失;差异有可查看依据及处理结论。输出非空、文字数量或转换器exit0不能作为通过。原件前后hash相同。最终输出保真要求若有调整须人工评审,不能以试验失败自行降低。
|
||||
- **限制**:转换与自动核对最多60分钟;每份转换最多120秒;不调用付费模型、不上传材料到外部服务;遇宏/密码、损坏、不可定位字段或环境无法隔离即停止相应路径,保留证据。剩余人工格式确认的时间另行列明,不假装60分钟包含全部人工审批。
|
||||
- **副作用与成果**:只创建可识别的临时转换产物、比较报告和SELF收据;原始模板及现有项目零修改。产物留在当前源码外记录目录供审核,未确认前不作为正式发布模板;回收临时环境先核对唯一成果已保存。
|
||||
|
||||
仅E1被明确批准后才运行;其结果用于阶段3–4的模板边界和方案设计,不代替正式产品验收。若用户选择先进入阶段3需求表,DOC完整性保持待核实,不能宣称已具备或在关键待核实项未处理时放行正式实施。
|
||||
|
||||
## 9. 当前出口与下一动作
|
||||
|
||||
本阶段已形成可评审的取舍与依赖记录:保留28项完整范围;推荐复用现有领域/平台而补齐缺口;不重写项目/权限体系;旧DOC路径通过E1验证;现有结构、数据与三权版本保真;在途导出/工作发现接口协调复用;必要通用能力按公开扩展申请推进。
|
||||
|
||||
**等待用户评审阶段2评估和E1范围**。推荐确认取舍并批准源码外E1试验,试验完成后形成阶段3需求表;也可以确认评估、先整理需求表而保留E1待批准。两个选择都保持manual授权和共享现场由原负责人收尾,不重新询问DYN-01或阶段1范围。
|
||||
|
||||
阶段4方案、阶段5实施/测试计划、阶段6–7产物及验收仍未评审;代码Review/PR合入按既有阶段8–9门禁,清理另审。软件测试、模型对照、浏览器、CI、转换试验、生产数据操作和部署本轮全部NOT_RUN。文档检查与源码/API核对仅SELF。
|
||||
|
||||
本记录暂存源码外。原负责人处理共享现场后,本任务经新的唯一precheck收据取得READY,再建立登记worktree并把阶段1原对象、用户批准、阶段2本记录及完整原始收据导入Documents/任务卡/PROJECT入口;导入不回填不存在的通过结论。
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
# 阶段2受影响需求评估:工作信息拆解与主动风险澄清 r1
|
||||
|
||||
记录日期:2026-10-14(Asia/Shanghai)。状态:**待人工评审**。本稿对应用户本轮新增要求:用户输入、智能体回复、检索结果和可见分析产物都经过拆分分析;有价值的内容进入两树一网;执行任务时主动识别矛盾与风险,及时通过对话或卡片提示、澄清。本稿只评估受影响范围和依赖,不修改此前已批准的阶段1–5原件,也不授权新增公开接口或业务实现。
|
||||
|
||||
## 已批准目标与本次增量
|
||||
|
||||
原始目标仍为44模板、项目差异结构、同项目成员的实际工作依据和完整可读审计。已确认的28项需求保持原ID和原结论;W2/W4a读取隔离和时间合同、Backend X1/X2隔离候选可按已批准范围继续。本次需要把“信息进入两树一网”扩充为**普通项目工作中的可观察来源处理流程**,并把冲突/风险检测扩充为**受影响动作之前的主动澄清**,供阶段3新增可判定条件。
|
||||
|
||||
原始[《08 核心数据模型》](/home/weichen/projects/Agent-System-Dev/.tmp/智能体系统/further-objective/08-核心数据模型-两树一网.md)(本地SHA256 `604cd8a9d0dd505af4c6c480d4ad3ae60dfd86c581d8261919b2daf8e5dc5618`)§二、§六已写“对话/上传/检索→相关性把关→拆解切片→标签→挂载”和切片互撞、切片与基线冲突。原[阶段3需求r1](rdm-two-trees-stage3-requirements-r1.md) TT-N01/G03/C02写了知识来源、问题和矛盾结论,但没有逐类验收**用户发言、助手回复、搜索、可见分析**的普通工作入口、处理回执与权限,也没有规定在可能错误的要求被用于生成/确认前的即时澄清。原[阶段4方案r1](rdm-two-trees-stage4-design-r1.md)§7保留私人对话边界,§5有结构提案HITL,未给上述所有来源提供受信观察入口。Backend最新已核主干 `607c38d7` 的公开面为`2.12.0-experimental`,还没有X1/X2;已批准X1/X2本地组合探针 `d9b00c2` 的公开面为`2.19.0-experimental`,含项目上下文提供方及受信审计链接,两者均未列普通项目消息与逐项检索的通用观察注册口。RDM的`Ingest`面向显式资料入库,不能由其存在推断普通聊天已自动拆解。
|
||||
|
||||
上述公开扩展面的限域SELF检查对固定Backend主干 `607c38d7e64298bb2db31ac9cdf81d341a244884` 与组合探针 `d9b00c23c818bfc4a8d8233c845266fabd863137` 的`pkg/extension/{surface.txt,extension.go,host.go}`执行。探针surface有124个导出条目及`ProjectContextRegistry`,无普通消息观察导出名/Registry或Host声明;主干无该注册面及观察导出。命令、对象和完整输出由Dev任务卡的工具收据 `ad404f00ba0f4cff2b02e07afc00ab4073ed1d91c1745caf826e1ada7209eec6`保存。独立限域源码审阅还指出普通用户消息在Backend持久化后才启动run、助手最终消息在run收口时持久化、检索直接返回命中而工具事件多为摘要;流式消息事件不能证明用户浏览器已呈现。这些是当前源码上的入口与时序差异,不是尚不存在的产品链路已完成的证据。
|
||||
|
||||
用户提供的测试句“要求效率和成本都低于人工”应触发**语义歧义/潜在风险**提示:若“效率”指单位时间产出,更低意味着更慢;用户也可能想表达“耗时和成本更低”或有意接受较低效率。系统不能擅自把原文改成“效率更高”,也不能未经澄清就固定为已批准需求。反例澄清可以问:“这里的效率是指单位时间产出,还是完成时间?您希望效率高于人工、成本低于人工;还是完成时间和成本都低于人工?”原句与答复需分别保留来源、人物、时间和版本。
|
||||
|
||||
## 建议新增的两个需求ID
|
||||
|
||||
| ID | 价值和行为 | 可判定范围 | 优先级 |
|
||||
|---|---|---|---|
|
||||
| TT-N03:工作来源拆解与候选入网 | 普通项目工作中的用户发言、已呈现的助手回复、实际检索/工具来源以及可见分析结果均产生受信处理状态;识别目标、要求、事实、依据、假设、建议、问题/风险等有价值的最小内容,保留原句/资源定位与版本,纳入项目作用域的候选笔记及来源网。审核或发布后才成为其他成员可用依据;无项目或私人来源保持原权限域。 | 两项目两成员实际输入、回复、搜索与分析各正反例;原文拆成多项/重复/撤权/恢复,逐来源看见处理成功、待确认、忽略理由或失败;仅已授权且已确认的条目进入同成员或跨成员下一次模型上下文。助手输出和搜索命中不能自动变成事实。 | P0 |
|
||||
| TT-R01:即时矛盾与风险澄清 | 在要求、结论或结构可能被采纳前,比较新片段自身、项目当前有效依据、同主题候选和适用要求;发现方向/单位/数值/条件不明、跨来源冲突、缺依据或影响受控状态时,展示具体原文、冲突对象、影响和可答复问题。高影响项在相关写入/生成/确认前触发HITL;可延期项进入持久工作卡且有状态。 | 示例句在同轮、相关业务动作前提示;纠正、确认原意、暂缓和误报反馈各自留来源及后续处理;没有真实用户澄清/确认时不写正式需求、不改变已批准正文或有效结构。撤权与项目切换不泄露风险卡正文,失败/重试不重复卡或事件。 | P0 |
|
||||
|
||||
“每条来源经过处理”不等于把所有原始会话或模型思考全文复制进共享项目树。处理完成须有可信状态及理由;只把需要的、可定位且符合权限/确认状态的内容作为候选或正式依据。可见分析结果是已输出/保存的结论、推导摘要或任务产物;不可获取的模型内部推理不冒充项目证据。助手回复的可核来源以**最终提交的消息ID/版本**为准;当前流式增量不等于已提交回复,是否真的在某一浏览器显示需另外的客户端确认,不能自行推断。检索/工具只留截断摘要时不得声称逐项原文已经被拆解;须取得受信命中/资源引用及实际用于生成的片段,缺失项列入处理状态。页面的提示与来源摘要应使用现有中栏对话和右栏工作卡,不另建管理界面。原始[《07 对话完备性方案》](/home/weichen/projects/Agent-System-Dev/.tmp/智能体系统/further-objective/07-对话完备性评估与交互调整方案.md)(SHA256 `520421ec7a4ff56edf6666043e53aa97436b48970545d0a22ea02be7713786b2`)已要求高风险动作通过同一张内联/右栏卡完成最终确认;普通澄清可先以对话提问,高风险应用仍消费现有人审通道。
|
||||
|
||||
## 可行性、重叠和职责
|
||||
|
||||
| 位置 | 当前可复用事实 | 缺口/评估结论 |
|
||||
|---|---|---|
|
||||
| Backend会话与运行 | 会话消息有持久`AppendMessage`;运行侧可产生消息、工具结果;X1候选可信项目身份/运行步骤、上下文manifest,X2候选已提交业务审计链接 | 普通工作未向RDM提供完整且受信的各类来源事件;仅靠提示词或RDM显式上传工具不能覆盖用户/助手/检索/分析四路。预计需独立的、可选公开观察接口或等价受信入口;具体字段/时序待阶段4评审,不能直接读取Backend `internal/`。 |
|
||||
| RDM领域 | 笔记唯一切片、多挂载、登记项、候选追溯边及项目事务;已批准的W2/W4a保留项目隔离 | 需逐项来源标识/引用、原片段位置、处理状态、相似合并/取代、权限/发布和恢复;助手推断与外部网页须保留“未核实”身份,不能直接喂给受控文档或其他成员。 |
|
||||
| 工作与界面 | W6/X1将提供默认授权上下文;W4b会加入结构确认;现有中栏对话/右栏任务卡与HITL命令面可复用 | 需在当前轮的相关动作前检测并提示,用户离开或后台发现时有同一持久卡;不能依靠刷新页面才发现,亦不能让模型自报“用户已确认”。W7/W10/W12需增补消费与真实浏览器/模型证据。 |
|
||||
| 审计与权限 | W8/W9已有业务事件、失败尝试、当前授权投影的计划;阶段4禁止原始私人会话跨成员共享 | 新来源的观察/候选/澄清/确认/忽略/撤销需要操作证据及字段级披露;项目ID只定位,实际成员、资源、正文与文档职责由服务端重验。未经发布的私人片段及卡片保持私域。 |
|
||||
|
||||
新增公开入口跨Backend/RDM并影响数据、权限与运行顺序,属于本项目`policy/delivery.md`中需要受影响设计重审的事项。推荐**受信观察→按项目/来源授权拆解候选→冲突检查→澄清/确认→版本化有效事实及追溯**;普通工作仍先回应用户,遇到影响要求/结构/受控文档的高风险歧义时暂停相关业务动作并即时提问。仅保留提示词的路线不能保证逐来源处理、幂等或后台恢复;把所有消息直接发布为共享知识则会混淆未经核实的模型输出与私人内容。推荐路线复用已有两树一网与HITL,不重建第二套知识库或审批中心。
|
||||
|
||||
## 成本与风险处理
|
||||
|
||||
- **处理量/时延**:每个消息或检索结果都需有处理状态;原文可用来源ID/版本/hash和最小引用定位,语义切片异步细化。会影响本轮要求/生成/确认的明显风险须在该动作前识别或明确阻塞;模型判断超时/不确定时记“待分析/待澄清”,不能默默采纳。指标、队列上限与降级在阶段4/5固定,并在本机及产品链路实测,不据当前源码捏造吞吐结论。
|
||||
- **误报与歧义**:风险发现是候选判断,不是项目事实。一次澄清保存人对当前版本的解释;模型不得代选答案。用户确认原意、指出误报或提供新资料都可关闭/修订卡并留下原判定/变更依据,避免相同版本反复打断。
|
||||
- **权限与保留**:原会话和工具结果可能包含个人或无权正文;新管道只通过受信主体/资源/项目绑定处理,跨成员共享须遵守现有发布与职责规则。撤权、源删除/替换、未完成工作恢复后,候选与模型上下文按当前权限重新评价;旧资料不靠不可验证的回填宣称来源完整。
|
||||
- **费用与依赖**:复用已批准的真实模型最多48次、300,000 tokens、人民币150元先到即停的总边界;新例应占用既有前后对照任务集,不扩容预算。Backend X1/X2本地候选不能代替新入口或已发布tag;公开契约变化需阶段4设计、人审和组件测试,真实服务/DB迁移仍待各自门禁。
|
||||
|
||||
本阶段建议**纳入 TT-N03、TT-R01**,并在阶段3明确验收/权限/例外,阶段4完成受信接口、记录状态及HITL设计,阶段5把W7/W8/W10/W12与新增入口顺序、预算和测试固化。当前28项验收不减少,建议新增后为30项。既有W2/W4a/时间合同及不受影响的W3递归结构可依已批准范围继续。本稿的评审只决定需求取舍与风险处理,不提前批准公开接口、产品实现或运行迁移。
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
# 两树一网阶段3:需求与验收条件 r1
|
||||
|
||||
记录时间:2026-10-14T10:22:37.191427+08:00;需求负责人/评审人:用户;编写:Codex。**待阶段3人工评审**。阶段1和阶段2取舍已批准;E1按用户“批准”执行完毕,结果待评审。本文形成可判定需求,不批准API、迁移、具体实现或正式测试计划。
|
||||
|
||||
## 本次评审范围
|
||||
|
||||
保留已确认的28项需求和44份最新Word模板全部范围,不以固定层数、几个模板、手动知识查询或操作码翻译替代目标。动态变更保持DYN-01:提出变更,确认后应用。需求主表在[Dev任务卡](../../../../../.task/feature-rdm-two-trees-latest-templates.md),每行引用本文对应ID的详细验收条件;当前状态以[主记录](../../proposals/2026-10-14-rdm-two-trees-latest-templates.md)为准。
|
||||
|
||||
处理结论均提议“纳入本增量”,尚待本阶段确认。P0是数据/权限/版本/可用依据及验收的前置项;P1是依赖P0形成完整业务价值的必做项,不表示可取消或本目标之外。具体分批、工时及先后顺序由阶段5计划决定。
|
||||
|
||||
输入沿用[阶段1原对象](rdm-two-trees-requirements-r1.md)、其附录A的44文件绑定候选、[阶段2评估](rdm-two-trees-stage2-evaluation-r1.md)及已保存源码快照。32个既有类型与12个细分/新增用途为候选:全部用途需覆盖,但12个是否新增独立类型、子类型或其他表达留阶段4决定。四份字节相同的阶段评审模板保持用途独立;其余无新模板的既有类型继续兼容。
|
||||
|
||||
## E1结果及本阶段处理
|
||||
|
||||
[E1结果报告](/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/e1-20261014-091421/REPORT-r1.md)及全部原始产物留源码外。14份均转换成功,148个表格/1127行的同引擎往返比较一致;原件hash未变。但有分页7→6、图形/文本顺序变化、批注/修订混入和预览中文缺字;另有49字符片段仍不能定位。**保真判据未通过**,不能发布为可无损替换的标准模板。
|
||||
|
||||
推荐本阶段确认的是“原件保全、转换稿仅候选、未核对不发布、44份内容/格式要求不降级”这些需求约束。阶段4须处理有效内容与图形/修订解析路线、目标字体/渲染基线和逐模板核对方法;正式实现计划放行前关闭关键解析未知或明确经人工批准的替代路线。此次批准不自动授权第二轮转换试验、全局安装软件或替换模板原件。
|
||||
|
||||
## 逐项验收条件
|
||||
|
||||
所有条目当前的产品验收结果均为NOT_RUN。E1和源码检查仅为可行性/差距证据,不代替下列验收。
|
||||
|
||||
<a id="tt-t01"></a>
|
||||
|
||||
### TT-T01 44份模板登记与来源保全
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;E1保真待解决;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:原44文件清单;E1。
|
||||
- 验收条件:44份均绑定稳定资产ID、原文件名/路径、真实格式、hash、阶段用途、解析器版本及覆盖/缺项;同字节的四份阶段评审模板保留独立用途。30 DOCX、14 DOC逐份可查,解析失败不得冒充已发布模板;已有69类型中无本次标准资产者保留并显示缺项。
|
||||
- 验证方法:逐文件清单与原件hash核对;错误格式、缺字、损坏及解析失败拒绝发布;检查原件可回取。
|
||||
|
||||
<a id="tt-t02"></a>
|
||||
|
||||
### TT-T02 内容要求、表格与示例完整
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;E1保真待解决;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-T01;E1未决项。
|
||||
- 验收条件:逐模板表达多级章节、固定文本、填写说明、字段类型/单位/条件、表格列与合并、重复块、附件和图形锚点;示例/批注/历史修订与有效要求分开。用户需求保留12组,UN/SR/DI及测试字段完整;不得仅生成标题或把蓝字示例填成项目事实。结构及可用格式通过原件对照后才可发布。
|
||||
- 验证方法:44份逐项对照表;至少包含嵌套章节、合并表格、重复用例、图形、批注/修订样本;专业语义人工核对,格式在中文可读目标环境验证。
|
||||
|
||||
<a id="tt-t03"></a>
|
||||
|
||||
### TT-T03 项目适用性与裁剪
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-T01/T02;项目范围。
|
||||
- 验收条件:每个内容要求具有必需/可选/条件适用规则及依据;软件、硬件、无菌等项目可形成不同结构。条件未知显示待确认;不适用保留理由、责任人和批准记录,不删除要求以抬高完成率;成员可补充项目特有要求。
|
||||
- 验证方法:至少两种差异项目;未知条件、条件变更、不适用拒绝/确认场景;核对必需项及进度分母。
|
||||
|
||||
<a id="tt-t04"></a>
|
||||
|
||||
### TT-T04 模板、实例与文档版本绑定
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-T01/T02;TT-D02/D04。
|
||||
- 验收条件:模板定义、项目实例、文档历史版分别有身份与版本,保留templateId/version/hash;升级展示新增/删除/语义和适用性差异,确认后应用。原实例/原历史仍回指旧模板;升级不自动覆盖正文或批准受控版。
|
||||
- 验证方法:旧实例+新模板、拒绝升级、确认升级、并发升级及历史回查;确认链可追溯。
|
||||
|
||||
<a id="tt-n01"></a>
|
||||
|
||||
### TT-N01 项目知识及问题组织
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:来源/确认/发布合同;TT-G03。
|
||||
- 验收条件:笔记树覆盖目标、资料切片、会议结论、需求约束、方案、风险、验证及转换确认依据;知识唯一ID可多挂载。保存来源/版本/适用范围/状态,结论取代有链;问题、冲突、假设及缺项可关联节点,不冒充已确认事实。
|
||||
- 验证方法:同知识多挂载、撤挂、软删除、结论取代、冲突未决和恢复;原件页/段/表或发言锚点可定位。
|
||||
|
||||
<a id="tt-n02"></a>
|
||||
|
||||
### TT-N02 项目独立字典与扩展
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;当前共用Dict;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:现有字典兼容;TT-D03。
|
||||
- 验收条件:项目可以增加/调整阶段、主题、工作事项、子系统、节点类型及有语义的扩展字段;两树一网使用一致的项目版本。项目A更名或扩展不改变B与全局种子;旧对象与标签引用可回查,废止保留历史。
|
||||
- 验证方法:两项目同名异义字段、项目扩展和更名、重启加载、旧数据回放;未知字段与非法类型验证。
|
||||
|
||||
<a id="tt-d01"></a>
|
||||
|
||||
### TT-D01 递归文档节点与稳定身份
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;现有层级不足;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-T02;TT-N02。
|
||||
- 验收条件:支持阶段、文档、多级章节、段落/字段/表格/重复项/附件的递归组合;稳定ID与父节点、排序分离。重名、改名、移动不改变身份和引用;防循环/跨项目父子错误。支持未开始、素材不足、草稿、待确认、评审中、已批准、依据变更待复核、不适用等可解释进度。
|
||||
- 验证方法:至少五层混合节点、重名章节、重复表格行组、附件及移动;循环拒绝与历史引用保持,进度按有效要求统计。
|
||||
|
||||
<a id="tt-d02"></a>
|
||||
|
||||
### TT-D02 动态结构提案与确认
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;DYN-01已确认;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-D01/D03/D04;可信证据。
|
||||
- 验收条件:新资料、需求变化、阶段推进、缺项、模板升级或成员主动整理可产生提案,列出具体差异、理由、来源、范围、直接/间接影响与风险。确认前有效结构不变;可接受、修改后接受、拒绝;保存提案与实际确认版本,重启后继续。
|
||||
- 验证方法:各触发源覆盖,接受/改后接受/拒绝/取消及重启;普通成员与无权限主体;界面和工具均不得绕过确认。
|
||||
|
||||
<a id="tt-d03"></a>
|
||||
|
||||
### TT-D03 原子、并发、幂等与恢复
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;复用现有事务/重放;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:当前结构与权限版本;事件合同。
|
||||
- 验收条件:确认时校验当前权限、项目、预期结构/内容/模板版本及受控状态;旧版本冲突返回可读差异。结构变更及成功事件整批提交或均不生效;同幂等键重试不重复,异参同键拒绝;故障恢复不产生半棵树、孤立边或重复业务效果。
|
||||
- 验证方法:两人并发确认、确认时撤权、事务各提交边界故障、超时后重试、进程重启重放;比较业务结构和审计水位。
|
||||
|
||||
<a id="tt-d04"></a>
|
||||
|
||||
### TT-D04 文档职责、版本与审签
|
||||
|
||||
- 优先级:P0;符合度:符合现行三权,须补结构联动;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:现有文档状态机/IAM;TT-D02。
|
||||
- 验收条件:结构确认权限与编制/审核/批准职责分开;实质变更已批准正文或要求时形成新候选并遵守现行重审。保留原批准版、职责和签署证据;普通结构确认不能自动批准内容,项目管理权不自动取得文档职责。
|
||||
- 验证方法:草稿/评审中/已批准三状态×各职责;正文和要求变更;HTTP、工具、后台恢复同规则。
|
||||
|
||||
<a id="tt-g01"></a>
|
||||
|
||||
### TT-G01 来源网与受控证据链
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;复用两类现有图;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-T02/D01;受控类型映射。
|
||||
- 验收条件:覆盖资料→结论、模板→章节、UN→SR→DI→设计→验证、风险→控制→需求/实现/验证、软件需求→架构/详设→三级测试→结果及输出→转换/确认。一般来源边和受控边语义分明,候选/已确认/缺项可辨;不得用日志数量代替覆盖率。
|
||||
- 验证方法:每条链至少一条完整及缺边样本;候选不得满足正式覆盖,回查具体端点及版本。
|
||||
|
||||
<a id="tt-g02"></a>
|
||||
|
||||
### TT-G02 升版影响与复核
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;端点已有版本语义;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-G01/D04;分析水位。
|
||||
- 验收条件:受控边绑定确切端点版本;升版不把旧验证自动视为新版有效。显示直接/间接影响、待复核与缺口、分析范围/截止;当时记录影响和当前重算影响分别标明。分析被截断/失败需可见,不声称影响为空。
|
||||
- 验证方法:端点升版、关系失效、循环关联、大图预算截断、历史水位;原影响快照不被当前分析覆盖。
|
||||
|
||||
<a id="tt-g03"></a>
|
||||
|
||||
### TT-G03 来源主体和可定位证据
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:可信来源字段;权限读面。
|
||||
- 验收条件:区分人工、规则、模型与系统来源;记录上传/产生/确认者及原件/模板/知识/章节/表格/发言锚点。网络来源保留URL、查询、获取时间和实际引用;缺少来源显式标明,不编造;引用定位与版本一致。
|
||||
- 验证方法:各来源类型、失效外链、删改对象、缺失页码和权限撤销;正文链接按当前权限检查。
|
||||
|
||||
<a id="tt-c01"></a>
|
||||
|
||||
### TT-C01 普通工作自动取得项目依据
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;公开入口待设计;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:RDM领域提供方;Backend通用上下文接缝。
|
||||
- 验收条件:同项目成员在普通任务/会话无需@knowledge,即取得当前有权使用的项目范围/阶段、任务要求、相关已确认结论、文档和来源;不能仅注入目录名或个人Memory。实际模型输入和产出引用能证明使用项目依据;无相关依据明确说明。
|
||||
- 验证方法:两项目两成员各自普通任务,包含有/无已发布依据;检查实际输入manifest和输出锚点,配真实模型前后对照。
|
||||
|
||||
<a id="tt-c02"></a>
|
||||
|
||||
### TT-C02 相关性、预算与渐进读取
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-C01/C03;预算合同。
|
||||
- 验收条件:先提供任务相关摘要及稳定引用,再按需读取细节;不每次全量读取所有文档。说明召回范围、水位、排序/预算、裁剪/遗漏和未决冲突;模板作为约束,来源中的指令仅为数据。无关资料不能挤掉必要任务要求。
|
||||
- 验证方法:长文档/多来源超预算、矛盾结论、检索无结果及不可信来源指令;记录实际裁剪原因与按需读取。
|
||||
|
||||
<a id="tt-c03"></a>
|
||||
|
||||
### TT-C03 共享、私域与当前权限
|
||||
|
||||
- 优先级:P0;符合度:符合现行IAM边界,须补全链路;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:可信成员/资源/职责权限;TT-C01。
|
||||
- 验收条件:只跨成员共享已确认/发布且当前可用的项目知识;个人对话、草稿、原件、受控正文各自鉴权。同项目身份不等于全读权;跨项目、任务切换、撤权后新输入不得夹带无权正文,后台恢复和工具也执行相同校验。
|
||||
- 验证方法:两项目、两个普通成员及不同文档职责;恶意projectId/resourceId、共享撤销、成员移除、缓存/恢复/历史对话带旧引用,检查模型实际输入。
|
||||
|
||||
<a id="tt-c04"></a>
|
||||
|
||||
### TT-C04 实际上下文清单与刷新
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;关联在途工作来源合同;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-C01/C03;任务/run与水位。
|
||||
- 验收条件:记录实际提供给模型的对象/版本/hash、权限及共享范围、检索范围、水位、摘要/裁剪和任务关联。新任务/项目或任务切换/相关有效变更/后台恢复时刷新;执行前重验已撤权或已失效依据,不以计划读取列表代替实际输入清单。
|
||||
- 验证方法:注入后升版/撤权、恢复与切换、读取失败/重试;对照实际模型输入、输出引用和可读审计。
|
||||
|
||||
<a id="tt-a01"></a>
|
||||
|
||||
### TT-A01 业务操作覆盖完整
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;覆盖矩阵固定;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:阶段1§7.1;宿主审计扩展。
|
||||
- 验收条件:对模板/结构、资料/知识、文档、需求/风险/测试/关系、成员/权限、智能体/后台工作六类操作建立逐动作覆盖矩阵;每格有事件/尝试证据或说明不适用。授权查看/下载/导出和拒绝访问按策略记录;不把UI悬停等噪声当完整性。
|
||||
- 验证方法:逐动作驱动并定位对应记录;宿主未覆盖面必须显式列出,不能用RDM事件总量冒充全覆盖。
|
||||
|
||||
<a id="tt-a02"></a>
|
||||
|
||||
### TT-A02 时间人物内容和影响事实完整
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;现有DTO信息不足;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-A01/G02/G03;事件schema。
|
||||
- 验收条件:按阶段1§7.2记录适用的开始/结束/生效/确认时间及时区精度,稳定身份和当时名称/职责,发起/执行/确认链,项目/任务/run/operation/batch因果关系,对象标题路径及前后版本、差异/理由/依据/原件hash、结果错误及实际影响,schema和水位;缺项明确。凭据和未授权原文不得因完整审计被泄漏。
|
||||
- 验证方法:更名/离职账号、人工+系统执行、多对象操作、敏感字段、未知历史值;对照不可变前后版与实际生效结果。
|
||||
|
||||
<a id="tt-a03"></a>
|
||||
|
||||
### TT-A03 成功、失败、拒绝和取消语义
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-D03;尝试与业务事件分离。
|
||||
- 验收条件:成功事件与业务提交一致;失败/拒绝/取消保留尝试、错误类别、发生时间、实际副作用及恢复状态,不成为已生效结构事件。等待确认与部分完成可辨;重试关联同一业务操作且不重复计算效果。
|
||||
- 验证方法:无权、并发冲突、提交前/后断开、跨系统部分失败、用户取消和重试;业务事实与展示状态一致。
|
||||
|
||||
<a id="tt-a04"></a>
|
||||
|
||||
### TT-A04 宿主关联与旧历史诚实出口
|
||||
|
||||
- 优先级:P0;符合度:需调整后符合;公开宿主读面待设计;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:Backend通用审计接缝;RDM投影。
|
||||
- 验收条件:宿主命令/模型/后台与RDM操作按真实可信项目/主体/资源和run关联;不能用owner全量审计冒充项目审计。跨宿主投递可恢复且状态明确;旧记录缺少姓名/内容/影响时显示当时未记录,不能用当前值或模型补造。
|
||||
- 验证方法:投递失败/恢复/重复,跨项目owner,旧事件schema及无字段样本;校验真实关联和缺项展示。
|
||||
|
||||
<a id="tt-u01"></a>
|
||||
|
||||
### TT-U01 可读摘要与结构化详情
|
||||
|
||||
- 优先级:P1;符合度:符合DESIGN方向;DTO需调整;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-A02/A03;现有审计入口。
|
||||
- 验收条件:默认按一次业务操作显示中文动作、可辨人物、时间、对象标题/路径、结果和影响摘要;展开是前后差异、理由、确认链、证据与影响清单。原始JSON、base64、内部op码不可充当业务记录;未知动作有诚实可读兜底,不让模型编造解释。
|
||||
- 验证方法:正常/失败/未知/旧数据四类记录的真实页面;用户能回答谁何时为何改了什么影响谁,检查未下发受限payload。
|
||||
|
||||
<a id="tt-u02"></a>
|
||||
|
||||
### TT-U02 可读对象与证据跳转
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;沿用唯一预览;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-G03/U04;标题/路径读契约。
|
||||
- 验收条件:来源、关系含义、直接/间接影响和历史对象用标题/路径/版本可识别;有权时进入现有对象详情及唯一文件预览,无权/已不存在时给明确状态。技术ID可辅助定位但不能取代业务名称。
|
||||
- 验证方法:文件页/章节/表格锚点、改名/移动/废止对象、权限变化;禁止重复预览界面和失效空白跳转。
|
||||
|
||||
<a id="tt-u03"></a>
|
||||
|
||||
### TT-U03 筛选、归组、分页与历史
|
||||
|
||||
- 优先级:P1;符合度:需调整后符合;复用导出水位在途成果;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-A02/A04;事件seq与读水位。
|
||||
- 验收条件:按时间、人物、业务动作、对象、结果和任务筛选;同一操作多事件/重试可完整展开,跨页不拆失或重复。历史按可读时间/正式版本选择并保留完整批次截止;项目/用户/筛选/历史切换后丢弃迟到响应,异步状态仅一个所有者。
|
||||
- 验证方法:跨页大批次、迟到响应、空列表/错误/加载、筛选往返、历史/当前切换及权限变更;导出沿用同一范围与水位。
|
||||
|
||||
<a id="tt-u04"></a>
|
||||
|
||||
### TT-U04 审计权与正文披露分离
|
||||
|
||||
- 优先级:P0;符合度:符合现行audit.read/正文权规则;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:当前IAM;服务端字段投影。
|
||||
- 验收条件:审计入口需要audit.read及相应资源许可;结构元信息、正文差异、历史原件、导出分别按当前权限制定披露。管理员/创建者或audit.read不得自动得到文档正文;限制在服务端完成,客户端隐藏不能代替。
|
||||
- 验证方法:可审计无正文、可正文无审计、历史撤权、导出/搜索/预览/模型同规则;直接检查网络响应无泄漏。
|
||||
|
||||
<a id="tt-v01"></a>
|
||||
|
||||
### TT-V01 需求到固定对象证据映射
|
||||
|
||||
- 优先级:P0;符合度:符合交付规则;正式验证未执行;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:全部需求;精确组件与配置。
|
||||
- 验收条件:每个纳入需求对应方案/工作项、正常/异常/边界/回归检查及当前对象结果;44模板有逐项对照,结构并发/原子/重放/旧数据/撤权有真实故障路径。明确SHA/pins/配置及SELF、REPLAY、GATE;缺项NOT_RUN不能以文档陈述补齐。
|
||||
- 验证方法:独立最小重放及故障注入;收据通过evidence记录;需求矩阵不得用非当前候选旧绿灯放行。
|
||||
|
||||
<a id="tt-v02"></a>
|
||||
|
||||
### TT-V02 真实模型行为前后对照
|
||||
|
||||
- 优先级:P0;符合度:符合行为面交付规则;预算阶段5确认;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-C/D02;真实模型环境。
|
||||
- 验收条件:用相同任务集比较改前/改后实际项目依据使用、召回、错误引用、失效处理及结构提案确认。两项目两成员、普通工作无@knowledge、权限拒绝/冲突/恢复均有样本;记录模型/配置/输入manifest/输出和判定,不以mock替代。
|
||||
- 验证方法:阶段5确定可复核样本数、模型及费用上限;不能调用时标NOT_RUN并保留验收缺项,不声称行为改善已验证。
|
||||
|
||||
<a id="tt-v03"></a>
|
||||
|
||||
### TT-V03 真实界面与当前HEAD组合验收
|
||||
|
||||
- 优先级:P0;符合度:符合交付规则;正式验证未执行;处理建议:纳入本增量(待确认)。
|
||||
- 依赖:TT-U;精确pins;阶段7环境。
|
||||
- 验收条件:真实浏览器完成两项目两成员流程:初始化/扩展、提案确认/拒绝、普通任务依据、升版影响、完整可读审计及权限回归;使用现有三栏/四入口/唯一预览与UI令牌、MotionKit、Collapsible。精确候选的相关测试、make test/build和当前HEAD CI齐备。
|
||||
- 验证方法:浏览器可见结果及网络权限检查;设计守护、精确组件组合测试;CI运行链接/执行身份/SHA核验,部署另按授权。
|
||||
|
||||
## 设计前必须保留的决策与实施停止条件
|
||||
|
||||
| 事项 | 当前依据/推荐处理 | 责任与关闭节点 |
|
||||
|---|---|---|
|
||||
| DOC及最终格式保真 | E1部分可行、验收未通过;原件不替换、候选不发布;需可读字体环境及逐项内容核对,未定位差异保留 | Codex准备路线/必要试验范围,用户在阶段4确认;关键路线未明确不得进入正式实施 |
|
||||
| 阶段/type和DI等受控映射 | 44项用途全部保留;不按文件名或YAML顺序误选type | RDM领域设计,阶段4给逐项映射及旧数据兼容 |
|
||||
| 项目扩展、递归节点、确认状态 | 范围已确认;具体schema/事件/迁移和冲突语义未设计 | RDM,阶段4;不能以全局字典修改替代项目独立扩展 |
|
||||
| 普通工作上下文和项目宿主审计 | 领域策略属于RDM,通用注入/读取属于Backend;必要公开扩展按四要素申请 | Dev/Backend/RDM,阶段4;不读Backend internal或owner全量审计绕过契约 |
|
||||
| 旧数据/历史/披露 | 旧字段不补造,受限正文不先传客户端;升级/恢复保持版本与身份 | RDM/Backend/Frontend,阶段4;迁移和正式测试另有批准计划 |
|
||||
| 在途重叠 | 沿用阶段2快照作为历史依赖,不宣称当前仍开放;审计导出/水位、快慢通道来源优先协调复用 | 阶段4/5开始核对最新main/PR和公开契约,不重建相同入口 |
|
||||
| 模型、浏览器和正式环境 | 真实任务对照必需,费用与样本/环境尚未批准 | 阶段5提交具体预算及测试计划;当前不运行付费模型、生产数据迁移或部署 |
|
||||
|
||||
本表没有把关键未知写成已解决。可确认需求及上述约束后开展方案设计;方案或试验发现需求范围、权限或验收条件需要改变时,回到本表重审受影响项,不降低既定目标。
|
||||
|
||||
## 人工评审出口
|
||||
|
||||
推荐确认28项全部纳入、优先级/验收条件及E1的风险处理边界,随后进入阶段4方案设计。阶段4产物应提供推荐方案/备选、职责与公开契约、数据/权限/历史兼容、失败恢复及保真后续验证安排;阶段4仍由用户批准后再形成实施计划。
|
||||
|
||||
本稿不是业务完成声明。业务代码、数据库迁移、正式模型/浏览器/CI、PR合入及部署均NOT_RUN。需要修改时按需求ID反馈;DYN-01、阶段1范围和阶段2取舍不重复询问。
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# 阶段3受影响需求表:工作信息拆解与主动风险澄清 r1
|
||||
|
||||
记录日期:2026-10-14(Asia/Shanghai)。状态:**待人工评审**。用户已在本聊天 `call_aea78d4156fe4ca89f4b9b6883b2b23f` 第0项确认[阶段2受影响评估r1](rdm-two-trees-stage2-work-observation-risk-evaluation-r1.md)(SHA256 `2627342f7d6e94137d5e7418d995ce57218093f6512f67fb7b221f01067da04d`),选择“确认增补,进入需求表(推荐)”。本稿只补两项稳定需求;此前[阶段3原28项r1](rdm-two-trees-stage3-requirements-r1.md)及其批准字节不变。通过本稿后需求总数为30,后续受影响设计和实施计划仍须人工评审。
|
||||
|
||||
## TT-N03 普通工作四类来源逐项拆解与受控候选
|
||||
|
||||
- **优先级/符合度/结论**:P0;需调整后符合;纳入本目标的受影响范围,阶段3待确认。现有显式 `rdm.ingest`、已发布知识和部分对话事件不能证明所有普通项目工作入口已接入。Backend固定主干 `607c38d7` 的surface 2.12和X1/X2本地组合探针 `d9b00c2` 的surface 2.19均无通用消息观察公开口;此结论的命令、对象、输出在Dev任务卡SELF收据 `ad404f00ba0f4cff2b02e07afc00ab4073ed1d91c1745caf826e1ada7209eec6`。
|
||||
- **需求**:在有受信项目工作绑定的普通对话、后台任务及恢复路径中,逐项处理①用户已提交的发言,②智能体最终提交的回复,③实际检索命中/工具提供的资料,④已输出或保存、可定位的分析产物。一个来源可拆出多条目标、要求、事实陈述、依据、假设、建议和待澄清项;同义重复可聚合,但保留每个实际来源及处理回执。对每项说明已形成候选、忽略且有原因、待分析/待确认、因权限受限、失败可重试等真实状态。未公开的模型内部推理、仅有流式片段或截断摘要的未知原文,不冒充完整来源。
|
||||
- **来源和权限**:候选有唯一身份、source kind、原消息/命中/产物稳定ID、版本/hash、原文片段位置或实际资源锚点、产生者/观察时间、受信项目与当前授权域、候选类别/范围/有效状态。搜索保存实际URL/查询/获取时间和已用片段;分析结果保留可见结论及其依据引用。无受信项目、已撤权/私域、无法定位或不可信内容不得借客户端 `projectId` 变成可跨成员项目事实;原始会话、工具大段输出仍按其原有权限保存。项目笔记树可显示受控候选及其来源网,只有符合发布/确认和当前对象权限的内容才进入其他成员的普通工作上下文、正式文档或有效追溯。
|
||||
- **状态和恢复**:来源新增、修订、撤销、换项目、授权变化与异步重试均按源ID/版本幂等处理;重复运行不产生重复切片/边,来源失效后新工作不再引用失效候选。保留已发生操作审计;旧会话不能因缺可靠归属/权限证明而被批量补造为项目知识。同一候选的用户、助手、检索多处引用只增加来源链接,不把模型复述算独立证实。
|
||||
- **可判定验收**:在两个项目、两名普通成员和至少一名受控文档成员的真实工作中,四类来源各有相关和无关样本;一段用户发言含两个不同要求须形成可回指的两项候选,同义助手复述不多造一个已确认事实;实际检索三条命中分别有处理状态,其中一条只有截断摘要须标不足以拆原文。换项目、私会话、撤权、来源修改/删除、后台恢复及重试后,私域正文和候选不进入其他成员或已撤权模型输入;经允许的确认/发布可在下一次普通工作中以精确版本被实际取用,manifest可回查。处理失败有可读状态,不静默丢源。
|
||||
- **验证方法**:领域/存储幂等与来源撤销、Backend实际用户/回复/检索/分析观察入口、RDM候选和授权、两成员两项目的输入manifest及浏览器来源视图分别检查;对“收到一个事件”“模型声称已分析”或后台队列里有任务,不直接判定最终来源已处理。
|
||||
- **依赖和边界**:TT-N01/N02/G03/C01–C04/U04/A02/A04;W2、W5–W10及后续真实模型/浏览器W12。Backend需要受信的可选观察入口/时序,具体公开契约、数据量和延迟在受影响阶段4/5固化;无法取得可验证来源时须明确缺项,不能伪造原句或用户确认。
|
||||
|
||||
## TT-R01 任务内及时发现矛盾、风险并安全澄清
|
||||
|
||||
- **优先级/符合度/结论**:P0;需调整后符合;纳入本目标的受影响范围,阶段3待确认。现有知识冲突、结构提案与HITL原语可复用,但没有普通用户消息/助手输出/检索发现到相关动作之前的一体化检测和可见处理路径。
|
||||
- **需求**:对本轮输入及TT-N03候选先查片段内部的量纲、方向、条件与措辞歧义,再按当前授权比较同主题候选、已确认项目要求、受控基线和来源版本。检测结论是带证据的**风险/矛盾候选**,可为需立即澄清、待成员处理或无问题;不得由模型独自把“可能冲突”裁为正式事实,也不得用“最新消息优先”覆盖批准节点。提示包含触发原句或有限摘录、与哪个有效对象/来源不一致、为何影响当前动作、可回答的问题及处理状态;对无权对象只给不泄露正文的通用阻塞说明。
|
||||
- **即时边界**:若本轮表达影响即将生成/确认的要求、结构、版本、审签或受控内容,在该相关操作生效前、同一轮交互中向有权用户提问或呈现绑定该对象/版本的HITL卡;无法在执行前完成可信判定时,相关业务动作维持待分析/待澄清,不提交为已确认事实。与该风险无关的普通工作可以继续。后台发现或用户离开时,风险持久列在同一右栏工作卡并可从中栏对话定位;右栏收起仍有可用的对话路径。正式高风险应用使用既有一次性真人确认凭据,模型或裸文本 `confirmed=true` 不能代签。
|
||||
- **指定语句**:输入“要求效率和成本都低于人工”时,应在把它写成项目已确认要求或据此生成正式文档前指出“效率低于人工”可能意味着更慢,并询问“效率更高且成本更低”“完成时间和成本更低”或“确实允许效率更低”的实际意思。不能自动改写用户原话。用户选择后保存原句、答复、actor、时间及版本;有意坚持低效率时不反复因同一已答版本打断,后续更改或新证据则可重新提示。此例是可疑表述,不自动认定逻辑矛盾或违规。
|
||||
- **状态和审计**:每条风险有唯一项目/来源/版本/受影响动作键、来源证据、直接影响、创建/发现时间、发起者及当前处理人,状态可待澄清、已回答、误报、已撤销、过期/再评估;重试不重复开卡。真人回复、拒绝/忽略理由和实际业务效果分开留痕;未确认候选不会产生已生效的结构/受控关系。权限撤销、切换项目、原来源修订和卡片迟到响应后重验授权与版本,旧答复不应用到新提案。
|
||||
- **可判定验收**:除指定语句,还测试同主题两个授权来源的不同周期数值、单位混淆、与已基线章节冲突、搜索页面注入伪装确认、助手提出无证据结论、真正允许低效率的反例及普通无关句。对每例观察当前轮消息或工作卡、相关动作零提交/确认后恰好一次生效、确认/暂缓/误报/撤权/重启后的状态与审计;无权成员看不到私人原句、标题或差异。实时流序号较旧的卡响应不得覆盖新的澄清。真实模型样例需检查是否在最终业务动作前提示,而非仅凭模型自述“已经提醒”。
|
||||
- **验证方法**:确定性规则和模型评测只提供风险候选;以受信身份、权限、版本、事务和HITL回执验证业务效果。SQLite/隔离PG做重试/冲突/恢复;真实浏览器在中栏与右栏及收起状态处理;模型前后对照占用原W12已批准预算,不扩容48次/300,000tokens/人民币150元上限。
|
||||
- **依赖和边界**:TT-N03/D02/D03/G02/C03/A02/A03/U01/U03/U04/V02;W4b、W5–W10/W12。当前HITL命令存在不等于普通消息已自动触发;具体同步调用、持久卡、严重度策略和错误降级须在阶段4/5设计并验证。检测时只能比较当前主体可合法使用的来源,不因风险提示泄露其他项目或私域的存在。
|
||||
|
||||
## 对原28项和实施顺序的影响
|
||||
|
||||
| 原ID/工作项 | 保持不变的验收 | 受影响需在阶段4/5补充的证据 |
|
||||
|---|---|---|
|
||||
| TT-N01/G03;W2/W5 | 唯一知识、多挂载、来源锚点、未决问题和追溯 | 由真实用户/助手/检索/分析来源生成候选,区分推断与确认、旧私域与当前可用来源。W2已完成的项目字典/事务基础不用重做。 |
|
||||
| TT-C01–C04;W6/W7 | 普通工作自动取得已授权项目依据,实际输入manifest与撤权刷新 | 经确认的新切片可在下一次普通任务中取得;来源处理未完/风险未决在预算内标示,不将私人消息默认跨成员提供。X1受信上下文并非四类来源的观察注册口。 |
|
||||
| TT-D02/D03;W4b | 结构确认、一次性真人凭据、CAS和无半态 | 风险澄清是变更前的受控输入;处理卡和提案确认复用同一权限/版本/事务边界,不能凭模型提示直接改树。 |
|
||||
| TT-A01–A04/U01–U04;W8–W10 | 人可读操作与当前权限投影 | 新候选、风险、答复及实际确认操作的时间/人物/原因/影响有类型化审计与可读卡片;未记录或无权字段诚实标示。 |
|
||||
| TT-V01–V03;W12 | 需求到固定对象证据、真实模型/浏览器/当前组合 | 新两项纳入矩阵;至少一组指定歧义、一组跨来源冲突、一组无关/误报,与同一总模型预算和两项目两成员场景并测。 |
|
||||
|
||||
原阶段3批准的28项及DYN-01不被替换;本轮只新增TT-N03、TT-R01。受影响的公开观察入口与时序可能改变阶段4方案和阶段5W6–W12分工,故本需求表通过后先形成人审方案及实施测试计划,再编写该新增能力的产品代码。旧数据不补造无出处的消息/命中;已批准W2/W4a/时间和不受影响的W3可依旧授权继续。
|
||||
+426
@@ -0,0 +1,426 @@
|
||||
# 两树一网阶段4:方案设计 r1
|
||||
|
||||
记录时间:2026-10-14T10:50:15.042190+08:00。状态:待人工评审;需求负责人/评审人:用户;方案编写:Codex。当前授权到方案设计,不包含业务实施、追加转换试验、运行库迁移、部署或发布。
|
||||
|
||||
本文承接已批准的[阶段3需求与验收条件r1](rdm-two-trees-stage3-requirements-r1.md),对象SHA256 `d685b9de14e1bd7c19a2a94dfab234c5a942f1281acd113ea924d24887246e15`。用户在本聊天 `call_87e7dc7218214a27a6a6d4911a44a387` 选择“确认阶段3,进入方案设计(推荐)”,同时接受原件保全、转换稿仅候选、保真问题未解决不发布。阶段1/2原对象、28项需求及44份模板范围保持。
|
||||
|
||||
## 1. 推荐方案与取舍
|
||||
|
||||
推荐在现有RDM领域模型、事务事件、持久提案、文档三权和检查工作区上扩展。模板与实例共用一套递归内容块合同;每项目拥有固定基础版本及独立扩展;资料和进度触发结构提案,成员确认后原子生效。基座提供按可信项目/主体调用领域上下文的入口及项目宿主审计读取能力。RDM将业务事件、操作尝试和宿主回执投影成可读操作记录,Frontend直接展示结构化事实。
|
||||
|
||||
| 路线 | 收益与成本 | 结论 |
|
||||
|---|---|---|
|
||||
| 扩展现有领域、提案和公开接口 | 保留已有项目、三权、事件重放与文件预览;需要完成递归模型、项目版本及兼容迁移 | 推荐;覆盖完整目标 |
|
||||
| 以通用知识图谱/动态表单平台整体替换 | 可配置面大,但要重建现有审签、权限、重放、模板与迁移语义,跨仓成本高 | 不采用;本目标不需要替换整套平台 |
|
||||
| 保留固定树,仅补标题/模板文本和审计文案 | 改动少,无法表达项目独立扩展、确认前后版本及真实成员工作依据 | 不满足已批准需求 |
|
||||
|
||||
方案以“已登记、可解析、语义已核对、可发布、实例已确认、文档已批准、文件已生成”分别表示状态,禁止用一个完成标志相互替代。P1需求与P0均在本目标内;没有把未解决的保真和权限问题移出范围。
|
||||
|
||||
## 2. 当前源码及在途工作依据
|
||||
|
||||
本轮SELF只读快照见同目录 `stage4-sources.json`,记录查询时间、源码SHA、文件hash、PR状态和DHF本地候选hash;不是运行验收。源码摘录留源码外,不在Documents复制业务源码。
|
||||
|
||||
| 对象 | 核验基线/关键位置 | 设计依据 |
|
||||
|---|---|---|
|
||||
| Dev | main `f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60`;本任务已合并该基线 | 逐阶段评审和公开模块边界继续有效 |
|
||||
| RDM | main `6fcb256205c2384abed35d3b6ab96ca7216e9297`;`domain/doctree.go`、`rdmapp/structure.go` | 现有Doc/Section为平面章节;装载按类型/标题去重,不能承载任意递归身份 |
|
||||
| 字典/事务 | `runtime.go`、`labels.go`、`tx.go` | Runtime.Dict传给各项目;已有TxProjectOp、opOnce、事件与审计outbox,应复用并补版本CAS及隔离 |
|
||||
| 上下文 | Backend main `5d5fc9891c0eb8994545ccb8b740535d9b99fb0e`;`runtime/llm.go`、`ctxasm`、extension | 普通知识注入仍依赖@knowledge;个人Memory不替代共享项目依据;公开面没有本方案所需Provider与项目宿主审计查询 |
|
||||
| 审计 | RDM `inspection.go`及Frontend main `eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b`的RdmAuditWorkspace | 当前按事件页内归组,DTO以op/actor/detail为主;需操作级完整分页与字段披露后的事实投影 |
|
||||
| Documents/UI | main分别为 `7bd4e17827d4c7c88647bf3c9199c495b60cb107`、`2c4322ef56df64ad72f65907d25b048a74bb5ffc` | 原两树方案状态回填已合入;沿用DESIGN、令牌、MotionKit、Collapsible及唯一文件预览 |
|
||||
|
||||
### 2.1 DHF专项的单一合同
|
||||
|
||||
发现并读取了DHF专项方案r0.1,SHA256 `f99e1424a9bb86f68ad6de91657102a36004c61fb0f36c8427e913d9e0cf9643`,以及 `Agent-System-RDM-wt-feature-dhf-template-assets` 的U1候选。该任务卡记录用户已批准实施U1和独立E1/E1-R1;这是其他任务的授权记录,不扩大本任务权限,也不证明其代码已合入或保真通过。
|
||||
|
||||
本方案采用以下分工,避免双方互等或各建一套:
|
||||
|
||||
- **DHF专项维护** `TemplateAsset`、资产目录/原件谱系、`ContentBlock`基础合同、WordSlot/渲染包及发布校验;44份台账唯一落在RDM模板资产目录。
|
||||
- **本专项维护**项目字典、内容块的项目实例/修订、结构提案/CAS/影响、普通成员上下文和完整审计。对ContentBlock所需字段作为同一合同的版本化扩展提交给DHF路径,不新建第二种模板树。
|
||||
- 文档实例化、模板绑定、生成采纳与整文冻结接口由本专项给出领域约束,DHF生成/导出消费;RDM是共同代码owner。阶段5以确定依赖提交/PR划分非重叠工作项,不把未提交候选当可消费版本。
|
||||
- 当前候选基础类型已有section/paragraph/table/row/cell/field/attachment、语义分类、WordSlot和稳定ID;还缺图形锚点、通用重复组、字段类型/单位/校验等本需求的表达。须在同一合同补足,不能因现有验证器只接受重复row而裁掉其他重复块。
|
||||
- 若DHF的v1合同尚未发布,在唯一合同中共同补齐后冻结;若届时已有发布消费者,则升级schema并提供兼容解码,不能以新增字段为名让旧严格读取器静默丢块。
|
||||
- 初步限制为深度64、每模板10000块的候选实现仅是资源保护,必须通过44份实测定限;超限给明确错误与调整入口,不静默截断或将固定层数变成业务规则。
|
||||
- 本任务E1与DHF的E1/E1-R1使用不同运行记录。只有输入hash、工具版本、差异与人工结论逐项对应才能复用;不以另一任务“已试验”覆盖本任务尚未解决的差异。
|
||||
|
||||
### 2.2 其他在途依赖
|
||||
|
||||
本轮API核验:审计导出/水位RDM #301/#307、Frontend #73、Dev #488仍开放;工作发现/来源Backend #193、Frontend #79、Documents #95、Dev #512仍开放。Documents #89与Dev #489已合入,已进入本轮文档基线。完整head及链接见快照。
|
||||
|
||||
本方案复用它们最终接受的导出截止、可信来源和任务卡合同;不另建导出或后台工作入口。它们尚未覆盖项目独立字典、默认项目上下文和完整审计读投影。阶段5开始及消费前重验当前main/PR,不把本快照当永久状态。
|
||||
|
||||
## 3. 权威对象与职责
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
S[原始模板与资料] --> A[DHF不可变模板资产]
|
||||
A --> P[RDM项目字典与递归实例]
|
||||
K[授权资料与已确认结论] --> P
|
||||
P --> Q[结构或内容提案]
|
||||
Q --> H[成员确认与当前权限校验]
|
||||
H --> T[项目事务: 版本 CAS / 事件 / 回执]
|
||||
T --> P
|
||||
T --> G[一般来源网与受控版本网]
|
||||
P --> C[RDM项目上下文提供方]
|
||||
G --> C
|
||||
C --> B[基座预算组装与实际输入清单]
|
||||
B --> W[成员普通工作]
|
||||
T --> U[可读审计投影]
|
||||
B --> U
|
||||
U --> F[现有审计工作区]
|
||||
```
|
||||
|
||||
| 对象 | 权威数据及不变量 |
|
||||
|---|---|
|
||||
| 模板资产版本 | templateId + version;原件、规范化DOCX、结构、渲染包各有完整hash;发布状态与评审证据绑定确切字节,不以文件名或字典序选最新 |
|
||||
| 项目字典版本 | projectId + dictionaryRevision;固定seed版本加项目扩展;ID与显示名分离,旧key别名可读;两树一网共同引用同一版本 |
|
||||
| 文档实例 | docId + projectId + templateBinding;实例有自己的节点ID,另存templateBlockId;一个模板可有多个同类实例,标题不参与身份判定 |
|
||||
| 递归内容 | 同一ContentBlock合同的实例视图;结构revision与内容revision分离;约束/说明/示例与成员实际填写值分离 |
|
||||
| 提案 | proposalId + revision + kind + baseVersions + bodyHash;草稿/内容/结构使用同一提案生命周期与确认入口;批准永远针对一个不可变提案版本 |
|
||||
| 知识 | 唯一知识ID及不可变来源/版本;挂载为关系,撤挂不删除知识本体;发布状态和索引投递状态分别记录 |
|
||||
| 追溯关系 | 边ID、语义、来源、确认状态、端点确切版本;受控网绑定证据,不把一般关联当正式验证 |
|
||||
| 业务操作 | operationId + requestDigest + actor/project/resource范围;事件和操作成功回执同事务,尝试/失败独立留痕 |
|
||||
| 模型工作依据 | 每次实际调用的ContextManifest,关联run/step、对象版本、内容摘要hash、预算裁剪及授权水位;不记录模型私有推理 |
|
||||
|
||||
RDM提供领域策略、对象和事件;Backend提供通用身份、上下文组装、执行/宿主审计及公开扩展。Frontend只消费授权后的DTO;UI仅复用既有原语。数据库仍走当前RDM store适配,不在本次替换团队存储架构或直接读取Backend internal。
|
||||
|
||||
## 4. 模板资产、内容块及实例
|
||||
|
||||
### 4.1 从原件到发布
|
||||
|
||||
流程为“登记原件 → 解析/规范化候选 → 内容分类与差异核对 → 确认用途/适用性/槽位 → 发布不可变版本”。运行时只消费已发布包,不增加常驻LibreOffice服务。准备工具在隔离环境运行,原件只读,禁宏/外部内容加载;未获批准不继续E1以外的试验。
|
||||
|
||||
资产状态沿用DHF候选 `needs-review / blocked / published / retired`。解析exit0不是发布条件;缺原件、hash不符、未决关键差异、用途未定、示例分类未确认、渲染槽位歧义均阻止发布。已发布版不原地改包,修正产生新版本。
|
||||
|
||||
44份逐文件范围与候选类型沿用阶段1附录A;原件与DHF台账按hash及逻辑用途核对。32个既有类型保留;12个新增/细分用途必须独立可辨,建议用途不同的计划/报告、详细设计、集成测试及阶段记录使用独立docType,最终键在阶段5前与共同合同对齐,不把“12”当固定数据库迁移数量。
|
||||
|
||||
系统需求使用明确的研发用途绑定,不按 `pm_system_reqs / rd_system_reqs` 注册顺序选择。《验证确认报告F02》的过程IQ/OQ/PQ用途、有效期与货架寿命边界、企业固定项/项目示例项等必须在资产评审单裁定;无裁定保持待发布。四份同字节评审模板保留四个阶段用途。无新资产的其余既有类型继续标“历史骨架/待标准模板”,不冒充本批已覆盖。
|
||||
|
||||
### 4.2 递归表达与语义
|
||||
|
||||
基础块沿用DHF的ContentBlock,不另建模板AST。补充合同包括:
|
||||
|
||||
- section、paragraph、field、table、row、cell、attachment及figure/reference;允许可重复的有名group,块种类决定允许的子种类,禁止无约束任意嵌套。
|
||||
- 稳定ID、文档顺序、内容要求、输入证据条件、必需/可选/条件适用、字段类型/单位/枚举/长度/数值范围、重复基数、表格合并与覆盖单元约束、附件类型及证据锚点。
|
||||
- semantic区分fixed/instruction/example/placeholder/signature及历史批注/修订引用。批注和未采纳修订保留在来源侧,默认不实例化为有效要求或项目事实。颜色和斜体只作分类线索。
|
||||
- 源锚点至少含原件hash、OPC part或DOC位置、段/表/单元/图形与可读路径。图形保留原内容及位置关系;无法可信展开的图形保持不透明证据块和待核对状态,不能自动推断业务边。
|
||||
- 适用规则采用受限的字段/比较/布尔表达式,禁止任意脚本;结果为适用/不适用/未知。未知不自动删节点;项目确认“不适用”需理由及确认者,保留原要求。
|
||||
|
||||
表格结构、字段值和重复组均使用此树。实例外层保存project/doc/node身份、父/顺序、源模板块、状态和revision;内容值按节点revision追加保存。模板的填写说明不与实例值共用同一字段。父子关系由同一权威结构生成索引,禁止树JSON和邻接表分别接受写入。
|
||||
|
||||
### 4.3 历史与审签
|
||||
|
||||
旧Section.ID继续有效,作为迁移后对应章节nodeId;旧版本正文保留为该章节下的legacy正文块,不拆分改写已批准文字。为旧段落自动推断模板hash、职责或精细锚点是不允许的。
|
||||
|
||||
模板升级形成提案,展示新增/废止/要求/槽位/适用性差异,按templateBlockId对齐。人工确认后只改变新结构/新候选;旧文档版继续绑定原模板。WordSlot只用于固定渲染包的槽位映射,不充当实例身份。
|
||||
|
||||
文档整版快照固定结构revision、节点内容revision、模板及渲染包hash、依据版本和真实审签。DHF导出从指定快照生成;已批准Word作为该快照的固定交付物保存,下载链接过期不删除批准文件。生成失败显示“文件待生成/失败”,不伪造Word已就绪,也不回滚既有批准事实。
|
||||
|
||||
进度是需求覆盖和工作状态的投影:未开始、素材不足、草稿、待确认、评审中、已批准、依据变化待复核、不适用。已批准状态只能来自审签;有文字、节点数量、提案已确认均不能自动批准正文。
|
||||
|
||||
### 4.4 E1风险的处理路线
|
||||
|
||||
本任务E1发现doc-03分页7→6、doc-01图形文本排序、doc-13图形表示差异、doc-06批注混入、doc-14修订及49字符未定位、PDF中文缺字。对应路线如下:
|
||||
|
||||
| 问题 | 设计处理 | 放行证据 |
|
||||
|---|---|---|
|
||||
| 中文字体/分页 | 固定可读的目标字体和Writer/Office基线,保留渲染环境说明;先分辨原DOC导入与DOCX往返各自差异 | 每文件可读页面、关键格式对照及人工差异结论;像素相同不是唯一判据 |
|
||||
| 文本框/连接线 | 图形源锚点与对象位置保留;阅读顺序由结构位置及核对结果确定 | 图形文字及关系语义可回指,未核对不展开为正式要求 |
|
||||
| 批注/修订 | 当前内容与批注、删除、未采纳修订分别提取;原件不执行接受全部修订 | doc-14未定位片段查清;有效文本选择有业务负责人裁定 |
|
||||
| 原件格式异常 | 只在有批准范围的派生副本修复,记录输入/输出hash及字节修改;原件保全 | 可复现实验、未损害其他内容/样式的对照;不得只看转换成功 |
|
||||
| 自动路径仍不可靠 | 可提出人工按原件重建结构/槽位与派生渲染包,保留差异和双向核对;仍不降低内容/格式要求 | 逐项资产审核;替代路线及额外预算经对应阶段批准 |
|
||||
|
||||
DHF已有独立E1-R1在途,可在验证输入谱系和结果后复用。当前方案不把该追加试验视作已通过,不擅自运行第二轮或声明所有14份可发布。
|
||||
|
||||
## 5. 项目独立结构与动态提案
|
||||
|
||||
### 5.1 项目字典
|
||||
|
||||
每项目引用一个不可变基础字典版本,再叠加该项目的版本化扩展。阶段、主题、工作事项、子系统、文档类型和扩展字段拥有稳定ID;显示名可改,删除采用废止。工作事项不再被迫等同docType,兼容旧WorkItem值时保留旧键与显式映射。
|
||||
|
||||
Runtime.Dict只作为只读默认基础;WorldFor按projectId和有效dictionaryRevision取快照,不共享可变指针。历史重放按事件所绑定的字典版本解释;历史未保存版本时标记解释依据有限,不能用当前名称假装当时名称。更改字典形成提案,验证两树与关系引用,确认后同事务写字典revision和事件,作废该项目缓存。
|
||||
|
||||
扩展字段先定义语义、类型、验证和可见范围再允许赋值。项目A的覆盖不写全局种子,B不受影响。全局种子/模板发布仍经现有仓库治理,不开放运行时全局模板管理权限。
|
||||
|
||||
### 5.2 提案合同与生命周期
|
||||
|
||||
复用既有持久提案服务,扩展kind及版本/目标/差异载荷:`content / structure / dictionary / template-upgrade`。现有草稿记录默认content,旧命令继续只返回旧形状;新增统一读面支持各种kind。结构提案与内容提案保存各自类型化载荷,共用确认、拒绝、幂等及审计服务,不创建第二个审批中心。
|
||||
|
||||
提案字段:projectId、proposalId/revision、发起/生成主体、触发原因、目标范围、baseStructureRevision/baseDictionaryRevision、涉及的doc/content/template版本、changes、evidenceRefs、impactAnalysis、风险、payloadHash、状态和时间。所有权限判断用执行端身份;模型不能指定最终actor或confirmedBy。
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Pending: 保存候选和来源
|
||||
Pending --> Superseded: 修改形成新修订
|
||||
Pending --> Rejected: 有权成员拒绝并说明
|
||||
Pending --> Cancelled: 发起者取消
|
||||
Pending --> Conflict: 当前版本或权限变化
|
||||
Pending --> Applied: 确认确切修订并事务提交
|
||||
Conflict --> Superseded: 重新分析形成新候选
|
||||
Applied --> [*]
|
||||
```
|
||||
|
||||
不存在长期持久的“已批准但未执行”结构状态。确认与生效是同一事务;网络返回丢失后按operationId查询已提交回执。修改后接受必须先生成新提案修订、重新展示差异与影响,再确认其hash,不能把旧确认套给新内容。
|
||||
|
||||
确认还必须携带由扩展后的现有HITL通道生成、服务端可核验的一次性确认凭据,绑定用户/项目/提案修订/payloadHash及有效期,并在应用事务中消费。模型以用户身份调用工具、传入confirmed=true或伪造confirmedBy均不构成人工确认。对话中的“批准”由真实用户消息与当前待确认对象关联;对象不唯一或已经变化时重新展示差异。UI按钮与对话入口消费同一确认服务,避免存在直接调用decide绕过DYN-01的路径。
|
||||
|
||||
动态触发包括资料发布/撤销、结论变更、新需求、阶段推进、发现缺项、模板升级和成员主动整理。触发只记录待分析任务,按项目水位合并重复触发;分析不得在每条资料变化时无界重建全部树。自动生成的候选不进入有效项目上下文;确认后的结论/结构才成为依据。
|
||||
|
||||
### 5.3 写入及恢复
|
||||
|
||||
确认步骤:可信身份与项目 → 读取提案修订 → 获取项目写事务 → 复验权限/受控状态/预期版本 → 校验整批操作 → 原子提交新revision、领域事件、提案applied、幂等回执和审计outbox → 发布新只读投影。
|
||||
|
||||
允许操作为新增、改名、移动、排序、改变要求/适用性、取代/废止及增加扩展字段。校验循环、跨项目/跨文档父子、重复ID、dangling引用、表格覆盖、字段值和结构规模。跨文档移动视为两个受控对象的变更,须拥有全部相关职责且对两文档生成候选版;普通导航挂载不移动受控正文。
|
||||
|
||||
复用TxProjectOp,增加数据库内project revision的条件更新及请求digest核验;进程内锁不能替代DB CAS。幂等范围绑定项目、主体、动作、资源及请求内容。同键同内容重试返回原回执;同键异参拒绝。所有相关写入口必须更新相同revision约束,不能仅在新API加锁而旧命令绕过。
|
||||
|
||||
读者只取提交后的不可变快照。不能让读服务拿到写事务正在修改的World指针:对既有World缓存增加同一项目读写协调或在隔离工作副本中演算,提交后一次替换;失败作废工作副本。具体锁实现可在阶段5确定,但必须覆盖全部读/写入口,故障测试证明无半新状态。
|
||||
|
||||
提交前错误为未生效尝试;提交结果未知先查回执,禁止重复执行。outbox投递失败不回滚已提交业务,状态显示待投递并按事件ID幂等恢复。旧应用遇不支持的事件schema拒绝继续写/重放,不能跳过未知事件启动空树。
|
||||
|
||||
### 5.4 权限映射
|
||||
|
||||
沿用现有上限∩角色∩项目覆盖∩资源∩职责/状态规则。普通成员在可读范围可提出建议,不能因此应用变更。
|
||||
|
||||
| 变更/读取 | 执行端要求 |
|
||||
|---|---|
|
||||
| 项目字典/阶段与非正文导航调整 | 项目设置权限;阶段推进还需stage.advance;涉及受控要求时同时检查相应文档职责 |
|
||||
| 文档内容/要求/结构采纳 | doc.write及指定编制人/当前文档状态;已批准对象须新候选并重审 |
|
||||
| 资料发布/撤销及结论成为共享依据 | knowledge.publish及对应资源权限;发布成功台账与索引状态分开 |
|
||||
| 受控关系确认/废止 | trace.edit及端点资源权限;不得以自动关联替代确认 |
|
||||
| 审计查询 | audit.read及当前项目许可;每个内容字段/对象再按资源和正文权限披露 |
|
||||
| 默认工作上下文 | 当前项目成员及相关知识/文档read权限;无需audit.read,不能通过上下文读出审计隐含私域 |
|
||||
|
||||
若现有project.settings粒度不能表达结构管理与权限管理的区别,新增专门动作必须同时给出默认/上限/旧角色迁移的明确方案,经权限合同评审;不能暗中给普通成员扩权。跨对象提案要求全部动作授权,不能部分应用后称整批成功。
|
||||
|
||||
## 6. 追溯与变更影响
|
||||
|
||||
一般来源网与受控合规网继续分别保存,统一引用为 `{projectId, kind, id, revision, anchor}`。内容块成为可定位的章节/要求证据落点,不把每个表格装饰单元都升级成受控需求实体。
|
||||
|
||||
UN、SR、DI、风险控制、软件需求/设计、测试用例、执行结果和报告保持不同业务身份;每个实体可绑定一个或多个块来源。候选关系不计入正式覆盖;新受控类型按现有CNode注册/重放合同增加明确语义,不以字符串节点冒充类型已支持。
|
||||
|
||||
端点升版时旧边保留原版本,当前视图标“待复核”;新的确认边绑定新版本,不自动移接旧测试证据。测试用例与测试执行结果分开,被测软件/配置版本在结果侧固定。
|
||||
|
||||
影响分析给出直接对象、传递路径、涉及的批准文档/验证缺口及分析水位。确认时若关键受控影响尚不清楚,阻止应用并要求完成分析;大图非关键补充影响可作为明确pending作业,不能将未计算显示为零。遍历去环、限定资源、返回截断及续查信息。
|
||||
|
||||
审计保存操作当时的影响分析ID及快照;用户另点“按当前版本分析”得到新的分析ID和水位,不能覆盖历史解释。模型建议的因果关系标候选,只有规则/确认事实进入确定性影响路径。
|
||||
|
||||
## 7. 成员工作上下文
|
||||
|
||||
### 7.1 公开扩展申请 X1
|
||||
|
||||
这是拟新增公开合同,尚未实现;符号最终以Dev扩展申请及surface版本为准。
|
||||
|
||||
| 四要素 | 内容 |
|
||||
|---|---|
|
||||
| 场景 | 普通成员在项目内开始、切换或恢复工作,未写@knowledge也应获得当前授权的任务要求和项目依据 |
|
||||
| 希望的公开能力 | 可选 `ProjectContextRegistry.RegisterProjectContextProvider`;提供方有 `Resolve` 和 `ReadEvidence` 两种受限读取;基座按可信run scope调用,不提供任意客户端owner查询 |
|
||||
| 现有组合不足 | AddCommandHandler只在命令调用时运行,KnowledgeSearch不提供默认任务要求/结构版本,ResourceAuthorizer只作许可判断,个人Memory按owner;都不能保证每次实际模型调用和恢复前注入 |
|
||||
| 兼容方式 | 新增可选接口及类型,不给必须实现的Host/Registry强加方法;无项目或未注册插件保持原流程;RDM声明必需能力时缺失须明确不可用,不能静默回退到手动@knowledge |
|
||||
|
||||
Resolve请求由宿主构造actor、pluginId、projectId、conversationId、taskId/runId/stepId、任务目标/当前对象、模型预算及上次水位。项目归属从受信会话/任务记录读取,不能从模型参数覆盖;恢复任务的项目绑定不可由旧payload改变。
|
||||
|
||||
返回ProjectContextBundle:项目概要/当前阶段、任务对象与要求、已确认结论、当前可读文档摘要、授权知识引用、未决冲突/缺项、精确来源版本、候选资料的限制状态、授权/发布epoch与领域commit水位。未知项目/无权/不完整分别返回明确状态,不能跨项目回落到全量World。
|
||||
|
||||
ReadEvidence只接受Bundle内可再鉴权的稳定引用及范围,不接受任意文件路径/owner。RDM通过当前IAM与发布台账选择对象,基座保留资源级model-context授权;多个插件不能覆盖彼此命名空间或把自己结果当全项目权威。
|
||||
|
||||
### 7.2 实际调用链
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant W as 普通成员工作
|
||||
participant B as Backend运行时
|
||||
participant R as RDM上下文提供方
|
||||
participant M as 模型
|
||||
W->>B: 项目内任务/对话
|
||||
B->>R: 可信作用域、任务目标、预算
|
||||
R->>R: 当前权限、发布与有效版本检查
|
||||
R-->>B: 摘要、要求、引用、缺项和水位
|
||||
B->>B: 预算裁剪,固定实际输入清单
|
||||
B->>M: 当前授权上下文
|
||||
M->>B: 必要时请求证据详情
|
||||
B->>R: 指定引用,重新鉴权
|
||||
R-->>B: 当前可读片段或明确拒绝
|
||||
B->>B: 记录实际使用版本及输出引用
|
||||
```
|
||||
|
||||
所有进入模型的路径,包括普通LLM、后台任务、Compose和恢复,使用同一提供方与manifest规则;Compose可提出更具体的块/文档目标,但不能自行从World取无权全量正文。不会把资料内容放入可覆盖平台规则的高权限指令。
|
||||
|
||||
Backend是最终注入和预算的唯一所有者。现有Host.Complete仅有prompt参数,不能靠插件在字符串中自报projectId补齐受信作用域;X1同时提出可选的 `WorkCompletionHost.CompleteForWork`,在已认证分发/任务上下文内解析目标及项目后走同一组装管线。Compose只提供生成目标和任务约束,已组装依据不再二次拼接;无可信工作作用域的普通Complete保留原有非项目能力,不能读取项目共享正文。后台恢复Host须从持久任务重新取得并验证作用域,而不是继承旧prompt内的身份。
|
||||
|
||||
预算顺序:系统/用户本轮目标及必需任务约束 → 项目和对象短摘要 → 必需的已确认依据 → 相关补充片段。每项记录保留或裁剪及原因;排序不静默裁决冲突。同任务先拿索引/摘要再渐进读取,不能在每轮扫描全部文档。
|
||||
|
||||
ContextManifest记录**实际最终输入**:bundle版本、对象ID/revision/hash、来源锚点、提供/丢弃片段、检索范围、模型/运行配置引用、预算与水位。候选检索列表单独记录,不能冒充模型已见;摘要内容保存受控版本或可复核hash,避免以后用新版摘要冒充旧输入。
|
||||
|
||||
### 7.3 撤权、恢复和失败
|
||||
|
||||
每次模型调用、细节读取、后台恢复及有副作用提交前复验当前成员/职责/资源权限及发布epoch;新任务、项目/任务切换和相关有效变更使旧Bundle失效。cache key包含actor/project/任务目标/权限epoch/内容水位,不能跨成员共用已裁剪正文缓存。
|
||||
|
||||
来源支持的历史工具片段及模型引用必须带出处,恢复时重新构造或移除已撤权/失效片段,不能仅检查新检索而继续把旧对话中的受限正文送入模型。无可靠出处的旧机器上下文标legacy,不能当授权读取入口;用户本轮自主输入与资源读取分开处理,不据旧引用授予访问。
|
||||
|
||||
权限在请求已发送后撤销,不能声称可撤回模型已处理的数据;记录实际输入时的授权水位,阻止后续调用和未获授权的派生结果交付/提交。具体外部模型留存政策不在本功能虚构保证。
|
||||
|
||||
提供方不可用/超时:普通对话显示项目依据暂不可用;依赖项目事实的生成/结构确认进入blocked或等待,不以无依据模型输出宣称已完成项目工作。只问一般问题可以继续,但清楚标出未使用项目依据。不得把可选能力故障变成全局平台不可用。
|
||||
|
||||
## 8. 完整审计事实与投影
|
||||
|
||||
### 8.1 三类记录和原子性
|
||||
|
||||
1. **业务事件**:已提交的结构/内容/关系/权限等事实,继续用于确定性重放。新增schema保存必要旧/新版本引用与业务元信息,成功回执与事件同事务。
|
||||
2. **操作尝试**:requested/started/waiting/rejected/failed/cancelled/committed/partially-completed/unknown等结果;保存实际已发生副作用、错误类别及恢复链接。失败不追加“已生效”业务事件。
|
||||
3. **宿主执行回执**:模型/工具/后台步骤/输入清单/投递的真实执行状态,经可信project/run关联读入。不能拿owner全量审计列表拼项目记录。
|
||||
|
||||
在发生副作用前持久化attempt起点;成功事务内写业务结果及attempt对应的commit receipt。若进程在更新attempt终态前退出,恢复根据commit receipt判定,避免“业务成功但审计显示失败”。没有回执且无法确认外部结果时记unknown,先对账再重试。
|
||||
|
||||
审计存储不可用时,要求留痕的写入不得继续无记录生效。受控查看/下载/导出也先记录可信读取尝试,再记录响应准备/流传输完成/中断等服务端可知状态;不能把HTTP完成写成用户已读。未解析为可信项目的恶意ID拒绝事件留宿主安全作用域,不挂到攻击者任意指定项目。
|
||||
|
||||
业务事务失败后在独立短事务结束attempt;两处均失败则保留起点/恢复缺项并明确报警,不宣称审计完整。后台投递用现有outbox扩展唯一sourceEventId,至少一次投递、幂等接收;离线期间显示缺少宿主回执范围。
|
||||
|
||||
### 8.2 操作信封
|
||||
|
||||
| 字段组 | 保存内容及规则 |
|
||||
|---|---|
|
||||
| 时间 | occurred/start/end/commit/confirm/recorded,UTC及原精度;未知显式缺项;页面按用户时区显示 |
|
||||
| 人物 | 稳定actorID、当时名称和角色/职责快照、发起/执行/确认/审核/批准者;系统/智能体/人工区别;来源从受信身份取得 |
|
||||
| 定位 | projectId、operationId、attemptId、requestId、run/task/step、因果父操作、对象kind/id/title/path、预期和实际前后版本 |
|
||||
| 内容/依据 | 类型化字段差异、不可变正文/结构引用及hash、原因和确认意见、模板绑定、知识/原件/发言/表格锚点;网络来源含实际URL/查询/获取时间 |
|
||||
| 结果 | 业务动作、状态、错误分类、可重试性、实际效果、生成产物、宿主投递/恢复状态;不把请求参数当已生效内容 |
|
||||
| 影响 | 直接对象、间接路径、需重审/重做/补证条目、当时分析ID/范围/水位及截断或未计算状态 |
|
||||
| 完整性 | event/schema/projection版本、domain commit水位、宿主source offset、来源标识、缺字段原因、披露状态 |
|
||||
|
||||
保存可记录的业务事实,不收集密码/token、模型隐藏推理、无关个人信息或完整未授权会话。完整输入依据采用受控内容引用/摘要hash和必要片段,不将整份私域正文复制成所有审计读者可见的detail字符串。
|
||||
|
||||
当时名称/路径与当前名称分别标示;旧记录不存在当时快照则显示“当时未记录”,当前解析名称只能作为“当前名称”。依据旧事件重放计算出的差异必须标推导来源与重放水位,不伪装成原操作当时记录。
|
||||
|
||||
### 8.3 公开扩展申请 X2与身份信息
|
||||
|
||||
| 四要素 | 项目宿主审计读取 |
|
||||
|---|---|
|
||||
| 场景 | RDM审计需要同项目的真实模型/工具/恢复/取消/投递事实及run关系 |
|
||||
| 希望的公开能力 | 可选 `ProjectAuditHost.QueryProjectAudit`,参数为可信项目范围、过滤、source cursor与截止;返回允许披露的类型化HostAuditReceipt及coverage |
|
||||
| 现有组合不足 | Host.Audit仅owner写入;现有owner列表无法同时证明项目归属、当前审计权及每个关联对象的披露权限 |
|
||||
| 兼容方式 | 新增可选Host接口;宿主保有可信归属和资源策略,RDM提供audit.read领域授权回调;旧部署返回coverage=unsupported,不得称全量审计已交付 |
|
||||
|
||||
身份显示优先由宿主在事件生成时绑定可信显示名快照;RDM自身写入可经可选最小actor身份接口取得当前主体及本次授权参与者名称。现有AccountLister/Searcher仅授权管理读面,不能为审计用户授予全账号目录权。若需要新身份接口,作为X2的最小附属字段/能力申请,输入限定本操作已验证参与者,返回ID/name/status,不含联系方式。
|
||||
|
||||
X1/X2均需在Dev正式提案、公开surface/契约测试及基座任务完成后按发版tag供RDM消费。阶段4批准不能替代tag发布的用户双钥匙操作,也不能允许改RDM pins内容或import internal。
|
||||
|
||||
### 8.4 可读投影、完整归组及游标
|
||||
|
||||
新增OperationSummary/OperationDetail读模型。由版本化的确定性动作词典生成“某成员调整了某对象”等中文摘要,参数只能来自事实字段;未知动作显示“未识别的历史操作(详情有限)”,不输出原JSON作为兜底,不让LLM生成审计解释。
|
||||
|
||||
列表以**operation**分页,不先截事件再页内分组。操作详情按operationId读取完整已提交批次;大型操作支持其子明细分页,同时始终显示可见范围内的完整性/剩余明细状态。同操作的重试、失败和最终效果关联,不把重试作为额外业务生效。
|
||||
|
||||
建议增加可重建的操作索引与不可变投影修订:记录operationId、project、发生/记录时间、状态、batchEnd、投影版本、关联引用和各来源水位。列表采用固定读取快照及稳定键集游标;游标绑定项目、主体授权版本、过滤hash、截止与最后排序键,篡改/过滤变化/撤权时失效。
|
||||
|
||||
domain seq与宿主offset不能比较成一个天然全局时钟。跨源审计采用本地摄入序列作为读取截止,同时保存domain commit和各宿主source offset;迟到回执在较新快照显示“补收到的执行记录”,旧快照不被悄然改写。历史截止只纳入完整提交批次,沿用在途导出水位合同。
|
||||
|
||||
状态过滤和汇总同样受当前披露规则约束。不能通过隐藏正文但暴露私域对象标题、差异长度或总计数量泄露内容;是否能显示受限对象的存在由字段策略决定,必要时仅“部分信息受限”。读DTO在服务端裁剪,内部重放payload不下发。
|
||||
|
||||
### 8.5 操作覆盖
|
||||
|
||||
实施时将阶段1§7.1六类覆盖矩阵逐动作接入:模板/结构、知识/资料、文档、需求/风险/测试/关系、成员/权限、智能体/后台。每动作至少关联入口→授权→尝试→实际生效事件/拒绝→可读投影→验证场景。
|
||||
|
||||
会话内个人草稿/未发布发现保持私域;项目审计只能见获准共享的关联摘要。宿主不能提供的字段明确not-recorded/unsupported,正式覆盖验收据此判缺项,不用“尽量记录”代替已批准完整范围。
|
||||
|
||||
## 9. 界面与命令合同
|
||||
|
||||
### 9.1 现有工作区内的用户流程
|
||||
|
||||
- 笔记树展示“知道什么、依据和有效状态”;文档树展示“需要交付什么、当前内容和缺项”;追溯视图展示“来源/实现/验证及影响”。项目切换沿用左栏,层级按项目内容展开,长树懒加载。
|
||||
- 成员在对话提出调整,右栏工作卡显示提案差异、理由和影响;确认/修改/拒绝同时有对话内路径。有效树与候选覆盖层视觉区分,不能先改树再要求确认。
|
||||
- 普通工作只在有用时显示“本次依据”短摘要,可展开确切版本与缺项;不把模板hash、schema或内部解析器信息放进默认业务流程。需要核对证据时沿用唯一文件预览。
|
||||
- 审计默认显示操作摘要、时间、人物、对象、结果及可见影响;展开“变更前后、依据、确认过程、影响、执行尝试”。默认无原始JSON/op码/base64。空数据、无权限、部分覆盖、加载和错误状态各自可辨。
|
||||
|
||||
示例仅用于说明设计,不是真实审计:
|
||||
|
||||
> 王某于10:42将“使用环境”移至“医院使用场景”,经李某确认后生效。结构版本8→9。依据为已确认会议结论。2份可读文档需要复核;展开查看前后路径、确认意见和影响条目。
|
||||
|
||||
数字和姓名仅由授权字段提供;受限时不保留该示例中的完整计数。旧记录显示“当时未记录原因”,不生成貌似合理的原因。
|
||||
|
||||
复用@ui tokens、字号标尺、mk-*与Collapsible;正文纸面保留文档字体/颜色。沿用三栏、四类检查入口及唯一文件预览,不新建模板后台或独立审批中心。窄屏和右栏收起仍能从对话完成确认。
|
||||
|
||||
### 9.2 拟定读写面
|
||||
|
||||
以下是方案合同名,不是已存在命令,实施时统一更新schema/公开目录并作兼容测试。
|
||||
|
||||
| 面 | 关键请求 | 关键响应 |
|
||||
|---|---|---|
|
||||
| `rdm.structure.propose/get/decide` | 可信项目、kind、目标/变更或提案ID、expectedRevision/hash、idempotencyKey、意见 | 持久提案/差异/依据/影响;确认回执、newRevision、commitSeq;冲突时返回当前可读差异 |
|
||||
| `rdm.project.schema.get` | 项目、指定revision或current | 有效基础+项目扩展的只读快照及历史限制 |
|
||||
| `rdm.inspect.tree`版本化扩展 | 项目、根/父节点、种类、revision、cursor | 递归子节点、种类、约束/进度、hasChildren、可见范围、稳定cursor |
|
||||
| `rdm.inspect.operations/get` | 项目、时间/人物/动作/对象/结果/任务、截止及cursor或operationId | OperationSummary页或类型化详情、完整性、披露、各来源水位 |
|
||||
| `rdm.context.inspect`(可选诊断) | 本人有权run/step | 已记录实际输入manifest的授权摘要;不能借此读取别人的完整会话 |
|
||||
|
||||
错误统一区分无权、提案/版本冲突、未知schema、必需来源缺失、模板未发布/不适用、保真未核对、分析未完成、提供方不可用、审计不可写、结果待对账。内部错误码用于诊断,页面显示对应动作、原因和可采取步骤。冲突不能自动重试成覆盖写入。
|
||||
|
||||
异步状态由一个store所有。页面请求带project/account/filter/history/request generation,事件按seq推进;旧响应直接丢弃。提案确认后以服务端回执刷新提交水位,不能以乐观更新伪造已生效;读模型追赶时显示同步状态。
|
||||
|
||||
## 10. 数据迁移、兼容与恢复
|
||||
|
||||
新增持久对象按领域分组:项目schema revisions、结构及内容修订/映射、提案类型化载荷、操作attempt/commit receipt、上下文manifest、可重建操作投影索引。已有事件/知识/正文/审批数据继续是各自权威;投影不能反向写业务事实。
|
||||
|
||||
数据库变更采用版本化迁移及最低读写schema fencing,不靠Get()散落DDL默默改变历史。阶段5先在副本建立旧数据基线、源hash和事件水位,演练迁移/重放/幂等中断恢复;运行库切换单独授权。
|
||||
|
||||
迁移原则:
|
||||
|
||||
1. 旧Doc/Section/Version和所有引用ID保持;生成新父子索引及legacy正文块时保存确定性映射,重复迁移不能生成新ID。
|
||||
2. 原版本/批准快照不改写;缺模板绑定或当时字典版本者保留legacy-unbound/unknown,不回填假的hash和审批。
|
||||
3. 新写路径及旧兼容命令统一经过同一事务/版本/权限服务。不能双写两套独立树后靠异步同步消除冲突。
|
||||
4. 事件schema采用兼容解码与明确版本门禁;新schema写入后不支持的旧二进制不得启动写入。回退使用已验证可读版本或迁移前完整副本,不删除新事实伪装回滚。
|
||||
5. 操作投影可按固定事实水位重建,后台重建与当前写入有checkpoint,原始事件和attempt不删除。历史缺字段继续缺字段。
|
||||
6. 数据库、原件/模板包、批准Word、附件及manifest引用作为一致性备份集合;不能只备数据库造成内容hash悬空。普通清理不得删除唯一历史证据。
|
||||
|
||||
故障矩阵应覆盖:确认前撤权、提交前/后进程退出、响应丢失、索引投递失败、宿主审计不可达、模板文件损坏、读投影落后、旧schema、迁移中断、模型运行中资料撤销。每条恢复路径返回实际结果与缺项,不默认重做所有外部动作。
|
||||
|
||||
## 11. 需求到设计和验证的追溯
|
||||
|
||||
下表是测试设计要求,当前产品测试均NOT_RUN;阶段5再给出具体命令、夹具、责任人、模型费用与环境。
|
||||
|
||||
| 需求 | 方案位置 | 必须提供的验证证据 |
|
||||
|---|---|---|
|
||||
| TT-T01 | §2.1、4.1 | 44路径/hash/逻辑用途、失败资产阻止发布、无源码目录的制品加载 |
|
||||
| TT-T02 | §4.2、4.4 | 44逐项内容/样式核对;表格/图形/修订/示例;目标环境可读格式 |
|
||||
| TT-T03 | §4.1–4.2 | 软件/硬件/无菌等差异项目;未知/不适用确认与进度分母 |
|
||||
| TT-T04 | §4.3 | 模板升版/退役/拒绝/旧实例回查,整文快照固定 |
|
||||
| TT-N01 | §3、6 | 唯一知识多挂载、来源锚点、结论取代、软删除和冲突登记 |
|
||||
| TT-N02 | §5.1 | 两项目扩展互不污染、同名异义、重启及历史字典解释 |
|
||||
| TT-D01 | §4.2–4.3 | 五层以上混合结构、重复组、移动/同名不变ID、循环拒绝 |
|
||||
| TT-D02 | §5.2 | 各触发源及接受/修改/拒绝/重启;确认前有效树不变 |
|
||||
| TT-D03 | §5.3 | 并发CAS、同键异参、提交各边界故障、读无半新态 |
|
||||
| TT-D04 | §4.3、5.4 | 三权/状态组合、实质变重新审签、旧批准版保全 |
|
||||
| TT-G01 | §6 | 一般/受控各条完整与缺项链、候选不能满足验证覆盖 |
|
||||
| TT-G02 | §6、8.4 | 端点升版、直接/间接/截断、当时与当前影响分离 |
|
||||
| TT-G03 | §4.2、6、8.2 | 人工/规则/模型/文件/网络来源与确切版本锚点 |
|
||||
| TT-C01 | §7.1–7.2 | 两项目两成员普通工作无需@knowledge,实际输入与输出来源 |
|
||||
| TT-C02 | §7.2 | 超预算、冲突、无结果、不可信来源指令、渐进读取 |
|
||||
| TT-C03 | §5.4、7.3 | 私域/共享、跨项目、撤权、缓存/历史/恢复无泄漏 |
|
||||
| TT-C04 | §7.2–7.3 | 每次调用最终manifest、切换/升版/撤权刷新及实际裁剪 |
|
||||
| TT-A01 | §8.1、8.5 | 六类逐动作覆盖矩阵,宿主缺项显式显示 |
|
||||
| TT-A02 | §8.2–8.3 | 时间/身份更名/前后版本/原因/确认链/影响及缺项 |
|
||||
| TT-A03 | §5.3、8.1 | 失败/拒绝/取消/部分完成/未知与实际效果一致 |
|
||||
| TT-A04 | §8.1、8.3–8.4 | 真实宿主归属、延迟投递/恢复、历史不补造 |
|
||||
| TT-U01 | §8.4、9.1 | 正常/失败/未知/旧记录可读,默认无原始payload |
|
||||
| TT-U02 | §9.1–9.2 | 来源/影响对象标题、权限内锚点与唯一预览 |
|
||||
| TT-U03 | §8.4、9.2 | 操作跨页完整、固定截止、迟到响应、筛选和历史切换 |
|
||||
| TT-U04 | §5.4、8.4 | audit.read/正文权交叉矩阵;网络DTO/导出/历史字段不泄漏 |
|
||||
| TT-V01 | §10–11 | 固定源码/pins/配置,正常/失败/迁移/重放及独立最小重放 |
|
||||
| TT-V02 | §7、11 | 真实模型同任务前后对照,召回/错误引用/撤权/结构提案场景 |
|
||||
| TT-V03 | §9–11 | 正式Frontend两人两项目流程、设计守护、精确组合与当前HEAD CI |
|
||||
|
||||
## 12. 后续实施顺序与评审出口
|
||||
|
||||
建议阶段5按依赖细化以下工作包;这只是方案依赖顺序,不代替尚未批准的实施计划:
|
||||
|
||||
1. 与DHF专项固定唯一ContentBlock/模板资产合同和每文件映射,明确E1未决项的验证/裁定责任;同时设计项目字典与旧对象映射。
|
||||
2. 递归实例/版本、事务与提案服务,先打通并发/恢复/三权,供DHF实例化和本任务动态调整共用。
|
||||
3. 受控关系、直接/间接影响及操作事实/attempt写入;不得等UI阶段再补无法从旧记录恢复的字段。
|
||||
4. X1/X2基座公开能力与RDM适配,接普通工作/Compose/后台恢复的实际manifest;按既有tag发布边界交付。
|
||||
5. 现有树/提案/追溯/审计UI消费新合同,保持唯一状态和权限投影。
|
||||
6. 全44资产与两项目两成员真实模型、浏览器、故障/迁移和精确组合验证;按阶段7–9审阅、Review和当前HEAD CI交付。部署与清理另按授权。
|
||||
|
||||
仍需验证的设计假设:DHF共享合同扩展及逐模板发布条件;X1覆盖所有模型入口且预算可控;现有事务读写协调能防半新状态;项目审计归组在大批次/迟到宿主回执下稳定;存量映射可保持所有旧引用。各项已给出负责模块与验证方法,尚未宣称实现可用。
|
||||
|
||||
本次请评审:推荐路线、单一DHF合同分工、项目版本/提案与权限边界、X1/X2公开扩展、可读审计事实/分页合同,以及E1未决项不放行发布的处理。通过后形成阶段5实施和测试计划;本阶段不运行新的转换试验、付费模型、业务代码测试或生产操作。若审议改变需求范围/权限/验收标准,仅回退受影响需求,不重开已确认DYN-01。
|
||||
|
||||
阶段5可将不依赖具体原件转换结果的结构/权限/上下文工作独立安排;真实资产仍在needs-review/blocked时不得对外宣称44份标准模板已可用。测试夹具只能验证机制,不能取代逐文件内容和格式验收。E1尚未解决的资产问题继续归入本目标最终完成条件。
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
# 阶段4受影响方案:工作来源观察、受控入网与主动风险澄清 r1
|
||||
|
||||
记录日期:2026-10-14(Asia/Shanghai)。状态:**待人工评审**。用户在本聊天 `call_b517d0f07af54aa188a01ddb100485b9` 第0项确认[阶段3增补需求表r1](rdm-two-trees-stage3-work-observation-risk-requirements-r1.md)(SHA256 `552a9fdea996bb547c185949b5072a51efafdce1339a9eaafd49537dfedd91b4`),TT-N03、TT-R01纳入目标,总需求由28项变成30项。本稿只修改[原阶段4方案r1](rdm-two-trees-stage4-design-r1.md)所受影响的普通工作来源、HITL、权限、上下文及审计合同;原W2/W4a、模板/递归节点及时间合同的其他设计结论保持。新公开接口、数据迁移与产品代码待本方案和受影响实施计划依次批准。
|
||||
|
||||
## 1. 现状、选择与接口归属
|
||||
|
||||
已批准Backend X1向RDM项目上下文提供方**拉取**当前已授权依据,X2仅将已提交项目业务事实与宿主审计可信关联;二者没有将普通工作消息和实际检索结果**推送**给RDM的入口。固定Backend主干`607c38d7`的公开surface 2.12与X1/X2本地组合探针`d9b00c2`的surface 2.19都没有通用观察注册口(Dev任务卡SELF收据`ad404f00ba0f4cff2b02e07afc00ab4073ed1d91c1745caf826e1ada7209eec6`)。代码限域复核确认:用户消息持久化后才启动普通run,插件命令处理器只在命中命令时运行;助手最终消息在run收口后才确定ID;检索在运行中直接返回hits,普通工具结果多只留截断摘要。现有`runCtx.AskHITL`已有对话内卡与右栏收件箱投影,但未连接这些来源。
|
||||
|
||||
比较三条路线:
|
||||
|
||||
| 路线 | 能否覆盖普通工作和即时风险 | 成本/风险 | 处理 |
|
||||
|---|---|---|---|
|
||||
| Backend提供可选、受信的工作来源观察与动作前决定口;RDM实现项目候选/风险领域规则 | 可在实际用户消息、检索、工具结果和助手最终落库处取得来源,并在有关写入/生成前提问 | 需新增公开面、宿主持久投递、权限及恢复用例;需和X1/X2同步版本 | **推荐** |
|
||||
| RDM定时读取整个宿主对话/工具日志 | 取不到未落库或已截断的逐项来源,也无法保证相关动作前提示;扩大私人会话读取权 | 易漏、误绑项目和越权 | 不采用 |
|
||||
| 只在提示词中要求模型自行记忆/提醒,继续要求用户手动上传 | 无处理回执、幂等、跨轮恢复或可信真人确认;模型可能漏掉例句 | 与TT-N03/R01验收不符 | 不采用 |
|
||||
|
||||
Backend只拥有跨应用的**受信观察接缝与调用时序**,从当前认证会话/持久run和实际资源构造身份;RDM保有拆解、项目领域候选、冲突语义、权限/发布、人审、入树入网及项目审计。Frontend/UI显示同一个受控状态,不在客户端自行判断哪些原话可共享。新增公开面遵循现有`pkg/extension`与`surface.txt`的可选能力方式,不能让RDM导入Backend`internal/`。其最终surface版本和数据库迁移序号以实施时同步后的权威主干为准,不在本稿假定旧探针已发布。
|
||||
|
||||
## 2. X3建议公开合同:来源和风险决定
|
||||
|
||||
建议新增`ProjectWorkObservationRegistry.RegisterProjectWorkObserver`,与X1注册面一样**可选**。Backend的运行/命令入口在经过原有认证和项目解析后调用注册的`ProjectWorkObserver`;没有RDM提供方的非项目工作保持原行为。RDM产品声明必须具备X3时,未装配或版本不兼容返回可理解的缺能力状态,不能悄悄假装已处理。
|
||||
|
||||
`WorkObservation`是不可由请求、模型或插件回填身份的受信信封,至少含:宿主唯一**观察事件ID**与来源阶段、认证actor、owner/plugin、从持久conversation或run核对的项目绑定、conversationID、持久消息ID或资源/检索命中ID、源种类、原版本与SHA256、时间和作用域/授权水位;可带经限额的原文片段及`partIndex`与UTF-8字节区间。`task/run/step`在实际创建后才出现,**用户消息提交时RunID可空**,聊天命令路径本来没有run;Backend随后用受信关联事件补齐,不因RunID空丢弃已提交消息,也不采信当前chat命令请求里可能为空的`HostProjectID`。Backend保证片段与保存的消息或当次实际命中相符;工具输出若只留下摘要,须标`summary-only`,并提供仍可重验的资源引用或诚实列为不可复原,不把摘要写成全文。助手来源以**最终持久提交的消息**为准,流式`message.delta`不生成独立已完成来源;SSE发送不代表浏览器收到,若需“已显示”另有客户端ACK,不影响本轮候选入网判据。可见分析产物仅指已保存/呈现的推导摘要、结论、工件和依据,未公开的内部推理不是来源。
|
||||
|
||||
公开合同至少区分观察、动作前决定、真人答复和当前来源授权:
|
||||
|
||||
1. `Observe(ctx, observation)`:以`owner/project/hostObservationID/sourceKind/sourceID/sourceVersion/partIndex-or-span`作稳定幂等键,**内容hash作为该键的值校验**;同键异内容拒绝并记录冲突,重投同键同字节返回原回执。不同run再次看到同一资源有新的hostObservationID和处理回执,可将语义候选归并,但不合并掉实际来源记录。返回`accepted/pending/denied/partial`和RDM处理回执ID;`accepted`只表示受信接收并落待处理账本,不表示风险分析完成、事实成立或已分享。每个实际来源/片段须有归并、忽略、受限、失败或候选的终态。消息必须已持久化;检索/工具命中在交给模型继续用之前保留来源引用与确实可见的片段,助手最终消息在收口事务成功后入账。撤销/版本更新以每源单调epoch和墓碑压住乱序旧事件,不因旧Observe迟到重新激活候选。
|
||||
2. `Preflight(ctx, workAction)`:针对即将执行的项目相关生成、正式要求/结构写入、确认或发布,带受信actor/project、动作、目标版本及**本次实际使用来源清单**(观察事件ID、sourceID、版本、hash、part与输入manifest水位),返回`proceed / clarify / pending / denied`及已保存的风险ID、需澄清的原句和可读理由。RDM必须证明清单中每项已经送达、完成对该动作适用的风险分析、没有交付offset空洞/`partial`来源;仅`accepted`或旧项目水位不能放行。本轮用户消息刚落库而outbox未投达时,Backend把同一**持久消息的受信快照**交给Preflight并由RDM在本地事务内先Observe/分析,再判定;也可等待其持久已处理水位,不得先分发chat命令或启动依赖它的模型run。检索/工具回调对后续模型/业务动作同理。待处理、超时或来源不全返回`pending`,相关动作零生效。`proceed`绑定确切来源/风险水位;一个新来源、更高项目版本、撤权或失败处理会使旧决定失效。Backend运行时在继续模型或命令前检查该决定,不能在调用RDM受影响命令后补问。
|
||||
3. `Respond(ctx, riskAnswer)`(仅风险HITL):Backend从当前认证会话、已保存风险卡及用户点击构造actor、riskID/版本、source/action摘要和幂等键,不接受模型参数自报的确认者;RDM在其事务中提交风险CAS与澄清答复并回已提交决定回执。Backend**拿到且核对该回执后**才销卡或恢复等待中的run;RDM未完成、版本过期或网络结果未知时,run继续等待/查回执,重试同键不二次决策。后续正式项目写入另执行W4b一次性真人确认和事务复验。
|
||||
|
||||
X3还需把受信来源检查明确分成**原件读取**与**已批准片段分享**两种用途。`CheckSourceAccess(raw-read)`从Backend当前会话/资源存储判定请求者能否读取**原消息/完整工件**;无权的项目成员不能借发布过摘要去打开原会话。私人来源主人A如要向项目分享,须经绑定来源ID/版本/hash、确切原文片段、**拟公开的实际摘要/文本及其hash**与项目的一次真人卡授权;Backend验证A当前拥有/可读该原来源并保存可撤销的`SourceExcerptGrant`(grantID、原片段hash、拟公开文本hash、项目及撤权epoch),RDM在自身库保存并核对相同grantID的项目发布许可及当前成员/文档职责。若只授权原片段而未批准改写,发布只能使用该原字节或可证明的确定性裁剪;摘要改字、补入其他私人内容或跨来源合成时,每个相关来源主人都须重看**最终将公开的文字**并重新授权,其各自grant绑定对应受控片段与最终发布payload hash。两方不是一次跨库事务:只有两份许可均已提交且当前有效,派生片段才可发布;任一失败保持待授权,不露出内容。Backend原grant先成功而RDM未应用时,它不能使任何RDM候选生效,取消/超时按同一幂等键撤销或恢复该悬置grant。
|
||||
|
||||
`CheckSourceStatus(derived-share)`只对已注册的RDM观察提供方返回来源owner、原版本/hash、当前存在/撤权epoch以及**Backend自己的grantID、原片段范围和拟公开文本hash**,不返回原文;Backend检验源仍属于A、未删除/撤权、原grant与原片段及拟公开payload hash/项目匹配,RDM独立核对其项目许可仍有效、实际派生摘要的**完整发布payload hash与grant相等**及B的当前项目/文档权限。该状态查询不是任意客户端可调用的消息目录;成员B可使用A明确授权的项目摘要,同时仍被拒绝读取A的私人完整会话或其他片段。X1的逐项来源重验继续核对**实际纳入模型输入**的文本hash;上述两种X3检查补当前原件状态和分享范围。任何所需的权威失联、epoch不符或资源已撤权时,相关原文或获准片段、正式项目写入都拒绝,返回可读缺项,不回退旧缓存。
|
||||
|
||||
后台观察投递采用Backend持久outbox:用户消息的受信入账与消息提交同一存储事务(此时只有message/conversation,可后补run关联);助手最终来源与fenced run收口同一提交;检索/工具若存在仅瞬时输出,先持久最小受信引用/片段或明确`partial`,再允许依赖其作为可确认项目证据。Backend向RDM至少一次投递,RDM以同一键去重;RDM提交ACK后Backend才标已送达,崩溃重放不重复生成。**Backend接收ACK只是观察递送结果,不是RDM项目事实提交回执。** 两仓没有分布式原子事务,界面必须明确`观察待送达/待分析/已形成候选/已发布/失败`。`Message`删除、资源撤权、知识版本变化与run恢复会投递失效/重评,而不会改写旧审计事实。现有历史消息只在可证实原项目、来源及当前授权时安全重评;无可靠绑定不补造项目知识。
|
||||
|
||||
覆盖点是四种实际运行器的**最终结果进入下一次模型请求之前**,不是SSE摘要:direct、SubLLM、Squad和CompiledWorkflow分别在授权检索返回、工具真实结果/工件引用和模型输入组装处适配X3,并用X1实际输入manifest核对实际纳入的来源。当前`runCtx.Retrieve`不发逐命中事件,`PartToolResult`只含摘要;仅接它们无法宣称四路已覆盖。一个运行器若无法提供受信的逐项来源/权限/版本,RDM项目所需的观察状态为`partial/unsupported`,相关项目事实生成或写入停在`pending`;未装配RDM的非项目任务继续既有行为。阶段5逐运行器列出入口与重放用例,不能只测direct就宣称完成。
|
||||
|
||||
## 3. RDM候选、风险与有效事实
|
||||
|
||||
RDM用**同一项目事务库**内的私域候选层记录`sourceRef → 分段/声明 → 标签/相关节点/初步来源边`。每个分段保存原文可回指区间、陈述类型(目标/约束/事实/推断/问题/风险等)、有效/待核实/被取代/忽略及原因,和当前项目分类/字典revision。语义相同的多个发言/助手复述可归并为一个候选陈述,但各自有单独来源边与人物,模型重复不增加证据独立性。原文和候选按owner及资源当前权限读取;搜索命中与助手分析一律先按**未核实候选**处理。未发布的私人原话、低可信搜索、个人草稿与处理中片段不能成为其他成员默认上下文或已批准文档事实。
|
||||
|
||||
候选可以在笔记树的“待核实”视图中定位,并在追溯网形成**候选**来源边;这不等于向现有有效`NoteTree`和正式受控网追加已生效事实。**能读一条私人发言与能向整个项目发布是两种权限。**私人消息/工件的来源拥有者须以实际身份和真人卡向Backend签发上述`SourceExcerptGrant`;RDM记录已验证grantID、sourceID/版本/hash、允许披露的原片段hash/范围、**真人看到并批准的最终公开payload hash**、目标项目与授权epoch,再独立核对项目分享职责。项目自有资源则按其发布职责和资源级权限验证。模型不能代授或靠“在项目会话里”取得分享权。公开项目事实可以是经同意的最小摘要;成员B读该派生摘要只需**Backend原片段grant + RDM项目发布许可**均有效、B具项目权限、实际文本hash等于两侧grant及原来源仍有效,**不需要也不取得A原会话的raw-read权**;私人原文/未获准片段与来源边仍按各自权限隐藏。
|
||||
|
||||
分享授权和必要的人审齐备后,RDM在**同一RDM项目事务**内校验当前sourceHash/分享epoch与资源权限、候选/风险/提案revision及项目CAS,消费一次性真人凭据,把候选转为`published`且相应风险/提案标为已消耗,并写入唯一有效`NoteTree`切片/一般来源边/适用Doc修订、项目revision、幂等回执和项目审计outbox,再提交并发布只读代;失败全部回滚。候选与风险状态必须在同一RDM事务库,不能外置后靠异步补状态。Backend观察ACK不得替代该提交回执,业务提交结果未知先查RDM幂等回执。受控文档还走三权与变更/重审,结构修改复用已批准W4b提案;所有现有正式要求/结构/发布写入口(含`rdm.reqs.add`等)经同一当前风险/来源/权限/版本事务门禁,不能靠宿主早先的`proceed`永久放行。拒绝/忽略保留审计依据,绝不在进度分母中当已完成要求。
|
||||
|
||||
来源撤销、项目分享权收回或对象权限变化后,RDM将对应当前候选及已发布切片标失效/待复核,受影响的需求/文档/网边列出直接与间接待复核范围。**失效outbox只是清缓存/留下审计,不是即时权限门禁**:W7/X1每次新模型输入、当前详情/审计字段披露、候选发布与正式提交、真人答复消费时,对**原始正文**执行Backend当前raw-read ACL;对**已批准派生片段**执行Backend原来源有效状态/撤权epoch及`SourceExcerptGrant`片段范围,并在RDM核对自身项目发布许可、成员/职责revision。B可读被授权摘要但不能读A原会话;任何适用的权威失联或epoch不符即拒绝相关文本/动作。这样Backend撤权已提交但RDM还没收到异步失效事件时,已批准片段也不会继续进入新模型输入。Backend原grant与RDM项目许可均可撤销;RDM项目许可的撤销与项目写事务按同一项目revision串行,跨Backend源撤销与RDM事务无法伪装成单库原子操作,提交点取得的来源epoch须入回执,后续读面仍按当前源权威实时拒绝。**历史批准Word及审计原字节保留**;当前请求若已失去正文或分享授权,服务端不把含受限正文的旧Word完整字节交给该主体,只给受限状态与有权元数据,待有职责的人重新裁定。已发布摘要是否可继续共享由其独立分享授权和当前来源政策决定,不能因曾经可读而默认永久有效。
|
||||
|
||||
风险判断顺序为本片段自检(量纲、比较方向、否定词、条件/主体)、同主题当前可读候选、项目已确认要求与受控基线,再分析对正在做的动作的影响。类型化`RiskFinding`至少有riskID、触发sourceID/版本/片段、相关对象精确版本、规则/模型判断来源、原因、严重度、影响动作、最小披露的选项及状态。规则和模型只提出**风险候选**,不得自签人类确认;不确定即标待分析。判断只能使用当前actor可读的比较对象,不能通过卡片存在、数量或措辞泄露无权私域来源。
|
||||
|
||||
对“要求效率和成本都低于人工”,先提出两个可解释的意思(效率更高且成本更低;完成时间与成本更低)并允许用户明确“效率确实更低”。原句、解释、真实actor/时间/版本与其后正式采纳动作各自留痕。澄清回复消除歧义,不自动通过受控要求或结构变更;正式采纳仍消费绑定项目/提案修订/hash的一次性真人凭据。已按同版本回答的问题不反复打断,来源或相关基线变更后重新判定。
|
||||
|
||||
## 4. 时机、HITL与工作卡
|
||||
|
||||
普通项目用户消息在Backend持久化后、相关run或聊天命令分发前,以**消息ID/会话ID、RunID可空**建立观察回执;同轮同步`Preflight`携带该持久消息快照或等待已完成分析水位。Backend从持久conversation重取项目,不能依赖当前chat命令尚未设置的`HostProjectID`。风险未完成或`partial`时,相关命令不进入`Bus.Dispatch`,相关模型任务不消费该要求为已确认依据;RDM内真正写入时再作事务复验。
|
||||
|
||||
为使“回复前发现风险”与现有运行时吻合,RDM项目工作中的**正文增量先由Backend在受信运行内有界缓冲**,先给用户进度/等待状态;当助手拟答复及其实际来源清单完整,完成风险检查、决定可呈现文本,并通过fenced收口保存最终消息后,才发送第一个该答复的可见正文。Backend为已提交消息生成带MessageID/seq的权威正文事件,**先于`run.completed`的流序号**发送;若提交后事件发送中断,重连按消息ID从存储取回并去重,不能把只有终态事件的run当作正文已送达。发生澄清时,显示提问/卡而不把未核实草稿先流出。旧实现的`message.delta`在`finishRun`之前已可见,故单做收口检查不满足此合同;正常非项目聊天继续现有流式体验。缓冲上限、长回复/客户端重连和首个可见文本等待成本列入阶段5测试,超预算时提示待处理并保留任务进度,不能绕过检查先显示未经确认结论。已流出的旧历史回复不能追溯抹去,只能在后来发现风险时给出可读纠正并阻断**后续受影响动作**。
|
||||
|
||||
检索/工具结果在当次run继续依赖前处理可见引用;direct、SubLLM、Squad、CompiledWorkflow各自有实际结果/模型输入边界,必须经过§2的适配或在项目必需模式下返回`partial/unsupported`。后台细分随后发现较轻风险时创建持久待办卡;新风险水位会使先前`proceed`失效,后续RDM正式写事务不得用旧决定。
|
||||
|
||||
高影响或当前动作必需的歧义:Backend在有run的路径复用`AskHITL`及现有同卡内联/右栏投影,等待时释放执行许可;无run的RDM命令通过同一风险ID生成待澄清卡及受控回执,不执行目标命令。**RDM风险账本是风险决定的唯一持久owner**;Backend ActivityCard只是由`riskID + riskRevision`生成的投影和答复通道,中栏与右栏消费同一个状态。用户点击后,Backend先让RDM在其事务中核对当前sourceHash、目标/风险版本、actor、项目权限与答复幂等键;只在取得RDM已提交决定回执后,才更新卡状态/恢复等待中的run。网络结果未知先查询同回执,不把前端点击本身记为“已确认”;RDM CAS冲突、卡被拒绝/取消/超时、项目切换或权限变化时保持相关动作待处理并显示原因。RDM澄清答复与真正结构/文档批准仍是两次有区别的操作。较轻且不阻碍当前动作的发现可进入右栏待处理卡并在当前对话摘要提示。前端单一异步状态owner按事件seq丢迟到响应;右栏收起时中栏仍可回答。UI沿[DESIGN.md](/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-two-trees-latest-templates/DESIGN.md)三栏与令牌、现有卡及Collapsible原语,不增审批后台。
|
||||
|
||||
提供方超时/崩溃:Backend保留已提交用户消息和投递状态;项目会话的风险判断未知时,相关run/命令保持`pending`,只显示进度和“项目内容待检查”,不输出项目依据、正文或推进项目事实。只有Backend能**确定性识别为非项目、不会读取项目资源也不会写项目状态**的白名单动作(如平台帮助)可独立继续;不能凭模型对“这只是一般咨询”的猜测放行项目会话。重启后根据outbox、来源hash和持久风险状态继续,不能让一次模型在无结论时自行继续旧写操作。捕获/细分有界,超长工具内容只保存来源引用和实际有权限的片段;超过预算列出裁剪原因,不伪造“已分析全部”。旧X1有效上下文只取已确认或当前授权的依据,未决风险可按字段政策显示状态给本人;不得把候选自动放进同项目其他成员的模型输入。
|
||||
|
||||
## 5. 审计、兼容与验证
|
||||
|
||||
RDM保存来源接收、提取候选、风险创建/变更、澄清回复、发布/拒绝/撤销与实际业务效果的操作ID、可信人物与各自时间、原/新状态、依据ref/hash、受影响对象及当前披露。Backend X2只对**已提交的项目业务事实**建立可信宿主审计链接;私人观察、原会话和未发布候选不因有项目ID成为跨成员项目审计。W8服务端输出类型化可读摘要和字段差异,W10以中文业务语言呈现风险/答复/影响,内部观察信封和原始payload不直接下发页面。缺失的旧来源、仅有摘要或不知道是否已呈现的内容明确标“当时未记录/仅有摘要/交付状态未知”。时间字段沿已批准schema2时间来源合同;日志seq与项目revision仍是因果/分页水位,不从墙钟构造全局顺序。
|
||||
|
||||
兼容:X3为可选注册面,未安装RDM的普通非项目流程不变;旧二进制/旧surface不能在RDM声明必须X3时默默退化。候选与风险表采用版本化迁移,先在隔离SQLite/PG副本测v1旧项目/旧消息无绑定、崩溃与重试,真实运行库不执行迁移。可回退旧版本不得解释新候选为正式事实;含新事件的降级按现有schema fencing拒写并保存全部原记录。资源权限和来源撤销须在读/模型输入/真人回答时重验,客户端projectId不构成授权。
|
||||
|
||||
验证应覆盖正常四路每种两项目两成员、一个发言拆多候选、助手复述去重、三个搜索命中逐项处理、工具仅摘要、可见分析产物、项目切换/私域/撤权/删除/恢复、相互矛盾的当前可读片段、先前批准要求与新发言冲突、用户给出的效率例句及三种澄清、误报、伪造确认、无权card、超时、崩溃/重试、旧消息不补造。正反例须额外固定:用户消息已落库但run尚未生成、聊天命令没有`HostProjectID`、outbox未ACK而命令立即分发、`Observe accepted`但风险未分析、某一来源`partial`或offset缺口、同键异hash/两处part、撤权墓碑后旧投递迟到、用户点卡但RDM风险CAS失败、RDM已提交答复而Backend回执丢失、模型正文delta早于最终审查、四运行器各自检索与工具原始结果无法取全。私人发言的读权与分享权交叉测试:A批准发布摘要X后项目编辑改成摘要Y或夹入另一私人来源,未重新向各来源主人展示最终文本/取得同hash授权则发布拒绝;B获准看X仍不能打开A原会话。**Backend来源撤权已提交但RDM失效outbox故意延迟**时,新W7模型输入、当前详情/审计字段、正式发布/写入/HITL答复与旧批准Word的当前披露都须按来源权威实时拒绝,历史字节/事实保留。`rdm.reqs.add`等既有正式写入口也要证明风险提交前复验,不能只测W4b新入口。
|
||||
|
||||
前置风险须以**相关业务事务未提交**和人类回复后恰好一次实际效果证明;带缺口的观察不能给`proceed`,Backend观察ACK不能替代RDM提交回执。中栏的首个可见正文应属于经风险决定、fenced提交的最终消息;浏览器是否实际呈现需客户端可核ACK,不能凭SSE发送推断。不能用“模型说已提醒”判PASS。真实模型前后对照在原48次/300,000tokens/人民币150元总上限内替换任务样本,不另购额度;原44模板、旧事件/审签与已经批准的W0–W4等目标继续各自验证。
|
||||
|
||||
## 6. 受影响分工与下一阶段
|
||||
|
||||
本设计需要新X3 Backend公开观察/前置决定口及受信投递;RDM接四类来源候选和风险账本,沿W4b/HITL确认进入有效两树一网;W7只读已授权有效来源;W8/W9链路只审计已提交事实;W10沿现有卡与审计工作台显示;W12做模型/浏览器真链。W2/W4a与时间修复继续解决事务及重放基础,W3递归文档实例继续使用已合入DHF唯一内容块合同,不因X3设计待评而停工。下一阶段5须确定唯一代码owner、基座组件与RDM的先后、X1/X2/X3同一最终公开surface和tag消费条件、最小回放/成本上限及TT-N03/R01完整证据映射。公开tag发布、真实库迁移、服务部署仍受原边界。
|
||||
|
||||
请评审“Backend受信X3观察和动作前决定、RDM私域候选/项目风险与现有HITL卡、确认后才入有效两树一网”的受影响方案。批准仅进入阶段5增补实施与测试计划,不放行新增公开接口或产品代码。
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
# 两树一网阶段5:实施与测试计划 r1
|
||||
|
||||
记录时间:2026-10-14(Asia/Shanghai);需求负责人/阶段评审人:用户;计划编写:Codex。**待阶段5人工评审**。本计划覆盖已确认的全部28项TT需求和44份DHF Word模板;计划获批前不启动本任务的业务代码、迁移、付费模型测试或部署。
|
||||
|
||||
已批准输入:[阶段3需求与验收条件r1](rdm-two-trees-stage3-requirements-r1.md),SHA256 `d685b9de14e1bd7c19a2a94dfab234c5a942f1281acd113ea924d24887246e15`;[阶段4方案r1](rdm-two-trees-stage4-design-r1.md),SHA256 `568aa26f6b2276f786109e2298b3ae36c6c14d3be5a54e0dfc95bf1b2db4603b`。用户于本聊天 `call_69f62a2617e74bfd93b75a8bef7d9809` 选择“批准方案,进入实施计划(推荐)”。本计划细化方案,不改变DYN-01“提出变更,确认后应用”、保真未通过不发布、成员当前授权或受控文档三权边界。
|
||||
|
||||
## 1. 交付终点和现场事实
|
||||
|
||||
交付终点是**整个目标**:44份新模板逐文件发布核对或有明确阻塞且不伪称已就位;项目专属的细粒度递归笔记/文档结构、经成员确认的动态扩展和版本追溯;同项目成员普通工作自动使用当前有权依据;详尽事实审计与人能读懂的审计页;两项目两成员真实模型、浏览器和故障恢复通过。只做一个试点、只覆盖若干模板或只翻译事件码均不构成完成。
|
||||
|
||||
本轮只读依赖快照:[stage5-dependencies.json](stage5-dependencies.json),记录六仓main、PR、DHF工作区HEAD和文件hash及采集时刻,来源SELF。它用于本计划分工,不是未来最新主干、现行部署或CI证据。`rg --files`当前核对 `.templates/DHF 文件模板/` 仍为44份Word。阶段4审阅时Frontend main已推进,Frontend #73审计导出已合入;RDM #301/#307、Dev #488、Backend #193、Frontend #79、Documents #95、Dev #512仍开放。开始对应代码工作和每次同步前重新获取真实状态;已经合入的导出入口及水位合同要复用。
|
||||
|
||||
DHF独立任务 `feature/dhf-template-assets` 已有单一 `TemplateAsset` / `ContentBlock` 候选与44项资产目录:工作记录为40项needs-review、4项blocked、0项published。其初次E1转换10份,追加E1-R1的4份也生成候选,但其结果仍为 `fidelityGate=NOT_PASSED`、`human_fidelity_review=NOT_REVIEWED`、`publishedAssets=0`。本任务自己的E1曾用另一隔离环境取得14份转换产物,亦未通过保真;这些不同路径的“转换成功”不互相证明。统一以原件hash、工具/派生hash、差异台账及逐文件人工裁定核对,不把双方候选任意合并为已批准资产。
|
||||
|
||||
实施采用既有注册worktree和独立任务分支。Dev此任务R0为`add097d06137c4912a4ed9279e98ca353e4e4cf1`,已纳入较新的main;具体每个新组件任务需从其**启动时权威origin/main**固定各自R0。Dev/Documents阶段记录当前仅本地候选,未形成业务提交或PR。阶段6开始前核对上游、共享现场、活跃任务owner与最初precheck;不接管DHF工作区或把其未提交代码当合入事实。
|
||||
|
||||
### 1.1 本计划的共同约束
|
||||
|
||||
- RDM只通过Backend `pkg/extension` 与Core公开类型交互;不导入Backend internal、不改RDM `pins/`内容。X1/X2公共能力按四要素申请,基座实现测试及其批准的发版tag由用户按双钥匙亲手发布;RDM在真实可消费tag后接线。
|
||||
- 项目ID/资源ID仅定位,不能授权;服务端重验项目成员、动作、资源、职责、状态及有效版本。审计读权不自动给正文,管理员/创建者不自动绕过文档职责。
|
||||
- 结构/字典/模板变更必须有不可变提案修订与实际人工确认;模型或工具自报确认无效。确认与业务事件/回执原子提交;失败尝试和已生效事件分别记。
|
||||
- 旧Section/Doc、引用、批准版和原件不被覆盖。迁移先用**隔离副本**验证并保留可恢复全组合;真实运行库迁移、部署及发布另有审批与执行计划,阶段5批准不直接操作线上。
|
||||
- 前端先读Dev `DESIGN.md`,使用`@ui/tokens.css`、`--fs-ui-*`、`mk-*`与Collapsible;三栏、四个检查入口和唯一文件预览不增冗余页面。异步状态只有一个owner,事件按seq丢弃旧响应。
|
||||
- 命令输出经各仓`make evidence`保留完整SELF收据;正式准入还须精确对象的GATE或独立REPLAY。命令、路径和测试环境在下面各任务核对当前仓版本后使用,不能把文档中的期望写成运行通过。
|
||||
|
||||
### 1.2 实施审阅重点
|
||||
|
||||
| 易漏输入/故障 | 应有行为 | 拥有验证的工作项 |
|
||||
|---|---|---|
|
||||
| CFB头异常、原件可导入但中文分页或图形阅读顺序变化 | 原件保全,候选留needs-review/blocked,发布拒绝且差异可查看 | W1的DOC对照、W11逐资产人工裁定 |
|
||||
| 同名节点、重复块或跨项目父节点 | 稳定ID与来源保持;非法父子/循环拒绝,不靠标题去重 | W3递归/旧数据用例,W4提交前校验 |
|
||||
| 模型以用户身份调用确认工具、过期提案或异参同幂等键 | 无实际人审凭据不生效;旧修订冲突、异参同键拒绝并留尝试记录 | W4人审/CAS/恢复用例 |
|
||||
| 成员撤权后后台恢复携带旧会话中的正文片段 | 实际下一次模型输入剔除已撤权来源,记录删去原因;不得跨项目继续引用 | W6受信作用域,W7恢复/撤权模型输入用例 |
|
||||
| 大批操作跨页、宿主回执迟到、审计员无正文权限 | 一次操作完整展开,迟到回执另有水位;服务端DTO不下发受限字段或泄漏计数 | W8操作分页,W9字段披露,W10真实浏览器/网络检查 |
|
||||
|
||||
## 2. 工作归属、依赖图与增量
|
||||
|
||||
RDM仓代码owner为本目标RDM实施分支;DHF资产、原件/渲染、逐文件评审和Word生成由**原DHF任务worktree owner**继续持有;Backend基座与Frontend/UI各有独立组件分支,Dev只做公开扩展申请、任务主记录和固定组合。两条RDM任务共享`ContentBlock`与`doctree.go`,不得同时在不同未合入分支修改同一权威合同。DHF U1先冻结基础合同并经审核合入;本任务随后从更新的RDM main扩展实例/项目语义。DHF后续U2–U6在本计划中作为同一目标的明确依赖和交付工作:阶段5评审同时确认其继续由原任务owner实施,并要求原任务卡引用本计划及本次批准;此前原任务仅有U1/E1-R1授权,不能由本计划草案自动扩权。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
P0[W0 冻结44清单与跨任务合同] --> P1[W1 DHF U1资产门禁]
|
||||
P0 --> P2[W2 项目字典与笔记]
|
||||
P1 --> P3[W3 递归实例与旧数据兼容]
|
||||
P2 --> P3
|
||||
P3 --> P4[W4 结构提案与确认事务]
|
||||
P4 --> P5[W5 追溯及影响]
|
||||
P2 --> P6[W6 基座X1公开能力]
|
||||
P6 --> P7[W7 RDM工作上下文]
|
||||
P4 --> P8[W8 RDM审计事实与操作投影]
|
||||
P0 --> P9[W9 基座X2宿主审计]
|
||||
P5 --> P10[W10 正式工作区]
|
||||
P7 --> P10
|
||||
P8 --> P10
|
||||
P9 --> P10
|
||||
P1 --> P11[W11 DHF发布/生成/全44]
|
||||
P3 --> P11
|
||||
P4 --> P11
|
||||
P7 --> P11
|
||||
P10 --> P11
|
||||
P10 --> P12[W12 真实组合及正式验收]
|
||||
P11 --> P12
|
||||
```
|
||||
|
||||
W2、基座W6和W9在W0后可从各自main的兄弟分支并行准备;W9与W6涉及同一Backend公开面时,先合入一个,再同步另一个至最新main并验证最终surface。W8可先完成RDM领域事实,接入宿主回执和界面前必须等W9。W3必须等待DHF U1真正合入并消费其**已核验**合同;不得从DHF脏分支私自复制代码。W11的独立资产整理可与W3–W10并行,发布/生成联调按图中的门禁推进。
|
||||
|
||||
阶段6建议四个可评审增量:A(W0–W4:共享合同、项目结构、动态确认)、B(W5–W7:追溯和成员上下文)、C(W8–W10:完整审计与界面)、D(W11及W12:44模板和全链路)。每增量的产物由用户按阶段6评审;局部自检与同一批准范围内的缺陷修复可继续。阶段7只在全目标候选固定后做正式验收;缺失的W11资产不能被A–C成功替代。
|
||||
|
||||
## 3. 近期工作项:合同、字典、递归结构与确认
|
||||
|
||||
### W0. 冻结共享合同和44份逐文件状态
|
||||
|
||||
- **需求/owner**:TT-T01–T04、D01;本任务RDM owner与DHF任务owner共同核对,业务用途和格式由用户/指定模板负责人裁定。
|
||||
- **范围/文件**:Dev `.templates/DHF 文件模板/`只读;DHF仓 `internal/domain/template_asset.go`、`internal/rdmapp/dhf_assets.go`、`internal/rdmapp/templates/dhf/catalog.json`、`docs/records/dhf/`;本任务既有阶段1附录A与E1报告。仅使用DHF的一份catalog和一套ContentBlock,不复制第二份资产表进运行库。
|
||||
- **动作**:逐文件对齐44逻辑ID、41不同原件hash、阶段/用途、候选docType、来源锚点、版式差异与状态;四份同字节评审原件分别保留用途。明确12个新增/细分候选的命名和旧69型兼容;系统需求研发/项目管理用途、《验证确认报告F02》、有效期/货架寿命及企业固定项须有逐项裁定。以字段/图形/通用重复组补齐共同ContentBlock;冻结schema/消费者兼容策略,未获业务裁定项保持blocked。
|
||||
- **验证**:脚本按原路径和hash比较两份E1输入谱系,不把docx文件存在当保真;校验重复内容不合并逻辑用途、未知/损坏/不适用资产拒绝发布。对照`docs/records/dhf/e1-r1-result.json`的4份候选,确认人工格式仍NOT_REVIEWED。
|
||||
- **完成/停止**:44/44处置行、合同版本、共同owner和未决项负责人明确;发布为0仍可完成合同准备。任一原件hash漂移、两个任务对同字段各有定义或需改变已批准保真要求时,停止受影响写入并返回阶段4/需求重审。
|
||||
|
||||
### W1. DHF U1资产基础合入与保真核对路径
|
||||
|
||||
- **需求/owner**:TT-T01/T02/T03/V01;原DHF任务owner,当前本地候选不作已交付事实。
|
||||
- **范围/文件**:RDM `internal/domain/template_asset.go`、`internal/rdmapp/dhf_assets.go`、`internal/rdmapp/templates/dhf/`、`docs/records/dhf/`及相应测试。后续规范化工具和产物只在其批准的隔离范围工作;原件只读。
|
||||
- **动作**:先完成现有U1回归/Review并按其阶段门禁合入;为图形/批注/修订、字段单位/条件与重复块补同一合同。把最初10份及E1-R1的4份转换稿记为不同工具链的候选,各自记录输入/输出hash。准备可读中文字体与目标Word/Writer人工核对表。已发现的分页、阅读顺序、PDF文本、49字符未定位等逐项分配“修复/人工重建/阻塞”决定;额外试验超出已批E1/E1-R1范围时先提交最小试验计划取得批准。
|
||||
- **验证**:`GOWORK=off go test ./internal/domain ./internal/rdmapp -run 'TestContentBlocks|TestDHF|TestBundledDHF' -count=1`(从RDM仓,按实际测试名调整);检查镜像工具版本、沙箱断网和原件hash;业务人员从原DOC/DOCX与候选逐项对照关键内容/表格/图形/修订及中文格式。
|
||||
- **完成/停止**:U1源代码合入且精确合同可消费;44份均保持真实状态,单份只在其审核绑定原件/结构/渲染hash后published。业务/版式未审、独立来源差异未解决或无可读渲染基线时该资产不得发布,W3的通用结构工作可继续但W11全量出口仍受阻。
|
||||
|
||||
### W2. 项目字典与笔记树扩展
|
||||
|
||||
- **需求/owner**:TT-N01/N02/G03;本任务RDM领域owner。
|
||||
- **范围/文件**:`internal/domain/labels.go`、`notetree.go`、`payloads.go`、`replay.go`、`internal/domain/store/store.go`、`internal/rdmapp/runtime.go`;新增聚焦的项目字典版本、知识挂载服务及测试文件。当前Runtime.Dict/WorldFor的读写路径全部纳入。
|
||||
- **动作**:以固定基础字典版本+projectId作用域的版本化overlay实现阶段/主题/工作事项/子系统/类型/扩展字段;词条稳定ID与显示名分离。保留旧WorkItem→docType映射,旧事件无当时字典版显示历史缺项。笔记本体唯一ID,多树挂载作为关系,结论取代/撤回、问题/冲突/假设独立于正式正文;索引及已发布台账与领域状态分开。项目A写入不能修改B或全局种子。
|
||||
- **验证**:RDM领域与存储测试:两个项目同名异义词、名称变更/废止、五类知识来源、同知识多挂/撤挂、旧事件重放、未知类型拒绝;SQLite和PostgreSQL隔离库各跑一次关键迁移/重放。`GOWORK=off go test ./internal/domain ./internal/rdmapp -run 'TestProjectDictionary|TestNoteMount|TestLegacyDictionary' -count=1`为目标测试名。
|
||||
- **完成/停止**:每项目的有效revision唯一,跨项目互不污染、旧ID与来源可回指。若迁移无法保留旧引用或需要全局运行库重置,停止迁移设计实施并回到阶段4调整;不通过覆盖旧值求过关。
|
||||
|
||||
### W3. 递归文档实例、模板绑定与旧数据兼容
|
||||
|
||||
- **需求/owner**:TT-T02/T04/D01/D04;本任务RDM领域owner;DHF U2消费已合并的实例接口,不平行写另一树。
|
||||
- **前置/文件**:W1已合入、W2字典;RDM `internal/domain/doctree.go`、`payloads.go`、`replay.go`、`internal/domain/store/store.go`、`internal/rdmapp/structure.go`、`runtime.go`、`templates.go`、`docsubmission.go`;必要新增`document_blocks.go`、旧对象映射与服务测试。
|
||||
- **动作**:Doc实例固定templateId/version/原件/结构/渲染hash,模板块ID与实例nodeID分开。递归块支持多级章节/段/字段/表/行/单元/重复组/附件/图形及其输入约束;项目自有节点和模板节点可共存。结构、值、整文批准版各有独立revision;旧Section.ID原样维持为章节节点身份,历史内容保存legacy块,旧批准和职责不改写。旧`StructureApply`按标题去重只用于既有兼容/迁移,不再用于新实例身份。
|
||||
- **验证**:深于五级、同名节点、重复表格、合并单元、图形不透明块、移动/改名保持引用;旧数据库备份副本迁移两次结果同值,未知未来事件拒绝启动写入;已批准版与旧下载仍可回取。`GOWORK=off go test ./internal/domain ./internal/rdmapp -run 'TestRecursiveBlock|TestLegacyDocMigration|TestTemplateBinding' -count=1`为目标测试名。
|
||||
- **完成/停止**:一个真实项目实例可表达新项目建议书及用户需求12组要求,旧ID/replay/批准版保留。解析块上限、适用性未知和缺字段均返回可处理状态;不能通过删除必需项抬高完成率。DHF资产未published时只能验证实例机制,不宣称其正式标准模板已可用。
|
||||
|
||||
### W4. 动态结构提案、人工确认与事务恢复
|
||||
|
||||
- **需求/owner**:TT-D02/D03/D04/T04;本任务RDM领域/应用层owner,UI后续消费。
|
||||
- **前置/文件**:W2/W3;RDM `internal/rdmapp/draftproposal.go`、`tx.go`、`runtime.go`、`internal/domain/eventlog.go`、`payloads.go`、`replay.go`、`internal/perms/perms.go`、`plugins/rdm/plugin.go`;新增`structure_proposals.go`及必要迁移/测试。沿用同一持久提案生命周期,不另设审批中心。
|
||||
- **动作**:kind为content/structure/dictionary/template-upgrade的提案保存不可变revision、baseVersions、差异/理由/证据/影响及payloadHash。真实人确认凭据绑定项目/提案修订/actor/hash,一次性消费;模型工具不能自设confirmedBy。项目事务内校验当前IAM、指定编制职责、结构/模板版本、循环与表格规则、请求digest;同键同请求重放原回执,异参同键拒绝。成功结构+事件+提案状态+回执+outbox同事务;失败尝试单独记录,未知提交结果先查询。全部旧写入口必须通过统一版本约束。
|
||||
- **验证**:资料发布/阶段推进/缺项/模板升级/人工触发;接受、改后接受、拒绝、取消、过期确认、模型冒充、并发两成员、确认瞬间撤权;事务每个故障点中断/重启和超时重试,无半棵树/重复边/双重确认。`GOWORK=off go test ./internal/rdmapp ./plugins/rdm -run 'TestStructureProposal|TestProjectCAS|TestHumanConfirm|TestProposalRecovery' -count=1`为目标测试名。
|
||||
- **完成/停止**:确认前有效树字节/版本不变,确认后一次生效且可重放;已批准正文变化进入既有三权重审。若需改变领域/公开权限契约或迁移语义,暂停受影响实现回到方案评审;与DHF同时编辑同一`doctree.go`时先确定唯一owner和合入顺序。
|
||||
|
||||
## 4. 后续工作项:追溯、上下文与审计
|
||||
|
||||
以下工作保持文件/契约、测试和出口,但阶段5批准后由阶段6增量A–C逐项展开到具体提交,不用“远期”豁免28项。
|
||||
|
||||
### W5. 追溯网、版本端点和影响
|
||||
|
||||
- **需求/owner**:TT-G01/G02/G03;RDM领域owner。前置W3/W4。
|
||||
- **文件**:`internal/domain/tracenet.go`、`compliance.go`、`compliance_rules.go`、`payloads.go`、`replay.go`、`internal/rdmapp/trace.go`、`inspection.go`及相应领域/命令测试。
|
||||
- **实施**:明确UN/SR/DI/设计/风险/软件三级测试/执行结果类型和模板块来源的映射;一般来源边与受控证据边分别保留;受控边锁定两端精确revision。端点升版标待复核,关键影响分析未完不得确认;当时影响快照与当前重算分开,遍历有环路/截断/水位。缺证据不得虚报覆盖。
|
||||
- **验证/出口**:六类完整链与缺项链、端点升版、候选未确认、环和超预算、间接影响、旧版本回查;检查事件重放后的关系/待复核状态及两种影响水位。两网统一读面可解释,无旧边自动升级。
|
||||
|
||||
### W6. 基座公开X1:项目上下文和受信生成入口
|
||||
|
||||
- **需求/owner**:TT-C01/C02/C03/C04;Backend基座owner,Dev负责四要素申请与固定公开面。W0后可准备;RDM消费必须等基座发布tag。
|
||||
- **文件**:Backend `pkg/extension/extension.go`、`host.go`、`surface.txt`、`internal/app/hostcaps.go`、`internal/runtime/llm.go`、`internal/ctxasm/ctxasm.go`、`internal/runmgr/`与store受信项目绑定;Dev文档申请、公开边界和CI测试。
|
||||
- **实施**:可选ProjectContextRegistry注册RDM提供方;Backend从认证会话/持久任务解出actor/project/task/run/step,按预算在普通LLM、后台恢复及受信`CompleteForWork`完成一次注入。提供方只返回当前授权摘要/可再鉴权引用;最终组装及实际输入manifest由Backend唯一持有。无项目/无提供方时正常非项目流程不变;RDM声明必需能力却未装配时明确缺失。
|
||||
- **验证/出口**:非项目兼容、默认项目普通输入、跨项目伪projectId、撤权后缓存/恢复/旧消息片段、摘要超预算和提供方超时。接口编译/宿主注入/资源授权正负例与真实发送给模型的manifest一致;未发布tag不得以本地replace或修改RDM pins消费。
|
||||
|
||||
### W7. RDM上下文提供方与实际依据刷新
|
||||
|
||||
- **需求/owner**:TT-C01–C04/N01/G03;RDM应用层owner。前置W2、W5、W6可消费tag;未达到tag时可做纯领域摘要与测试,但不得宣布自动注入完成。
|
||||
- **文件**:`internal/rdmapp/knowledge_publication.go`、`runtime.go`、`compose.go`、`inspection_visibility.go`、`plugins/rdm/plugin.go`;新增`project_context.go`及测试。
|
||||
- **实施**:项目范围/阶段、任务对象要求、当前已确认结论、未决冲突/缺项和已发布知识来源组成短摘要,按任务相关性渐进ReadEvidence。个人草稿、原始会话、未发布发现和无职责受控正文不跨成员;切换/撤权/废止使bundle失效。Compose仅提供目标约束,调用同一受信生成入口,防止双次注入和旧prompt凭据。
|
||||
- **验证/出口**:两项目两成员普通任务不用@knowledge、项目A特有节点不进B、私域资料不共享、恢复/撤权后从实际模型输入中消失,冲突和裁剪显式出现;source ID/revision/hash和输入manifest可回查。不能仅用`KnowledgeSearch`返回命中证明模型真实看到或使用。
|
||||
|
||||
### W8. RDM审计事实、失败尝试和可读操作投影
|
||||
|
||||
- **需求/owner**:TT-A01–A04/U01/U03/U04;RDM领域/应用owner。前置W4/W5,W9宿主部分可并行落入。
|
||||
- **文件**:`internal/domain/eventlog.go`、`payloads.go`、`replay.go`、`internal/domain/store/store.go`、`internal/rdmapp/tx.go`、`inspection.go`、`inspection_visibility.go`、领域操作/权限入口及服务端测试;新增`operation_audit.go`、类型化DTO/词典与投影索引。
|
||||
- **实施**:项目可信操作/attempt/commit receipt、人物当时名称/职责、各适用时间、对象前后版本/差异/理由/证据、实际直接/间接影响、错误及未知状态。成功事实与领域事件同事务,失败尝试不写已生效事件;宿主回执用可信run关联、幂等摄入并保留延迟状态。按**operation**分页,游标绑定项目/主体/授权epoch/筛选/截止,内部payload绝不直下客户端。旧缺项标“当时未记录”,当前名称只标“当前”。
|
||||
- **验证/出口**:阶段1§7.1六类操作逐动作覆盖矩阵,至少各有成功、拒绝/失败和无副作用实例;网络断开、提交前/后崩溃、outbox重试/重复、人物改名、旧schema、跨页多事件、迟到宿主回执、历史截止、权限字段差异。每个操作能回答谁/何时/做了什么/内容前后/依据/真实结果和影响;不以原始op码或JSON作为业务记录。
|
||||
|
||||
### W9. 基座公开X2:项目宿主审计与可信参与者姓名
|
||||
|
||||
- **需求/owner**:TT-A01/A02/A04/U04;Backend基座owner,Dev四要素申请;W0后可与X1兄弟分支开发,最终按主干顺序同步surface。
|
||||
- **文件**:Backend `pkg/extension/extension.go`、`surface.txt`、`internal/app/hostcaps.go`、`internal/store/audit.go`、相关server/hostcaps测试;RDM `perms`/审计适配消费端。
|
||||
- **实施**:可选ProjectAuditHost按受信项目、actor、resource、run、source offset与截止读取,结合RDM `audit.read`回调和每对象正文权作服务端裁剪;为本操作已验证参与者保存最小当时显示名,不给审计员全账号目录。owner全量审计不当作项目流;缺基座能力返回unsupported覆盖范围。
|
||||
- **验证/出口**:同owner跨项目/两成员、恶意projectId、audit.read无正文、正文无audit.read、对象已撤权/删改、历史、导出和长分页;旧记录不补造字段。RDM消费与W8的domain水位/宿主offset组合不声称天然全局时间序。
|
||||
|
||||
### W10. 正式Frontend与现有工作区
|
||||
|
||||
- **需求/owner**:TT-D02/U01–U04/V03及两树一网可读入口;Frontend owner,UI仅有必要新原语时单独组件PR。前置W3–W9稳定读写合同。
|
||||
- **文件**:Frontend `src/components/RdmAuditWorkspace.tsx`、`src/api.ts`、相应项目/任务工作组件与测试;`e2e/rdm-audit.playwright.ts`及新增结构提案/依据场景。维护已合入Frontend #73的导出与水位,不重造第二下载或预览入口。
|
||||
- **实施**:笔记树/文档树递归懒加载、知识多挂载、工作卡呈现候选差异/影响及确认/拒绝;普通对话显露本次实际依据。审计列表业务中文摘要、人物、时间/结果/对象路径,展开字段差异、来源/确认链/当时与当前影响、权限内证据跳转。旧数据/无权限/部分覆盖/加载/错误可读;右栏收起仍有对话确认路径。页面只消费服务端已裁剪DTO,单一异步状态owner按seq丢迟到响应。
|
||||
- **验证/出口**:`npm test -- --run test/design-guard.test.ts`及相关Vitest;`npm run build`;指向auth-on真实RDM产品组合的Playwright测试(现有`e2e/rdm-audit.playwright.ts`扩展,命令`npm run e2e -- e2e/rdm-audit.playwright.ts`按实际配置核对)。视觉检查浅/深主题、窄屏、长对象名和Collapsible;网络响应不得包含无权正文或原始重放payload。
|
||||
|
||||
## 5. 全量模板、正式验证与交付
|
||||
|
||||
### W11. DHF U2–U6:固定实例、生成、Word和44份逐项发布
|
||||
|
||||
- **需求/owner**:TT-T01–T04/D01/D04/G01/V01–V03;原DHF任务owner。阶段5批准若覆盖此跨任务工作,原任务卡先引用本计划及批准对象,再在原登记worktree继续;不得由本任务或另一分支并发改写资产目录。
|
||||
- **前置/文件**:W1已合入,W3/W4/W7接口已就绪;DHF既有方案U2–U6涉及RDM `templates.go`、`templates_embed.go`、`structure.go`、`compose.go`、`draftproposal.go`、`docsubmission.go`、`docx.go`、`doc_export_visibility.go`、`plugins/rdm/plugin.go`、模板包及`docs/records/dhf/`。Frontend消费W10的同一状态/预览路径。
|
||||
- **实施顺序**:U2不可变发布包、显式用途绑定及实例化;U3有依据的逐块生成与真实编制人采纳;U4固定批准快照的原模板槽位渲染、受控下载和历史文件持久保存;U5正式RDM产品的对话/预览/离线包;U6按文档族扩至44逻辑资产。试点用项目建议书、系统需求和F02压力样本,但试点成功只放行该文档族后续,不替代全量完成。
|
||||
- **保真与发布**:每份保留原件、转换派生、结构、渲染与review绑定hash;人工逐项裁定内容、蓝字/斜体/黑字示例、图形、表格/合并、页眉页脚、编号、关键格式与中文可读性。公司固定文字/项目示例、IQ/OQ/PQ/F02用途和旧DOC 49字符未定位单独列裁定。任何未通过项保持needs-review/blocked。可批准人工重建结构/槽位的替代路线,但须有同等级原件对照,不静默降标。
|
||||
- **验证/出口**:每个发布资产一个有真实合成材料的正常样例与一个缺证据/冲突样例;在RDM真实产品运行“对话→生成候选→编制人采纳→审核/批准→固定Word→预览/下载”,三用户职责及撤权通过;旧批准Word在短期工件TTL后字节hash不变。`GOWORK=off go test ./internal/domain ./internal/rdmapp ./plugins/rdm -run 'TestDHF|TestTemplateBinding|TestApprovedWord' -count=1`及`make test`/`make product`或当前真实构建入口辅助验证。44/44均有逐文件结果;**目标完成需要适用且已发布的资产全部通过**,blocked条目明确保持目标未完成,不将44/44“登记”误写为“可用”。
|
||||
- **停止条件**:新转换试验超过既有授权、原件hash漂移、槽位有歧义、关键格式无可读基线、人工语义结论缺失或旧批准文件保全失败,立即停止对应资产发布;其他已授权独立工作可继续。
|
||||
|
||||
### W12. 全目标组合验证、模型行为与正式验收
|
||||
|
||||
- **需求/owner**:TT-V01–V03及全部28项最终证据;Dev协调者、各组件测试owner和用户阶段7审阅。
|
||||
- **场景矩阵**:至少项目A(软硬件结合、用户需求12组、已发布知识/受控文档)与项目B(不同阶段/主题、私域资料、不适用模板规则);每项目两名普通成员,另有文档编制/审核/批准职责的三个真实测试身份。覆盖新建/模板升级、项目自有扩展、提案拒绝/改后接受/确认、并发/失败/重启/撤权/项目切换、UN→SR→DI→设计→测试及风险链、当时/当前影响、可读审计与权限内证据跳转。
|
||||
- **域/数据库**:SQLite与隔离PostgreSQL各完成迁移/重放/幂等;测试备份含原库、模板包、附件和批准Word,注入迁移中断/回滚/未知新schema、两实例并发写及旧二进制拒绝。没有可用PG环境则标NOT_RUN并阻塞对应正式验收,不以SQLite替代。
|
||||
- **真实模型**:改前/改后同一合成任务集,在已经配置且有明确费用上限的隔离模型环境运行;普通工作不加@knowledge,检查实际最终ContextManifest、输出引用/缺项、项目/私域边界、恢复撤权及错误引用。基线`modules/backend/eval/live/`可复用公开HTTP和usage统计,但它的旧用例默认自动选择首个HITL选项;本任务新提案用例**必须禁用自动确认**,由测试操作者用真实用户身份和绑定修订的显式确认动作完成。模型自述不能充当实际输入证明。
|
||||
- **模型试验资源边界**:拟最多48次任务运行(24个改前+同任务24个改后),全部模型总usage不超过300,000 tokens且费用上限人民币150元,三个上限任一先到即停。用不含生产/个人秘密的合成项目材料;每次调用前确认所选实际模型的可计费规则与剩余额度,运行时逐次累加usage。无法获得可信费用/usage数据或配置需更改时停止收费调用,保留NOT_RUN并提交修订预算;不自动购买额度。正式模型使用本计划经阶段5批准后才授权,除此之外的付费模型调用另行批准。
|
||||
- **浏览器/产物**:构建固定Backend/Frontend/RDM组合和模板包,在auth-on隔离实例做真实浏览器流程;包括右栏收起、窄屏、审计筛选/操作跨页/历史、无权网络响应、唯一预览、文件字节和DHF逐文件状态。浏览器证据记录运行制品hash、组件/pins/配置及实例身份;Vite预览不能代替实际产品。
|
||||
- **正式命令/出口**:各仓当前HEAD的`make test`及`make build`;Dev `make test`+`make build`及适用`make test-backend-pg`/`make test-lifecycle`/真实组合检查,缺必需服务为失败或NOT_RUN并阻塞;RDM `make product-smoke`与包外运行。阶段7先`make task-sync`固定候选,按需求ID→工作项→检查→当前SHA/输出形成矩阵,由用户审阅正常/异常/边界/回归与缺项;SELF不升级为CI/独立REPLAY。
|
||||
|
||||
### W13. Review、PR合入、组合核验和收口
|
||||
|
||||
- **owner/顺序**:组件分支各从权威`origin/main`启动;DHF U1和公共X1/X2先过各自Review/CI并在获准条件下合入,RDM消费经用户发布的真实基座tag,Frontend固定UI/Core契约,最后RDM产品与Dev组合。若确需堆叠按仓库`PARENT/PARENT_PR`登记,父先合、子同步回main;同一共享文件由单一owner串行,不跨任务隐式接管。
|
||||
- **准入**:阶段6每增量有人审,阶段7固定候选后有人审;阶段8由智能体审阅者重放最小关键集并解决问题;阶段9在同一目标窗口核验最新base/head/精确pins/必需当前HEAD CI与平台准入后智能体合入,不另请人工点击。相关审计导出/水位和工作发现PR若先合入,重新评估契约及受影响测试。缺CI/失败/取消/跳过、Review失效或基座tag未就绪均不合入依赖PR。
|
||||
- **结果核对**:查询真实PR merge SHA和实际组件指针;核对RDM制品内模板包、Frontend bundle、Backend API与被测候选一致,产品浏览器再现主要路径。部署和生产迁移另经明确授权;阶段10回收前核对全部写者退出及本任务/DHF唯一成果,外部备份stash/原件/收据有处理清单,不强删工作区。任务卡归档及闭合PR按既有门禁完成。
|
||||
|
||||
## 6. 横向覆盖与完成判据
|
||||
|
||||
以下表格将28项需求逐一绑定工作项及证据;阶段5批准后按实际代码/测试版本在任务卡更新。每项的产品测试状态当前都是NOT_RUN。W0/W1的SELF资产现状、E1产物和本计划不能替代正式功能/模型/浏览器证据。
|
||||
|
||||
| ID | 负责工作项 | 最小实际证据 |
|
||||
|---|---|---|
|
||||
| TT-T01 | W0/W1/W11 | 44原件hash、逻辑用途、发布门禁和包外读取 |
|
||||
| TT-T02 | W0/W1/W3/W11 | 多级块、表格/图形/修订/示例的44份原件对照及人工格式结论 |
|
||||
| TT-T03 | W0/W3/W11 | 不同项目适用规则、未知/不适用确认与进度分母 |
|
||||
| TT-T04 | W3/W4/W11 | 模板/实例/批准版三层hash及升级历史 |
|
||||
| TT-N01 | W2/W7 | 知识唯一ID多挂载、来源、结论取代及问题登记 |
|
||||
| TT-N02 | W2/W4 | 项目A/B扩展隔离、旧标签与重放 |
|
||||
| TT-D01 | W1/W3 | 递归混合块、稳定ID、移动/同名与旧Section兼容 |
|
||||
| TT-D02 | W4/W10 | 各触发、确定人工确认、拒绝/重启/改后接受 |
|
||||
| TT-D03 | W4/W12 | 并发CAS、幂等、事务失败、重启后零半态 |
|
||||
| TT-D04 | W3/W4/W11 | 三权职责、状态及旧批准版本保持 |
|
||||
| TT-G01 | W5/W11 | 一般来源和受控UN/SR/DI/风险/软件验证链及缺边 |
|
||||
| TT-G02 | W5/W8 | 端点升版待复核、直接/间接影响与水位 |
|
||||
| TT-G03 | W0/W2/W5/W7 | 人工/规则/模型/文件/网络来源与精确锚点 |
|
||||
| TT-C01 | W6/W7/W12 | 两项目成员普通工作实际输入,无@knowledge |
|
||||
| TT-C02 | W6/W7/W12 | 按需读取、预算裁剪、冲突/缺项及不可信来源 |
|
||||
| TT-C03 | W6/W7/W9/W12 | 发布/私域/职责、跨项目/撤权/恢复无泄漏 |
|
||||
| TT-C04 | W6/W7/W12 | 最终输入manifest、版本/水位与恢复刷新 |
|
||||
| TT-A01 | W8/W9/W11 | 六类逐动作覆盖及宿主缺项 |
|
||||
| TT-A02 | W8/W9 | 当时身份/时间/内容差异/依据/确认/影响字段 |
|
||||
| TT-A03 | W4/W8 | 成功、失败、拒绝、取消、部分完成、未知与实际效果一致 |
|
||||
| TT-A04 | W8/W9 | 受信run/宿主关联、迟到回执、历史缺项诚实出口 |
|
||||
| TT-U01 | W8/W10 | 中文业务摘要/前后差异/影响;默认无原payload |
|
||||
| TT-U02 | W5/W8/W10 | 对象标题路径、权限内锚点及唯一预览 |
|
||||
| TT-U03 | W8/W10 | 按操作分页/完整归组、筛选、历史/迟到响应 |
|
||||
| TT-U04 | W8/W9/W10 | audit.read与正文权限交叉及网络/导出投影 |
|
||||
| TT-V01 | W0–W13 | 需求→当前精确对象→正常/异常/恢复证据矩阵 |
|
||||
| TT-V02 | W6/W7/W12 | 真实模型前后对照与实际依据使用 |
|
||||
| TT-V03 | W10/W12/W13 | 真实浏览器、设计守护、精确组合和当前HEAD CI |
|
||||
|
||||
完成声明须同时满足:44份原件各有经过内容/格式审核的可发布资产及明确适用范围,并在各自适用项目完成生成/审签/Word对照,blocked项清零;一个项目选择“不适用”不能豁免整份资产的交付;项目差异结构及真实人工确认;默认成员授权上下文;完整且可读审计;旧数据/并发/撤权恢复;两项目两成员真实模型和浏览器;当前精确组件与CI/REPLAY/阶段7审阅。哪项缺证据就标NOT_RUN/未达目标,不把局部增量说成整个两树一网完成。
|
||||
|
||||
## 7. 停止、变更和评审事项
|
||||
|
||||
| 触发 | 动作与责任 |
|
||||
|---|---|
|
||||
| 原件、合入的DHF合同或公开扩展与本计划不同 | 负责owner锁定真实SHA和差异;等价细节在阶段6内自检修订,改公开契约/数据/权限/技术路线则回阶段4评审 |
|
||||
| DOC或44资产关键保真无法核对 | DHF owner保留blocked及完整差异,继续不依赖该资产的工作;新试验提交范围/隔离/预算获批后执行,不降低零关键静默丢失条件 |
|
||||
| 同一文件有两个未合入写者/共享工作区脏 | 保留各自现场,指定唯一owner与合入顺序;不强制清理、覆盖或偷用另一分支结果 |
|
||||
| 凭据、真实模型费用或隔离环境不满足预算 | 停止对应模型/浏览器/测试,不补写PASS;用户审阅具体缺项和调整后的资源方案 |
|
||||
| 历史数据、批准文件或权限边界无法保全 | 停止迁移/交付受影响增量,保留备份/固定对象与错误收据,回设计/计划受影响节点重审 |
|
||||
| 组件base/head、tag、schema或CI定义改变 | 重新判断已有证据与批准有效性;阶段7–9按当前目标同步、补测/复审并核验全部必需检查 |
|
||||
|
||||
请在阶段5评审时同时确认:W0–W13的依赖和四个阶段6增量、DHF U2–U6仍由原工作区owner交付并在其任务卡引用本计划、48次/300,000 tokens/人民币150元的模型上限,以及仅在隔离副本进行数据恢复演练。批准本计划才进入阶段6;业务代码、真实模型、浏览器、CI交付和部署在本文编写时均未执行。发布基座tag、真实运行库迁移及部署继续遵守各自明确授权边界。
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# 阶段5增补实施与测试计划:普通工作来源与主动风险澄清 r1
|
||||
|
||||
记录日期:2026-10-14(Asia/Shanghai)。状态:**待人工评审**。用户在本聊天 `call_a6853c4232f34285a6cbae19dfbeeec5` 第0项批准[受影响阶段4方案r1](rdm-two-trees-stage4-work-observation-risk-design-r1.md),固定 SHA256 `c9edb25c1decbbcb31220ef0cec8703c37e4aaa87bee31eb308169000b335d8c`,只授权形成此阶段5计划。需求依据是[阶段3增补需求表r1](rdm-two-trees-stage3-work-observation-risk-requirements-r1.md)的 TT-N03、TT-R01;[原阶段5计划r1](rdm-two-trees-stage5-implementation-test-plan-r1.md)的 W0–W13、原28项与已批准实施保持有效。本稿获批前不写 X3 产品接口或据此执行收费模型任务;阶段6现有 W2/W3/W4a/时间等不受影响的工作继续。
|
||||
|
||||
## 1. 交付范围、owner 与依赖
|
||||
|
||||
本增补把“观察到、分析完、允许分享、成为项目事实、实际进入模型输入、相关业务动作已提交”分别设为可观察状态,不能用任一中间 ACK 代替后一步。新增 X3 是 Backend 可选公开能力,基座仓 owner 负责来源可信身份、持久 outbox、四运行器接入、同步动作前屏障和最终消息显示时序;RDM 仓 owner 负责来源切片、候选/风险账本、项目权限、HITL 回执、有效两树一网与审计。Frontend 仓 owner 负责在现有工作台呈现来源状态、澄清卡与可读影响;UI 仓仅在已有原语不足时由组件 owner 单独改动。Dev 仓 owner 固定跨仓合同、gitlink、任务卡与组合证据。DHF U2–U6仍由原工作区 owner 续办,新增观察能力不得代替44份逐文件验收。
|
||||
|
||||
实施依赖按实际发布关系而非旧本地探针判定:
|
||||
|
||||
1. Dev 与 Backend owner 先核对最新 `origin/main`、X1/X2 的真实公开状态、已有迁移号和 surface;Backend 在其登记任务工作区实现 X3,并把 X1/X2/X3 合成一份可测试公开面。当前 `d9b00c2` 只是本地 X1/X2 组合探针,不能被 RDM 当已发布 tag 消费。新 X3 与 X1/X2 的 owner、迁移、surface 冲突在 Backend 最终候选里解决,按原仓 Review/CI 处理;正式 tag 仍由用户亲手发布。
|
||||
2. RDM 可先在隔离分支实现不依赖 X3 的候选/风险纯领域逻辑及 SQLite/隔离 PostgreSQL 测试;只有 Backend 最终公开 tag 真正存在、RDM `go.mod` 与 Dev gitlink 指向该固定版本后,才接入受信观察与宣布端到端可用。W2 字典、W3 文档实例、W4b 真人结构确认、W5 追溯网是正式入网的前置业务能力;来源候选可以先落账,但不能假扮这些工作已完成。
|
||||
3. W7 消费被确认、当前授权的候选和 X1 实际输入 manifest;W8 输出类型化审计;W10 使用同一 RDM 风险状态及 Backend 卡投影。W12 在固定组件 SHA 后做两项目两成员、真实模型、真实浏览器与故障注入。每个独立仓先执行自己的 precheck/task-start 或已登记 task-resume;相互依赖的代码顺序推进,共享工作树只允许其当前 owner 写。
|
||||
|
||||
## 2. 工作包、可审查出口与测试
|
||||
|
||||
| 包 / 关联需求 | 唯一代码 owner 与范围 | 局部完成条件和必须重放的测试 |
|
||||
|---|---|---|
|
||||
| X3a 受信信封与事务投递 / TT-N03 | Backend:`pkg/extension` 公开可选 registry、运行/消息持久化、资源/检索引用、outbox 和迁移;RDM只消费公开包 | 用户消息入库时 RunID 可空、命令从持久 conversation 取项目;最终助手 MessageID/seq 与观察同 fenced 收口;每来源/part 有稳定 ID、source版本/hash、actor、时间、scope、处理状态。崩溃前后/重复投递、同键异hash、缺 part/offset、撤权墓碑后迟到事件、跨项目伪造都有确定结果;旧无绑定消息不批量补造。SQLite 与隔离 PG 的失败注入须证明消息/outbox 原子和不丢源。 |
|
||||
| X3b 实际四路捕获与前置屏障 / TT-N03/R01 | Backend:direct、SubLLM、Squad、CompiledWorkflow 的检索/工具真实结果边界、模型输入组装、聊天命令入口、SSE 收口 | 每路分别用三条命中、工具原始结果及只留摘要反例,逐条核对实际给模型的片段和输入 manifest;未知全文标 `partial/summary-only`。本轮用户消息已提交但 outbox 未送达、`Observe accepted` 未分析、缺口/提供方超时均阻止相关模型/命令和后续项目写入;重试恢复恰好一次业务效果。项目回复正文先完成风险决定与 fenced 最终消息提交,再按 MessageID/seq 发首个正文,且先于 run.completed;断线重连不重影。测缓冲上限、长文本、延迟和零项目读写白名单,不能从旧流式 delta 推断通过。 |
|
||||
| R3a 来源候选、双重分享权 / TT-N03 | RDM:项目事务库候选/切片、sourceRef、去重与失效、Backend 受信原件/派生片段检查;Backend owner 实现 SourceExcerptGrant 和权威状态查询 | 一段话拆两要求,用户/助手复述只聚合语义但保留各自来源;搜索 URL/查询/时间/片段、可见分析结论与依据可回指。私人 A 原会话仍只给 A;A 经真人卡批准确切原片段和**最终将公开的文本/hash**,Backend grant 与 RDM 项目发布许可均有效后 B 可读派生摘要 X,却不能打开 A 原会话。X 被编辑成 Y、混入第二私域来源、任一 grant 撤回、源删除/修订或 Backend 权威不可用时,新输入/详情/Word 当前下载/正式写入均拒绝受影响正文;历史批准字节保留。撤权 outbox 故意延迟仍不泄漏。 |
|
||||
| R3b 风险判定、HITL 与业务门禁 / TT-R01 | RDM:同库 riskID/版本/证据/状态、规则与可选模型候选、事务 `Preflight`/`Respond`;Backend 复用现有 AskHITL/ActivityCard 并等待 RDM CAS 回执 | 先查片段的量纲/方向/条件,再比当前可读候选、正式要求、基线;“效率和成本都低于人工”在正式写入前同轮澄清三种意思,不擅自更改原句,也不把它自动判死为矛盾。卡点击只有 RDM 回执提交后恢复 run;回执丢失按同键查询,迟到答复/撤权/版本变化不得套用。风险澄清与 W4b 正式一次性确认分离;`rdm.reqs.add` 等旧正式入口与新入口同做提交前源状态、风险、actor、权限、项目/目标版本复验。误报、忽略、拒绝及动作零生效各有记录。 |
|
||||
| R3c 已确认上下文、追溯与审计 / TT-N03/R01 | RDM W5/W7/W8,Backend X1/X2 owner 维持真实来源/宿主链接 | 仅已确认且当前有权、来源状态有效的节点/片段进入普通成员下一轮模型输入;私域候选可给本人显示待审状态,不变成跨成员有效事实。发布/取代/撤权列出直接和间接网边待复核。审计分开保存观察、候选、风险/答复、确认、实际效果的人物、各自时间、前后差异、依据、影响及未知项;私人观察不因项目ID自动进入跨成员宿主审计。审计服务端 DTO 只投当前可见字段及中文摘要,旧缺项如实显示。 |
|
||||
| F3 可读工作台 / TT-N03/R01 | Frontend owner;按需 UI owner | 中栏与右栏同一 riskID/revision,一处回答另一处同步,右栏收起仍可答;来源分段显示候选/待分析/受限/失败、锚点和受控操作,不显示原始审计 payload。单一异步状态 owner 按 seq 丢弃旧事件;跨项目切换、撤权后卡片/详情/网络响应不泄露私人正文。修改界面前读 Dev `DESIGN.md`,字号/颜色/圆角用 UI tokens、动效用 motion、折叠用 Collapsible,通过两仓 design-guard。 |
|
||||
| V3 固定组合验收 / TT-N03/R01 及原28项 | Dev 组合 owner;各组件 owner 提供当前 SHA 与证据 | X1/X2/X3 真实公开版本与 RDM/Frontend/Dev 精确 pin、Backend/RDM/Frontend 各自直接测试、`make test && make build`、当前 HEAD 的 CI/独立 Review、真实浏览器和受限模型对照均记录命令×SHA×输出。缺某仓 tag/接线、只见局部 SELF、模型自述“已提醒”或只见 SSE 发送,均不得判端到端 PASS。 |
|
||||
|
||||
X3a/X3b 与 R3a/R3b 的公开接口和数据库迁移若实施中改变阶段4职责、权限或时序,先形成受影响设计修订并人工评审;等价的局部缺陷修复仍在阶段6已授权范围内继续。所有版本化迁移只在隔离 SQLite/PG 副本实施,先验证含旧记录恢复及降级 fence;真实运行库迁移和部署不在本计划授权内。
|
||||
|
||||
## 3. 分层场景和测量方法
|
||||
|
||||
**确定性场景。** 每路捕获与RDM领域测试至少包含两个项目、两个普通成员、一个受控文档成员;四类来源各有相关/无关样本、同一源多切片、搜索三命中一条仅摘要、分析产物有/无可见依据、助手复述去重。来源身份/权限矩阵覆盖原始会话、派生摘要、项目成员、audit.read、文档职责和撤权;客户端伪造 projectID/actor/confirmed、搜索页提示注入、同键异参、单个 part 缺失、outbox 乱序、Backend/RDM 崩溃、风险 CAS 丢回执和旧历史缺项都须保留可重放输出。权限测试检查 HTTP/模型输入/浏览器网络正文,不能只验页面隐藏。
|
||||
|
||||
**风险样本。** 固定例句“三种解释”,再覆盖同主题不同周期数值、单位相反、与批准章节冲突、无证据助手建议、伪造用户确认、真允许效率较低、正常无关句及私域不可比较对象。断言必须是:在受影响写入前同轮可见澄清或待处理卡;回答前实际项目事务零提交;有权真人澄清、必要 W4b 正式批准后恰好一次生效;原句/答复/actor/时间/版本/影响可读审计;误报、暂缓、重启、撤权、卡片迟到响应保持正确状态。无权主体只见不泄露原句或隐含对象存在的阻塞状态。风险规则/模型为候选,不能自签批准。
|
||||
|
||||
**真实性和性能。** 对比实际来源逐项处理完成率、风险前置提示/误报、模型最终输入 manifest、阻断前是否有实际效果、用户可读审计。记录每路消息提交至首个可见正文的 p50/p95、缓冲峰值、outbox积压及重放耗时,用隔离样本报告成本与未达场景;本计划不虚构固定性能阈值,超预算时应保持待处理且提供进度。浏览器证明中栏、右栏、折叠、断线重连与审计字段投影;SSE 发出不等于浏览器已显示,若验收需确认可见送达,使用客户端 ACK/可复核浏览器记录。测试数据为合成内容,不把私人或生产原文送至收费评测。
|
||||
|
||||
**真实模型预算。** 继续消耗原 W12 的**同一总额**:最多48次任务运行、累计300,000 tokens、人民币150元,任一先到即停;将指定歧义、跨来源冲突、无关/误报、撤权后的输入刷新替换进原24组前后对照,不新增48次额度。逐次记录模型、配置、输入/输出 manifest、usage、价格依据、累计费用和 SHA;拿不到可信 usage/费用即停止付费调用,标 NOT_RUN 并提预算修订。阶段5获批后才可按这个总预算执行新场景;不能用模型的自我宣称替代事务、UI 和来源证据。
|
||||
|
||||
## 4. 需求到证据与评审出口
|
||||
|
||||
| 稳定需求 | 固定方案和工作包 | 阶段6/7可判定证据;当前状态 |
|
||||
|---|---|---|
|
||||
| TT-N03 | 阶段4§2–3;X3a/X3b、R3a/R3c、F3、V3 | 四来源逐项最终状态、源ID/版本/hash/span与实际检索引用;候选/分享/授权交叉、同义去重、撤权及恢复、下一轮当前模型输入 manifest;两项目两成员浏览器与固定组合。产品链 **NOT_RUN**。 |
|
||||
| TT-R01 | 阶段4§3–5;X3b、R3b/R3c、F3、V3 | 指定语句与风险样本的同轮提示/卡、业务零提交及真人后恰好一次、原话和答复分离审计、无权/迟到/重启/误报/流式前置屏障;真实模型和浏览器。产品链 **NOT_RUN**。 |
|
||||
| 原 TT-N01/G03/C01–C04/D02/D03/A01–A04/U01–U04/V01–V03 受影响行 | 原阶段5矩阵保持;本稿 R3/F3/V3 增补逐来源及动作前条件 | 原证据仍逐项有效但不能覆盖新增来源和风险;阶段6实施记录补每个当前代码 SHA 与失败/未执行项,阶段7全目标候选统一核验。 |
|
||||
|
||||
每个工作包给出 owner、固定代码 SHA、直接相关命令及完整脱敏输出、局部结果和未执行项;Dev 任务卡只用 `make evidence` 导入完整 SELF 收据,CI/独立重放分别标 GATE/REPLAY。阶段6按原 A–D 增量评审:X3/R3 的新候选可提前隔离开发,但新增 TT-N03/R01 不因原增量 A 局部通过而宣告完成;当其真实组合可审查时同相应受影响增量提交人审,阶段7再对30项统一验收。Review/PR/合入依 `policy/delivery.md` 的阶段8–9和当前 HEAD CI;真实迁移、基座 tag、部署各守原边界。
|
||||
|
||||
**停止条件。** 任一来源没有可信绑定/原件、Observe 与风险处理水位不一致、私域许可不全、来源权威无法重验、已有正式入口绕过事务门禁、项目可见正文早于风险决定/最终消息提交、完整源被截断却标完整、风险卡以 Backend 点击代替 RDM CAS、或费用/usage无法核算,停止受影响业务动作及相应通过声明,保留状态和可读原因。局部检测到这些失败先修复和重放;若需改变已批准阶段4接口/权限/成本边界,则形成修订送相应阶段人工评审。
|
||||
|
||||
请评审此增补实施与测试计划。批准仅将 TT-N03/R01 的 X3/R3/F3/V3 本地实现、隔离测试与原预算内模型评测纳入阶段6,不等于批准真实库迁移、发布 tag、部署、增量验收或全目标完成。
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# 阶段6受影响设计修订:跨成员项目宿主审计关联 r1
|
||||
|
||||
记录时间:2026-10-14T11:44:03.481784+08:00。状态:**待人工评审**;影响已批准阶段4方案§8.3 X2及阶段5计划W9/W8的公共合同与测试。阶段1–3范围、DYN-01、W2项目字典、W6上下文和W9已批准的安全局部不变。W9尚未完整交付,跨成员已提交业务操作的关联功能在本修订获批前不写入正式公共API。
|
||||
|
||||
## 发现和证据边界
|
||||
|
||||
Backend当前 `command_audit` 是owner/会话日志。W9隔离分支通过正负例发现:仅以会话当前projectId连接旧行,可能在会话后来转移时重归属旧操作;若对持`audit.read`者返回同项目全部行,还会暴露别人的**私有会话**。W9正在将新审计行在写入时固定可信projectId,owner仅看自己的项目绑定命令,旧无快照行明确not-recorded。这是安全且可审的局部能力,**不能**作为完整跨成员项目审计。
|
||||
|
||||
已批准X2设想按受信项目和RDM `audit.read`查询宿主回执,但当前Backend没有“某条宿主命令确实对应已提交、可共享的项目业务操作”的可靠关联。`project_event_shares`与`command_audit`缺少共同的sourceEvent/operation关联;会话项目绑定只证明定位,不证明该会话内容已发布。这个缺口影响TT-A01/A02/A04、TT-U04、W8/W9/W12;若不补,用户不能可靠审阅同项目另一成员实际推动的命令/后台操作。
|
||||
|
||||
此结论基于源码及W9当前隔离分支的SELF测试结果;未将其标为已合入或生产验证。W9当前可继续完成固定项目快照、owner私域读取、缺项coverage与负例;跨成员扩展等待本修订结论。
|
||||
|
||||
## 方案选择
|
||||
|
||||
| 路线 | 后果 | 决定建议 |
|
||||
|---|---|---|
|
||||
| 会话当前projectId + audit.read直接共享全部命令 | 私域泄漏且历史归属可变 | 拒绝 |
|
||||
| 永远只读owner自己的命令 | 安全,但缺少同项目已提交业务操作的宿主追溯 | 保留为W9首段能力,不能满足完整目标 |
|
||||
| 对**已提交项目业务事实**建立受信宿主链接,仅共享经字段授权的回执 | 需要新增最小公共写/读合同和幂等索引;可区分私域与项目事实 | 推荐;补齐W9而不重做owner日志 |
|
||||
|
||||
## 建议合同
|
||||
|
||||
在X2基础上增加可选`ProjectAuditPublisher.PublishProjectAuditLink`。申请四要素为:
|
||||
|
||||
| 要素 | 内容 |
|
||||
|---|---|
|
||||
| 场景 | 成员A确认结构/文档/关系等项目业务操作后,具项目`audit.read`且获对象披露许可的成员B可看到此操作相关的真实工具/后台结果;A的普通个人会话不因此共享 |
|
||||
| 希望的公开符号 | 可选`ProjectAuditPublisher.PublishProjectAuditLink(ctx, ProjectAuditLinkRequest)`及`ProjectAuditLinkVerifier`注册回调;扩展`QueryProjectAudit`只返回owner自有行或已验证链接允许披露的项目行,附coverage和稳定分页水位 |
|
||||
| 既有接口不足 | 原`Host.Audit`只写owner日志;会话/项目当前关系不能证明业务提交或可共享性;RDM事件outbox与Backend命令审计缺同一可信关联键 |
|
||||
| 兼容性 | 全部为可选加法接口,旧Host和旧记录不变;无新能力时`coverage=cross-member-unsupported`,未链接旧行不自动回填成项目事实;不修改RDM pins或导入Backend internal |
|
||||
|
||||
链接请求最少含:Backend固定的hostAuditOffset/受信owner+项目,RDM已提交的domainCommit或Backend已提交的projectEvent来源种类与sourceID,operationID、resourceKind/resourceID、runID、disclosureClass和幂等键。**客户端、模型或未受信插件不能自行宣布已提交/可共享。** Backend验证原审计行属于同一owner与当时projectId;RDM注册的校验器以RDM存储核验source event已提交且项目/主体/操作/资源一致;Backend自身项目事件用自己的持久事实验证。只有受信执行链能申请链接。
|
||||
|
||||
索引按hostAuditOffset+sourceKind/sourceID保存不可变关联及项目、操作、资源和披露级别;同绑定重复幂等,异绑定拒绝,不重复增加业务效果。查询端先校验当前project `audit.read`,再调用领域资源披露判定:metadata、内容差异、历史正文、导出分别独立授权。无权正文的字段在服务端不下发;必要时隐藏对象是否存在与计数。普通owner私有会话仍只属于本人,不能只因它有projectId就出现在共享列表。
|
||||
|
||||
领域事务先提交业务事件和待投递outbox;后台把真实hostAuditOffset与domainCommit绑定并可重试。Backend不可达或查询结果未知时,RDM保留领域事件与“宿主链接待核/未知”状态,先查幂等回执后恢复,不回滚已经成功的业务提交,也不伪称宿主证据不存在。日志和索引使用各自source offset及RDM commit水位;完整操作分页在RDM投影层完成,不假定两来源有统一天然seq。
|
||||
|
||||
## 数据、授权及回归判据
|
||||
|
||||
- 新审计行写入时固定当时可信projectId;旧没有可信快照/提交链接的行保持owner私域或历史缺项,不按今天的会话归属回填。
|
||||
- 两成员同项目:A私有会话命令对B不可见;A确认并提交的结构操作经可信链接后,B若有`audit.read`且可看对象元数据则可读授权摘要;正文/差异按当前资源权裁剪。
|
||||
- 会话项目从P1转至P2后,历史链接仍固定P1;P2审计读面不能见P1旧操作。成员撤权、文档职责变化、对象废止和下载另作字段及访问复核。
|
||||
- 重复投递、同key异link、outbox部分失败、链接前/后进程退出、旧schema、跨页大批次及迟到链接均保留真实结果;不泄漏其他项目/owner,时间排序不伪造跨源提交顺序。
|
||||
- 发布合同前在Backend `pkg/extension`给出公开接口/负例,RDM在自己任务中提供验证回调及投递适配;Frontend只消费RDM已裁剪的可读DTO。精确版本及三仓组合测试、真实浏览器和独立重放保留阶段5计划门禁。
|
||||
|
||||
## 受影响工作与评审出口
|
||||
|
||||
W9现有安全切片可以本地提交并进入阶段6增量C的候选;它的coverage必须明示跨成员未覆盖,不能报W9整体完成。**本修订获批后**再增加链接写/读、W8领域outbox适配、W10页面的已授权关联展示,按W12两个成员与私域/撤权场景验证。阶段5原预算与44模板工作范围不变;阶段7仍须完整TT-A/U证据。
|
||||
|
||||
请评审上述推荐的“已提交项目事实建立可信链接”合同。若否,需给出同等安全且能让项目有权成员审计真实跨成员业务操作的替代方案;不能以owner私域切片或会话当前项目连接宣称完整目标已实现。审批仅放行此受影响公共合同与相应测试,基座tag发布仍由用户按双钥匙亲手执行。
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
# 阶段6 Backend X1/X2 组合验证探针 r1
|
||||
|
||||
记录日期:2026-10-14。来源:本地 SELF 与两位独立只读审阅者的限域源码核对;**不是 CI/GATE、正式阶段7验收、已合入代码或已发布组件**。组合探针工作树 `/home/weichen/projects/Agent-System-Backend-wt-feature-rdm-two-trees-backend-combination-probe`,分支 `feature/rdm-two-trees-backend-combination-probe`,固定 HEAD `d9b00c23c818bfc4a8d8233c845266fabd863137`,未推送或建 PR。
|
||||
|
||||
## 对象与组合
|
||||
|
||||
| 来源 | 固定对象 | 作用 |
|
||||
|---|---|---|
|
||||
| Backend 权威 `origin/main`,组合前实际 fetch | `8e80e2618eb7471dd12d5f172ff3cd23622b7d2f` | 已有账号审计迁移 v31;主仓工作树未接管/未改写 |
|
||||
| X1 成员工作上下文候选 | W6 `d8129abead96be7c35ab2650e949ac817745e786` | 可信项目上下文、逐项来源复验、去原文回执及候选库清理 |
|
||||
| X2 项目宿主审计候选 | W9 `130ac344aaba988026fbc497c9548cdb59f5774f` | 固定项目审计、可信已提交链接及 PostgreSQL 全写入截止门禁 |
|
||||
| 仅本地组合探针 | `d9b00c23c818bfc4a8d8233c845266fabd863137` | 合并上述来源、解决共享文件冲突并验证;原 W6/W9 分支未修改 |
|
||||
|
||||
冲突保留两边意图:`hostcaps` 同时装 `contexts` 与 `projectAudit`;扩展 surface 同时列出 X1/X2,探针版本 `2.19.0-experimental`;离线复制同时保留 work task、context manifest、workflow step source 与 project audit link。迁移编号在探针中为 v31 `account_audit`,v32–v36 X1,v37–v40 X2;各迁移名称按顺序唯一。原已发布主干 v1–v31 名称与探针一致,独立未发布候选因复用 v31 等编号但名称不同,不能被当成已应用的另一套 DDL。
|
||||
|
||||
针对这一真实三方冲突,探针还加了 `(version,name)` 整账本校验:Backend 打开库时、`MigrateDown` 开始前及 `storage-migrate migrate` 打开目标前均拒绝同号异名源库。RED 证明原本会接受/执行错误下游步骤;新测试在探针 HEAD 通过。这个保护是**探针新增代码**,尚未进入 W6/W9 各自分支或主干。旧未发布候选数据库会安全拒绝,而不是自动重解释;若其中有需保留的独有数据,须在原版本隔离环境备份、净化和制定显式迁移/处置,不用数字碰巧相同来升级。当前两支候选未部署,未对真实库执行迁移。
|
||||
|
||||
## 本地检查与证据
|
||||
|
||||
三份完整脱敏原始收据已通过 Dev `IMPORT_RECEIPT=… make evidence` 原样写入 `.task/feature-rdm-two-trees-latest-templates.md`,均为 `SELF`,命令打印组合探针前后完整 HEAD 及 clean 分支状态:
|
||||
|
||||
| 检查 | 收据 | 结果范围 |
|
||||
|---|---|---|
|
||||
| `AGENT_PG_TEST_DSN=… go test ./... -count=1` | `/tmp/backend-combo-full-pg-d9b00c2-20261014.json` | 隔离 PostgreSQL 18.6 上 Backend 全包测试 exit 0;包含 SQLite 常规回归与有 PG 条件的测试 |
|
||||
| PG 定向 `go test -race` | `/tmp/backend-combo-race-d9b00c2-20261014.json` | store/app/runmgr/storage-migrate 的项目上下文、审计、候选清理和迁移负例 exit 0 |
|
||||
| `go vet ./...` + 两个静态构建 | `/tmp/backend-combo-build-d9b00c2-20261014.json` | Backend 服务与迁移工具编译 exit 0 |
|
||||
|
||||
非空 `work_task_bindings` 与 `workflow_step_sources` 的 SQLite→隔离 PG 复制,已在同一组合探针测试中从实际源行经各自读接口取回;审计链接与 manifest 亦有复制/对账测试。隔离 PG 只绑定本机 `127.0.0.1:55445`,测试后已停止;源码外目录 `/tmp/backend-combo-pg-20261014-Pkl5O2` 暂保留供核查,不是服务或真实数据库。独立限域审阅核对迁移顺序、两个注册槽、surface、离线复制列和固定收据,未发现探针新增高影响问题。
|
||||
|
||||
## 未完成与后续门禁
|
||||
|
||||
组合探针不能代替 W6/W9 各自从新主干同步、正式 PR 的 exact head/base、当前 HEAD CI 和平台独立批准;版本冲突的最终解法须在实际合入顺序下重做并复验。RDM W7 的真实提供方、W8 的领域操作/outbox/操作级分页、Frontend 人可读审计页面、44份模板发布、真实模型/浏览器与阶段6/7人工结论均未在本探针中完成。发布 Backend tag、迁移真实运行库、部署和清理仍遵守原授权边界。
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
# W6/W9:基座公开扩展申请 r1
|
||||
|
||||
依据:用户已批准[阶段4方案](rdm-two-trees-stage4-design-r1.md)与[阶段5计划](rdm-two-trees-stage5-implementation-test-plan-r1.md);当前处于阶段6实施。负责人:Dev/Backend公开面owner;领域策略与消费由RDM负责。此文是**实施申请与接口边界**,不是已发布surface或运行通过证据。Backend分支分别实现X1与X2,最终按最新主干串行同步其公共surface并做组合核验。
|
||||
|
||||
## X1:普通工作自动取得当前项目依据
|
||||
|
||||
| 必需四要素 | 申请内容 |
|
||||
|---|---|
|
||||
| 用户场景 | 同项目的成员在正常对话、文档编制及后台任务中,无需手写`@knowledge`即可使用当前有权、已确认的两树一网事实;项目/任务切换、撤权与恢复后依据及时刷新。实际模型输入须可审计。 |
|
||||
| 希望的公开符号/路径 | Backend `pkg/extension`新增可选`ProjectContextRegistry`注册RDM提供方,提供方受信作用域中`Resolve`短摘要与`ReadEvidence`按引用渐进读取;可选`WorkCompletionHost.CompleteForWork`供RDM编制入口使用。Backend统一组装最终模型输入并持久化`ContextManifest`,附资源版本、来源、预算/裁剪和权限/发布水位。 |
|
||||
| 当前组合为什么不足 | `Host.KnowledgeSearch`仅owner/项目检索,普通`runtime/llm.go`仅在显式`@knowledge`时注入;`runmgr`个人Memory不是可共享项目依据。`Host.Complete(ctx,prompt)`只有字符串prompt,不带可信任务绑定;`AddCommandHandler`只在被调用时执行,不能保证普通对话/后台恢复每次得到当前依据。 |
|
||||
| 兼容方式 | 新增可选接口和类型,不给现有必实现`Host`/`Registry`强加方法;非项目会话原行为不变。RDM要求该能力时缺失明确不可用,不退化为默默无项目依据。Backend从认证会话/持久任务解析actor、hostProject与run/step,验证RDM项目映射,不能相信模型或请求体自报projectId;权限/资源确认在注入前和恢复前复验。 |
|
||||
|
||||
安全与测试:ProjectContextBundle只含当前允许的概要、要求、已确认结论、未决冲突和可再鉴权引用。草稿、未发布发现、个人会话及无职责正文不可因同项目身份泄漏;`ReadEvidence`不可接受任意owner/路径。跨项目ID、撤权后旧摘要/旧历史片段、缓存复用、后台恢复、超时和预算截断都必须有负例。Backend记录**最终送入模型**的对象/版本/摘要hash与裁剪,RDM不能以候选检索列表冒充实际输入。Compose只提供任务约束,由Backend独占最后注入;无可信工作作用域的普通`Complete`不能读取项目共享正文。
|
||||
|
||||
## X2:按项目读取真实宿主审计及当时人物
|
||||
|
||||
| 必需四要素 | 申请内容 |
|
||||
|---|---|
|
||||
| 用户场景 | 追溯审计要把领域操作与实际模型/工具/后台任务/run/取消/失败/投递事实关联,向有权成员展示人物、时间、动作、内容与影响,而不是只列RDM结构事件码或owner全量命令日志。 |
|
||||
| 希望的公开符号/路径 | Backend `pkg/extension`新增可选`ProjectAuditHost.QueryProjectAudit`,以受信项目、actor、资源、操作/run、过滤与source offset/截止读取类型化HostAuditReceipt;支持RDM的`audit.read`领域授权回调及按对象/正文权限的服务端字段投影。写入时可绑定本操作已核验参与者的最小当时姓名/职责快照;不返回账号全目录或联系方式。 |
|
||||
| 当前组合为什么不足 | 现有`Host.Audit`只写owner名下事件;owner维度查询不能证明项目归属、当前项目`audit.read`许可、文档正文权或run资源关联。RDM领域事件DTO没有完整宿主执行、失败尝试和当时身份字段,Frontend无法凭op/detail安全推算。 |
|
||||
| 兼容方式 | 公开可选Host接口及类型,旧部署返回明确`coverage=unsupported`并保持旧入口可用,不伪称完整;事件和已有审计存储不直接改写。RDM旧历史缺失字段标“当时未记录”;新读面按项目/主体/资源/权限快照服务端裁剪,不能先下发原payload再在前端隐藏。 |
|
||||
|
||||
安全与测试:项目/资源/run归属来自Backend受信存储,不接受任意客户端projectId当授权。`audit.read`仍受项目许可,上下文、历史、导出、下载及正文差异分别受当前资源权控制。对于同owner的两个项目、两个成员、审计权无正文权、已撤权历史、恶意ID、长分页及迟到宿主回执做正负例。RDM领域`seq`与Backend source offset不假定全局全序;操作级归组在RDM只读投影完成,Backend提供真实来源及截止。
|
||||
|
||||
## 交付约束
|
||||
|
||||
W6与W9分别从Backend权威main创建独立任务工作区,独立提交/测试/人审;两者都可能改`pkg/extension/extension.go`和`surface.txt`,合入第一个后第二个同步主干、解决语义冲突并重跑受影响检查。各自按所在仓实际启动门禁工作;Backend独立开发核对clean与权威origin/main同步,Dev父任务用evidence原样保存命令×Backend SHA×完整输出的SELF收据,不强制虚构Backend的task-start或任务卡。SELF测试不提升为GATE。公开surface/API契约须有后向兼容测试及精确版本;RDM只有在基座获批准的真实发布tag可消费后接线,不导入Backend internal、不改RDM pins内容,也不自行执行需用户双钥匙的tag发布。
|
||||
|
||||
本申请不改变成员权限上限或自动批准结构;RDM项目字典/结构提案由另一个工作项负责。阶段6增量仍须人工评审,项目级审计/上下文真实能力由后续功能与浏览器/模型证据证明。
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
# 阶段6受影响设计修订:领域时间持久化与历史缺项 r1
|
||||
|
||||
记录日期:2026-10-14(Asia/Shanghai);状态:待人工评审。关联 TT-D03、TT-D04、TT-A02、TT-A04、TT-V01;在 W4a 读取隔离之后、W3 之前闭合当前时间重放缺口,W8/W10消费同一时间来源规则。批准前只调查、记录和补充失败用例,不修改生产时间或事件版本语义。
|
||||
|
||||
## 事实与影响
|
||||
|
||||
固定 RDM 提交 `8f80e55a4dade05d0445426bd7ac02818aeeac39` 的 `TestLegacyEventReplayPreservesWriteTime` 使用每次前进一分钟的确定性时钟:Slice 写态为00:01、事件/重放为00:02;章节 Version 为00:05/00:06;普通边为00:07/00:08。三项 SELF RED 的命令、固定对象和原始输出保存在 [RDM任务卡](/home/weichen/projects/Agent-System-RDM-wt-feature-rdm-two-trees-project-dictionary/.task/feature-rdm-two-trees-project-dictionary.md),收据摘要 `c255f389636465ea`。这是一种放大偏差的测试钟,不是线上实际存在一分钟偏差的证明。
|
||||
|
||||
原因是领域对象和事件分别取钟,而事件载荷没有保存领域对象那次取钟结果。重启、另一Runtime冷读或历史导出根据事件重放,无法恢复原写态时间。已批准的读取隔离可以保住同一canonical代,却不能补回事件中从未记录的字段。
|
||||
|
||||
另一个固定源码问题涉及数据完整性:`LoadWorldFromStore` 和 `LoadWorldForProjectDetached` 以末事件At作为完整装载的截止,而 `ReplayAt` 遇到第一个晚于截止的事件就停止。seq递增但时钟回拨时,前一个事件At可能晚于末事件At,冷装载会提前结束。该判断目前为独立源码审阅发现,需先补确定性RED再修;不能以“墙钟一般递增”豁免完整装载。
|
||||
|
||||
固定源码另有下列同类路径;除前三项外,表中的风险由源码检查确认,仍须补实际用例,不把静态检查写成运行通过。
|
||||
|
||||
| 对象/字段 | 当前写侧与重放行为 | 本修订处理 |
|
||||
|---|---|---|
|
||||
| Slice.IngestedAt、Section.Version.At、普通 Edge.At | 对象先取钟,事件另取钟;重放用Event.At | 新事件保存对应领域时间 |
|
||||
| Slice/Section删除时间 | 先写本地删除标记,再Append;重放用Event.At | 保存删除时间;成功Append后才更新私有投影 |
|
||||
| Conclusion删除、普通Edge退役时间 | Append成功后另取钟;重放用Event.At | 先固定本次领域时间并入事件;成功后应用 |
|
||||
| CEdge.At、ComplianceSnapshot.At | 独立取钟;载荷缺本体时间,重放用Event.At | 保存本体时间,不改快照ID和已有内容hash算法 |
|
||||
| OpenItem.OpenedAt/ClosedAt | 独立取钟;重放用Event.At | 保存打开/关闭时间,失败不发布状态 |
|
||||
| ReviewCard.At | 提交时取钟;重放构建卡未赋时间,得到零值 | 新submit载荷保存提交时间;旧缺项保持未知 |
|
||||
| Conclusion创建、CNode创建/升版 | 成功Append后已以Event.At回填;重放也用Event.At | 保留这个已一致的合同,加入对照用例 |
|
||||
| 同版本CNode元数据更新(VR被测版本、ARC登记SOUP) | 写态保留原节点At/Actor;复用OpCNodeAdd,重放却取这次更新Event.At/Actor | 新事件明确区分新节点版本与同版本元数据更新;更新保存并重放原节点At/Actor,实际修改者仍由本次Event.Actor记录;创建/升版保持现有定义 |
|
||||
| FormalRevInfo.At、Requirement.At、RegClaim.At及外部来源FetchedAt | 已保存显式领域/来源时间 | 保留原值与含义,回归验证;不统一替换成Event.At |
|
||||
|
||||
这不声称已经查清其他所有重放元数据问题;本增量针对时间字段及CNode同版本更新中与之不可分的原主体字段,完整人物、理由、影响仍由W8的覆盖矩阵验证。原节点主体与本次修改者分别保存,不能用修时间的机会覆盖当时人物。
|
||||
|
||||
## 推荐方案与取舍
|
||||
|
||||
推荐**保存新操作真实取到的领域时间,并保留独立事件时间**。给上述缺失字段增加类型化载荷,采用事件schema 2的显式要求;不通过改变旧事件或在读取时重新取当前时间让测试转绿。延续已有Formal/Requirement载荷保存时间的做法,比把所有时间改成Event.At更符合不同字段的业务含义。
|
||||
|
||||
备选“所有新领域时间统一Event.At”可减少载荷字段,但改变现有字段的取时含义,且无法覆盖法规获取等外部时间;不推荐。本修订不改变已有一致路径,也不增加另一套事件存储。
|
||||
|
||||
时间含义必须明确:
|
||||
|
||||
- 领域时间是服务端执行相应领域动作时所取的UTC时刻,或既有合同允许的外部来源时刻。新增字段由受信写入代码生成,模型/请求不能任意填充最终操作时间。
|
||||
- `Event.At` 是构造该事件时的时间,发生在持久sink调用和项目事务提交之前。它不是已证实的数据库commit时间,也不自动等于用户点击、真人确认或外部事实发生时间。
|
||||
- 新事件载荷保留领域时间及原精度,写态、提交后投影、重放和导出使用同一保存值;不通过JSON往返复制当前状态,不按本机时区改写历史。
|
||||
- 事件顺序/操作原子性仍由seq、operationId、项目revision与事务保证。时钟可能回拨,多实例时钟可能有偏差,不把墙上时钟当全局提交顺序,也不强制领域时间小于Event.At来拒绝真实记录。
|
||||
|
||||
完整库装载和固定seq水位重放必须按seq应用全部被选定的已提交事件,不得以末事件At或当前墙钟再截断。时间点查询须验证请求能对应一个连续、完整操作的seq前缀:如果根据At选择会在前缀中留下空洞或把操作切开,应明确报“该时间点无法唯一定位,请使用操作或版本”,或沿用已经明确约定的操作边界归一化;不得跳过后续更早时间的事件后声称还原完整。全部事件均落在查询时间内时仍可按seq完整回放,不因存在回拨就拒绝完整读取。时间字段保存和历史选择是两个独立测试面。
|
||||
|
||||
## schema与兼容边界
|
||||
|
||||
事件schema从当前1推进到2,使用现有 `events.schema_version` 字段,不改写历史行或增加时间列;另以存储迁移安装最低写版本门禁。具体载荷使用与领域属性对应的类型化字段;需要时间的schema 2操作必须具备合法、非零的对应字段,`review.submit`明确要求卡提交时间;没有领域时间的操作不人为增加空时间。已按Event.At定义的结论/CNode创建保持该定义,CNode同版本更新明确携带原时间/主体并校验操作种类及目标版本;原主体允许缺项时显式区分“已记录为空”和“字段缺失”,不伪造姓名。已有显式Formal/Requirement/RegClaim字段延用原合同。
|
||||
|
||||
新写事件由EventLog显式设置schema 2,Store不得把调用者传入的0自动升级成2。历史合法版本固定为1;现有数据库迁移给旧行默认值1,现有Store写入也曾把未设置版本保存为1,所以不能把任意零值当成已证明的旧事件。加载、项目事务重建、`ReplayAt`/序号历史重放/导出均校验支持的事件版本;0、负数、未来版本、schema 2未知操作或损坏的必填时间立即报错,不返回半棵树,不跳过该事件继续写。旧手工夹具应显式标记其实际版本1;若隔离副本检查发现真实历史零值,保留原件并登记来源后另作专用兼容处理,不自动改行或猜测版本。回放错误包含事件seq/操作类型和缺失字段,不回显正文。
|
||||
|
||||
已知但由其他投影负责的操作不等于未知操作。例如 `change.requested/approved/applied` 由 `fc.ReplayChanges` 消费,World当前不直接改树;新校验须使用固定已知操作白名单和明确的投影分工,继续容许这些事件通过World重放,并验证独立ChangeSet重放。禁止把通用默认分支直接改成拒绝而误伤已知操作;也禁止用通配前缀把任意未知操作都放行。schema 2的领域时间要求按上述具体操作/action执行。
|
||||
|
||||
兼容规则按字段判定,不能仅凭旧schema断言所有时间缺失:旧Formal等确有载荷的时间仍属已记录事实;旧缺失字段沿用既有Event.At回退值,使既有历史投影保持兼容;旧ReviewCard.At原本为零则继续表示未记录。**回退值是兼容投影,不是恢复了原领域时间。** 不写旧载荷、不重算旧事件hash、不回填猜测值,也不从ID中的数字反推快照原操作时间。
|
||||
|
||||
仅提高常量不能阻止已经启动、持有缓存的旧程序继续写schema 1。推荐同次SQLite/PG存储迁移设置最低写事件版本2,并对所有在线`events INSERT`执行数据库版本门禁;旧连接、显式schema 1及省略版本而落到旧默认值1的写入均拒绝,失败随原事务回滚。门禁限定BEFORE INSERT,不能用会同时约束旧行UPDATE的CHECK误阻现有 `MigrateLegacy` 归属更新;既有v1读取/归属迁移仍需通过。新应用启动也校验数据库最低版本和迁移版本是否受支持;旧程序遇已有schema 2时须保留其拒绝行为。门禁安装与版本状态更新原子完成,迁移失败不留下半启用状态;PG迁移要与活动事件写入互斥,SQLite迁移使用真实写事务。PG函数DDL须作为完整语句执行,不能经当前按分号切分的通用脚本处理器拆坏函数体;迁移编号以实施时权威基线后的空闲编号为准。
|
||||
|
||||
此DB门禁只保证事件INSERT,不声称阻止旧程序修改成员/项目等其他业务表。真实升级切换仍须停止旧写者并核验进程版本,不能用事件trigger代替完整部署隔离。普通旧DOC/资料入库是今天的新操作,应写schema 2并在来源字段保留原件时间,不属于“旧事件复制”。
|
||||
|
||||
旧数据复制不是在线Append。本修订不增加运行时绕过开关;历史事件应在停写的隔离目标中按原字节导入,完成校验后再原子安装新写门禁,或由已核验的离线迁移工具在排他事务完成等价流程。现有完整备份恢复后仍保留门禁;直接导入新记录到在线项目不得伪装旧历史。适配现有复制入口前先查源码,没有真实入口时只做隔离副本恢复演练,不能声称已交付在线导入能力。DB管理员直接删门禁不在普通应用写者保证内。
|
||||
|
||||
运行库升级/回退不在本次授权内;安装最低写版本门禁或含schema 2事件后,不能直接用旧二进制继续写该库。回退须保留全部新数据、确认读写兼容并另审处理方案,禁止删除新事件或降低门禁来掩盖不兼容。
|
||||
|
||||
## 审计显示与历史完整性
|
||||
|
||||
W8服务端按字段输出时间值、来源和缺项解释,W10用人能读懂的文字展示:新载荷时间显示相应动作时间;旧Event.At回退显示“事件生成时间;原操作时间当时未记录”;不存在任何可信值时显示“当时未记录”。已有准确载荷时间照常显示,不给整条旧操作笼统贴不准确标签。
|
||||
|
||||
来源必须关联具体事件seq/op/schema/action和字段,区分载荷原值、事件时间回退、未记录;可由投影读取原事件或由重放器给出等价来源元数据。不能仅凭两个时间值相等推断来源,因为合法新领域时间也可能恰好等于Event.At。
|
||||
|
||||
原始payload仍仅用于内部重放。页面不直接显示schema编号/JSON,不把Event.At改名成commit时间;详细操作生成、开始/结束、确认、提交和接收时刻只有各自真实记录时才能显示。时间来源由服务端从固定事件事实派生,不信任模型自由文本,也不改变审计权与正文权边界。
|
||||
|
||||
## 实施与可判定验证
|
||||
|
||||
由W2/W4a原分支owner在读取隔离完成后实施,避免多人并改domain文件。顺序为固定新RED → 载荷/版本兼容修复 → 写侧与重放对齐 → 隔离库/跨Runtime恢复验证 → 独立复审。无需等待DHF模板发布,W3仍须等待唯一U1合同实际合入。W8/W10后续消费时间来源规则。
|
||||
|
||||
1. 保留当前8f80旧缺口证据。将新写态与重放一致性用例转为schema 2正例;另用固定原始schema 1事件构建旧历史用例,证明回退和未知标记,不把“旧原始时间不可恢复”的事实改成假通过。
|
||||
2. 对表中全部缺失路径先建立确定性时钟RED,随后比较写态、同进程新读、第二Runtime、关闭重开、历史导出和完整事件重放的字段;覆盖创建、修改、删除、退役、打开/关闭、审核提交/终批以及新旧混合事件。
|
||||
3. 测试新字段缺失、零值、无效格式、未来schema、非法schema0/负数、schema1历史、新旧时间已有/缺失组合;SQLite及隔离PG均在任何部分投影发布前拒绝损坏事件。旧/新change事件同时通过World和独立ChangeSet重放,真正未知操作按新合同拒绝。测试旧读者拒绝schema 2、写事务因历史不支持而零提交;使用迁移前已打开的旧连接模拟旧写者,分别显式写schema 1、零、缺省值,验证所有在线写法被DB门禁拒绝。新schema 2正常写入、v1归属UPDATE、迁移失败回滚、并发旧写者、隔离旧历史复制后启用及备份恢复均须实测,不凭常量推断结果。
|
||||
4. 失败sink、事务回滚、CAS冲突和未知提交结果不发布新的领域时间/成功操作;保留原有操作时间、事件seq、ID和审签数据。提交重试从既有回执恢复,不能重取钟伪造第二次成功。
|
||||
5. 两事件seq递增但At递减的确定性RED,分别覆盖全量/项目冷装载、重启及固定seq历史导出;修复后完整应用所有已选事件。时间点查询覆盖全部包含、空洞和切开操作,空洞不能静默成功。非UTC输入的既有外部时间、相同时间多个seq、不同时钟精度均不导致排序改写或丢行;完整操作截止仍以seq水位验证,时间接口无法判定时明确报错。
|
||||
6. 新旧固定事件字节/hash基线保持;新字段经持久化后的精度/时区按既有UTC序列化合同验证。`go test ./...`、相关race、SQLite/隔离PG测试及构建形成固定SHA SELF收据,独立审阅者重放最小集。W8/W10完成时再验证最终中文显示及权限裁剪,当前领域修复不冒充页面已交付。
|
||||
|
||||
本修订需要用户确认,因为它明确新增持久化字段、事件版本和旧历史时间解释,属于 `policy/delivery.md` 要求人审的数据合同变化。批准仅放行隔离分支实施和测试;阶段6增量A人审、阶段7验收、正式CI、合入、真实迁移与部署仍按原门禁。
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
# W0:44份模板与唯一资产目录对照 r1
|
||||
|
||||
记录:2026-10-14T11:34:31.197445+08:00;来源SELF。DHF工作区HEAD `d32dc8fb6dffdd52fa33d53bcb7e802fe705a919`,目录工作树状态 `clean`;目录原字节快照SHA256 `e5088653010dd30219f465c35bebd40fe44509d60820333bab1bf7717f963c6a`,保存在源码外 `/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage6-w0-catalog-snapshot.json`。
|
||||
|
||||
本表逐文件验证了本任务来源台账、当前Dev原件、目录中的原件hash、来源提交对应Git对象及候选docType的一致性。它只证明资产**身份和字节来源**,不证明结构/适用性/格式经人工批准。DHF原工作区由原owner继续,当前本任务没有修改其目录。
|
||||
|
||||
结果:44/44路径、hash和候选类型一致;41个不同原件SHA256;44个不同逻辑templateId。当前目录状态 `{'needs-review': 44}`,适用性人工确认 0/44。目录中所有资产仍无已批准发布结论;有未决问题者不得发布。
|
||||
|
||||
| 序号 | 阶段与原件 | 原件SHA256 | 逻辑模板ID | 类型候选 | 当前目录状态 | 未决问题 |
|
||||
|---:|---|---|---|---|---|---|
|
||||
| 1 | 0. 商务阶段 / 0.1初始要求申请表.docx | `eb9d28701491` | `dhf.a7850d18814bc8ba` | `bd_intake` | needs-review | classification, fidelity |
|
||||
| 2 | 1. 策划阶段 / 1.1、731QCP29-F01 项目建议书 02.docx | `3f54f060d9c5` | `dhf.2750fbaf1f67d10c` | `rd_proposal` | needs-review | classification, fidelity |
|
||||
| 3 | 1. 策划阶段 / 1.2、731QCP29-F02 设计开发计划任务书 02.docx | `d152b0b4d2bb` | `dhf.d2f75aedd6dcf8b7` | `rd_design_plan` | needs-review | classification, fidelity |
|
||||
| 4 | 1. 策划阶段 / 1.3、731QCP29-F07 设计开发(策划)评审记录 02.docx | `d6f3cca9c3c1` | `dhf.8848f283d317f027` | `rd_planning_review` | needs-review | classification, fidelity |
|
||||
| 5 | 2. 设计输入阶段 / 2.10.1、731QCP29-F13 配置管理计划 02.docx | `94e8e7fc868d` | `dhf.e9a9112aa2852eef` | `rd_sw_config` | needs-review | classification, fidelity |
|
||||
| 6 | 2. 设计输入阶段 / 2.10.2、软件维护计划模板.docx | `76fc4d4fddec` | `dhf.ca12336e5b75ed30` | `rd_sw_maintenance_plan`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 7 | 2. 设计输入阶段 / 2.11.1、731QCP29-F16设计输入规格书模版.docx | `3fef2ed7d0aa` | `dhf.ceb63a04cb0c2fbb` | `rd_design_input_spec` | needs-review | classification, fidelity |
|
||||
| 8 | 2. 设计输入阶段 / 2.12、731QCP29-F05 设计开发输入清单 02.docx | `de990de6bf13` | `dhf.3b89d5608cf50699` | `rd_design_input_list` | needs-review | classification, fidelity |
|
||||
| 9 | 2. 设计输入阶段 / 2.13、RDDHF0213-xxxx产品系统设计方案.doc | `8168ea37c7ca` | `dhf.1f7e7cee081218f5` | `rd_system_design` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 10 | 2. 设计输入阶段 / 2.14、731QCP29-F07 设计输入评审记录.docx | `a3677cb06a39` | `dhf.4a26f4b618141021` | `rd_input_phase_review` | needs-review | classification, fidelity |
|
||||
| 11 | 2. 设计输入阶段 / 2.1、731QCP29-F14 用户需求模板.doc | `2f9c6795f811` | `dhf.1e44e6e91bb1ff19` | `rd_user_needs` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 12 | 2. 设计输入阶段 / 2.2、RDDHF0202-xxxx 医疗器械法规和标准清单.docx | `2b36daeedc8c` | `dhf.09be7a246cf575d3` | `rd_regs_stds` | needs-review | classification, fidelity |
|
||||
| 13 | 2. 设计输入阶段 / 2.3、RDDHF0203-xxxx 同类产品不良事件信息.docx | `f7cd69b08c1e` | `dhf.fa7eba95ef189eb5` | `rd_adverse_events` | needs-review | classification, fidelity |
|
||||
| 14 | 2. 设计输入阶段 / 2.4、731QCP29-F15 系统需求规格书模板.doc | `b58d1b900c95` | `dhf.ab9245edad538328` | `rd_system_reqs` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 15 | 2. 设计输入阶段 / 2.5、731QCP29-F07 需求评审记录表.docx | `102ed2b6418b` | `dhf.9b9e08868a513bf7` | `rd_req_review` | needs-review | classification, fidelity |
|
||||
| 16 | 2. 设计输入阶段 / 2.6、731QCP29-F03 风险管理计划 02.docx | `0c1484d6b295` | `dhf.10319ff21c64042d` | `rd_risk_plan` | needs-review | classification, fidelity |
|
||||
| 17 | 2. 设计输入阶段 / 2.7.3、731QCP29-F04 风险管理报告 02.docx | `d4f18eb817da` | `dhf.86f9573d8ddc7ae8` | `rd_risk_report` | needs-review | classification, fidelity |
|
||||
| 18 | 2. 设计输入阶段 / 2.8、731QCP29-Fxx 软件开发计划-模板.doc | `2dee0e085113` | `dhf.f5c7df2bf53bbedd` | `rd_sw_plan` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 19 | 2. 设计输入阶段 / 2.9、软件需求规格书模板.docx | `aa12be2b8158` | `dhf.fa4123ac9f683ade` | `rd_sw_reqs` | needs-review | classification, fidelity |
|
||||
| 20 | 3. 设计输出阶段 / 3.12、原材料进货检验规范-模版.docx | `34608b520ebf` | `dhf.3a76c152e144832a` | `rd_incoming_iqc` | needs-review | classification, fidelity, external-image |
|
||||
| 21 | 3. 设计输出阶段 / 3.15、产品技术要求.doc | `b787295c6c66` | `dhf.885cddb95919204c` | `rd_tech_req` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 22 | 3. 设计输出阶段 / 3.17、731QCP29-F06 设计开发输出清单 02.docx | `f53a2f271bf2` | `dhf.199acbb3323bd854` | `rd_design_output_list` | needs-review | classification, fidelity |
|
||||
| 23 | 3. 设计输出阶段 / 3.18、731QCP29-F07 设计输出评审记录.docx | `e37ab2828e64` | `dhf.aa47448f266e8e65` | `rd_output_review` | needs-review | classification, fidelity |
|
||||
| 24 | 3. 设计输出阶段 / 3.6.2、软件详细设计模板.docx | `e1089b1de6d2` | `dhf.9a2de08325a6c9cd` | `rd_sw_detail_design`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 25 | 3. 设计输出阶段 / 3.8、RDDHF0213-xxx采购技术说明-结构&硬件.doc | `77fd422be6f3` | `dhf.33c2e9fe0c42fa0d` | `rd_purchase_spec` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 26 | 3. 设计输出阶段 / 3.9.1、731QCP29-Fxx 工艺流程图模板.doc | `1d702e1cdbdc` | `dhf.3e7fa9e5e236f63c` | `rd_process_flow` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 27 | 3. 设计输出阶段 / 3.9.2、RDSOP00xx-00xx xxx作业指导书.docx | `e2d5e596ee1f` | `dhf.95c9bb231da8822d` | `rd_work_instruction`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 28 | 3. 设计输出阶段 / 731QCP33-F01 软件可追溯性分析报告 02.docx | `23d6402dc851` | `dhf.cc8edf04e512018f` | `rd_sw_trace_report`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 29 | 4. 设计验证阶段 / 24.产品有效期验证.doc | `425e993090eb` | `dhf.5b326f0a5a862a13` | `rd_lifetime` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 30 | 4. 设计验证阶段 / 41.软件单元测试用例-模板.doc | `02f41e077038` | `dhf.de69adc198a48f70` | `rd_sw_unit_test` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 31 | 4. 设计验证阶段 / 42.软件集成测试用例-模板.doc | `1a373f9bec23` | `dhf.fa6315877d495f9e` | `rd_sw_integration_test`(新/细分候选) | needs-review | classification, fidelity, doc-normalization, type-mapping |
|
||||
| 32 | 4. 设计验证阶段 / 43.软件系统测试用例-模板.doc | `22b211453d73` | `dhf.349e7913aab2d0cd` | `rd_sw_sys_test` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 33 | 4. 设计验证阶段 / 49. 软件配置管理报告-模板.doc | `243993a6ab53` | `dhf.33db9024b12d6bc3` | `rd_sw_config_report`(新/细分候选) | needs-review | classification, fidelity, doc-normalization, type-mapping |
|
||||
| 34 | 4. 设计验证阶段 / 731QCP29-F07 设计验证评审记录.docx | `e37ab2828e64` | `dhf.59806d243a57f310` | `rd_verification_review` | needs-review | classification, fidelity |
|
||||
| 35 | 4. 设计验证阶段 / 731QCP29-F08 设计开发验证记录 02.docx | `c5b84546e647` | `dhf.b71d90c0f60bc558` | `rd_verification_record`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 36 | 4. 设计验证阶段 / 756QCP26-F02 验证确认报告 V03-.docx | `f5bbe7816e79` | `dhf.b96b7fad425d30a3` | `rd_verification_validation_report`(新/细分候选) | needs-review | classification, fidelity, type-mapping, process-validation-purpose |
|
||||
| 37 | 5. 设计转换阶段 / 731QCP29-F04 风险管理报告 02.docx | `8a17e5b4cff1` | `dhf.7775dc1df440fd86` | `rd_risk_report_t` | needs-review | classification, fidelity |
|
||||
| 38 | 5. 设计转换阶段 / 731QCP29-F07 设计转移评审记录.docx | `e37ab2828e64` | `dhf.13458c561985fcd9` | `rd_transfer_review` | needs-review | classification, fidelity |
|
||||
| 39 | 5. 设计转换阶段 / 731QCP29-F09+试产总结报告+03-20250730.docx | `7600083fa867` | `dhf.a046cc77128b7b66` | `rd_trial_production_report`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 40 | 6. 设计确认阶段 / 53. 使用错误评估报告-模板zlx.doc | `75cafe0c4c26` | `dhf.42b787cc4d5c9141` | `rd_use_error` | needs-review | classification, fidelity, doc-normalization |
|
||||
| 41 | 6. 设计确认阶段 / 731QCP29-F07 设计确认评审记录.docx | `e37ab2828e64` | `dhf.a277ed8557709b89` | `rd_confirmation_review`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 42 | 6. 设计确认阶段 / 731QCP29-F11 设计开发确认记录 02.docx | `d01ff3c56841` | `dhf.3aac75ddc616d53a` | `rd_confirmation_record`(新/细分候选) | needs-review | classification, fidelity, type-mapping |
|
||||
| 43 | 6. 设计确认阶段 / 756QCP20-F01 计算机软件确认报告 02.doc | `45e57b363abf` | `dhf.6b440531e6ff12f8` | `rd_sw_validation_report`(新/细分候选) | needs-review | classification, fidelity, doc-normalization, type-mapping |
|
||||
| 44 | 6. 设计确认阶段 / 756QCP26-F01 验证确认方案 V03-.docx | `525b2c40d74e` | `dhf.fb87560f7ffd8144` | `rd_validation_plan` | needs-review | classification, fidelity |
|
||||
|
||||
## 需在同一合同继续关闭的事项
|
||||
|
||||
- 内容块合同:沿用DHF的TemplateAsset/ContentBlock,补齐图形锚点、非表格重复组、字段类型/单位/校验、结构与实例ID映射;只有已合入的合同版本才可供W3和DHF U2消费。
|
||||
- 原件保真:本任务E1和DHF E1/E1-R1均有转换候选,但自动保真判据未通过。图形顺序、分页、中文可读、批注/修订及49字符未定位差异逐份审核。不能凭转换exit0或44条目录宣称模板可用。
|
||||
- 业务含义:F02验证确认报告、系统需求研发/项目管理用途、有效期与货架寿命、企业固定文本/项目示例、四份同字节阶段评审用途需逐项人审。DHF项目建议书评审单仍标HUMAN REVIEW / NOT_APPROVED;无结构/渲染包及人工评审,不得转published。
|
||||
- 合入与交接:DHF原任务owner完成U1已批范围并记录合同/发布证据;经W1合入、精确SHA、独立Review/CI核验后,本任务从RDM权威main消费。DHF U2–U6由原owner依已批准阶段5计划续办,在其任务卡引用批准版本。
|
||||
- 后续验证:W0机械对照不提升为GATE或业务审核结论。每个模板的内容/关键格式对照、适用项目生成/审签/导出及权限行为须各有当前对象证据;阻塞归属和人工决定记录在唯一DHF台账/评审单。
|
||||
|
||||
阶段6增量A的当前进展仅为W0来源/身份核对。W0的“共同合同已冻结、44份用途均裁定、DHF U1已合入”出口仍未达到;W2可按已批准计划独立推进,不把W0部分工作冒充整个增量完成。
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
# 阶段6受影响实施顺序修订:先封闭项目事务,再继续 W2/W3 r1
|
||||
|
||||
记录日期:2026-10-14。状态:**待人工评审**。本修订仅调整已批准阶段5计划中 W2、W3、W4 的关键依赖顺序;阶段4的事务方案、28项需求、DYN-01 人工确认、DHF 独立 owner、模型费用上限及四个增量的验收范围不变。原阶段5 r1 作为已批准历史对象保留,不在原文上回写。
|
||||
|
||||
## 发现与可复核对象
|
||||
|
||||
RDM 独立分支 `feature/rdm-two-trees-project-dictionary` 当前本地 HEAD `059fab07a53aad3a5dff796f25abedc441940303` 保留两条失败回归:`TestProjectDictionaryConcurrentIngestAndSection` 在 `-race` 下发现 `World.setDictionary` 与笔记入库/重标及文档章节写入竞争;`TestProjectDictionaryRevisionCannotDisappearWithAnotherTransaction` 证明字典修订返回成功后,另一个回滚的 `TxProject` 可使持久 revision 仍为 0。失败原始命令和输出在该分支任务卡 `.task/feature-rdm-two-trees-project-dictionary.md`,来源 SELF。较早 HEAD 的四包通过不能替代当前失败 HEAD。W2 的项目字典不能视作可提交或可合入成果。
|
||||
|
||||
原计划让 W3 等 DHF U1 合入,再由 W3 引出 W4。然而 W2 的正确性已依赖阶段4 §5.2 批准的 W4 基础事务约束:私有工作 World、项目写入串行与数据库 revision CAS、提交后一次发布快照,旧写入口共用版本边界。等待 W3 才处理该基础会使 W2 长期保留已知丢失更新与数据竞争。DHF U1 仍由原 owner 负责,当前未形成可消费的已合入合同;本修订不接管其工作区或复制候选。
|
||||
|
||||
## 仅调整的依赖与 owner
|
||||
|
||||
将原 W4 拆为同一工作项内两个有明确边界的实施步骤:
|
||||
|
||||
1. **W4a 项目事务基础先行**:W2 的 RDM owner 在原 W2 独立分支上完成基础隔离和读写协调,覆盖当前字典修订、笔记入库/重标、文档已有章节/审签以及其他已存在的项目写入口;事务私有 World 持有事件 sink,提交前不修改共享 World;同一事务持久化事件与项目 revision 条件更新,成功后原子发布只读快照,失败丢弃工作副本。跨进程 CAS 必须同时验证 SQLite 和隔离 PostgreSQL;不能以仅进程内互斥替代。W4a 不增加结构提案、人工确认公开接口,也不编辑 DHF 的 `ContentBlock`/模板资产合同。
|
||||
2. **W2 完成门禁**:两条现有 RED 在普通及 race 运行下变 GREEN,补提交前后故障/回滚、两进程冲突、读者不见半新态、旧项目与旧审签重放,并跑当前 HEAD 四包和隔离数据库测试。测试证明字典 revision、笔记/文档引用与事件持久状态相符后,才把 W2 与 W4a 作为阶段6增量 A 候选;这不是 W4 全部完成。
|
||||
3. **W3 保持原依赖**:仍须等待 DHF U1 真正合入、核验单一 `ContentBlock` 合同,再做递归实例和旧数据兼容;W2/W4a 必须先满足上述门禁,W3 不从 DHF 未提交目录取代码。
|
||||
4. **W4b 仍在 W3 后**:结构/内容/字典/模板升级提案、一次性真人确认、授权与幂等、事件/提案/回执/outbox 同事务,以及相关 UI/工具入口,仍按已批准 W4 和阶段4方案实现。W4a 是 W4 的基础子集,不可宣称 DYN-01 已就位;完整 W4 完成仍以 W4b 和原验收测试为准。
|
||||
|
||||
相应依赖改为 `W0 → W2/W4a → W3(另需 W1) → W4b → W5/W8`。同一 RDM 工作区只有 W2 owner 写 W4a 涉及的事务文件;如 DHF owner 后续需改同一文件,仍按阶段5单一 owner/先后合入规则协调。W6/W9 的 Backend 独立工作、X2 已批准修订及 W11 逐资产审阅不受此顺序改变影响。
|
||||
|
||||
## 影响、测试和回退
|
||||
|
||||
提前的是**既有方案明确要求的事务隔离基础**,不降低项目权限、人工确认或旧记录兼容验收,也不放行未发布模板。W4a 若发现必须修改公开权限合同、旧事件含义或受控文档职责,先停受影响实现,另回阶段4评审。若失败,保留 W2 RED 和工作分支,已合入主干与 DHF 原现场不受改动;不能删测试、临时全局锁或跳过 PostgreSQL 来报绿。
|
||||
|
||||
请仅评审这一关键依赖顺序调整。批准后允许 W2 owner 先实现 W4a 并完成门禁,再继续 W3/W4b;增量 A 的阶段6实现评审和阶段7正式测试仍分别进行。
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
# RDM W2/W4a P2 read isolation: independent local review
|
||||
|
||||
Reviewed object: `57a8d7caedf72d9be4bdca179ae2a93e456ba009` against `7980551b78509c19074f7d683178dacbe6d956d7`. The supplied short name `57a8d7ce` does not resolve in this repository; the reviewed commit is `57a8d7c`. Reviewer: independent /root/w2_review agent. Scope: P2 read isolation only; no source edits, push, service operation, or full test rerun.
|
||||
|
||||
## Review result
|
||||
|
||||
No new high impact P2 defect was confirmed in the fixed source. The private canonical is returned only through `FrozenReadCopy`; a committed transaction publishes `FrozenCanonicalCopy` after commit. The clone separates the note tree, document tree, dictionary indexes, network, register, review state, requirements, conclusions, and nested maps/slices. The same generation shares only a sealed event log. `Append`, `Seed`, setters, and delayed restore closures cannot change that log; `Snapshot` copies mutable event `Payload` and `From`.
|
||||
|
||||
The production `Get()` constructor creates independent public and private dictionaries before returning. A test-created literal `Runtime` with no `privateDict` still copies public `Dict` on its first `dictionarySeed()` call, so mutation before that first call can contaminate its seed. No production literal constructor was found. This is a test-constructor boundary, not a confirmed production P2 defect.
|
||||
|
||||
The older deterministic three-case event-time RED remains an independent data-contract issue. It is not counted as a P2 regression. Full Go testing without excluding it is still failing. The new state-copy path preserves values within a generation and does not reconstruct missing legacy timestamps.
|
||||
|
||||
## Independent replay and provenance
|
||||
|
||||
The source was extracted with `git archive` into `/tmp/rdm-p2-review-8shrap`. The receipt command re-created the archive and compared every non-pin source file, checked all four pin Git heads against the reviewed commit's gitlinks and their clean state, then compared the copied pin files. It ran the focused domain/application `-race` suite. The command exited 0. The full, sanitized output is in:
|
||||
|
||||
- `/tmp/rdm-p2-review-57a8d7ca-replay-20261014-01.json` — `make evidence` RECEIPT capture, SHA-256 `3b8c0bc10d97b6564dc766b5df92738f6ede1ec2bd0456ed0a75a5ed3b2c15b9`
|
||||
- `/tmp/rdm-p2-review-57a8d7ca-replay.sh` — exact replay and identity-check script, SHA-256 `66658b68d8d4bad7282730c60df178a01355474718cff23fd4478682af27e6a7`
|
||||
|
||||
The receipt's Git `before.head` is the Dev checkout `d23fb4363dcc0a206e71e47f9cd23a644c7e1c70`, because that repository supplies the RECEIPT-capable evidence tool. It is **not** the tested RDM object. The tested archive SHA and pin identities are checked and printed inside the captured command output. The tool labels this local receipt `SELF`; the independent reviewer identity and command are stated here, without upgrading the receipt's source label.
|
||||
|
||||
The focused replay covered pointer pollution, nested clone aliases, event input/output aliases, sealed setters and restore closures, public/private seed, history/template reads, retained transaction pointers, same-revision first-wins, later-instance commits, commit-to-publication readers, SQLite two-instance CAS, attribution refresh, and the slowHost test-fixture race. All selected cases passed. The separate time test was run in the same fixed snapshot and failed in its three expected legacy-time cases; it was not included in the P2 receipt.
|
||||
|
||||
The author's task card has fixed-code SELF rows for all-package tests excluding the time RED, domain/application race tests, isolated PostgreSQL read/CAS/attribution tests, build, and Web/governance checks. This review did not independently replay PostgreSQL, full packages, build, CI, or PR gates.
|
||||
|
||||
## Performance and acceptance limit
|
||||
|
||||
Each warm `WorldFor` copies materialized state; per-read allocation and latency therefore grow with live object count. Event history is copied once per committed canonical generation, and `Snapshot` copies it on demand. The repository includes a profiling harness, but no human-approved cost threshold or production workload acceptance is established by this review. Performance remains a separate stage-6 review decision.
|
||||
|
||||
W3 and W4b remain outside this P2 conclusion.
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# 阶段6受影响设计修订:项目只读快照的指针隔离 r1
|
||||
|
||||
记录日期:2026-10-14。状态:**待人工评审**。本修订影响已批准阶段4 §5.2“读者只取提交后的不可变快照”和阶段5 W2/W4a 的应用读语义、内存与性能;不改变 DYN-01 真人确认、W3/DHF 内容块合同、项目权限上限、旧事件身份或审签规则。RDM 独立分支当前本地 HEAD `0cff1161e4f85f847d1121be09160bc50b13d61f`,未推送、合入或部署。
|
||||
|
||||
## 发现与当前有效成果
|
||||
|
||||
W2/W4a 已把项目写入纳入私有事务 World、数据库 revision CAS、提交后发布;原两条并发/回滚 RED 与后续旧归属迁移跨实例 P1 均有局部修复。发布 World 的领域写方法在内存改动前拒绝写,`domain.LoadWorldForProject` 也默认冻结;独立复审确认这些路径的本地 SELF/定向重放。**但方法拒写不等于返回对象不可变。** `Runtime.WorldFor` 缓存并返回同一 `*World`;`NoteTree.Slice/Query`、`DocTree.Doc/AllDocs`、`DictionarySnapshot` 返回可变内部指针。固定 `TestPublishedReadPointersCannotPolluteOtherReaders` 在提交 `bc1024e131` 和最终 HEAD `0cff1161` 保留 RED:读者 A 直接修改返回的 Slice/Doc/Dictionary 字段,无事件或数据库提交,同项目下一位读者却看到被污染的缓存。当前生产源码尚无这样赋值的用户/模型可触达入口,故这不是已证实的跨用户远程攻击;它仍违背已批准的“只读、提交后”工程合同,未来动态结构和成员上下文会放大误用风险。当前 HEAD 无条件全仓 Go SELF **FAIL**;明确排除该 RED 时通过不能作为 W4a 完成证据。原始命令、对象与输出保存在 RDM 任务卡 `.task/feature-rdm-two-trees-project-dictionary.md`。
|
||||
|
||||
## 方案比较
|
||||
|
||||
| 路线 | 一致性与兼容 | 成本/风险 | 决定建议 |
|
||||
|---|---|---|---|
|
||||
| 私有 canonical + **已封闭的不可变事件日志**;每个 `WorldFor` 深拷当前树/网/字典并共享该日志读核 | 保留 `*World` 函数形状与**同一 canonical 代内**已有 ID、时间、revision、hash 字节;返回指针身份不再稳定,调用者只能污染自己的状态副本 | 热读不逐次复制全部事件,但仍复制当前投影;每次提交/冷装载要深拷/重建一次日志,`Snapshot` 按需复制事件。必须证明日志封闭和所有别名入口 | **推荐先实现并实测**,成本不过关再重审 |
|
||||
| 每次连日志历史一起完整深拷 World | 指针隔离较直观,保持旧函数形状 | 日志含全部历史且事件 `Payload`/`From` 可变;每次热读下界 O(历史字节),与长期项目扩张不相称 | 不推荐 |
|
||||
| 每次从事件重放一个独立 World | 无共享指针,历史可复核 | 成本随全部历史事件增长;当前若干 `IngestedAt`/`Version.At`/边 `At` 在直写和重放中取时刻不同,可能使旧字节漂移 | 本轮不采用 |
|
||||
| 只读 `WorldView`/DTO 与按需拷贝 getter | 可按请求复制少量对象,长期更适合巨大项目 | 改现有领域/应用读接口;静态约26文件、46处 `WorldFor/worldForParam` 和73处主要树/字典 getter 调用,需另定职责与兼容 | 深拷贝成本不满足门槛时再评审 |
|
||||
|
||||
## 推荐的隔离与失败边界
|
||||
|
||||
`Runtime` 的 canonical 已提交 World 只由同项目 revision 的发布流程持有,绝不直接返回给普通读者;`TxProject` 私有工作指针也不能作为 canonical 原样外露。一次提交在 DB 成功后,按同一项目锁建立/替换新的 canonical;事务工作日志中捕获 `sql.Tx` 的 sink/`seqErrFn` 等闭包必须在发布前去除,不能让 canonical 长期保活已提交事务。推荐以**同一个已固定的项目 revision/事件水位**构造 canonical 状态图与新的 frozen EventLog,深拷该水位内历史 Event 后封闭,供同一 canonical 代的读副本共享;不直接共享 Tx 工作日志。可从 A 已提交事务的私有工作日志深拷确定事件水位,或从数据库在 revision 前后核验一致后同时重建图与日志;不得让 A 状态图配上 B 后来提交的日志。发现更高 revision 时重建完整新代或拒绝旧代发布,绝不覆盖较新代。Tx 回调对私有 World 的所有权只在回调期间有效,禁止启动并发写者或把它交给异步任务;返回后即使受信调用者误持指针并**串行**改字段,也不能改变已发布 canonical。`Runtime.Dict` 目前也是公开可变指针,项目装载必须改用私有规范 seed/字典版本并与该字段做深度隔离;`WorldAtSeq` 导出、inspection 历史重放及 templates 读面仍直接读 `rt.Dict`,也须切到私有 seed 或验证等价隔离,不能只保护 WorldFor/TxProject。
|
||||
|
||||
`WorldFor` 若读到 DB revision 新于缓存,必须等本进程持同项目锁的写者发布或从已提交事件重装,不能在“DB 已提交、canonical 尚未替换”窗口返回旧缓存;较旧发布不得覆盖较新 revision,**同一个 revision 也只允许一个 canonical 首次安装获胜,随后不能用 warm/重放的另一份 World 覆盖**。否则同 revision 的 `IngestedAt` 等现有时间差会令同进程读者见到两种字节。读入口在短锁中 pin 某个不会再修改的 canonical/revision,**释放全局 worldsMu 后**复制当前投影并关联这份已封闭日志,避免巨大项目热读阻塞别的项目;返回新冻结 World 的线性化点是 pin 的已提交 revision。旧读者保留自己的旧 revision 副本,不被后续提交修改;新读者只拿完整新 revision。失败/回滚不替换 canonical。不能靠浅拷贝 Go struct、只关闭事件 sink、仅在 getter 复制顶层 map,或复用可变 `World.Dict` 指针过关。
|
||||
|
||||
每次状态副本须递归覆盖笔记与多挂载、文档章节/版本/审签、两类追溯网/边、需求/结论/合规快照、项目字典及别名索引、所有可变 map/slice/pointer;只有能证明不可变的字节块才可共享。实现须**新建** World、NoteTree、DocTree、TraceNet、Register、RegCheckStore 的内部回指与同步对象(如 Notes.w、Docs.w、各 log、Register.net),不能按值复制 `sync.Mutex`。`NewWorld(dict)` 当前复制字典切片但会别名部分索引 map;不能对已物化 overlay 字典直接 `reindex` 而重复追加项目词条,须显式深拷索引且复核项目字典版本。`time.Time` 直接复制,不走 JSON 往返或重新取钟。
|
||||
|
||||
共享日志必须是**真正的 sealed read-only 对象**:从事务日志构造时深拷每个 Event 的 `Payload []byte`、`From *Ref`;`Append` 入日志和返回 Event、`Seed` 接收、`Snapshot` 返回也都隔离这些可变引用。`Close/Seal` 清空持久 sink、事务序号分配器/时钟闭包、操作上下文;封闭后 `Append` 报错,`Seed/AdvanceSeqTo/UseRealClock/SwapSink/UseSeqAllocator/UseErrorSeqAllocator/BeginOperation` 及其恢复闭包均不可再改内部状态,现有无错误返回的 setter 可保持签名并安全 no-op。`Snapshot` 当前仅浅拷外层 Event,且每次排序,按需读取实际为 O(H log H),H 为历史事件数;若需改善,须保持 Seq 顺序不改历史,不靠共享可变 Payload 减成本。返回副本的领域变更方法继续在入口拒绝持久/内存写。**这里的“不可变”指共享 canonical/DB 与其他读者不可被该副本污染;调用者自己的副本仍有 Go 导出字段可被本地赋值,这种赋值不提交项目事实,却可能影响该调用者后续自行计算的报告/导出等输出。** 权威写入、授权和外部副作用不得信任可能被本地改过的读副本,须在私有事务或新取的规范快照中复验;若要求连调用者本地对象也不可改,须选择只读 DTO 路线。`WorldForParam` 的非空项目分支与项目成员工作上下文读面必须走同一隔离路径;空项目旧过渡域另保留既有权限门禁,不因本修订获得跨项目读取。旧 Section.ID、事件 seq、模板候选及已批准文件不得在复制时重建或改写;**本修订不声称修复已有重放时间漂移**:现有写侧对若干领域 `At` 与事件 `Event.At` 分别取时,重启重放可能出现微秒级差异,该领域时间合同须另有固定字段/事件用例闭合,不能把读隔离测试外推成跨重启时间字节一致。
|
||||
|
||||
如果实现发现无法在保留这些字节和现有签名下彻底隔离,或测得用户可见热读成本不可接受,应保留 P2 RED,转回 `WorldView` 方案做人审,不能退化为“当前没有生产代码写裸指针”后宣称 W4a 完成。
|
||||
|
||||
## 测试与性能判定
|
||||
|
||||
- 固定 P2 RED 转 GREEN:A 修改自己返回的 Slice、Doc、Section、Dictionary、网边、审签、getter 嵌套 map/slice,以及 `Log().Snapshot()[i].Payload/From` 后,A 后续**新一次** WorldFor、同项目成员 B、另一个 Runtime、项目 C、DB 重放与事件水位均仍为原提交值;同一副本内用户自改字段不构成业务提交。`rt.Dict`/seed 指针被误改后,既有 A/B 与未来 C 项目仍用原规范基础字典。旧指针在新事务提交后保持旧版本;新读者一次只见完整新版本。重复 `WorldFor` 现有测试中的指针恒等断言须改为 `w1 != w2` 且同 revision 内容相同,并审计生产是否依赖旧指针随写更新。`TxProject` 回调故意保留 working 指针并在返回后**串行**改其嵌套值,canonical 与后续读者仍须不变;并发持有 working 指针由内部所有权合同禁止并以 race 检查生产路径。正常读取不能丢失模板/节点/证据来源。
|
||||
- 逐字段比较**同一已提交 canonical 代内**复制前后的 ID、revision、hash、时间/审签及日志事件水位;不把它当跨重启 Event.At 漂移已修。SQLite 和隔离 PostgreSQL 各跑并发读者与写者、CAS冲突/回滚、归属迁移、恢复;两实例交错让 B 在 A commit 与 A sealed log 建立之间提交,断言任何被返回的一代树/网/字典/日志均属同一 revision,旧代不覆盖新代。再注入同进程 A commit 后读者抢先冷装同 revision、A 后发布 warm World 的时序,证明同一 revision 只安装一次,后续不出现两种时间字节。误改公开 `rt.Dict` 后,普通 WorldFor、历史导出/inspection/模板读面及未来项目仍取原规范基础。另给时间漂移建立独立固定用例与修复入口。运行 `go test -race`、完整 RDM 包回归;已批准 DHF U1 合同未合入前不声称 W3/模板实例可用。
|
||||
- 在同一机器和固定数据集上新增可重复数据生成与延迟/RSS采集载具(仅 `go test -benchmem` 不会给 p95/p99或峰值RSS),同时测现行缓存返回与推荐混合方案:0/1千/1万/10万事件,历史量与当前节点数不同比例,1/8/32读者+1写者,以及一个大项目加一个小项目的非对称负载;分别记录冷装载、提交后建 sealed log、热 `WorldFor`、按需 `Snapshot`、跨项目锁等待及报告/追溯/导出/入库路径的 p50/p95/p99、allocs/op、字节分配和峰值存活 heap/RSS。另在10万历史事件项目中连续提交 N 次、每代保留一个旧读指针,再释放这些指针,量测多代 sealed 日志/状态副本的存活 heap 与回收,不能以同代共享掩盖跨代内存增长。`TxProject` 当前仅为项目存在性调用 `WorldFor`,改为只读副本后不得为一次写入无谓复制整个状态。**阶段6人工评审决定可接受成本**;实现前不把任务卡中“1万事件 p95≤1.2倍、RSS≤2倍”的候选数字写成已批准性能门槛。软删切片、全部文档版次和退役边仍留在当前投影,热读仍可能随历史量增长;若严重影响成员工作,停止将本方案称作最终实现,提交 DTO/按需投影修订。
|
||||
|
||||
请评审是否批准“私有 canonical + 每次 WorldFor 独立状态副本 + 同版本共享 sealed 事件日志”的受影响读合同与上述完整性/性能验证。批准仅放行 W2 原隔离分支继续实施、测试和独立复审;W4a 增量 A、W3、合入、真实迁移与部署仍遵守原阶段门禁。
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
# 阶段6 W4b 真人确认受影响设计修订候选 r1
|
||||
|
||||
状态:待阶段4受影响方案人工评审;本文不是实施授权、基座公开面、确认成功回执或阶段6验收。记录日期:2026-10-14。影响范围仅为动态结构、字典及模板升级提案的确认入口和可信凭据;W3 递归实例及无副作用的提案展示可以按原批准方案继续。
|
||||
|
||||
## 1. 固定事实与阻断
|
||||
|
||||
- RDM 已同步的隔离分支固定源码为 3869738d575fbf5e8b42dc82c7fff0c20aa0fed8,基于 RDM origin/main 7828925787fbdb0086675f72af05289c7045dbce;该组合 pin 的 Backend 为 ead5ade30e8a9475277ba72505f5029feea93304,公开 extension SurfaceVersion 为 2.12.0-experimental。此处是 2026-10-14 的源码快照,不证明未来主干或运行实例。
|
||||
- 固定 Backend 的 extension.Host 不含可核验真人确认的可选能力,extension.Request 只有 Actor、Owner、ConversationID、Entrance、HostProjectID 等分发字段。Entrance 的 button/card/chat/api 是入口分类,不是受信人工动作的证明,也没有一次性提案修订与 payloadHash 绑定。基座内部已有 HITL 挂起与响应机制,但没有给 RDM 一个可在项目事务内使用的公开确认凭据合同。
|
||||
- W3 的独立失败测试 TestDHFInstantiateMaterializesTemplateBlockIdentity 在 RDM 测试提交 7c9a19385e 下为 SELF RED,收据见 RDM 任务卡 SHA256 前缀 a5eddadb:受控已发布夹具的模板块 purpose 未生成项目 nodeID/templateBlockID。该 RED 证明 W3 实例差距,不替代本 W4b 的可信真人确认验证。
|
||||
- Dev/Documents 首次独立 precheck 因 Dev 分支落后主干返回 SYNC_REQUIRED,故未写仓;协调者同步后,第二次外部 SELF 收据 /tmp/rdm-w3-w4b-dev-precheck-ready-20261014-1605.json 返回 READY,SHA256 3eb298d362236aa0bf691e2175b54eb6b412f3553f1ff0106ccba7527ba20d43。本候选在获准的独占文件窗口写入。
|
||||
|
||||
阶段4 r1 第5.2–5.3节已批准的硬约束是:实际人确认绑定 projectId、proposalId、revision、payloadHash、actor 和有效期,在同一 RDM 项目事务中消费;模型以人名调用工具、confirmed=true 或伪造 confirmedBy 均不能生效。当前公开接口无法证明这个条件,故 W4b 确认写入和插件决定命令保持阻断,不能以入口字符串、RDM 自签 token 或当前草稿采纳入口代替。
|
||||
|
||||
## 2. 候选路线与取舍
|
||||
|
||||
| 路线 | 可核的人工来源 | 事务边界 | 判断 |
|
||||
|---|---|---|---|
|
||||
| 推荐:基座 HITL 响应生成仅面向 RDM 的受信确认凭据;可选 Host 能力向本次分发提供已核验声明;RDM 在自己的项目事务中以凭据 ID 唯一约束消费 | 由基座认证响应及当前 pending 对象生成,模型工具不可领取;Host 不信任 Params 里的 actor/入口自报 | 提案 applied、领域事件、项目 revision、凭据消费、操作回执和审计 outbox 同一 RDM 事务 | 保留既有宿主身份边界与 RDM 事实源,无跨库两阶段提交 |
|
||||
| 基座先消费 token、再调 RDM apply | 基座可证明真人 | 两库不原子;RDM 回滚会丢失一次性凭据,未知结果难恢复 | 不采用 |
|
||||
| RDM 根据 button/card 或文本自签确认 | 无法区分模型调用与真实人动作 | 即使 RDM 事务原子,也没有可信授权起点 | 禁止 |
|
||||
|
||||
建议新增可选公开能力 HumanDecisionVerifier(名称待基座 X3 评审定稿),由受信 Host 在本次命令分发上下文回答 VerifyHumanDecision(expectedBinding),而不是把可复制的秘密 token 放入模型可见 Params。expectedBinding 至少包含 audience=rdm.structure.decide、actor、projectId、proposalId、proposalRevision、payloadHash、decision;返回只读 proofId、issuer、humanActor、projectId、proposalId、revision、payloadHash、decision、issuedAt、expiresAt、conversationId/runId 及基座持久 HITL 响应引用。Host 必须证明当前分发确由认证人对该确切待确认卡作出选择;模型工具、后台重放、无项目/无 pending 卡、过期或不匹配均 fail closed。RDM 不得自行铸造这份证明。
|
||||
|
||||
proofId 在 RDM 仅作消费键和审计引用,原始凭据不写入领域事件、模型上下文或普通读面。基座只验证并出具已发生的人类响应,不在独立基座事务中先标记 token 已消费;RDM 的 proofId 唯一约束承担一次性消费。凭据限定为该 RDM audience,其他插件不能把同一证明当作自己的确认。基座公开面必须同步 surface.txt、可选能力装配和兼容测试;RDM 只消费正式可用的固定组件版本,不改 pins、导入 Backend internal 或用本地替身替代发布合同。
|
||||
|
||||
## 3. 确认顺序、权限与恢复
|
||||
|
||||
1. 提案读面展示不可变 proposalId/revision、payloadHash、差异/理由/依据/影响、受控对象与当前 baseVersions;编辑产生新修订和新 hash,旧确认不转移。自动生成只到 pending,不更改有效树。
|
||||
2. 受信人从现有 HITL 卡或同一受控 UI 路径确认。基座把认证 actor、确切 pending 对象和响应持久化,再给本次分发可核验的证明;自然语言“批准”只有在 pending 对象唯一且经同一基座响应路径绑定时有效。
|
||||
3. RDM 按可信 actor/project 获取项目私有事务与数据库 CAS,围栏内再校验项目成员、doc.write 或明确经评审的结构管理动作、当前职责/整文锁定、字典/结构/模板版本、提案修订/hash、证明有效期和 audience。跨文档变更要求所有目标授权;不能以 project.settings 隐式扩权。
|
||||
4. 在同一 RDM 事务中 INSERT 唯一 proofId 消费行、校验 requestDigest/operationId 幂等范围、应用整批结构事件、更新 proposal applied、写回执和审计 outbox。任一校验或写入失败全回滚,确认前有效结构字节不变;失败尝试另留非已生效记录。提交后一次发布只读快照。
|
||||
5. 网络断开或返回未知时,先以 operationId 加 actor/project/proposal 查询已提交回执。已提交同键同内容返回原回执;同键异参拒绝;未提交且证明仍有效才允许重试。证明过期、权限撤销或提案改版需新人工确认。基座证明记录与 RDM 消费记录可按 proofId 对账,不把未收到响应等同未提交。
|
||||
|
||||
旧 content 草稿/审签记录保持旧事件与下载语义;新结构确认不会自动把正文标为批准。旧提案默认 content,旧命令只能返回其原形状;在可信证明未就位前,结构/dictionary/template-upgrade 的 decide 必须显式拒绝,不能降级到现有 AdoptDraftProposal 或其他旧直写入口。任何影响公开权限动作、事件载荷或旧库迁移语义的实现差异须回到本修订评审。
|
||||
|
||||
## 4. 最小重放集和停止条件
|
||||
|
||||
- 基座公开面:认证 HITL 响应正例;模型调用、伪 Entrance、错 actor/project、错 revision/hash、卡已改、过期、撤销、不同 audience 负例;同一 proofId 不能给第二个资源或插件使用。核验 Host 缺能力时 RDM 明确拒绝且零领域副作用。
|
||||
- RDM 事务:确认前树/版本/事件序号不变;提交后整批一次生效、重启可重放,凭据消费与 proposal/applied/事件/outbox/回执同提交;故障注入逐个中断点均无半树。两人并发仅一胜,确认瞬间成员或职责撤销拒绝,整文已锁定拒绝;拒绝/取消/改后接受留下可辨状态和新修订链。
|
||||
- 恢复与审计:提交后响应丢失按 operationId 找回原回执;同键异参拒绝;失败尝试不成为已生效结构事件;普通审计读面只见 proofId 引用及人类响应事实,不泄露凭据材料。SQLite 与隔离 PG 各做关键 CAS/重放/撤权;真实模型与浏览器确认路径待后续已批准验证阶段,当前 NOT_RUN。
|
||||
|
||||
停点:基座 X3 公开能力、可信发行链和 RDM 原子消费合同经用户批准且形成固定可消费组件前,W4b decide 写入口不实施、不宣称确认可用。W3 不受此缺口影响的递归实例和旧数据兼容可继续;本文仅请求对这一受影响阶段4合同作人工评审,不重开已批准的 W2 数据保全与读隔离结论。
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
# W4b 本地实现进展
|
||||
|
||||
更新时间:2026-10-15。这是实施记录,不改写已固定的设计修订 r1。
|
||||
|
||||
## 状态
|
||||
|
||||
| 事项 | 状态 |
|
||||
|---|---|
|
||||
| 本地实现 | 已完成 |
|
||||
| 本地验证 | SELF,见下 |
|
||||
| 合入 main | 未合入 |
|
||||
| 部署 | 未部署 |
|
||||
| CI GATE | 未运行 |
|
||||
| 交付同步 | 未做。启动时交付预检为 SYNC_REQUIRED,本次按本地模式继续 |
|
||||
|
||||
## 固定对象
|
||||
|
||||
- Backend `a4d6404c5ff9fecd2c0d40d94c6896773f797ba4`:可选 `HumanDecisionVerifier`;证明由基座签发、不由基座消费;迁移 45 登记为不破坏旧读者。
|
||||
- RDM `528dd0c04a7174949a0297c131fe71fd470b94af`:结构、字典、模板升级提案;不可变修订与 payloadHash;项目事务内唯一消费 proofId;`rdm.structure.decide` 拒绝 `confirmed` / `confirmedBy`。旧 content 草稿仍走原表。
|
||||
- Dev 组合指针:`modules/backend` 固定到上述 Backend。架构基线补上该组件已经存在的 `projectcontext` 依赖边。
|
||||
|
||||
## 已验证
|
||||
|
||||
- RDM SQLite SELF:确认前有效树不变;四个故障注入点回滚;两人并发只有一个生效;整文锁定、文档职责不符、成员撤权都拒绝;同一 operationId 重放原回执,同键异参拒绝;修订后旧 hash 不能应用;重启后章节仍在;content 草稿保持 pending。
|
||||
- Dev SELF:`make test && make build` 退出码 0。任务卡收据 `edb81a90dfbd270b0a68d8679c6b3a1a8d5da3e89de92bad2647478a7eb77bc0`,来源 SELF。
|
||||
- 工作台:未连接时「结构」按钮提示先连接。用桩命令总线时,提案卡展示修订、哈希、理由、依据、影响和基线,确认按钮调用 `rdm.structure.issue`,参数不含自签标记。
|
||||
|
||||
## NOT_RUN
|
||||
|
||||
- 隔离 PostgreSQL。当时 `pg_isready` 没有可用实例。
|
||||
- 真实模型确认路径。
|
||||
- 真实基座 HITL 卡的端到端确认。浏览器没有接上运行中的基座。
|
||||
- 相对 `origin/main` 的 `task-sync`、当前 HEAD 的 CI,以及合入。
|
||||
|
||||
## 下一步
|
||||
|
||||
W3 已知 RED `TestDHFInstantiateMaterializesTemplateBlockIdentity` 仍不在本次范围。合入前需要把分支同步到权威 main、完成人审,并由当前 HEAD 的 CI 通过。
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
# 阶段6受影响设计修订:项目模型历史来源逐项复验 r1
|
||||
|
||||
记录日期:2026-10-14。状态:**待人工评审**。本修订影响已批准阶段4方案 §7 与阶段5 W6/W7 的 X1 Backend–RDM 公开合同和 Backend `ContextManifest` 存储;不改变项目权限上限、普通私域会话、DYN-01、44份模板范围或模型评测预算。W6 Backend 独立分支当前候选 HEAD `6ba53e43ede296e192bb8875d284ba5a9dc27acc` 尚未推送、合入或部署。
|
||||
|
||||
## 发现、复现与立即边界
|
||||
|
||||
W6 独立审阅先发现 CompiledWorkflow 的 judge 使用独立模型 guard:若前一步输出含当时有权的受控正文,随后撤权,judge 可把旧 `output.md` 当一条新 user prompt 送模。W6 已在本地增加持久 run/step/执行尝试/已响应模型回执/输出字节 hash 的绑定,judge 前复验;源码及固定 HEAD SELF 全包、race、构建显示这条泄漏路径被阻断。第二轮审阅又发现按目标筛选来源的合法提供方会被空 Goal 误拒;候选修订把原 Goal 写入私有 `context_manifests.resolve_goal` 后恢复了正常流程。
|
||||
|
||||
第三轮审阅确认该私有列又引入新的持久化问题:普通 RoleUser 可以是完整任务文本,judge 的 RoleUser 则包含前一步 `output.md`;`attempted` 和 `responded` 两行都把原文复制进长期数据库、迁移与备份。未提交的 `TestContextManifestDoesNotPersistWorkflowOutputInResolveScope` 在 HEAD `6ba53e4` 上为 RED,合成标记 `OLD_RESTRICTED_BODY` 确实落入两行 `resolve_goal`;完整 SELF 收据见 `/tmp/w6-scope-privacy-red-6ba53e4-20261014.json`。该代码仅在未合入分支,不能称生产数据已经泄漏。阶段4已批准的 Manifest 边界是对象版本、hash、实际纳入片段与水位,不是保存完整 prompt/模型产出。
|
||||
|
||||
**修订获批前暂停 W6 的公开接口和迁移实现。** 已有安全 RED、原分支与收据保留;不以删掉 goal-sensitive 正例、撤权负例或把正文藏进另一个通用日志来过关。
|
||||
|
||||
## 方案取舍
|
||||
|
||||
| 路线 | 能否同时满足正常按目标检索、撤权与内容最小化 | 建议 |
|
||||
|---|---|---|
|
||||
| 永久保存原 Goal/Target 后重新 `Resolve` | 可重得当时筛选集合,但直接保存完整受控正文,重复进备份 | 拒绝 |
|
||||
| 只保存 Goal hash、仍调用 `Resolve` | 无法从 hash 恢复合法提供方的原筛选集合,正常 critic 误拒 | 拒绝 |
|
||||
| 将原 Goal 放独立加密短期存储 | 需密钥/ACL/TTL/恢复语义,过期时仍 fail closed;增加新的敏感正文存储 | 暂不采用 |
|
||||
| 保存已实际纳入来源的稳定 ID/修订/hash,由领域提供方按当前权限逐项复验 | 不存 prompt/output,能复验同一来源和撤权;须增加可选公开复验接口 | 推荐 |
|
||||
|
||||
## X1 最小公开合同增量(四要素)
|
||||
|
||||
| 要素 | 修订内容 |
|
||||
|---|---|
|
||||
| 用户场景 | 同项目成员正常对话或 CompiledWorkflow 多步骤工作时,先前模型实际用过的来源在下一次调用、任一步骤消费旧产物、judge、后台恢复前须按**当前**项目/对象/文档职责/发布状态复验;有权且来源未变时正常推进,撤权/升版/正文改变时旧机器内容不得回流模型。 |
|
||||
| 希望的公开符号 | Backend `pkg/extension`给**同一已注册 X1 提供方**增加**可选** `ProjectContextSourceRechecker.Recheck(ctx, ProjectContextSourceRecheckRequest) (ProjectContextSourceRecheckResult, error)`;不强加给旧 `ProjectContextProvider` 或通用 Host。请求仅含从受信持久 run/会话/任务取得的 actor、plugin、project、conversation、task、run/step、当前对象 ID,及旧可信 Manifest 中**实际纳入**的 sourceID/revision/sourceHash/inputSHA256、实际展示给模型的 `OfferedReferences` 和已读 `ReadEvidence` 稳定引用;不含 Goal、完整 prompt、output 或正文,已丢弃/未提供的候选项不能冒充实际所见。响应为每项当前可读/发布状态、精确身份/版本/hash、授权的当前 `Text` 或等价可复算的规范输入、当前授权的相同 EvidenceRef、权限/发布 epoch 与领域水位。Backend 在受信调用内逐项核对数量、ID/revision/sourceHash,再临时复算 `Text` 的模型输入 SHA;这些文本不写入通用回执。当前 EvidenceRef 经重新授权后仍须调用 `ReadEvidence` 再读正文并复算 InputSHA256,不能只回显旧 hash 当再鉴权。具体类型名可按代码规范等价命名,但受信输入、逐项结果和 fail-closed 语义不得删。 |
|
||||
| 当前组合不足 | 现有 `Resolve(Goal)` 可按 Goal 筛选;单存 Goal hash 不能重新选出当时 Source A,空 Goal 只得 Source B 会误拒。现有 `ReadEvidence` 只覆盖详细引用,不能证明旧短摘要/要求项仍有权;仅比较项目 epoch 可能漏掉资源级撤权或正文替换。 |
|
||||
| 兼容方式 | 非项目会话和现有普通 `Resolve`/`ReadEvidence` 保持原行为;旧 X1 提供方不实现复验接口时,项目态旧机器产物/judge/恢复明确受阻,不退化为无来源放行。RDM W7 消费真实 Backend 发布版时实现该接口并按对象逐项查 IAM、文档职责、批准/发布与版本;不能从调用者自报的 sourceID 推断权限。 |
|
||||
|
||||
Backend 仍独占最终模型输入及可信回执。`Recheck` 请求只能从受保护 Manifest、持久 run/step/attempt 与当时实际纳入清单构造,客户端/模型/任意插件不可补造;响应仅由同一注册的领域提供方返回,受 3 秒上限约束,超时 fail closed。新增入模门禁:Included 若缺稳定 sourceID/revision/sourceHash,或 OfferedReferences 缺可再鉴权 ID,当轮就拒绝计入可恢复的项目模型输入,不能到恢复时才发现无法定位。`InputSHA256` 是模型所见 `Text` 摘要,不等同于领域 `SourceHash`;Backend 逐项重算,不能接受提供方只回显请求中的 hash。当前 EvidenceRef 必须重新授权并经 `ReadEvidence` 再读正文。少一项、同ID异正文、跨项目/主体、提供方拒绝/超时、同一步骤混有 attempted/unknown 未定回执、并行归属不明、目标切换或当前 epoch/水位不一致均拒绝旧产物进入下一模型调用。候选检索或已丢弃片段不可充当旧模型实际所见。普通用户本轮自主输入与旧机器产物分开处理。
|
||||
|
||||
内部工作流不能只在 judge 校验:第二个 prompt、blackboard 汇总、`{{steps.X.output}}` 插值及其他把旧步骤输出带入模型的消费点均须绑定原 run/step/执行尝试与实际字节,调用上述逐项复验;无法识别旧机器来源时项目态拒绝发送。一次模型请求中的全部早轮/并行来源都要重验,不能只取最后一个 responded 回执。普通本轮用户自主输入不从旧机器片段继承权限。
|
||||
|
||||
## 数据、恢复与测试
|
||||
|
||||
- 新回执只保存受信 run/step/model attempt、项目、实际纳入项/证据引用的稳定 ID、revision/hash、输入摘要、预算裁剪、权限/发布 epoch 与来源水位;不在 `context_manifests`、通用 audit、导出或日志保存 Goal、judge prompt、`output.md` 正文。无法建立稳定来源的旧项目机器产物 fail closed。
|
||||
- 当前 v34 仅在未合入分支。实施时修订尚未发布的 v34,让**新安装路径从一开始就不创建含原文的列**;对已经运行过候选 v34 的隔离库提供条件式向前清除/删除原文列的迁移与核对,不以改文件声明既有字节已从备份消失。`storage-migrate` 若目标表无原文列会忽略旧源列,但其旧源快照/备份仍可能有正文;`cmdBackup` 遇旧 v34 源须先净化或明确拒绝,不能把目标复制成功当全链清零。历史回执缺可信逐项来源/attempt 时不能猜测补齐;若曾生成包含原文的本地备份,列为受控隔离/处置清单。与 W9 的 v31/v32 顺序冲突在真实串行合入后重排并重测。
|
||||
- 先使上述数据库无正文 RED 转绿;完整 goal-sensitive `prompt→judge` 同权限正例、A→B 多轮后撤回早轮 A、第二个 prompt/blackboard/步骤插值负例、发布变化、内容替换、输出字节替换、错误 run/step/attempt、无 rechecker/恶意响应、同一步骤含 attempted/unknown、恢复、并发和取消负例覆盖实际模型请求。SQLite 和隔离 PostgreSQL 的新库、候选 v34 升级以及现有 `storage-migrate` **SQLite→隔离 PostgreSQL** 复制/核对与幂等重跑,分别证明目标库无原文、旧源快照/备份被拒绝或经受控净化;不虚构不存在的 PostgreSQL→SQLite 回迁。RDM W7 真实提供方和真实模型前后对照保留阶段5预算与阶段7验收。
|
||||
|
||||
请评审是否批准“按已实际纳入的稳定来源逐项重新授权”的 X1 加法合同与去原文迁移边界。批准只放行 W6 隔离分支继续实现和测试;公开 tag 发布仍为用户双钥匙操作,RDM W7/Dev 组合及阶段6、7出口仍需后续证据和评审。
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# 阶段6受影响设计修订:审计 ID 的全部写入路径 r1
|
||||
|
||||
记录日期:2026-10-14。状态:**待人工评审**。本修订补足已批准 [PostgreSQL 截止水位修订 r1](rdm-two-trees-stage6-w9-pg-audit-cutoff-adjustment-r1.md) 的一个未满足负例;不扩大可共享审计范围,不改变 X2“仅可信已提交项目业务操作可跨成员链接”的权限边界。Backend W9 隔离分支当前本地 HEAD `63ebc85695790e7d0c2b758e5c0ed1b4adaec008`,未推送、合入或部署。
|
||||
|
||||
## 发现与影响
|
||||
|
||||
W9 v33 给省略 `command_audit.id` 的在线 INSERT 加事务级 advisory 锁和 `CACHE 1` 序列检查,默认写入口的真实跨页、并发、迁移及回滚测试为 SELF PASS。独立复审发现:显式 `INSERT(id=空洞低号)` 不求值列默认函数,因此不取得该锁。新增测试-only `TestProjectAuditPostgresExplicitLowIDCannotHideAcrossPages` 已在隔离 PostgreSQL 18.6 实测为 RED:已提交 ID 1/2、隐式取 3 回滚,事务 A 显式插入 3 暂不提交,B 正常 `AppendAudit` 提交 4;真实 `QueryProjectAudit` 第一页返回 `[4,2]`、`CutoffOffset=4`、`NextOffset=2` 且报告 `committed-prefix`,A 提交后下一页只有 `[1]`,永久遗漏 3。完整失败收据 `/tmp/backend-w9-explicit-low-red-20261014-01.json`,来源 SELF,退出码 1;Backend HEAD `63ebc85695790e7d0c2b758e5c0ed1b4adaec008`,唯一未提交改动为该测试,diff SHA256 `a85633c58a0841ecb1f479b9ceaed237aacacad1a5bafe761996fc7e9b711ecd`。这证明当前强 coverage 断言错误,**并不证明修复已就位**。
|
||||
|
||||
已批准 r1 明确把在线显式 ID 列为禁止维护动作,并要求负例证明强 coverage 不会误报。当前软件无法强制这一约束;只靠操作规程或当前 Backend 唯一生产调用点,不能给项目审计页面作无条件“已提交前缀”的保证。W9 `63ebc85` 因此仅是受支持默认写入口的局部候选,完整 W9 与阶段6增量 C 都未完成。当前强 coverage 先保持未发布;必要时读面退回 `offset-upper-bound-only` 或失败关闭,不能发布已知可误报版本。
|
||||
|
||||
## 选择与推荐
|
||||
|
||||
| 方案 | 对现有接口和数据的影响 | 取舍 |
|
||||
|---|---|---|
|
||||
| 保持默认函数,只在文档禁止显式 ID | 对直连 SQL 不设数据库门禁,强 coverage 仍可误报 | 不满足本次验收 |
|
||||
| 保留默认函数,给**所有** `command_audit` INSERT 加同一事务锁与单调检查的行级门禁 | 在线隐式/显式写均在提交前排队;公开游标字段不变;需调整离线显式复制与重试 | 推荐,先在隔离 PG 验证可实现性 |
|
||||
| 运行账号与迁移账号分离,按列权限阻止运行账号写 `id` | 权限与部署配置变化大,现有 DSN/测试未证明双账号可用;维护账号仍可破坏顺序 | 备选 |
|
||||
| 用服务端持久快照/新游标身份替换整数 cutoff | 不再依赖提交序 ID,但改公开分页合同、授权 epoch 和快照清理 | 若门禁方案无法证明则重新评估 |
|
||||
|
||||
推荐的数据库门禁是 `BEFORE INSERT` 行级 trigger 或等价受信 DB 路径:在任何行进入 `command_audit` 前取得与当前默认函数**相同**的事务 advisory 锁,先确认 `current_setting('transaction_isolation')` 为 `read committed`,再以锁后的新可见快照验证 `NEW.id > 0` 且严格大于当前表最大 ID。`REPEATABLE READ/SERIALIZABLE` 事务即使等到了锁,也可能用旧快照漏看已提交高 ID,故项目在线写入须明确拒绝这两档,不能靠“锁已取得”推断安全。显式高 ID 若超过当前已预留序列位置则直接拒绝,不能让随后默认取号退回其后;本轮不增加在线 `setval` 通道。事务持锁至提交/回滚,后续在线写者不能在低 ID 尚未确定时提交高 ID。保留当前默认函数供省略 ID 的 Backend `AppendAudit` 使用;trigger 不二次分配 ID,避免正常写入双取号。PostgreSQL 默认值在行级 BEFORE trigger 前已经填入,因此“`NEW.id` 非空即拒绝”会误伤正常写入。[默认值规则](https://www.postgresql.org/docs/18/ddl-default.html)、[触发器与事务](https://www.postgresql.org/docs/18/trigger-definition.html)、[旧事务快照与锁](https://www.postgresql.org/docs/18/sql-lock.html)。
|
||||
|
||||
门禁的证明前提需明确:`CACHE 1`、正向非循环序列、默认函数与 trigger 均存在,`pg_trigger` 显示确切 BEFORE ROW/函数身份且 `ENABLE ALWAYS`,强读和写入均核验,而不只看默认表达式。`ENABLE ALWAYS` 防 session_replication_role 改变通常的触发器触发范围;受控离线复制只短暂禁用**指定审计门禁**,保留主键/外键等约束触发器,并以排他表锁阻断读写。[ALTER TABLE 触发器启用模式](https://www.postgresql.org/docs/18/sql-altertable.html)。审计行还须 append-only:在线 `UPDATE` 或 `DELETE` 都应由独立的 DB 级门禁拒绝,业务修正只能追加新事实。受控升级建议使用版本化函数身份;运行时能检出 trigger 禁用、改绑、默认表达式/序列参数或schema版本漂移,不以只看同一 OID 声称能发现有权限者的 `CREATE OR REPLACE FUNCTION` 同 OID 换体。DB 管理员改写/禁用门禁、强制修改序列或物理库文件仍属于受控维护/事故,不声称软件能防恶意 DBA。任一受支持运行不变量无法核验时不返回强 coverage。
|
||||
|
||||
## 离线迁移与恢复边界
|
||||
|
||||
现有 `storage-migrate.copyRows` 逐表开启一个事务,源查询没有 ID 顺序保证,使用显式 ID + `ON CONFLICT DO NOTHING`,事务提交后才由 `advanceSequences` 另行推进序列,`migration_table_state` 又另写 done。直接加单调 trigger 会拒绝乱序复制、已存在 ID 的幂等重试,也会留下“复制已提交而序列未推进/状态未记”的窗口。需给 `command_audit` 单独设计**排他停写、独立于在线请求的受控复制事务**:锁表并验证无在线写者 → 在同一事务内临时停用指定门禁或采用等价受限写入能力 → 复制及逐行/最终 hash 对账 → 只向前推进序列至不低于当前已预留位置和最大保留 ID → 恢复门禁并核验启用与参数 → 写同一事务的完成状态 → 提交。复制和对账期间 `ACCESS EXCLUSIVE` 会阻塞该表读取及写入,停顿随源数据量增长,必须在隔离库量测。现有 `advanceSequences` 只按目标 `MAX(id)` 调用 `setval`,可能把更前进的序列**回拨**,不能原样复用;须在停写/排空旧缓存后比较序列当前状态和目标最大 ID,空表、失败重跑也不能降低下一个 ID。失败或进程退出应使门禁停用/复制/完成状态一同回滚;`setval` 非事务性,失败后仅允许向前空洞,仍以运行时检查证明下一个 ID 大于已提交最大值。[序列状态与回滚](https://www.postgresql.org/docs/18/functions-sequence.html)。`migration_table_state` 的 done/idempotent 重跑也应在这一约束下对账,不把 `ON CONFLICT DO NOTHING` 当成功证明。
|
||||
|
||||
真实运行库迁移仍未获授权。本修订只放行隔离库升级/回滚/复制演练;W6 的 v31–v35 与 W9 的 v31–v33 冲突仍须真实串行合入后重排,并以最终组合版本重测。公开 `CutoffOffset`/`BeforeOffset`/链接 `HostAuditOffset` 保持现状,RDM W8 的 operation 级分页及对象权限仍未实现。
|
||||
|
||||
## 验证与停止条件
|
||||
|
||||
1. 先在隔离 PostgreSQL 将上述“低号显式插入等待、高号先提交、跨页漏行”制成 RED;门禁后它应表现为低号先提交或该显式操作被拒,绝不再出现 `committed-prefix` 加漏行。并测多行乱序、`ON CONFLICT` 幂等、`REPEATABLE READ/SERIALIZABLE` 旧快照拒绝、锁超时/取消、回滚空洞、显式高 ID、在线 UPDATE/DELETE、默认函数与门禁 trigger 的禁用/改绑及可检测配置漂移;同 OID 的有权限函数体替换属于受控DDL事故,不虚构运行时可检测。
|
||||
2. 旧库→新 schema、v33 候选已应用库、离线 SQLite→隔离 PG 复制及中断重跑各保持原 ID/链接/owner 项目边界;门禁恢复、序列推进、对账与强 coverage 相互一致。读写 8 并发及大页查询记录吞吐/p95/锁等待,和 W9 r1 的 SELF 条件并列;用户未批准数值阈值,成本须留阶段6评审决定。
|
||||
3. 任何路径无法保证全部在线 INSERT 经同一提交顺序,立即停止强 coverage 声明,保留真实 `offset-upper-bound-only`/失败状态并回到设计评审,不改写旧记录、放宽权限或用前端隐藏遗漏。
|
||||
|
||||
请评审是否批准覆盖所有在线 `command_audit` INSERT 的事务门禁,以及上述排他离线复制/恢复边界。批准仅放行 W9 隔离分支实现与测试;真实库迁移、阶段6/7验收、PR/合入与部署仍按原门禁。
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# 阶段6受影响设计修订:PostgreSQL 宿主审计截止水位 r1
|
||||
|
||||
记录日期:2026-10-14。状态:**待人工评审**。本修订只影响 Backend W9 的 PostgreSQL `command_audit` 新写入顺序、固定截止分页和迁移恢复;X2 已批准的“仅可信已提交项目业务操作可跨成员关联”、owner 私域、当前权限检查与 RDM 操作级投影不变。W9 当前独立分支 HEAD `0e8cd040cc75c329eb8950676acc7a9a08487ad2` 尚未合入或部署。
|
||||
|
||||
## 发现与风险
|
||||
|
||||
隔离 PostgreSQL 18.6 的 `TestProjectAuditPostgresCutoffLateCommit` 已实际复现:事务 A 先分配低 `command_audit.id` 但暂不提交,事务 B 后分配较高 ID 并先提交;同一 `CutoffOffset` 后来可读到原先不可见的低 ID。该测试证明当前截止水位**不是固定可见快照**,尚未直接模拟跨页漏行;正式 RED 还需构造已提交的更低 ID、未提交的中间 ID、已提交的较高 ID,第一页游标越过中间 ID 后再提交。现有页面诚实标 `cutoffConsistency=offset-upper-bound-only`,不能作为 W9/W8 稳定历史分页完成证据。SQLite 当前单写连接没有该并发路径;它的测试结果不能证明 PostgreSQL 安全。
|
||||
|
||||
`command_audit.id` 同时是宿主审计 source offset 和可信链接的定位键。`REPEATABLE READ` 只固定一次 HTTP 请求内快照,不能固定多次请求;在现有 `CutoffOffset` 整数合同下,读取端无法识别之后才提交的低 ID。若改为服务端持久分页快照或新提交序列列,就要扩展游标/存储和清理规则。当前生产写入口 `cmdbus → Store.AppendAudit` 省略 `id`;离线 `storage-migrate` 及测试会显式复制 ID。以下为**方案建议,不是已实施或通过的能力**。
|
||||
|
||||
## 建议的最小修复
|
||||
|
||||
在 W9 PostgreSQL 迁移中,把 `command_audit.id` 的默认生成器改为 `next_command_audit_id('command_audit'::regclass)`:函数先取得该表的**事务级 advisory lock**(独立双整数命名空间+表 OID),再调用原序列 `nextval`,锁随事务提交/回滚释放。所有受支持的在线审计 INSERT 均省略 ID、走此生成器;后一个事务不能在前一个分配 ID 的事务结束前取得 ID。**前提是该序列 `CACHE 1`、正向、不循环、下一 ID 始终为正且高于既有最大 ID**:PostgreSQL 官方文档说明 `CACHE > 1` 可使不同会话从预留块取号而乱序;迁移必须核验配置与当前位置,不满足时失败关闭并要求先停写、排空持有旧缓存的连接后单独处理,不能单靠 `ALTER SEQUENCE ... CACHE 1` 认为旧连接缓存立即失效。函数及启动检查也应拒绝后续不符配置。在线显式插入 ID、`setval`/`RESTART` 回退、运行中调整序列参数都列为禁止的维护动作;授权的离线复制只能在排他停写窗口进行,随后把序列推进到已复制最大 ID 之上。否则即便主键唯一也可能利用空洞制造低 ID 迟提交。提交成功的受支持在线新行因此形成 ID 前缀;回滚造成的空洞不被误认为待提交行。表迁移锁应等待旧写事务退出,避免新旧生成器在过渡窗口并发分配。该锁只串行审计 append 的事务,不作为项目业务事务或 RDM 事件的统一顺序。[序列缓存与跨会话乱序](https://www.postgresql.org/docs/18/sql-createsequence.html)、[ALTER SEQUENCE 对既有缓存连接的影响](https://www.postgresql.org/docs/18/sql-altersequence.html)、[事务级 advisory lock](https://www.postgresql.org/docs/18/functions-admin.html)。
|
||||
|
||||
仍保留现有数值 `CutoffOffset`、`BeforeOffset` 和 `HostAuditOffset` 字段,不改历史链接身份。PostgreSQL 固定截止只在 schema、序列不变量及受支持写入口均经运行时核验后报告 `committed-prefix`;任一条件无法证实时失败关闭或降为明确 `offset-upper-bound-only`,不能裸报强保证。迁移前的旧历史行在迁移完成时已提交,可纳入之后的新查询。迁移前已发出的旧游标若可能被外部使用,应拒绝或显式标旧语义,不能静默升级;本 W9 公开读面目前仅未合入候选,应在首次发布前验证没有已部署使用者。若回滚到旧 schema/二进制,先停写并执行受控 down;旧二进制会因未知迁移版本拒绝启动,降级后覆盖语义须回到 `offset-upper-bound-only`,不能继续声称已提交前缀。
|
||||
|
||||
离线复制的显式 ID 不经默认函数,`storage-migrate.advanceSequences` 当前只识别 `column_default LIKE 'nextval%'` 或 identity;改为函数默认后必须通过 `pg_get_serial_sequence` 所有权识别并在恢复后推进原序列至最大已有 ID。迁移 up/down 要在隔离副本验证,down 先恢复原 `nextval` 默认再移除函数。SQLite 保持现有行为。锁键应稳定限定该表,避免与其他 advisory lock 冲突;函数、权限和升级过程须在目标 PostgreSQL 版本重放,不把测试库成功当现网迁移授权。
|
||||
|
||||
## 影响与取舍
|
||||
|
||||
好处是无需新增公开分页字段或复制整批 ID 的服务端快照,能在同一数值 cutoff 下保证**新在线写入**的已提交前缀。代价是 PostgreSQL 全部 `command_audit` append 按事务串行;一个长事务或卡住的写入会使后续审计写入等待,进而影响命令完成时延。迁移需锁表和停顿写入,必须测等待、超时及回滚。继续使用现有无序列化 ID 只能维持 `offset-upper-bound-only` 且会漏读,不满足当前完整追溯审计验收;服务端持久快照可避免写入串行,但引入快照生存期、清理和授权 epoch 绑定,范围更大。
|
||||
|
||||
## 验证与停止条件
|
||||
|
||||
- 隔离 PG 至少三行/两事务的真实跨页漏行负例先 RED 后 GREEN;`CACHE 10` 跨连接乱序负例以及 `CACHE 1` 正例;回滚空洞、迟到可信链接、同项目两成员/撤权、长事务等待与锁/语句超时均保持真实结果。当前 `AppendAudit` 没有 `context.Context`,本次只用 PostgreSQL `lock_timeout`/`statement_timeout` 测等待中止,不宣称请求取消可直接中止。当前 SQLite/PG 宿主审计和链接测试不得回退。
|
||||
- 从既有 schema/数据升级并回滚,再在排他停写窗口运行离线 `storage-migrate` 复制显式 ID 并新增审计行;证明下一 ID 正且高于最大已有 ID、无重复键、原链接定位不变。用序列回退到空洞、在线显式 ID、`CACHE > 1`、不正常 down/旧二进制等负例证明强 coverage 不会被误报。迁移需与 W6 的 v31/v32 冲突在真实串行合入时重排并做组合验证,不能在两个未合分支各自宣称组合通过。
|
||||
- 压力测试记录审计 append 的等待/吞吐变化,超出可接受运行预算则停下并回到替代方案;阶段7继续验证 RDM operation 级分页及当前授权过滤。这个 Backend 修复不等于 W8 RDM 投影已完成。
|
||||
|
||||
请评审是否接受上述 PostgreSQL 新写入提交前缀语义和串行化代价。批准仅放行 W9 在隔离分支实现与测试;真实运行库迁移、发布及完整阶段6/7出口仍按原门禁。
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"source": "SELF read-only API refresh, no PR mutation or merge performed",
|
||||
"checkedAt": "2026-10-14T08:43:14.885657+08:00",
|
||||
"repos": [
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"oldMain": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"main": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"changed": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"oldMain": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"main": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"changed": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"oldMain": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"main": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"changed": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"oldMain": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"main": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"changed": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"oldMain": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"main": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"changed": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-UI",
|
||||
"oldMain": "2c4322ef56df64ad72f65907d25b048a74bb5ffc",
|
||||
"main": "2c4322ef56df64ad72f65907d25b048a74bb5ffc",
|
||||
"changed": false
|
||||
},
|
||||
{
|
||||
"repo": "Development-Guidelines",
|
||||
"oldMain": "2f5b19872be2a4597838a4131ad75d1be089ee5e",
|
||||
"main": "2f5b19872be2a4597838a4131ad75d1be089ee5e",
|
||||
"changed": false
|
||||
}
|
||||
],
|
||||
"prs": [
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"number": 193,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193",
|
||||
"oldHead": "5f834544b0b808cb16214a36725f2ae3cb90bfd4",
|
||||
"head": "5f834544b0b808cb16214a36725f2ae3cb90bfd4",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 488,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488",
|
||||
"oldHead": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"head": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 489,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489",
|
||||
"oldHead": "3e7f0360087b126f41fa9ce18dbd1e53d0a8f067",
|
||||
"head": "3e7f0360087b126f41fa9ce18dbd1e53d0a8f067",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 512,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512",
|
||||
"oldHead": "e31443a8ff1f099f9b2ef320c295b0ddcdaf503d",
|
||||
"head": "e31443a8ff1f099f9b2ef320c295b0ddcdaf503d",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 89,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89",
|
||||
"oldHead": "b8df6f3c2a3180b06c61d2303bbfea9a3914f186",
|
||||
"head": "b8df6f3c2a3180b06c61d2303bbfea9a3914f186",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 95,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95",
|
||||
"oldHead": "c7cb2d8d89aaef0329c9a8a2045fcd42abb36e39",
|
||||
"head": "c7cb2d8d89aaef0329c9a8a2045fcd42abb36e39",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 73,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73",
|
||||
"oldHead": "d9bb780384b16f661d71a5e6ad288a77426d9d98",
|
||||
"head": "d9bb780384b16f661d71a5e6ad288a77426d9d98",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 79,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79",
|
||||
"oldHead": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"head": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 301,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301",
|
||||
"oldHead": "6252f62524ef34360fdcdf8844d7e729378ffbfb",
|
||||
"head": "6252f62524ef34360fdcdf8844d7e729378ffbfb",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 307,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307",
|
||||
"oldHead": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"head": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"headChanged": false
|
||||
}
|
||||
],
|
||||
"files": []
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/persist.go",
|
||||
"sha256": "7d16e107d522311e106625776d8414c6d2c5d7bc19915364345298afde7fbc2c",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/domain/persist.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/tx.go",
|
||||
"sha256": "94892e4b85bf395c2f5059b26c9c694f202c4d1898af6c57bdd69b2d020b05f5",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/tx.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"ref": "d9bb780384b16f661d71a5e6ad288a77426d9d98",
|
||||
"pr": 73,
|
||||
"path": "src/components/RdmAuditWorkspace.tsx",
|
||||
"sha256": "825c3dc3f01d28e41c6a05e8ece09663f65c714213d2808fef7e618f9cf01fa1",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/pr-candidates/Agent-System-Frontend/73/src/components/RdmAuditWorkspace.tsx"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"ref": "c7cb2d8d89aaef0329c9a8a2045fcd42abb36e39",
|
||||
"pr": 95,
|
||||
"path": "docs/proposals/2026-10-13-fast-slow-u3-r03-evidence-backed-judgments-design.md",
|
||||
"sha256": "3acd6b99184748ceb25453a30c7d4e3c972fbe465d6dc9b11709fa725264038e",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/pr-candidates/Agent-System-Documents/95/docs/proposals/2026-10-13-fast-slow-u3-r03-evidence-backed-judgments-design.md"
|
||||
}
|
||||
]
|
||||
+876
@@ -0,0 +1,876 @@
|
||||
{
|
||||
"source": "SELF authenticated PR metadata and changed file list",
|
||||
"checkedAt": "2026-10-13T19:45:45.206279+00:00",
|
||||
"prs": [
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"number": 193,
|
||||
"title": "[WIP] Verify source-backed stage judgments before publication",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "5f834544b0b808cb16214a36725f2ae3cb90bfd4",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "deps/agent-system-core",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "eval/live/work_checkpoints_persistence_test.go",
|
||||
"status": "added",
|
||||
"additions": 40,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "eval/live/work_checkpoints_test.go",
|
||||
"status": "added",
|
||||
"additions": 295,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/app/app.go",
|
||||
"status": "changed",
|
||||
"additions": 19,
|
||||
"deletions": 20,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/app/task_startup_test.go",
|
||||
"status": "added",
|
||||
"additions": 96,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/cardsvc/cardsvc.go",
|
||||
"status": "changed",
|
||||
"additions": 54,
|
||||
"deletions": 3,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/cardsvc/task_projection.go",
|
||||
"status": "added",
|
||||
"additions": 63,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/cardsvc/task_projection_test.go",
|
||||
"status": "added",
|
||||
"additions": 63,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/cardsvc/task_visibility.go",
|
||||
"status": "added",
|
||||
"additions": 98,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/cardsvc/task_visibility_test.go",
|
||||
"status": "added",
|
||||
"additions": 41,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/background_card_test.go",
|
||||
"status": "changed",
|
||||
"additions": 37,
|
||||
"deletions": 16,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/checkpoint_claim_guard.go",
|
||||
"status": "added",
|
||||
"additions": 99,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/checkpoint_claim_guard_test.go",
|
||||
"status": "added",
|
||||
"additions": 89,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/events.go",
|
||||
"status": "changed",
|
||||
"additions": 37,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/material.go",
|
||||
"status": "changed",
|
||||
"additions": 67,
|
||||
"deletions": 26,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/material_evidence.go",
|
||||
"status": "added",
|
||||
"additions": 286,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/material_evidence_test.go",
|
||||
"status": "added",
|
||||
"additions": 414,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/material_sources.go",
|
||||
"status": "added",
|
||||
"additions": 165,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/material_sources_test.go",
|
||||
"status": "added",
|
||||
"additions": 171,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/material_test.go",
|
||||
"status": "changed",
|
||||
"additions": 15,
|
||||
"deletions": 18,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/recovery_hold_test.go",
|
||||
"status": "changed",
|
||||
"additions": 2,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/runmgr.go",
|
||||
"status": "changed",
|
||||
"additions": 192,
|
||||
"deletions": 61,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/subagent_n2_test.go",
|
||||
"status": "changed",
|
||||
"additions": 42,
|
||||
"deletions": 3,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/subagent_transcript.go",
|
||||
"status": "changed",
|
||||
"additions": 19,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/task_checkpoint.go",
|
||||
"status": "added",
|
||||
"additions": 205,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/task_checkpoint_evidence_test.go",
|
||||
"status": "added",
|
||||
"additions": 227,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/task_checkpoint_test.go",
|
||||
"status": "added",
|
||||
"additions": 200,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/task_notice_revalidation_test.go",
|
||||
"status": "added",
|
||||
"additions": 56,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/task_projection.go",
|
||||
"status": "added",
|
||||
"additions": 409,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runmgr/task_projection_test.go",
|
||||
"status": "added",
|
||||
"additions": 186,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/checkpoint_plugin_test.go",
|
||||
"status": "added",
|
||||
"additions": 16,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/llm_direct.go",
|
||||
"status": "changed",
|
||||
"additions": 3,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/llm_test.go",
|
||||
"status": "changed",
|
||||
"additions": 4,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/material_final_reserve.go",
|
||||
"status": "added",
|
||||
"additions": 31,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/material_final_reserve_test.go",
|
||||
"status": "added",
|
||||
"additions": 29,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/provider_run_identity.go",
|
||||
"status": "added",
|
||||
"additions": 30,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/run_budget_stream.go",
|
||||
"status": "added",
|
||||
"additions": 65,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/run_budget_stream_test.go",
|
||||
"status": "added",
|
||||
"additions": 35,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/sub_loop.go",
|
||||
"status": "changed",
|
||||
"additions": 135,
|
||||
"deletions": 11,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/usage_n3_test.go",
|
||||
"status": "changed",
|
||||
"additions": 44,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/work_checkpoint.go",
|
||||
"status": "added",
|
||||
"additions": 97,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/runtime/work_checkpoint_test.go",
|
||||
"status": "added",
|
||||
"additions": 367,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/server/server.go",
|
||||
"status": "changed",
|
||||
"additions": 36,
|
||||
"deletions": 6,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/server/task_sources.go",
|
||||
"status": "added",
|
||||
"additions": 54,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/server/task_sources_test.go",
|
||||
"status": "added",
|
||||
"additions": 38,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/server/work_checkpoint_eval_budget_test.go",
|
||||
"status": "added",
|
||||
"additions": 309,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/server/work_checkpoint_eval_test.go",
|
||||
"status": "added",
|
||||
"additions": 473,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/store/content.go",
|
||||
"status": "changed",
|
||||
"additions": 39,
|
||||
"deletions": 13,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/store/messages.go",
|
||||
"status": "changed",
|
||||
"additions": 22,
|
||||
"deletions": 10,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/store/notices.go",
|
||||
"status": "changed",
|
||||
"additions": 23,
|
||||
"deletions": 3,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/store/task_deletion_test.go",
|
||||
"status": "added",
|
||||
"additions": 55,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/store/task_projection.go",
|
||||
"status": "added",
|
||||
"additions": 307,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/store/task_projection_test.go",
|
||||
"status": "added",
|
||||
"additions": 158,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/tools/exec_backend_test.go",
|
||||
"status": "changed",
|
||||
"additions": 13,
|
||||
"deletions": 5,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 488,
|
||||
"title": "Pin the audit overview export",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": ".task/feature-rdm-audit-export-entry.md",
|
||||
"status": "added",
|
||||
"additions": 170,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "modules/frontend",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "scripts/e2e.sh",
|
||||
"status": "changed",
|
||||
"additions": 25,
|
||||
"deletions": 4,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 489,
|
||||
"title": "Pin the approved U8, U7, and export status",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "3e7f0360087b126f41fa9ce18dbd1e53d0a8f067",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": ".task/feature-proposal-status-20261012.md",
|
||||
"status": "added",
|
||||
"additions": 132,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "modules/documents",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 512,
|
||||
"title": "[WIP] Deliver progressive U2/U3 work with evidence-backed judgments",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "e31443a8ff1f099f9b2ef320c295b0ddcdaf503d",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": ".task/feature-fast-slow-u2-u3-plan.md",
|
||||
"status": "added",
|
||||
"additions": 6760,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "PROJECT.md",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "modules/backend",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "modules/core",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "modules/documents",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "modules/frontend",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "modules/ui",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_svc.py",
|
||||
"status": "changed",
|
||||
"additions": 7,
|
||||
"deletions": 3,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_svc_recover.py",
|
||||
"status": "changed",
|
||||
"additions": 22,
|
||||
"deletions": 14,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 89,
|
||||
"title": "Record the approved U8, U7, and export status",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "b8df6f3c2a3180b06c61d2303bbfea9a3914f186",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "docs/proposals/2026-10-11-rdm-two-trees-trace-audit-integration.md",
|
||||
"status": "changed",
|
||||
"additions": 3,
|
||||
"deletions": 2,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/2026-10-12-service-restart-data-recovery.md",
|
||||
"status": "changed",
|
||||
"additions": 4,
|
||||
"deletions": 3,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md",
|
||||
"status": "changed",
|
||||
"additions": 3,
|
||||
"deletions": 2,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 95,
|
||||
"title": "[WIP] Record U3 evidence design, implementation, and validation",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "c7cb2d8d89aaef0329c9a8a2045fcd42abb36e39",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "docs/proposals/2026-10-12-fast-slow-channel-display.md",
|
||||
"status": "changed",
|
||||
"additions": 8,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/2026-10-13-fast-slow-u2-u3-plan.md",
|
||||
"status": "added",
|
||||
"additions": 462,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/2026-10-13-fast-slow-u3-quality-implementation-plan.md",
|
||||
"status": "added",
|
||||
"additions": 259,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/2026-10-13-fast-slow-u3-quality-revision.md",
|
||||
"status": "added",
|
||||
"additions": 45,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/2026-10-13-fast-slow-u3-r03-evidence-backed-judgments-design.md",
|
||||
"status": "added",
|
||||
"additions": 56,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/2026-10-13-fast-slow-u3-r03-evidence-implementation-plan.md",
|
||||
"status": "added",
|
||||
"additions": 144,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/proposals/INDEX.md",
|
||||
"status": "changed",
|
||||
"additions": 4,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/reports/2026-10-13-fast-slow-u2-u3-code-review.md",
|
||||
"status": "added",
|
||||
"additions": 135,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/reports/2026-10-13-fast-slow-u2-u3-extra-a01-review.md",
|
||||
"status": "added",
|
||||
"additions": 83,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "docs/reports/2026-10-13-fast-slow-u2-u3-validation.md",
|
||||
"status": "added",
|
||||
"additions": 130,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 73,
|
||||
"title": "Add audit overview export without widening the readiness gate",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "d9bb780384b16f661d71a5e6ad288a77426d9d98",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "e2e/rdm-audit.playwright.ts",
|
||||
"status": "changed",
|
||||
"additions": 20,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/components/RdmAuditWorkspace.tsx",
|
||||
"status": "changed",
|
||||
"additions": 114,
|
||||
"deletions": 2,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/store.ts",
|
||||
"status": "changed",
|
||||
"additions": 6,
|
||||
"deletions": 2,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/styles.css",
|
||||
"status": "changed",
|
||||
"additions": 8,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/workspaces.ts",
|
||||
"status": "changed",
|
||||
"additions": 18,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "test/workspaces.test.ts",
|
||||
"status": "changed",
|
||||
"additions": 26,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 79,
|
||||
"title": "[WIP] Preserve reading and show pending stage findings",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "e2e/work-checkpoints.playwright.ts",
|
||||
"status": "added",
|
||||
"additions": 63,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "knip-baseline.json",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/api.ts",
|
||||
"status": "changed",
|
||||
"additions": 2,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/components/ConversationWork.tsx",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/components/PreviewPane.tsx",
|
||||
"status": "changed",
|
||||
"additions": 7,
|
||||
"deletions": 4,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/components/Workbench.tsx",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/contracts.ts",
|
||||
"status": "changed",
|
||||
"additions": 27,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/previewtabs.ts",
|
||||
"status": "changed",
|
||||
"additions": 2,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "src/store.ts",
|
||||
"status": "changed",
|
||||
"additions": 74,
|
||||
"deletions": 10,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "test/work-state.test.ts",
|
||||
"status": "changed",
|
||||
"additions": 60,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 301,
|
||||
"title": "Bind audit exports to the captured watermark",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "6252f62524ef34360fdcdf8844d7e729378ffbfb",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": ".task/feature-rdm-u5-export-completion.md",
|
||||
"status": "added",
|
||||
"additions": 73,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/domain/persist.go",
|
||||
"status": "changed",
|
||||
"additions": 21,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/rdmapp/cgraph_export.go",
|
||||
"status": "changed",
|
||||
"additions": 15,
|
||||
"deletions": 42,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/rdmapp/export_artifact.go",
|
||||
"status": "changed",
|
||||
"additions": 33,
|
||||
"deletions": 17,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/rdmapp/export_report.go",
|
||||
"status": "added",
|
||||
"additions": 249,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/rdmapp/u5_export_test.go",
|
||||
"status": "changed",
|
||||
"additions": 203,
|
||||
"deletions": 5,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "internal/rdmapp/xlsx.go",
|
||||
"status": "changed",
|
||||
"additions": 80,
|
||||
"deletions": 52,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "plugins/rdm/plugin.go",
|
||||
"status": "changed",
|
||||
"additions": 6,
|
||||
"deletions": 4,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 307,
|
||||
"title": "Pin the audit overview export frontend",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"headStable": true,
|
||||
"files": [
|
||||
{
|
||||
"path": ".task/feature-rdm-pin-frontend-export.md",
|
||||
"status": "added",
|
||||
"additions": 32,
|
||||
"deletions": 0,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
{
|
||||
"path": "pins/agent-system-frontend",
|
||||
"status": "changed",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"patchSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
}
|
||||
+538
@@ -0,0 +1,538 @@
|
||||
{
|
||||
"source": "SELF authenticated read-only API snapshot",
|
||||
"checkedAt": "2026-10-13T19:41:27.766582+00:00",
|
||||
"readIdentity": {
|
||||
"login": "weichen"
|
||||
},
|
||||
"credentialSource": "~/.secrets/gitea; unique token bound to verified git-home URL_PREFIX; token omitted",
|
||||
"repos": [
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"main": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 193,
|
||||
"title": "[WIP] Verify source-backed stage judgments before publication",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193",
|
||||
"state": "open",
|
||||
"draft": true,
|
||||
"head": "5f834544b0b808cb16214a36725f2ae3cb90bfd4",
|
||||
"headRef": "feature/fast-slow-u2-u3",
|
||||
"base": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-13T18:20:36Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 185,
|
||||
"title": "Commit account changes and audits in one transaction",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/185",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "9754531cc98393cb8a936d0e25a7526dfabbe2c4",
|
||||
"headRef": "feature/u7-account-tx-audit",
|
||||
"base": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:49:44Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 183,
|
||||
"title": "Refuse a second SQLite service before migration",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/183",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "167609b3db6ef850c31eee71421c650f849a009c",
|
||||
"headRef": "feature/u8-sqlite-instance-guard",
|
||||
"base": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:46:24Z",
|
||||
"relevanceCandidate": false
|
||||
}
|
||||
],
|
||||
"pages": 1
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"main": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 512,
|
||||
"title": "[WIP] Deliver progressive U2/U3 work with evidence-backed judgments",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512",
|
||||
"state": "open",
|
||||
"draft": true,
|
||||
"head": "e31443a8ff1f099f9b2ef320c295b0ddcdaf503d",
|
||||
"headRef": "feature/fast-slow-u2-u3-plan",
|
||||
"base": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-13T18:20:38Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 489,
|
||||
"title": "Pin the approved U8, U7, and export status",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "3e7f0360087b126f41fa9ce18dbd1e53d0a8f067",
|
||||
"headRef": "feature/proposal-status-20261012",
|
||||
"base": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:54:15Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 488,
|
||||
"title": "Pin the audit overview export",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"headRef": "feature/rdm-audit-export-entry",
|
||||
"base": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T16:04:53Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 486,
|
||||
"title": "Pin account transactions and note deprecated credential flags",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/486",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "5156d66302b3dcabd0a2306b1857d12ea4ec6a08",
|
||||
"headRef": "feature/u7-account-tx-audit",
|
||||
"base": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:50:47Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 482,
|
||||
"title": "Pin the SQLite activity guard and document its refusals",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/482",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "d5e8d6ab7a368f08b29e968b6f65f8898f2b28f5",
|
||||
"headRef": "feature/u8-sqlite-instance-guard",
|
||||
"base": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:47:57Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 471,
|
||||
"title": "Close merged task cards (feature/card-close-20261012-123313Z)",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/471",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "f0e8a87b8e2dca989637d3b136faf2f0bc3ddd4b",
|
||||
"headRef": "feature/card-close-20261012-123313Z",
|
||||
"base": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T12:33:14Z",
|
||||
"relevanceCandidate": false
|
||||
}
|
||||
],
|
||||
"pages": 1
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"main": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 95,
|
||||
"title": "[WIP] Record U3 evidence design, implementation, and validation",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95",
|
||||
"state": "open",
|
||||
"draft": true,
|
||||
"head": "c7cb2d8d89aaef0329c9a8a2045fcd42abb36e39",
|
||||
"headRef": "feature/fast-slow-u2-u3-plan",
|
||||
"base": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-13T18:20:37Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 89,
|
||||
"title": "Record the approved U8, U7, and export status",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "b8df6f3c2a3180b06c61d2303bbfea9a3914f186",
|
||||
"headRef": "feature/u8-u7-rdm-export-status",
|
||||
"base": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:43:05Z",
|
||||
"relevanceCandidate": true
|
||||
}
|
||||
],
|
||||
"pages": 1
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"main": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 79,
|
||||
"title": "[WIP] Preserve reading and show pending stage findings",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79",
|
||||
"state": "open",
|
||||
"draft": true,
|
||||
"head": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"headRef": "feature/fast-slow-u2-u3",
|
||||
"base": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-13T18:20:36Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 73,
|
||||
"title": "Add audit overview export without widening the readiness gate",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "d9bb780384b16f661d71a5e6ad288a77426d9d98",
|
||||
"headRef": "feature/rdm-audit-export-entry",
|
||||
"base": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:38:15Z",
|
||||
"relevanceCandidate": true
|
||||
}
|
||||
],
|
||||
"pages": 1
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"main": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 307,
|
||||
"title": "Pin the audit overview export frontend",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"headRef": "feature/rdm-pin-frontend-export",
|
||||
"base": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:58:16Z",
|
||||
"relevanceCandidate": true
|
||||
},
|
||||
{
|
||||
"number": 301,
|
||||
"title": "Bind audit exports to the captured watermark",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301",
|
||||
"state": "open",
|
||||
"draft": false,
|
||||
"head": "6252f62524ef34360fdcdf8844d7e729378ffbfb",
|
||||
"headRef": "feature/rdm-u5-export-completion",
|
||||
"base": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-12T15:31:06Z",
|
||||
"relevanceCandidate": true
|
||||
}
|
||||
],
|
||||
"pages": 1
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-UI",
|
||||
"main": "2c4322ef56df64ad72f65907d25b048a74bb5ffc",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 51,
|
||||
"title": "[WIP] Separate source records, judgments, and pending questions",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-UI/pulls/51",
|
||||
"state": "open",
|
||||
"draft": true,
|
||||
"head": "ac5b617e9e7ee6b9417b36c66d7c6e3b58ecbb42",
|
||||
"headRef": "feature/fast-slow-u2-u3",
|
||||
"base": "2c4322ef56df64ad72f65907d25b048a74bb5ffc",
|
||||
"baseRef": "main",
|
||||
"updatedAt": "2026-10-13T18:20:36Z",
|
||||
"relevanceCandidate": false
|
||||
}
|
||||
],
|
||||
"pages": 1
|
||||
},
|
||||
{
|
||||
"repo": "Development-Guidelines",
|
||||
"main": "2f5b19872be2a4597838a4131ad75d1be089ee5e",
|
||||
"openPulls": [],
|
||||
"pages": 1
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/ctxasm/ctxasm.go",
|
||||
"blob": "010a3d55235ce1caf419a521421358a851b64729",
|
||||
"sha256": "f5e7350628d1289c8f024dff5d21db04f733366a98100d31258f3e49b77ff933",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/internal/ctxasm/ctxasm.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/internal/ctxasm/ctxasm.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/ingest/ingest.go",
|
||||
"blob": "e409c49b4d23bf49318d91b395f8b070b62ed071",
|
||||
"sha256": "7a9249a212b91488d3a273afc64f61e8b2ce50ea4187db05ad4eda3fd3ccf163",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/internal/ingest/ingest.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/internal/ingest/ingest.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/runmgr/memory.go",
|
||||
"blob": "c9bf4326df411cacd289ef767fd003642da6fc2f",
|
||||
"sha256": "03d235349d56e3feae29d36b63c284857ec77595aa2e647730f8e192db2fa7a1",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/internal/runmgr/memory.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/internal/runmgr/memory.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/runtime/llm.go",
|
||||
"blob": "d06dae1149ae402f1482fbec14069d2062a37bb7",
|
||||
"sha256": "5ae366d8c2c01e2b79fb6ff9d3f78147b82dce9dccee163d8cc880f5d3caa8d1",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/internal/runtime/llm.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/internal/runtime/llm.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/store/audit.go",
|
||||
"blob": "b5479a852abe47be35884c2bf55a0bbddc0982f9",
|
||||
"sha256": "54a7c6ab8315f3c0b3f0ec97ab857925a7a745453a2a41fb28051e54423ecf9a",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/internal/store/audit.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/internal/store/audit.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "pkg/extension/extension.go",
|
||||
"blob": "2454e4e0337eb6f3858f01b58b49f3d809c11e8d",
|
||||
"sha256": "57e00f6e5d21e28c4bfddf8b2fe3929e70826581d3feb94d557f1c9e2830ed42",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/pkg/extension/extension.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/pkg/extension/extension.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "pkg/extension/host.go",
|
||||
"blob": "c528b810020b95c4d1b39a9637cebb0abdb2608c",
|
||||
"sha256": "4ad991e1a63c2051c96ff50ae55bf346ebb16aa56e2fef5f408d8fd03bc61f2d",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/pkg/extension/host.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/pkg/extension/host.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "pkg/extension/projects.go",
|
||||
"blob": "d0f50421836b90bef13cc5ee05bbcd80b897322f",
|
||||
"sha256": "f00cca35978c61d267e692b6960318bd874d219114c184435ae6c313c7bbefaa",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Backend/pkg/extension/projects.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/src/commit/5d5fc9891c0eb8994545ccb8b740535d9b99fb0e/pkg/extension/projects.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"ref": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"path": "PROJECT.md",
|
||||
"blob": "10eba3415ae45bee28b0e1c0ae7b3fe371a8f18b",
|
||||
"sha256": "38ef642f201d005be043b9228b84af7b13a0edffdb33807a6d033067e8a73b6e",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Dev/PROJECT.md",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/src/commit/add097d06137c4912a4ed9279e98ca353e4e4cf1/PROJECT.md"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"ref": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
|
||||
"path": "policy/delivery.md",
|
||||
"blob": "252aa9c2e4d4878fefb21eaab56543878bb46eac",
|
||||
"sha256": "cbf854a915fd32d18a33c0a9b342ac6e5914ad10d0ec6563ccf4016d8b152614",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Dev/policy/delivery.md",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/src/commit/add097d06137c4912a4ed9279e98ca353e4e4cf1/policy/delivery.md"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"ref": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"path": "docs/proposals/2026-10-11-rdm-template-dialog-generation.md",
|
||||
"blob": "a843824d11a222785e26ac5e3c74855c1f7bcc92",
|
||||
"sha256": "70c816164b612cddf56ed897d3528cfedc8db3d024a49a8b28fe03e9136a5a20",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Documents/docs/proposals/2026-10-11-rdm-template-dialog-generation.md",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/src/commit/a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c/docs/proposals/2026-10-11-rdm-template-dialog-generation.md"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"ref": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"path": "docs/proposals/2026-10-13-system-project-membership.md",
|
||||
"blob": "db9aa3d7094f9f6df88e61516ed0d539d471cbee",
|
||||
"sha256": "0c622e12fde58e38b50929299e3c99ebb28956973b7b2803e03af6a606121987",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Documents/docs/proposals/2026-10-13-system-project-membership.md",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/src/commit/a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c/docs/proposals/2026-10-13-system-project-membership.md"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"ref": "a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c",
|
||||
"path": "docs/proposals/INDEX.md",
|
||||
"blob": "4043a589170b020bfed3c62c4f50ad2ada0fd821",
|
||||
"sha256": "cf9e330cec2e5c329e941c8c42488dd1e694de98fe28a0f713f25e8e036c4538",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Documents/docs/proposals/INDEX.md",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/src/commit/a7ff466d9ae91fc67a53d2bf4991f47fc63a2a4c/docs/proposals/INDEX.md"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"ref": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"path": "src/components/RdmAuditWorkspace.tsx",
|
||||
"blob": "7653201b70934b85a82dc02bcd900c4e6511fb31",
|
||||
"sha256": "ac406be59baab7eeb859dba49636aa5af579dbcf7aadbf1929a0aa346a56d1d6",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-Frontend/src/components/RdmAuditWorkspace.tsx",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/src/commit/eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b/src/components/RdmAuditWorkspace.tsx"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "README.md",
|
||||
"blob": "5caeb8dd714d6e6f5999a7bec324bea686f8a9cb",
|
||||
"sha256": "7dbe615f0aebe88bc2bcd0c35c4e102ba2917738bcf0c0e7ffc8bf5810676d07",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/README.md",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/README.md"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "go.mod",
|
||||
"blob": "fe5c6e3bf641f9631b595e14d2a6769207c31d13",
|
||||
"sha256": "9408a2113325d19339d4533f065c8371f7d9ef0141faa427f9c104a1bbd1612f",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/go.mod",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/go.mod"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/compliance.go",
|
||||
"blob": "badff2b02703a630ebe1ff62b247530144b3bea5",
|
||||
"sha256": "5791c647bfd1579b3c512006c9ce03200db13023dc350324fccecb2d29da0fb9",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/domain/compliance.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/domain/compliance.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/data/labels_seed.json",
|
||||
"blob": "4af596ea44a4d98bd8ee0540296a678fcc895aa0",
|
||||
"sha256": "2267284dacaa19693f531722de0233ea9bbf3b74f54bc58dd71648d60416d22e",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/domain/data/labels_seed.json",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/domain/data/labels_seed.json"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/doctree.go",
|
||||
"blob": "e2441f7bf3f0961f51fc4fd9d18058f83b0967ec",
|
||||
"sha256": "9d0d9d72b252de0011be863ab50fd976f54bcd239b27d42ab3f3cc7b94727285",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/domain/doctree.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/domain/doctree.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/eventlog.go",
|
||||
"blob": "aa0fac0b6d6a1d56bdc2e9f859a3bfb991533eaf",
|
||||
"sha256": "3450726fc9c0dc4a3fea6b5225fff081d5d56ccdf151ce8a1b1a8fbc57333e8c",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/domain/eventlog.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/domain/eventlog.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/labels.go",
|
||||
"blob": "ce2f15505463ecb7a0372aebfe77bc1d4851ab3e",
|
||||
"sha256": "2c796df8c0ace2d8044a83d4115c4f5956d71d9049c87b7fbe9a06e6fdae944c",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/domain/labels.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/domain/labels.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/notetree.go",
|
||||
"blob": "e4d8003799b174d6a61026cb6be2adeac7bc953e",
|
||||
"sha256": "bb6228fd00fbc0a5aaff4958cd70c7789ff1d7d2c34dcb1ee2dfc1630a43ef0e",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/domain/notetree.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/domain/notetree.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/compose.go",
|
||||
"blob": "b9fddaf7178968f05f1c8b3cd8b91aeaaa786475",
|
||||
"sha256": "b2da219785cbf44ee53d1408e56628f44619c8dd93fb4415f2daa9013b591349",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/compose.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/rdmapp/compose.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/inspection.go",
|
||||
"blob": "5d0eb1c377a344acb70dc82202d2ffd2f0599ac7",
|
||||
"sha256": "27368362233f8ff8b0c3e2d7c78a12162e5d12dc2545347b1270521182a2651e",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/inspection.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/rdmapp/inspection.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/knowledge_publication.go",
|
||||
"blob": "fa6689f289734fa00379b6dbc9171fae50fcfa3b",
|
||||
"sha256": "10e19a7729b8b27125bd8de6a94f0373df9db09c401b7b1294b65a796ba9f985",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/knowledge_publication.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/rdmapp/knowledge_publication.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/runtime.go",
|
||||
"blob": "ae9af0048d1f760189a8e0f4c5fa1a96f528e435",
|
||||
"sha256": "b6891677477e0bfe596c7cf2ce074497bd316037145d116745b66e79edb29fee",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/runtime.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/rdmapp/runtime.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/structure.go",
|
||||
"blob": "57a28e963c16eda7727e3bb5e94986b0e46b0f3f",
|
||||
"sha256": "116a25bf5e76f940f54ba67b87b855c5953b944a4ca4f088953766a35563fa86",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/structure.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/rdmapp/structure.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/templates/registry.yaml",
|
||||
"blob": "fada623997e4a23a695445332a69175a15df566b",
|
||||
"sha256": "094da101f08ce686c92475d2f03090596d0b203ce61ac24cb7438a0bf0485ab0",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/templates/registry.yaml",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/rdmapp/templates/registry.yaml"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/templates_gen.go",
|
||||
"blob": "5b4d71f968a40a3114c2331fc3d6c876b97c7ec0",
|
||||
"sha256": "8d4a68a31b69ab1834e66acc583211614d8177d23e1844bd4aa61c98ff57547c",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/internal/rdmapp/templates_gen.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/internal/rdmapp/templates_gen.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "plugins/rdm/plugin.go",
|
||||
"blob": "41f927e96d9c48bf61cdb792dae497a5956e20e6",
|
||||
"sha256": "25382894886fef7e9015d254fc416766d9cd7ce355671c088d2c34b0870a2eb8",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage2-sources/Agent-System-RDM/plugins/rdm/plugin.go",
|
||||
"sourceUrl": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/6fcb256205c2384abed35d3b6ab96ca7216e9297/plugins/rdm/plugin.go"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
{
|
||||
"source": "SELF",
|
||||
"checkedAt": "2026-10-14T10:39:40.639912+08:00",
|
||||
"repos": [
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"main": "f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 537,
|
||||
"title": "[WIP] Replace submodule coupling with versioned dependencies and source workspaces",
|
||||
"head": "12d875c615cdd8394b9b8bdb586bbca4c02b4241",
|
||||
"branch": "feature/dependency-workspace",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/537"
|
||||
},
|
||||
{
|
||||
"number": 512,
|
||||
"title": "[WIP] Deliver progressive U2/U3 work with evidence-backed judgments",
|
||||
"head": "a74318ab4b7d4f6fadd06675f3d1893361df722f",
|
||||
"branch": "feature/fast-slow-u2-u3-plan",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512"
|
||||
},
|
||||
{
|
||||
"number": 488,
|
||||
"title": "Pin the audit overview export",
|
||||
"head": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"branch": "feature/rdm-audit-export-entry",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488"
|
||||
},
|
||||
{
|
||||
"number": 486,
|
||||
"title": "Pin account transactions and note deprecated credential flags",
|
||||
"head": "5156d66302b3dcabd0a2306b1857d12ea4ec6a08",
|
||||
"branch": "feature/u7-account-tx-audit",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/486"
|
||||
},
|
||||
{
|
||||
"number": 482,
|
||||
"title": "Pin the SQLite activity guard and document its refusals",
|
||||
"head": "d5e8d6ab7a368f08b29e968b6f65f8898f2b28f5",
|
||||
"branch": "feature/u8-sqlite-instance-guard",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/482"
|
||||
},
|
||||
{
|
||||
"number": 471,
|
||||
"title": "Close merged task cards (feature/card-close-20261012-123313Z)",
|
||||
"head": "f0e8a87b8e2dca989637d3b136faf2f0bc3ddd4b",
|
||||
"branch": "feature/card-close-20261012-123313Z",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/471"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"main": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 363,
|
||||
"title": "[WIP] Build RDM from versioned dependencies and a fixed product composer",
|
||||
"head": "842a864d140dd4371989c2491b132973b48d728d",
|
||||
"branch": "feature/versioned-dependencies",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/363"
|
||||
},
|
||||
{
|
||||
"number": 307,
|
||||
"title": "Pin the audit overview export frontend",
|
||||
"head": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"branch": "feature/rdm-pin-frontend-export",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307"
|
||||
},
|
||||
{
|
||||
"number": 301,
|
||||
"title": "Bind audit exports to the captured watermark",
|
||||
"head": "6252f62524ef34360fdcdf8844d7e729378ffbfb",
|
||||
"branch": "feature/rdm-u5-export-completion",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"main": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 196,
|
||||
"title": "[WIP] Build the Backend from versioned Go libraries and fixed frontend composition",
|
||||
"head": "fffd5790cfab317fadafb40fa55a11bab6e9a847",
|
||||
"branch": "feature/versioned-dependencies",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/196"
|
||||
},
|
||||
{
|
||||
"number": 193,
|
||||
"title": "[WIP] Verify source-backed stage judgments before publication",
|
||||
"head": "5f834544b0b808cb16214a36725f2ae3cb90bfd4",
|
||||
"branch": "feature/fast-slow-u2-u3",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193"
|
||||
},
|
||||
{
|
||||
"number": 185,
|
||||
"title": "Commit account changes and audits in one transaction",
|
||||
"head": "9754531cc98393cb8a936d0e25a7526dfabbe2c4",
|
||||
"branch": "feature/u7-account-tx-audit",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/185"
|
||||
},
|
||||
{
|
||||
"number": 183,
|
||||
"title": "Refuse a second SQLite service before migration",
|
||||
"head": "167609b3db6ef850c31eee71421c650f849a009c",
|
||||
"branch": "feature/u8-sqlite-instance-guard",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/183"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"main": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 84,
|
||||
"title": "[WIP] Build Frontend from versioned UI and contract packages",
|
||||
"head": "5467517e1831e7ca8b58bb5df52494a3a2c9d468",
|
||||
"branch": "feature/versioned-dependencies",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/84"
|
||||
},
|
||||
{
|
||||
"number": 79,
|
||||
"title": "[WIP] Preserve reading and show pending stage findings",
|
||||
"head": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"branch": "feature/fast-slow-u2-u3",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79"
|
||||
},
|
||||
{
|
||||
"number": 73,
|
||||
"title": "Add audit overview export without widening the readiness gate",
|
||||
"head": "d9bb780384b16f661d71a5e6ad288a77426d9d98",
|
||||
"branch": "feature/rdm-audit-export-entry",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"main": "7bd4e17827d4c7c88647bf3c9199c495b60cb107",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 100,
|
||||
"title": "[WIP] Record approved version-dependency and active-branch transition requirements",
|
||||
"head": "1de7d17110efaa5ed2ed30a44d415f28987f89f3",
|
||||
"branch": "feature/dependency-workspace-plan",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/100"
|
||||
},
|
||||
{
|
||||
"number": 95,
|
||||
"title": "[WIP] Document U3 r0.4 recovery design and plan",
|
||||
"head": "276f885e7301bd39ae2d464c7469a37fe10ebf22",
|
||||
"branch": "feature/fast-slow-u2-u3-plan",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-UI",
|
||||
"main": "2c4322ef56df64ad72f65907d25b048a74bb5ffc",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 54,
|
||||
"title": "[WIP] Consume UI as a fixed package and verify packed consumers with cold caches",
|
||||
"head": "63d289e6bc15b701356cfe2d5b8740210fac0dcc",
|
||||
"branch": "feature/versioned-dependencies",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-UI/pulls/54"
|
||||
},
|
||||
{
|
||||
"number": 51,
|
||||
"title": "[WIP] Separate source records, judgments, and pending questions",
|
||||
"head": "ac5b617e9e7ee6b9417b36c66d7c6e3b58ecbb42",
|
||||
"branch": "feature/fast-slow-u2-u3",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-UI/pulls/51"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/doctree.go",
|
||||
"sha256": "9d0d9d72b252de0011be863ab50fd976f54bcd239b27d42ab3f3cc7b94727285",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/domain/doctree.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/labels.go",
|
||||
"sha256": "2c796df8c0ace2d8044a83d4115c4f5956d71d9049c87b7fbe9a06e6fdae944c",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/domain/labels.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/domain/eventlog.go",
|
||||
"sha256": "3450726fc9c0dc4a3fea6b5225fff081d5d56ccdf151ce8a1b1a8fbc57333e8c",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/domain/eventlog.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/runtime.go",
|
||||
"sha256": "b6891677477e0bfe596c7cf2ce074497bd316037145d116745b66e79edb29fee",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/rdmapp/runtime.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/tx.go",
|
||||
"sha256": "94892e4b85bf395c2f5059b26c9c694f202c4d1898af6c57bdd69b2d020b05f5",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/rdmapp/tx.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/inspection.go",
|
||||
"sha256": "27368362233f8ff8b0c3e2d7c78a12162e5d12dc2545347b1270521182a2651e",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/rdmapp/inspection.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/inspection_visibility.go",
|
||||
"sha256": "20e298145dbed6949caf8ee3510115b6916f9685c8ab21841f09dc987832e7e9",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/rdmapp/inspection_visibility.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/compose.go",
|
||||
"sha256": "b2da219785cbf44ee53d1408e56628f44619c8dd93fb4415f2daa9013b591349",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/rdmapp/compose.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/knowledge_publication.go",
|
||||
"sha256": "10e19a7729b8b27125bd8de6a94f0373df9db09c401b7b1294b65a796ba9f985",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/rdmapp/knowledge_publication.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"ref": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"path": "internal/rdmapp/templates.go",
|
||||
"sha256": "3defc58f0e20dc15d8cee9d846da0d998ca3caf659af2cca2603b6d8f1741419",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-RDM/internal/rdmapp/templates.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "pkg/extension/extension.go",
|
||||
"sha256": "57e00f6e5d21e28c4bfddf8b2fe3929e70826581d3feb94d557f1c9e2830ed42",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-Backend/pkg/extension/extension.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "pkg/extension/host.go",
|
||||
"sha256": "4ad991e1a63c2051c96ff50ae55bf346ebb16aa56e2fef5f408d8fd03bc61f2d",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-Backend/pkg/extension/host.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/runtime/llm.go",
|
||||
"sha256": "5ae366d8c2c01e2b79fb6ff9d3f78147b82dce9dccee163d8cc880f5d3caa8d1",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-Backend/internal/runtime/llm.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/ctxasm/ctxasm.go",
|
||||
"sha256": "f5e7350628d1289c8f024dff5d21db04f733366a98100d31258f3e49b77ff933",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-Backend/internal/ctxasm/ctxasm.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"ref": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"path": "internal/store/audit.go",
|
||||
"sha256": "54a7c6ab8315f3c0b3f0ec97ab857925a7a745453a2a41fb28051e54423ecf9a",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-Backend/internal/store/audit.go"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"ref": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
|
||||
"path": "src/components/RdmAuditWorkspace.tsx",
|
||||
"sha256": "ac406be59baab7eeb859dba49636aa5af579dbcf7aadbf1929a0aa346a56d1d6",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/Agent-System-Frontend/src/components/RdmAuditWorkspace.tsx"
|
||||
}
|
||||
],
|
||||
"priorPRs": [
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"number": 193,
|
||||
"head": "5f834544b0b808cb16214a36725f2ae3cb90bfd4",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 488,
|
||||
"head": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 489,
|
||||
"head": "5e6bf4aa0546d68fb3f872158f22b2791c301a60",
|
||||
"state": "closed",
|
||||
"merged": true,
|
||||
"mergeCommit": "f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 512,
|
||||
"head": "a74318ab4b7d4f6fadd06675f3d1893361df722f",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 89,
|
||||
"head": "10b442169ce0964a19e504dfc07395507b37db05",
|
||||
"state": "closed",
|
||||
"merged": true,
|
||||
"mergeCommit": "7bd4e17827d4c7c88647bf3c9199c495b60cb107",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 95,
|
||||
"head": "276f885e7301bd39ae2d464c7469a37fe10ebf22",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 73,
|
||||
"head": "d9bb780384b16f661d71a5e6ad288a77426d9d98",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 79,
|
||||
"head": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 301,
|
||||
"head": "6252f62524ef34360fdcdf8844d7e729378ffbfb",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 307,
|
||||
"head": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"mergeCommit": null,
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307"
|
||||
}
|
||||
],
|
||||
"wip": [
|
||||
{
|
||||
"worktree": "/home/weichen/projects/Agent-System-RDM-wt-feature-dhf-template-assets",
|
||||
"head": "a16aaca19bf8eeef076c06f4471c4f5387565c85",
|
||||
"path": "internal/domain/template_asset.go",
|
||||
"sha256": "c8f39cbca1236cfd813b751c5af123d771c06f1941124e37739aa1ba8804168b",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/wip/projects/Agent-System-RDM-wt-feature-dhf-template-assets/internal/domain/template_asset.go",
|
||||
"status": "unmerged local candidate; task narrative not proof of acceptance"
|
||||
},
|
||||
{
|
||||
"worktree": "/home/weichen/projects/Agent-System-RDM-wt-feature-dhf-template-assets",
|
||||
"head": "a16aaca19bf8eeef076c06f4471c4f5387565c85",
|
||||
"path": "internal/rdmapp/dhf_assets.go",
|
||||
"sha256": "b7e9c88039328281afcd800fdd27537c6ad7ac1e73c7afd9f685b2fac93673a6",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/wip/projects/Agent-System-RDM-wt-feature-dhf-template-assets/internal/rdmapp/dhf_assets.go",
|
||||
"status": "unmerged local candidate; task narrative not proof of acceptance"
|
||||
},
|
||||
{
|
||||
"worktree": "/home/weichen/projects/Agent-System-RDM-wt-feature-dhf-template-assets",
|
||||
"head": "a16aaca19bf8eeef076c06f4471c4f5387565c85",
|
||||
"path": ".task/feature-dhf-template-assets.md",
|
||||
"sha256": "6984cf670c25dd53f88467d1966c0617e17995e15472d42ff82eb61bc44e2f2f",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/wip/projects/Agent-System-RDM-wt-feature-dhf-template-assets/.task/feature-dhf-template-assets.md",
|
||||
"status": "unmerged local candidate; task narrative not proof of acceptance"
|
||||
},
|
||||
{
|
||||
"worktree": "/home/weichen/projects/Agent-System-Dev-wt-feature-dhf-template-pipeline-plan/modules/documents",
|
||||
"head": "8e9587ca1d63dca3867e8de131d5761a8abe9a2f",
|
||||
"path": "docs/proposals/2026-10-14-dhf-template-generation-plan.md",
|
||||
"sha256": "f99e1424a9bb86f68ad6de91657102a36004c61fb0f36c8427e913d9e0cf9643",
|
||||
"localCopy": "/home/weichen/.codex/visualizations/2026/10/13/01a13639-7c7c-7f20-aece-a3937edf6229/stage4-sources/wip/modules/documents/docs/proposals/2026-10-14-dhf-template-generation-plan.md",
|
||||
"status": "unmerged local candidate; task narrative not proof of acceptance"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
{
|
||||
"source": "SELF read-only Gitea and worktree checks",
|
||||
"checkedAt": "2026-10-14T11:15:04.729322+08:00",
|
||||
"repos": [
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"main": "f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 537,
|
||||
"title": "[WIP] Replace submodule coupling with versioned dependencies and source workspaces",
|
||||
"head": "12d875c615cdd8394b9b8bdb586bbca4c02b4241",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/537"
|
||||
},
|
||||
{
|
||||
"number": 512,
|
||||
"title": "[WIP] Deliver progressive U2/U3 work with evidence-backed judgments",
|
||||
"head": "a74318ab4b7d4f6fadd06675f3d1893361df722f",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512"
|
||||
},
|
||||
{
|
||||
"number": 488,
|
||||
"title": "Pin the audit overview export",
|
||||
"head": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488"
|
||||
},
|
||||
{
|
||||
"number": 486,
|
||||
"title": "Pin account transactions and note deprecated credential flags",
|
||||
"head": "5156d66302b3dcabd0a2306b1857d12ea4ec6a08",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/486"
|
||||
},
|
||||
{
|
||||
"number": 482,
|
||||
"title": "Pin the SQLite activity guard and document its refusals",
|
||||
"head": "d5e8d6ab7a368f08b29e968b6f65f8898f2b28f5",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/482"
|
||||
},
|
||||
{
|
||||
"number": 471,
|
||||
"title": "Close merged task cards (feature/card-close-20261012-123313Z)",
|
||||
"head": "f0e8a87b8e2dca989637d3b136faf2f0bc3ddd4b",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/471"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"main": "7bd4e17827d4c7c88647bf3c9199c495b60cb107",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 100,
|
||||
"title": "[WIP] Record approved version-dependency and active-branch transition requirements",
|
||||
"head": "1de7d17110efaa5ed2ed30a44d415f28987f89f3",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/100"
|
||||
},
|
||||
{
|
||||
"number": 95,
|
||||
"title": "[WIP] Document U3 r0.4 recovery design and plan",
|
||||
"head": "276f885e7301bd39ae2d464c7469a37fe10ebf22",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"main": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 363,
|
||||
"title": "[WIP] Build RDM from versioned dependencies and a fixed product composer",
|
||||
"head": "2b37fb26bbb023bd0118ba52e590daaa9dc8b478",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/363"
|
||||
},
|
||||
{
|
||||
"number": 307,
|
||||
"title": "Pin the audit overview export frontend",
|
||||
"head": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307"
|
||||
},
|
||||
{
|
||||
"number": 301,
|
||||
"title": "Bind audit exports to the captured watermark",
|
||||
"head": "bd973e1e8de639d6fafee92fbfe349bc22a57c9a",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"main": "5d5fc9891c0eb8994545ccb8b740535d9b99fb0e",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 196,
|
||||
"title": "[WIP] Build the Backend from versioned Go libraries and fixed frontend composition",
|
||||
"head": "fffd5790cfab317fadafb40fa55a11bab6e9a847",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/196"
|
||||
},
|
||||
{
|
||||
"number": 193,
|
||||
"title": "[WIP] Verify source-backed stage judgments before publication",
|
||||
"head": "efed68ca2c8fbf148a2c40d61906612a9cc006f1",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193"
|
||||
},
|
||||
{
|
||||
"number": 185,
|
||||
"title": "Commit account changes and audits in one transaction",
|
||||
"head": "9754531cc98393cb8a936d0e25a7526dfabbe2c4",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/185"
|
||||
},
|
||||
{
|
||||
"number": 183,
|
||||
"title": "Refuse a second SQLite service before migration",
|
||||
"head": "167609b3db6ef850c31eee71421c650f849a009c",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/183"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"main": "5313cfad4e633d0909ed40dcdfa28a11bc1902c0",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 84,
|
||||
"title": "[WIP] Build Frontend from versioned UI and contract packages",
|
||||
"head": "5467517e1831e7ca8b58bb5df52494a3a2c9d468",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/84"
|
||||
},
|
||||
{
|
||||
"number": 79,
|
||||
"title": "[WIP] Preserve reading and show pending stage findings",
|
||||
"head": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-UI",
|
||||
"main": "2c4322ef56df64ad72f65907d25b048a74bb5ffc",
|
||||
"openPulls": [
|
||||
{
|
||||
"number": 54,
|
||||
"title": "[WIP] Consume UI as a fixed package and verify packed consumers with cold caches",
|
||||
"head": "63d289e6bc15b701356cfe2d5b8740210fac0dcc",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-UI/pulls/54"
|
||||
},
|
||||
{
|
||||
"number": 51,
|
||||
"title": "[WIP] Separate source records, judgments, and pending questions",
|
||||
"head": "ac5b617e9e7ee6b9417b36c66d7c6e3b58ecbb42",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-UI/pulls/51"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"trackedPRs": [
|
||||
{
|
||||
"repo": "Agent-System-Backend",
|
||||
"number": 193,
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "efed68ca2c8fbf148a2c40d61906612a9cc006f1",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/193"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 488,
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "334d2e2375095f3b4160ab232296f9c92065c565",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 489,
|
||||
"state": "closed",
|
||||
"merged": true,
|
||||
"head": "5e6bf4aa0546d68fb3f872158f22b2791c301a60",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Dev",
|
||||
"number": 512,
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "a74318ab4b7d4f6fadd06675f3d1893361df722f",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/512"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 89,
|
||||
"state": "closed",
|
||||
"merged": true,
|
||||
"head": "10b442169ce0964a19e504dfc07395507b37db05",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Documents",
|
||||
"number": 95,
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "276f885e7301bd39ae2d464c7469a37fe10ebf22",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/95"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 73,
|
||||
"state": "closed",
|
||||
"merged": true,
|
||||
"head": "4e1eb39035e785810bfca02751cf29572c388768",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-Frontend",
|
||||
"number": 79,
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "006c81567546deb1cbd95abbb7ca6a36f99241b2",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/79"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 301,
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "bd973e1e8de639d6fafee92fbfe349bc22a57c9a",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301"
|
||||
},
|
||||
{
|
||||
"repo": "Agent-System-RDM",
|
||||
"number": 307,
|
||||
"state": "open",
|
||||
"merged": false,
|
||||
"head": "8ae52a6d9a4d8b60e875f9c56862f34dffed7705",
|
||||
"url": "https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/307"
|
||||
}
|
||||
],
|
||||
"dhfWorktree": {
|
||||
"path": "/home/weichen/projects/Agent-System-RDM-wt-feature-dhf-template-assets",
|
||||
"head": "773676162c9e9492788f19ea344a6a961dcbf251",
|
||||
"status": [
|
||||
" M .task/feature-dhf-template-assets.md",
|
||||
" M internal/rdmapp/dhf_catalog_test.go",
|
||||
" M internal/rdmapp/templates/dhf/catalog.json",
|
||||
"?? docs/records/dhf/e1-r1-result.json",
|
||||
"?? docs/records/dhf/pilot-project-proposal-review.md"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "docs/records/dhf/u1-progress.md",
|
||||
"sha256": "9b44c4e2b608705014825ba4b7c123a9beca8dca657994bd4db68e93526217f7",
|
||||
"bytes": 3782
|
||||
},
|
||||
{
|
||||
"path": "docs/records/dhf/e1-r1-result.json",
|
||||
"sha256": "596bd7ed376824239fd441ae8879f465133a58bae76bdabd117e96ee8b324201",
|
||||
"bytes": 3695
|
||||
},
|
||||
{
|
||||
"path": "docs/records/dhf/pilot-project-proposal-review.md",
|
||||
"sha256": "fdefeb1b8e43b269873d9241a3ce21737e919be983eae0bdcaec33e6f8f3eea7",
|
||||
"bytes": 33241
|
||||
},
|
||||
{
|
||||
"path": "internal/domain/template_asset.go",
|
||||
"sha256": "c8f39cbca1236cfd813b751c5af123d771c06f1941124e37739aa1ba8804168b",
|
||||
"bytes": 8054
|
||||
},
|
||||
{
|
||||
"path": "internal/rdmapp/dhf_assets.go",
|
||||
"sha256": "b7e9c88039328281afcd800fdd27537c6ad7ac1e73c7afd9f685b2fac93673a6",
|
||||
"bytes": 30551
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
# 统一文档渲染器第一批实施评审 r1
|
||||
|
||||
日期:2026-10-15。状态:**待人工评审**。批准来源:用户在本聊天确认“批准,按方案开始实施吧”。批准对象为[统一文档渲染器方案文档集](../2026-10-15-unified-document-renderer/README.md),本批严格限制为实施计划 Task 1–3。
|
||||
|
||||
## 1. 本批范围
|
||||
|
||||
| 任务 | 结果 | 固定对象 |
|
||||
|---|---|---|
|
||||
| Task 1 公司 Word 样式普查 | 44 份已发布 DHF 模板生成确定性 JSON/Markdown 普查;有界读取 ZIP/XML,不访问外部关系 | RDM `c188df36fbb77671048d6a40607bd14bf21c23a4` |
|
||||
| Task 2 统一文档与审阅模型 | 稳定节点、来源范围/置信度/可见性、审阅主体、严格校验、深拷贝、规范 JSON 与 SHA256 | Renderer `0d1f4d0bbe06d32b7a742dff0c0c53efeaa054cd` |
|
||||
| Task 3 RenderProfile | 严格 YAML/JSON、受控资产、继承展开、不可变快照、生命周期、四级选择与适用性校验 | Renderer `a08ae7ac81d4c648b350d890da97c91e64950769` |
|
||||
|
||||
Renderer 是独立本地 Git 仓 `/home/weichen/projects/Agent-Document-Renderer`,分支 `codex/unified-document-renderer`。本批没有创建远端仓库、加入 Dev gitlink 或接入 RDM/Backend 运行路径。
|
||||
|
||||
## 2. Task 1 普查结果
|
||||
|
||||
机器记录:`Agent-System-RDM/docs/records/renderer/corporate-style-inventory.json`,SHA256 `027b0a67a6592e8668229b9cc0d51ed8b5d874c2ff3a4b53b934e3241b245580`。人类摘要:`corporate-style-inventory.md`。
|
||||
|
||||
| 指标 | 结果 |
|
||||
|---|---:|
|
||||
| 已发布模板 | 44/44 |
|
||||
| 原生 DOCX / 旧 DOC 转换 | 30 / 14 |
|
||||
| 规范化件含页眉或页脚 | 44 |
|
||||
| 含图片 | 8 |
|
||||
| 含合并表格 | 41 |
|
||||
| `family-rule` / `template-exception` / `unverified` | 151 / 112 / 1 |
|
||||
|
||||
`dhf.33c2e9fe0c42fa0d` 的规范化件存在 21 条外部关系。普查只保存关系所在部件、类型和目标 SHA256,不保存或访问目标。该项标记 `unverified`;后续 RenderProfile 发布与 Word 输出仍禁止外部关系。
|
||||
|
||||
字体、Logo 规则、色板和标题体系仍是 `unverifiedCorporateValues`。本批没有把出现频率自动升格为公司设计标准。
|
||||
|
||||
## 3. Task 2 模型合同
|
||||
|
||||
- `CanonicalDocument` 固定项目、文档类型、语言、标题和递归节点。
|
||||
- `Node` 支持章节、标题、段落、列表、表格、图片、提示、附件和签署节点。
|
||||
- `SourceRef` 保存来源类型、定位、摘录、置信度、私域/项目/公开范围和有效文本区间。
|
||||
- 校验拒绝重复节点 ID、祖先循环、越界来源区间、未知节点/来源/可见范围和未知 schema。
|
||||
- `ReviewSnapshot` 分离批注、修订、审阅决定和批准决定;缺少可信人物快照时拒绝。
|
||||
- `Clone` 深拷贝节点、来源和审阅集合;规范 JSON 与 SHA256 在相同输入下确定。
|
||||
- `render.Request/Result/Manifest/Diagnostic/Renderer` 提供后续格式适配器的最小公共合同;`Request.Profile` 只能接收确切的不可变 `profile.Snapshot`,不能由调用方伪造只有 ID/哈希的替代对象。
|
||||
|
||||
## 4. Task 3 规则合同
|
||||
|
||||
- 规则只能使用已知 YAML/JSON 字段;`script`、任意 XML 等未知字段拒绝。
|
||||
- 资产由 manifest 中的 `assetId@version + path + SHA256` 绑定;远程 URL、父路径、未登记资产和字节漂移拒绝。
|
||||
- 受控规则配置 `allowDefaultFallback=true` 时拒绝编译。
|
||||
- 未知渲染原语、重复锚点、空选择器、不安全目标和超限递归拒绝。
|
||||
- 继承在编译时展开;快照不保留运行时父指针,返回规则、规范 JSON 和能力集合均为副本。
|
||||
- 生命周期仅允许 `draft → validated → published → retired`;发布或退役版本不能被同 ID/版本新内容替换,历史发布哈希仍可取。
|
||||
- 选择顺序固定为文档显式、文档类型、项目默认、公司默认。高优先级绑定不存在、未发布或不适用于当前文档类型、项目、阶段时直接失败,不继续回退。
|
||||
- 页眉页脚的 `fixed/field/slot/asset` 逐项校验;资产只能引用已经验证的资产角色。
|
||||
|
||||
## 5. 独立 Review 与修复
|
||||
|
||||
独立审阅者检查 RDM `6a5b6a0` 和 Renderer `c54822e`,首次结论为 **No**,没有 Critical,发现三项 Important:
|
||||
|
||||
1. 规则选择未校验文档类型、项目和阶段。
|
||||
2. 页眉页脚资产引用绕过 manifest 校验。
|
||||
3. UTF-16 XML 的 DTD/实体可绕过 ASCII 字节检测并被解析展开。
|
||||
|
||||
三项均先加入复现测试并观察 RED,再实施修复:Renderer `7c089a9`、RDM `c188df3`。修复后的完整套件重新通过。按 inline 执行流程没有再派第二位审阅者;最终结论由复现测试、修复和完整套件固定。
|
||||
|
||||
提交后合同核对又发现 Task 2 的临时 `ProfileSnapshot` 接口在 Task 3 已有具体快照后不应继续保留;该接口可能接受调用方伪造对象,也不能向后续 WordAdapter 提供完整规则。`TestRequestRequiresConcreteProfileSnapshot` 先复现 RED,Renderer `a08ae7a` 将请求收紧为具体 `profile.Snapshot`,完整测试、race 和 vet 再次通过。
|
||||
|
||||
审阅另有一项 Minor:普查器模块注释仍写“拒绝外部关系”,实际策略是“记录哈希元数据且不访问”。该项不影响执行行为,本批按流程登记为 deferred,后续文档整理时修正。
|
||||
|
||||
## 6. SELF 验证
|
||||
|
||||
RDM 最终对象 `c188df36fbb77671048d6a40607bd14bf21c23a4`:
|
||||
|
||||
- `python3 -m unittest tests.test_render_profile_inventory -v`:6 项通过。
|
||||
- `python3 scripts/render-profile-inventory.py --check`:44 份已提交输出逐字节一致。
|
||||
- `git diff --check`:通过。
|
||||
- `make test`:退出码 0;产品组合构建、29 项 Node 测试、4 项任务钩子测试及 Go 全仓测试通过。
|
||||
|
||||
Renderer 最终对象 `a08ae7ac81d4c648b350d890da97c91e64950769`:
|
||||
|
||||
- `go test ./... -count=1`:通过。
|
||||
- `go test -race ./... -count=1`:通过。
|
||||
- `go vet ./...`:通过。
|
||||
- `git diff --check`:通过。
|
||||
|
||||
以上均为本地 **SELF**,不是 CI/GATE、合入或部署证据。
|
||||
|
||||
## 7. 未实施边界
|
||||
|
||||
- Task 4 Markdown 解析器及稳定节点标记。
|
||||
- Task 5 WordAdapter、OPC 写入和输出安全验证。
|
||||
- Task 6 Word 修订、批注、回复、批准稿与留痕稿。
|
||||
- 公司默认规则、44 份 RenderProfile、字典迁移、RDM/Backend/Frontend 接入。
|
||||
- 真实 PostgreSQL 迁移、真实 Word 视觉验收、浏览器验收、远端仓库、PR、CI、合入、部署和发布。
|
||||
|
||||
## 8. 下一批建议
|
||||
|
||||
按已批准的追踪清单,本批需要人工评审后再进入 Task 4–6。下一批应先实现 Markdown→CanonicalDocument,再实现 WordAdapter,最后实现修订/批注和批准/留痕双 Word;每项继续 RED→GREEN,并保持本批规则快照与资产边界不变。
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
# 统一文档渲染器第二批实施评审 r1
|
||||
|
||||
日期:2026-10-15。状态:**待人工评审**。批准来源:用户在本聊天确认“评审通过,可以进入 Task 4-6”。本批固定对象为本地 Renderer `0efa07f8ce5cb4e1ff93886cf6769d111cba9872`。
|
||||
|
||||
## 1. 实施结果
|
||||
|
||||
| 任务 | 结果 | 主要提交 |
|
||||
|---|---|---|
|
||||
| Task 4 Markdown 解析 | 受控 front matter、稳定节点、首导入 ID 物化、列表/表格后代 ID、结构节点与边界拒绝 | `f31e048`,评审修复纳入 `0efa07f` |
|
||||
| Task 5 WordAdapter | 确定性 OPC、模板锚点、样式、编号、重复行、合并单元格、页眉页脚、图片、节点书签、安全校验 | `883922f`,评审修复纳入 `0efa07f` |
|
||||
| Task 6 审阅与批准 | `w:ins/w:del`、批注、回复、Unicode 范围、孤立附录、可信签署、批准稿/留痕稿双输出 | `485a6c7`,评审修复纳入 `0efa07f` |
|
||||
|
||||
## 2. Markdown 合同
|
||||
|
||||
- 解析标题、段落、列表、表格、图片、提示、签署、重复行、受控字段和分页节点。
|
||||
- 受控文档拒绝未知 front matter、隐藏 HTML、危险指令、坏表格、重复 ID、无 ID 的后续保存和超限输入。
|
||||
- 首次导入为顶层节点补写独立标记,为列表项和表格单元格补写内联标记。
|
||||
- 列表项、表格行和单元格的 ID 在插入、重排及已物化内容编辑后保持稳定;重复 ID 仍 fail-closed。
|
||||
- 图片来源允许受控资产角色及确切版本,Word 阶段重新核对版本与冻结规则一致。
|
||||
|
||||
## 3. Word 输出合同
|
||||
|
||||
- 克隆已验证模板包,限制压缩包大小、条目数、单条目和总展开量;拒绝重复路径、穿越和加密条目。
|
||||
- 包条目按名称排序并固定时间戳,相同冻结输入产生相同 DOCX 字节和哈希。
|
||||
- 同一语义锚点可以按文档顺序承载多个段落;不兼容原语仍拒绝合并。
|
||||
- 列表项、表格、行和单元格均生成可追溯书签及 NodeAnchor 映射。
|
||||
- 有序/无序列表使用不与模板冲突的实际 numbering ID;重复表格行在原模板表格上下文中展开,并受列合同和最大重复数约束。
|
||||
- 图片自动补齐 `r/a/wp/pic` 命名空间,使用唯一 drawing ID,并验证 PNG/JPEG 与关系目标。
|
||||
- 页眉页脚固定文本、字段、槽位和图片资产走受控规则;Word 字段只允许 `PAGE/NUMPAGES/DATE/TIME` 及安全 `MERGEFORMAT`。
|
||||
- 校验所有 XML、关系目标、关系类型和内容类型;拒绝外链、VBA、ActiveX、OLE、远程模板、任意对象和危险字段,不依赖约定文件名。
|
||||
|
||||
## 4. 审阅与批准合同
|
||||
|
||||
- 审阅稿保存插入、删除、替换、批注、重叠批注、回复、人物和 UTC 时间。
|
||||
- 批注范围按 Unicode code point 处理;哈希/范围失配或节点删除时进入显式孤立批注附录,不错误重绑。
|
||||
- 批注可继续精确锚定在被修订的当前文本、列表项和表格单元格。
|
||||
- 删除修订和孤立批注使用明确的 review-only 附录边界;“接受全部修订”的主正文投影与批准稿一致。
|
||||
- 批准稿拒绝带模板遗留修订/批注的底稿,移除普通评论和跟踪设置,只输出当前已批准内容。
|
||||
- 工作稿和预览稿不显示文档正文自行提供的签署文字;缺少可信人物快照时签署区为空。
|
||||
- ReviewSnapshot 绑定确切 `documentHash` 和 `profileHash`;不匹配时审阅和批准输出均被阻止。
|
||||
- `RenderPair` 对同一冻结输入分别生成 review 和 approved DOCX,文件名和 manifest 模式明确区分。
|
||||
|
||||
## 5. 独立 Review 与修复
|
||||
|
||||
独立审阅者检查 `a08ae7a..485a6c7`,结论为 **Ready to merge: No**,没有 Critical,发现 12 项 Important:危险字段、按文件名识别可执行对象、批准稿遗留审阅标记、伪签署回退、同锚点多段冲突、后代 ID 漂移、后代无 Word 锚点、图片命名空间/ID、编号忽略、重复行上下文错误、审阅/批准正文不一致、修订文本批注错误孤立或拒绝。
|
||||
|
||||
全部 Important 在一个修复批次 `0efa07f` 中加入复现用例并完成 RED→GREEN。额外补齐 ReviewSnapshot 的文档/规则哈希绑定,以及 Markdown 版本化资产来源与 Word 资产角色合同。
|
||||
|
||||
## 6. SELF 验证
|
||||
|
||||
最终对象 `0efa07f8ce5cb4e1ff93886cf6769d111cba9872`:
|
||||
|
||||
- `go test ./... -count=1`:Markdown、model、profile、render、word 五个包通过。
|
||||
- `go test -race ./... -count=1`:五个包通过。
|
||||
- `go vet ./...`:通过。
|
||||
- `git diff --check`:通过。
|
||||
- 测试使用有效 1×1 PNG;覆盖危险关系类型、宏内容类型、危险模板字段、模板遗留审阅标记、重复/穿越 ZIP 条目、稳定后代 ID、同锚点多段、后代锚点、Unicode/重叠/修订文本批注、删除/孤立附录及批准正文一致性。
|
||||
|
||||
以上均为本地 **SELF**,不是 CI/GATE、桌面 Word 视觉验收、合入或部署证据。
|
||||
|
||||
## 7. 延后事项和边界
|
||||
|
||||
Minor:已存在的同名 Word 样式尚未与配置值逐项对账;长流程取消尚未在解压、渲染、校验各阶段轮询;已存在的关系 ID 尚未验证其原类型/目标是否与新增关系相同。第一批遗留的普查器外部关系注释表述也尚未整理。
|
||||
|
||||
NOT_RUN:桌面 Word/LibreOffice 打开与修复行为、视觉保真、分页和实际字段行为;项目授权、撤权、事务交付与下载;远端 Renderer 仓库、Dev gitlink、CI/GATE、数据库迁移、浏览器验收、部署和发布。
|
||||
|
||||
## 8. 下一批建议
|
||||
|
||||
下一批按计划进入 Task 7–8:先由已评审的公司视觉普查发布公司默认规则,再为 44 份 DHF 模板生成确切 RenderProfile 并处理两份字典阻塞。只实施代码、规则包和隔离测试;真实数据库迁移、远端发布和部署继续保持未放行。
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
# 统一文档渲染器第三批实施评审 r1
|
||||
|
||||
日期:2026-10-15。状态:**待人工评审**。批准来源:用户在本聊天确认“评审通过,启动 Task 7-8”。本批固定对象为本地 Renderer `732e7e7fc44e4871c7e1f6ba7aff2fc25173a10f`、RDM `ec24a42b79604f3ccbf581abb7c43378a1173c21`。
|
||||
|
||||
## 1. 结论和需要人工决定的事项
|
||||
|
||||
Task 7 已形成可运行的公司默认规则候选,但没有发布。现有 44 份公司文档只能确认常见 A4 页面族、保密页脚和页码字段,不能可靠推断公司 Logo、字体、字号、颜色、标题层级和实际分页。候选因此保持 `draft`,`publicationAllowed=false`,待真人视觉对照后再升版或发布。
|
||||
|
||||
Task 8 已生成 44 份独立、可重复生成、可由真实编译器编译的专用 RenderProfile 候选;两项过程确认文档类型已补入版本化字典。44 份仍全部是草稿,不自动继承旧模板目录的发布决定。底稿安全预检为 **41 通过、3 阻断**:
|
||||
|
||||
| 模板 | 阻断事实 | 发布前需要的处置 |
|
||||
|---|---|---|
|
||||
| `dhf.33c2e9fe0c42fa0d` | `word/_rels/document.xml.rels` 含外部购物链接;正文含遗留修订 | 形成去外链且明确接受/拒绝旧修订的安全派生件,逐字及视觉复核 |
|
||||
| `dhf.6b440531e6ff12f8` | 正文、页眉和设置含遗留修订/跟踪标记 | 明确旧修订取舍,形成干净派生件并视觉复核 |
|
||||
| `dhf.a046cc77128b7b66` | 设置中启用了遗留跟踪修订 | 形成关闭遗留跟踪状态的干净派生件并复核 |
|
||||
|
||||
这三份未通过安全门禁,不能通过放宽外链或继承修订限制来凑数。其机器可读状态已进入对应 `review.json` 的 `basePackagePreflight`。
|
||||
|
||||
## 2. Task 7:公司默认规则候选
|
||||
|
||||
Renderer 提交 `92f238e` 建立 `profiles/company-default/1.0.0/`:
|
||||
|
||||
- `profile.yaml`:DOCX、公司默认、普通文档可回退、受控文档不使用该回退;
|
||||
- `assets.json`:冻结最小 Word 底稿与测试图片的版本、路径和 SHA256;
|
||||
- `review.json`:列出未核实的公司视觉值并禁止发布;
|
||||
- `assets/base.docx` 与 `assets/sample.png`:仅供规则验证,不冒充公司批准 Logo;
|
||||
- 自动映射支持标题、段落、列表、表格、图片、提示、签署、受控字段和分页节点;测试样稿插入 30 个显式分页符。
|
||||
|
||||
候选使用 A4 纵向、公司全称保密页脚、`PAGE/NUMPAGES` 字段;字体、东亚字体、字号、颜色及 Logo 保持空白或未配置。实际桌面 Word 页数、分页稳定性和视觉可读性尚未验收,30 个分页符不能等同于已经证明 30 页排版。
|
||||
|
||||
## 3. Task 8:44 份专用规则包
|
||||
|
||||
RDM 提交 `d4d2c8b` 先生成 44 份 `profile.json + review.json`;`3f60265` 加入生成一致性、字典迁移和产品链验证;最终 `ec24a42` 增加精确底稿安全预检。
|
||||
|
||||
每份候选:
|
||||
|
||||
- 绑定目录中确切 `templateId`、版本和 render SHA256;
|
||||
- `appliesTo.documentTypes` 与模板目录一致;
|
||||
- 从递归结构文件复制确切节点 ID、Word part、锚点和目标种类,共 6,115 条映射;
|
||||
- `selection.controlled=true`、`allowDefaultFallback=false`,受控文档 fail-closed;
|
||||
- `styles={}`,不猜测字体、颜色或标题排版;
|
||||
- 带六类模板例外、未核实公司值、来源/规范化/结构/render 四组摘要及待审状态;
|
||||
- 由 `scripts/generate-render-profiles.py --check` 逐字复验,目录或普查对象缺失、重复及生成漂移均失败。
|
||||
|
||||
最终 Renderer 的跨仓 SELF 探针按每份 catalog 精确底稿执行 `DecodeJSON → Compiler.Compile`,结果 **44/44 可编译**。单节点预览探针为 **41 通过、3 因上述底稿安全问题被正确拒绝**;这不是完整内容填充或桌面 Word 视觉验收。
|
||||
|
||||
## 4. 字典升级
|
||||
|
||||
种子字典从 `0.1.0` 升为 `0.2.0`,新增:
|
||||
|
||||
- `rd_process_validation_plan`:过程确认方案,阶段 10,DHF;
|
||||
- `rd_process_validation_report`:过程确认报告,阶段 10,DHF。
|
||||
|
||||
存量升级只接受固定字节摘要:
|
||||
|
||||
- `0.1.0`:`10b0d316210dc0729e3b52e302b7621d4056d5381ac54101d8f00c7a2ad02944`;
|
||||
- `0.2.0`:`3e71c6b020cdf1fe0f944bec71dd3a7c62ff33f79cef3d81b14a0f347517e421`。
|
||||
|
||||
升级保留旧行,在一个事务中插入新行;同字节重放幂等,旧版本或目标版本字节漂移时拒绝。SQLite SELF 与隔离 PostgreSQL SELF 均已通过;真实运行库迁移仍为 **NOT_RUN**。
|
||||
|
||||
## 5. 44/44 RDM 产品链的准确含义
|
||||
|
||||
更新后的 `scripts/dhf-u6-acceptance-matrix.py` 使用当前账户激活、API key 文件、项目会话和锚点消息,驱动组合产品执行实例化、三权分配、提交、审核、批准、交付和下载。结果为 **44 PASS、0 BLOCKED、0 FAIL**,两项字典阻塞已清零。
|
||||
|
||||
该矩阵验证的是现有 RDM `docs.delivery.*` 链路,当前尚未调用独立 Renderer。它证明模板目录和现有交付链可用,不能替代新 RenderProfile 的 41/3 安全预检、完整渲染矩阵或桌面 Word 视觉验收。
|
||||
|
||||
## 6. 独立 Review 与修复
|
||||
|
||||
独立审阅者检查 Renderer `0efa07f..92f238e` 与 RDM `c188df3..3f60265`,结论为 **Ready to merge: No**,没有 Critical,发现 2 项 Important:
|
||||
|
||||
1. 默认规则的 `auto → image` 路径在替换后覆盖 DrawingML 命名空间,生成无法被严格 XML 解析的 DOCX;
|
||||
2. 44 个生成候选没有经过真实编译器契约,ASCII 锚点限制使 12 份中文内容控件标签无法编译,现有 44/44 产品矩阵没有消费新配置,因而漏报。
|
||||
|
||||
Renderer `732e7e7` 在一个修复批次中完成 RED→GREEN:
|
||||
|
||||
- 自动图片在读取和替换原 XML 前准备 `a/wp/pic` 命名空间;真实默认规则图片输出通过严格 XML 解析;
|
||||
- 锚点允许 Unicode 字母/数字和受控标点,仍拒绝空白、换行及 XML 特殊字符;
|
||||
- 只放行 `PAGE/NUMPAGES` 的 `ARABIC` 与通用 `MERGEFORMAT` 安全开关组合;危险 Word 字段仍拒绝;
|
||||
- 接受空的安全 ZIP 目录项,继续拒绝穿越、重复、加密和含数据目录项。
|
||||
|
||||
修复后 44/44 配置可编译。进一步精确底稿探针暴露的外链和遗留修订没有通过放宽规则处理,而是在 RDM `ec24a42` 中转为三份草稿的显式阻断记录。
|
||||
|
||||
## 7. SELF 验证
|
||||
|
||||
Renderer 最终对象 `732e7e7fc44e4871c7e1f6ba7aff2fc25173a10f`:
|
||||
|
||||
- `go test ./... -count=1`:通过;
|
||||
- `go test -race ./... -count=1`:通过;
|
||||
- `go vet ./...`:通过;
|
||||
- `git diff --check`:通过;
|
||||
- 默认图片输出的 `word/document.xml` 由严格 XML 解析器通过;
|
||||
- 跨仓探针:44/44 配置编译,41 份单节点预览通过,3 份按安全门禁拒绝。
|
||||
|
||||
RDM 最终对象 `ec24a42b79604f3ccbf581abb7c43378a1173c21`:
|
||||
|
||||
- `python3 scripts/generate-render-profiles.py --check`:44 份逐字一致;
|
||||
- profile 矩阵:44 个唯一配置、精确类型/摘要/槽位、草稿/禁止发布、41/3 预检结果通过;
|
||||
- SQLite 字典升级、幂等及篡改回滚:最终对象重跑通过;隔离 PostgreSQL 同项测试在 `3f60265` 通过,`ec24a42` 只改配置安全预检元数据,未重跑 PostgreSQL;
|
||||
- 认证产品矩阵在 `3f60265`:44/44 PASS;`ec24a42` 未重跑该矩阵;
|
||||
- `make test && make build`:通过。
|
||||
|
||||
以上均为本地 **SELF**。独立代码审阅属于评审意见,未成为 CI/GATE;PostgreSQL 结果为本轮作者先前启动的隔离临时库测试,不是本次审阅者 REPLAY。
|
||||
|
||||
## 8. 未执行和后续门禁
|
||||
|
||||
NOT_RUN:公司视觉值裁定;3 份阻断底稿的安全派生与视觉复核;44 份完整内容正常/负例新渲染矩阵;桌面 Word/LibreOffice 打开、修复、视觉保真和实际分页;真实数据库迁移;RDM/Backend 项目授权、撤权、交付事务与历史下载集成;远端 Renderer 仓库、Dev gitlink、CI/GATE、浏览器验收、推送、PR、合入、部署和发布。
|
||||
|
||||
人工评审需要分别确认:
|
||||
|
||||
1. 公司默认规则继续保持草稿,并提供或指定 Logo、字体、字号、颜色和标题层级的权威值;
|
||||
2. 41 份预检通过的专用配置是否进入后续完整渲染验证;
|
||||
3. 三份阻断底稿是否允许生成“去外链 + 明确处理遗留修订”的新派生候选,并在逐字/视觉复核后重新绑定;
|
||||
4. 上述决定完成前,不进入 Task 9 的项目级渲染事务接线。
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
# 统一文档渲染器第三批实施评审 r2
|
||||
|
||||
日期:2026-10-15。状态:**待人工视觉与内容评审**。本记录替代 r1 的“41 通过、3 阻断”实现快照;r1 保留为问题发现依据。用户已确认允许为三份阻断底稿生成“去外链、明确处理遗留修订”的安全派生候选,同时保持全部配置未发布,并要求后续实施由 CLI 工作单元完成、既有成果不重做。
|
||||
|
||||
固定对象:
|
||||
|
||||
- CLI 实施基线:RDM `ec24a42b79604f3ccbf581abb7c43378a1173c21`;
|
||||
- CLI 首次实现:RDM `522f9d8c2a303b266f627b03487f12ecf093bccc`;
|
||||
- 独立 CLI Review:`522f9d8` 相对 `ec24a42`;
|
||||
- CLI 修复后 RDM:`48120ed45f53e699bc8c68b705024795b22bc4fb`;
|
||||
- 只读 Renderer:`732e7e7fc44e4871c7e1f6ba7aff2fc25173a10f`;
|
||||
- CLI 实施线程:`01a13fcb-3e9e-75d1-bc9c-8c3bddb2f94c`。
|
||||
|
||||
## 1. 结果
|
||||
|
||||
三份原底稿保持逐字不变,catalog、sources、normalized/render candidates 和 pins 未修改。系统新增三个内容寻址的安全派生候选、不可变 manifest、转换器、生成检查、跨仓兼容探针和标准测试门禁。
|
||||
|
||||
| 模板 | 固定输入 SHA256 | 安全派生 SHA256 | 状态 |
|
||||
|---|---|---|---|
|
||||
| `dhf.33c2e9fe0c42fa0d` | `9e2fc466f1406fdc044c7162c508f614cac35a1fd49904f78e9b7dbabb514f61` | `0afb181c54a1693464df4e6ab0a39318a0b3dd9553eb3c9cb72145aae122c5b6` | 待人工视觉/内容复核,禁止发布 |
|
||||
| `dhf.6b440531e6ff12f8` | `6c50bda0ff2e6bd3b66b45df56f25c6c94c889b59195946555c4ce299f4acd3b` | `262a7cdfb46b84e3ddd23b724ede067d0bbc76f5465b459f061bb0b780774fe2` | 待人工视觉/内容复核,禁止发布 |
|
||||
| `dhf.a046cc77128b7b66` | `51fc944a405320930596ee503959b76035eeb86d7d5253fb3b0f703b46506fae` | `fc9099ef830f168655042defb06e7263387baca95ea54ca1e02614aac63ce46b` | 待人工视觉/内容复核,禁止发布 |
|
||||
|
||||
最终 44 份 RenderProfile 均为 `draft`,44 份 review 均为 `publicationAllowed=false`;41 份继续绑定 catalog render,三份绑定上述派生件。选定底稿安全预检为 **44 PASS、0 BLOCKED**,但安全预检不等于视觉批准或发布授权。
|
||||
|
||||
## 2. 安全派生规则
|
||||
|
||||
转换版本为 `1.1.0`,规则和输入/输出摘要固定在 `internal/rdmapp/templates/dhf/safe-bases/manifest.v1.json`:
|
||||
|
||||
- 删除外部 hyperlink relationship,并将对应 `w:hyperlink` 解包,保留可见子内容和顺序;
|
||||
- 识别简单 `w:fldSimple` 及复杂字段中的外部 `HYPERLINK` 指令;结构明确时保留显示结果并移除指令,结构含混时 fail-closed;
|
||||
- 接受普通插入内容、移除普通删除内容;清除评论锚点、引用、部件、关系和内容类型;关闭遗留跟踪修订;
|
||||
- 对删除段落标记按 Word 语义合并相邻段落,保留前段 paragraph properties 和两侧 run properties;插入段落标记保留边界并去除修订标记;
|
||||
- `dhf.6b440531e6ff12f8` 的真实正文由 455 段变为 426 段:29 个删除段落标记完成合并,3 个插入段落标记保留边界;manifest 另区分 75 个内容删除和 11 个内容插入;
|
||||
- 遇到 move、cell/customXml 修订、跨结构段落合并、歧义字段或其他未支持构造时拒绝生成;
|
||||
- 输入 XML 仅接受严格 UTF-8/UTF-8 BOM,解析前拒绝 DTD/ENTITY;
|
||||
- 拒绝路径穿越、重复/点段/重复分隔符、非法或别名百分号编码、规范化碰撞、加密、条目数/单项/展开量/原包大小超限;
|
||||
- 输出使用固定顺序、时间戳与 `ZIP_STORED`,不依赖 zlib 版本生成内容摘要;
|
||||
- 重写 XML 后验证 `mc:Ignorable`、`Requires`、`Preserve*`、`ProcessContent` 中的 QName 前缀全部可解析;
|
||||
- 两个生成器都枚举完整输出树,任何多余文件、目录、profile 或 review 都导致 `--check` 失败,不静默删除未知对象。
|
||||
|
||||
## 3. 标准门禁和跨仓收据
|
||||
|
||||
`make test` 已接入:
|
||||
|
||||
1. `python3 -B -m unittest tests.test_safe_dhf_bases -v`;
|
||||
2. `python3 -B scripts/generate-safe-dhf-bases.py --check`;
|
||||
3. `python3 -B scripts/generate-render-profiles.py --check`。
|
||||
|
||||
Gitea CI 原有入口调用 `make test`,因此无需 Renderer checkout 即覆盖安全转换和生成漂移。跨仓兼容探针独立要求:
|
||||
|
||||
- RDM 与 Renderer 均为 Git checkout;
|
||||
- 两仓 HEAD 与调用方提供的完整 SHA 完全一致;
|
||||
- staged、unstaged 和 untracked 均为空;
|
||||
- 收据同时输出 `rdmCommit` 与 `rendererCommit`。
|
||||
|
||||
提交后固定收据:
|
||||
|
||||
```json
|
||||
{
|
||||
"rdmCommit": "48120ed45f53e699bc8c68b705024795b22bc4fb",
|
||||
"rendererCommit": "732e7e7fc44e4871c7e1f6ba7aff2fc25173a10f",
|
||||
"profiles": 44,
|
||||
"compilePass": 44,
|
||||
"normalPreviewPass": 44,
|
||||
"wrongDocumentTypeRejected": 44,
|
||||
"unsafeOriginalBaseRejected": 3
|
||||
}
|
||||
```
|
||||
|
||||
`normalPreviewPass` 是每份 profile 的一个真实 paragraph mapping 预览,不冒充完整内容、全部 primitive、视觉分页或桌面 Word 保真验收。
|
||||
|
||||
## 4. 独立 CLI Review 和修复
|
||||
|
||||
独立只读 CLI Review 对 `ec24a42..522f9d8` 给出 **Ready to merge: No**:1 个 Critical、7 个 Important、3 个 Minor。
|
||||
|
||||
Critical:删除段落标记只移除空 `w:del`,没有合并段落。Important:Markup Compatibility 前缀丢失;新安全测试未进入标准 CI;隐藏 hyperlink field 可残留 URL;UTF-16 DTD 可绕过原始字节扫描;非规范 ZIP 别名可共存;生成器不拒绝孤儿产物;跨仓收据没有绑定 RDM SHA。Minor:DEFLATE 输出依赖未记录 zlib;读取前没有原包大小上限;显式 `--rdm-root` 仍依赖当前目录是 Git checkout。
|
||||
|
||||
CLI 在新提交 `48120ed` 中完成一次修复批次,全部 Critical/Important/Minor 均有判别测试并修复。没有改写 `522f9d8` 历史。按一次 Review + 一次修复批次流程,没有把作者自检升级为第二次独立 Review。
|
||||
|
||||
## 5. 验证证据
|
||||
|
||||
CLI 实施工作单元:
|
||||
|
||||
- 首轮 TDD:缺少转换器和 selected-base 绑定分别观察 RED;
|
||||
- Review 修复 TDD:20 个测试中观察到 15 FAIL + 1 个预期 ERROR,逐类修复后 20/20 PASS;
|
||||
- 三份派生件逐字再生成:3/3 PASS;
|
||||
- 44 份 profile/review 逐字再生成:44/44 PASS;
|
||||
- Go profile 矩阵:PASS;
|
||||
- `make test`:exit 0;
|
||||
- `make build`:exit 0;
|
||||
- 提交后双仓兼容矩阵:44/44 编译、44/44 单映射正常预览、44/44 错误文档类型拒绝、3/3 原危险底稿拒绝。
|
||||
|
||||
主编排器在最终提交上重新执行:
|
||||
|
||||
- Python 安全测试:20/20 PASS;
|
||||
- 两个 generator `--check`:3/3 与 44/44 PASS;
|
||||
- focused Go profile/dictionary 测试:PASS;
|
||||
- exact-clean 双仓兼容矩阵:44/44、44/44、44/44、3/3;
|
||||
- `make test && make build`:exit 0。
|
||||
|
||||
以上为本地 **SELF** 与独立 CLI Review 记录,不是远端 CI/GATE、发布、部署或用户视觉验收。
|
||||
|
||||
## 6. 仍需人工评审与未执行项
|
||||
|
||||
三份安全派生候选仍需逐字和桌面 Word/LibreOffice 视觉对照,重点检查:
|
||||
|
||||
- 外链解包后可见文字、图片、表格、合并单元格和布局是否保持;
|
||||
- `dhf.6b440531e6ff12f8` 接受遗留修订后的 426 段内容与分页是否符合业务意图;
|
||||
- 页眉页脚、字体替代、图片、编号和打印分页是否符合原批准口径。
|
||||
|
||||
NOT_RUN:三份派生件人工视觉批准;公司默认 Logo/字体/字号/颜色/标题层级裁定;完整内容/全部 primitive 渲染;桌面 Word/LibreOffice 保真和分页;真实数据库迁移;profile 发布;远端 Renderer 仓库与 Dev gitlink;推送、PR、合入、部署;Task 9 项目级事务接线。
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
# 统一文档渲染器第四批 Task 9 实施评审 r1
|
||||
|
||||
日期:2026-10-15。状态:**待人工评审**。用户已确认 Task 8 安全派生结果并批准继续 Task 9,同时要求后续实施由 CLI 工作单元完成,主智能体只负责依赖编排、独立 Review、验证与记录。
|
||||
|
||||
固定对象:
|
||||
|
||||
- Renderer 私有远端:`weichen/Agent-Document-Renderer`;
|
||||
- Renderer pin:`732e7e7fc44e4871c7e1f6ba7aff2fc25173a10f`;
|
||||
- RDM 依赖准备:`e40d08e5f80e5c8051cdc4b27fe13a8556a9c5ab`;
|
||||
- RDM Task 9 初始实现:`d68110c95714c95788363ba56c17fe19ba13dbaf`;
|
||||
- RDM Task 9 Review 修复:`019d60d4b003fea060eba04c2455ea7ee1c269f3`;
|
||||
- CLI 实施线程:`01a1402a-6cc8-7cc2-8c68-bf35354aae1a`;
|
||||
- 独立 CLI Review 线程:`01a14056-f149-7250-b43c-11a85ce28bea`。
|
||||
|
||||
## 1. 依赖门禁
|
||||
|
||||
Task 9 首次 CLI 启动在写入前发现 Renderer 只有本地历史、没有远端,RDM 无法从干净克隆取得依赖,因此以零改动、零提交停止。主编排器随后:
|
||||
|
||||
1. 创建私有 `weichen/Agent-Document-Renderer` 仓库;
|
||||
2. 将已评审历史发布到远端 `main`,精确指向 `732e7e7`;
|
||||
3. 在 RDM 添加 `pins/agent-document-renderer` gitlink 和 `agent-document-renderer v0.0.0` 本地 pin;
|
||||
4. 通过 no-local 临时 RDM clone 从远端初始化该子模块,得到相同 SHA 且工作树干净;
|
||||
5. 通过 Renderer 全套测试、RDM `GOWORK=off go test ./...` 后提交 `e40d08e`。
|
||||
|
||||
依赖准备没有修改 Renderer 源码、发布 profile、迁移业务数据或部署服务。
|
||||
|
||||
## 2. Task 9 最终能力
|
||||
|
||||
### 2.1 schema v9 与不可变输入
|
||||
|
||||
schema v9 持久化:
|
||||
|
||||
- 完整递归 Markdown/canonical source 版本及稳定节点 ID;
|
||||
- profile snapshot、选择来源、项目/文档绑定及全部资产身份和哈希;
|
||||
- submission 冻结的正文、职责、来源披露和完整 Renderer `ReviewSnapshot`;
|
||||
- durable render job、输入摘要、状态、失败/取消原因和重试身份;
|
||||
- delivery、所有 blob、manifest、diagnostics、完整 node anchor map;
|
||||
- source/profile/review/delivery trace events 和 edges;
|
||||
- schema 指纹和确切唯一约束/索引定义。
|
||||
|
||||
提交审阅时冻结完整事实;正式 review/approved export 只读取 submission snapshot,不能用当前内容、调用方规则或调用方身份替换既有审签对象。旧 submission 缺少可信人物、时间、批注或修订事实时 fail-closed,不合成人物或时间。
|
||||
|
||||
### 2.2 内容与来源
|
||||
|
||||
- 正常编制的 `正文` 通过显式 `sectionId → canonical nodeId` 绑定进入确切模板槽位,不按名称或遍历顺序猜测;缺失、重复或目标不属于 profile 时拒绝。
|
||||
- Markdown 递归保存全部子节点和稳定 ID;子节点变化形成新 source identity。
|
||||
- 测试对 canonical JSON、Markdown、preview/review/approved DOCX 回读精确正文,而非只断言文件非空。
|
||||
- 来源逐项授权:允许披露的引用进入 canonical/Markdown/manifest/trace;受限来源只保留受控标记,私人正文不会进入 DOCX、manifest、diagnostics、anchors 或 trace。
|
||||
|
||||
### 2.3 原子事务、幂等与恢复
|
||||
|
||||
- 渲染前持久化 frozen job,再进入 running;失败和取消形成 durable 状态。
|
||||
- 渲染后、提交前重新核验成员、职责、动作权限、项目 revision、正文、profile/assets、review state 和来源披露。
|
||||
- delivery、blobs、manifest、anchors、trace events/edges 和 receipt 在一个事务提交;七个故障点逐项验证零残留。
|
||||
- 幂等摘要覆盖完整 source/profile/assets/binding/review/mode/Renderer identity;同 operationId 同输入返回确切旧回执,任何隐式输入变化都拒绝。
|
||||
- 取消在渲染前和提交前轮询;失败只允许对同一 frozen snapshot 重试。
|
||||
- 历史交付直接返回冻结 blob;profile/Renderer 升级和服务重启不会重渲染或覆盖旧字节。
|
||||
|
||||
### 2.4 权限、审签与下载
|
||||
|
||||
- validate、submit 和 delivery commit 均在提交时权限/项目 revision 栅栏内重验。
|
||||
- download/status 重新检查当前项目、文档读取权和当前职责;`audit.read` 本身不授予正文或制品。
|
||||
- 审阅/批准人物、显示名、时间、原因、批注、回复和修订来自受项目/文档范围约束的可信账户与审签记录。
|
||||
- 命令入口拒绝 `approvedBy`、`confirmed`、签名等调用方冒充字段。
|
||||
- profile 未发布时允许受权维护者 validate/preview,但 review/approved 正式交付拒绝;受控文档永不回退公司默认规则。
|
||||
|
||||
### 2.5 资源和可复核清单
|
||||
|
||||
- 限制节点数、深度、文本、Markdown/JSON、profile/assets、单 blob、任务数和项目保留字节;在产生大副本前尽量拒绝。
|
||||
- 命令下载使用有界响应,避免无限 base64 扩张。
|
||||
- 要求 renderer 返回的 anchors 与所有期望节点完全一致,只允许明确的 renderer-owned 合成锚点。
|
||||
- manifest 固定 Renderer pin/adapter identity、source/profile/review hashes、所有资产,以及每个交付 blob 的名称、SHA256 和大小。
|
||||
|
||||
## 3. 命令面
|
||||
|
||||
新增并注册七个受控命令:
|
||||
|
||||
1. `rdm.render.validate`;
|
||||
2. `rdm.render.preview`;
|
||||
3. `rdm.render.submit`;
|
||||
4. `rdm.render.review`;
|
||||
5. `rdm.render.approved`;
|
||||
6. `rdm.render.status`;
|
||||
7. `rdm.render.download`。
|
||||
|
||||
命令 schema 为闭集;身份、审签和签署事实不从请求参数读取。现有 44 份 profile 继续保持 `draft`、`publicationAllowed=false`,因此当前正式 review/approved 命令会按发布门禁拒绝,未绕过 Task 7–8 的人工发布决定。
|
||||
|
||||
## 4. 独立 CLI Review
|
||||
|
||||
独立只读 Review 对 `e40d08e..d68110c` 给出 **Ready to merge: No**:
|
||||
|
||||
- 2 Critical:旧批准可授权新内容/新 profile;正常受控正文被 canonical 转换过滤。
|
||||
- 9 Important:递归 Markdown 丢子节点、幂等摘要漏隐式输入、失败/取消 job 不持久、人物时间与批注修订为合成/缺失、来源追溯被整体删除、anchor 只检查非空、validate/submit 缺提交时栅栏、v9 接受残缺 schema、内存/数据库增长无界。
|
||||
- 1 Minor:manifest 缺 Renderer/资产/全部 blob 身份。
|
||||
|
||||
CLI 在 `019d60d4` 完成一次 Review 修复批次。所有 finding 均加入能区分错误实现的 RED 测试并修复;没有 amend 或重写 `d68110c`。按一次 Review + 一次修复批次流程,没有把作者自检升级为第二次独立 Review。
|
||||
|
||||
## 5. SELF 与隔离 PostgreSQL 验证
|
||||
|
||||
CLI 在最终 HEAD `019d60d4` 执行:
|
||||
|
||||
- Task 9 聚焦功能、迁移、命令、并发、重启、回滚、来源和安全测试:PASS;
|
||||
- `GOWORK=off go test -race ./internal/domain/store ./plugins/rdm ./internal/rdmapp -run 'Render|Renderer|Version9' -count=1`:PASS;
|
||||
- `GOWORK=off go vet ./...`:PASS;
|
||||
- `GOWORK=off make test`:PASS;
|
||||
- `GOWORK=off make build`:PASS;
|
||||
- 临时 PostgreSQL:schema v8/v9、重启、同/异 operationId 并发、权限栅栏、错误唯一索引定义和残缺 v9 rollback:PASS;临时服务停止、数据库与数据目录删除。
|
||||
|
||||
主编排器在同一最终 HEAD 重放:
|
||||
|
||||
- focused store/RDM/plugin 测试:PASS;
|
||||
- Task 9 精确 race:PASS;
|
||||
- `go vet ./...`:PASS;
|
||||
- `make test && make build`:PASS;
|
||||
- Renderer gitlink 精确为 `732e7e7` 且工作树干净。
|
||||
|
||||
全仓 `go test -race ./...` 另发现既有 slow-lane `ledgerUpdate` 与 `TestUnknownSchemaVersionStopsReplay` 中 `Reset` 的竞争;Task 9 精确 race 范围通过。该既有 race 未在本批扩大修复范围,需单独任务处理,不能把本批 SELF 升级为全仓 race 通过。
|
||||
|
||||
以上均为本地 **SELF** 与独立 CLI Review 记录,不是远端 CI/GATE、合入、部署或用户运行验收。
|
||||
|
||||
## 6. 未执行和下一阶段边界
|
||||
|
||||
NOT_RUN:profile 人工发布;公司默认视觉值;桌面 Word/LibreOffice 完整内容和分页验收;真实运行库 schema v9 迁移;现有数据备份/恢复演练;远端 CI/GATE;推送 RDM 分支、PR、合入、部署和发布;Task 10 Backend 路径替换;Task 11 UI。
|
||||
|
||||
人工评审重点:
|
||||
|
||||
1. submission 冻结事实和旧 submission fail-closed 边界;
|
||||
2. 显式正文节点绑定与来源披露裁剪;
|
||||
3. durable failed/cancelled job、幂等摘要和历史下载;
|
||||
4. schema v9 严格指纹、资源配额与迁移门禁;
|
||||
5. 是否接受该 Task 9 本地候选进入后续交付/Task 10 评审。
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# 统一文档渲染器第五批 Task 10 实施评审 r1
|
||||
|
||||
日期:2026-10-16。状态:**实现与复审闭合(SELF)**。用户已预先授权后续阶段连续推进、不再逐阶段请求人工评审;profile 发布、公司视觉值裁定和三份安全派生件视觉批准仍属业务验收,未在本批执行。
|
||||
|
||||
固定对象:
|
||||
|
||||
- Backend 分支:`feature/unified-document-renderer-task10`(已推送远端),基线 `d9d8f016ece5015ff6872a6a8c6a449a7353c062`;
|
||||
- Backend 最终 HEAD:`a2f4978be83514ae0e474039fb42b76bfc2a05d4`;
|
||||
- Renderer gitlink:`0d1c5121d137be817db5f98d3c13320dfa919c8a`(Renderer 远端 `main`);
|
||||
- Dev `modules/backend` gitlink 随本记录同批更新到上述 Backend HEAD。
|
||||
|
||||
## 1. 提交序列
|
||||
|
||||
| 提交 | 内容 |
|
||||
|---|---|
|
||||
| `b0dd533` | 引入 `deps/agent-document-renderer` gitlink 与 `agent-document-renderer` 本地 replace |
|
||||
| `a21a3b5` | 普通工作区 Word 交付改走共享 Renderer(`render_document`) |
|
||||
| `9aa9129` | 生产提示词与 house-style 配方退役旧 Word 指引 |
|
||||
| `35bd87c` | 跟进 Renderer 语义与协作式取消修复 |
|
||||
| `fec2d16` | 首轮独立 Review 的 Important/Minor 全量修复:可信冻结时间、持久幂等交付、Markdown 优先持久化、真实对照、Python/DOCX 旁路封闭 |
|
||||
| `6c01d00` | 二轮 Review 三项 Important:改名 DOCX 旁路、完整旧 fixture 语义对照、对齐/任务/分隔线/编号的真实对照 |
|
||||
| `a2f4978` | 三轮 Review 唯一 Important:按 `_rels/.rels` officeDocument 关系与 `[Content_Types].xml` 识别 WordprocessingML,畸形/歧义/不安全元数据按 Word 拒绝 |
|
||||
|
||||
## 2. 最终能力
|
||||
|
||||
- 普通 Word 生成只经共享 Renderer 与公司默认 profile;旧 Go/Python 路径仅在迁移对照模式可用,不再是生产路径。
|
||||
- 项目受控文档、`review`/`approved` 模式在写入任何制品前拒绝并转交 RDM,Backend 不提供默认规则回退。
|
||||
- 交付为 Markdown 优先、DOCX 与 manifest 派生;同一冻结输入幂等,重启后节点 ID 稳定,部分失败返回 partial/unknown 回执。
|
||||
- 直接制品登记按 OPC 内容(而非文件名)拒绝 WordprocessingML(含模板与宏变体),普通 ZIP/二进制制品不受影响。
|
||||
- 新旧对照覆盖完整旧 fixture:标题、行内样式、惰性链接、引用、反引号与波浪线代码块、嵌套有序/无序列表、任务勾选、分隔线、起始编号与表格对齐,注入丢失可被检出。
|
||||
|
||||
## 3. 评审轨迹
|
||||
|
||||
| 轮次 | 评审对象 | 结论 |
|
||||
|---|---|---|
|
||||
| 1 | `d9d8f01..9aa9129` 完整 Task 10 范围(独立 CLI) | 0 Critical;多项 Important(旧 Python 路径仍可生产调用等) |
|
||||
| 2 | `d9d8f01..fec2d16`(全新独立 CLI) | 0 Critical / 3 Important(改名 DOCX、对照 fixture 不全、对齐丢失漏报) |
|
||||
| 3 | `fec2d16..6c01d00` 窄闭合复审(全新 CLI) | 2、3 项关闭;1 项因固定 `word/document.xml` 判定未完全关闭 |
|
||||
| 4 | `6c01d00..a2f4978` 窄闭合复审(当前主模型,未参与实施) | PASS:0 Critical / 0 Important |
|
||||
|
||||
第 4 轮记录的非阻塞次要项(后续改进,不阻塞交付):`_rels/.rels`、`[Content_Types].xml` 部件名与 content type 字符串按精确大小写匹配,刻意构造的大小写变体包可被识别为非 Word。该绕过需要恶意构造,不影响正常模型输出路径。
|
||||
|
||||
## 4. 验证(来源等级)
|
||||
|
||||
- SELF(实施 CLI,`a2f4978` 同树):聚焦测试、`go test -count=1 ./internal/tools`、全量 `go test ./...`、`go test -race ./internal/tools ./internal/runmgr`、`go vet ./...`、`go build ./...`、`git diff --check` 均通过。
|
||||
- REPLAY(当前主模型,`a2f4978` 干净树):`go test -count=1 ./internal/tools ./internal/docgen/...` 通过;Dev 检出该 gitlink 后 `go build ./...` 通过。
|
||||
- GATE:NOT_RUN(Backend PR/CI 尚未创建,留待 Task 13 组合交付)。
|
||||
|
||||
## 5. 未执行项
|
||||
|
||||
profile 发布、公司默认视觉值裁定、三份安全派生件视觉批准、真实运行库迁移、PR/合入与部署均未执行;RDM 的 Renderer pin 仍为 `732e7e7`,需在 Task 13 组合前升级到 `0d1c512` 并重验。
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
# 统一文档渲染器第六批实施评审 r1:Task 11/12、公司默认发布与 DHF 44 份发布
|
||||
|
||||
日期:2026-10-16。状态:**实现与复审闭合(SELF/REPLAY)**;Task 13 全量验收另行记录。用户已预先授权连续推进;本批两项业务决定由用户本聊天裁定(见第 2 节)。
|
||||
|
||||
固定对象:
|
||||
|
||||
| 仓库 | 分支 | 最终 HEAD | 远端 |
|
||||
|---|---|---|---|
|
||||
| Renderer | `main` | `31fbe54fae8bf11be664919ce173da0d68ebfdc9` | 已合入:[PR #1](https://git-home.u1680832.nyat.app:30319/weichen/Agent-Document-Renderer/pulls/1)(`44df4cc`)、[PR #2](https://git-home.u1680832.nyat.app:30319/weichen/Agent-Document-Renderer/pulls/2)(`31fbe54`),均 fast-forward |
|
||||
| RDM | `feature/rdm-two-trees-work-observation` | `d63f1db` | 未推送(随父任务交付) |
|
||||
| Backend | `feature/unified-document-renderer-task10` | `1afe1647981e1f331c379757b100e10a9b47ed90` | 已推送 |
|
||||
| Frontend | `feature/unified-document-renderer-task11` | `de650262382e8e1b9c65120365960872b522145f` | 已推送 |
|
||||
|
||||
## 1. 提交序列
|
||||
|
||||
| 仓库 | 提交 | 内容 |
|
||||
|---|---|---|
|
||||
| Renderer | `94d51c2` | Task 12:休眠的上传模板分析器,只产出草稿候选、类型化报告与置信度,无发布入口 |
|
||||
| Renderer | `44df4cc` | 公司默认 `company.default@1.0.0` 按用户裁定发布(经 draft→validated→published 生命周期);段落样式输出对齐与 keepWithNext;专用样式回退 `body` 不改变其他 profile 输出 |
|
||||
| Renderer | `2c18c31` | DHF 身份渲染:内容写入模板槽位并保留 pPr/rPr、分页符、重复行原型与签名占位;节点书签按映射目标部件(页眉/页脚)校验;仅放行内部锚点超链接 |
|
||||
| Renderer | `31fbe54` | 悬空内部锚点原样保留(.doc 转换模板的无效目录链接,Word 中为无操作);锚点形状收紧;外部/关系型链接、HYPERLINK 域与其他活动内容仍拒绝 |
|
||||
| RDM | `0cb10f0` | Task 11 服务端:`rdm.render.profiles/deliveries/review.view/review.annotate/review.revise` |
|
||||
| RDM | `f2a5a16` | 44 份 DHF 可复现身份渲染与 LibreOffice 页面/文本/像素对照工具 |
|
||||
| RDM | `c96907f`、`d5eeb61` | Renderer pin `732e7e7`→`44df4cc`→`31fbe54`;44 份模板经产品预览路径零失败 |
|
||||
| RDM | `dcdb1de`、`5feca0f` | Task 12:管理员发布的休眠候选规则(analyze/list/view/publish,迁移 v10,SQLite/PG);跨文件可达性守卫;列表精简列 |
|
||||
| RDM | `b933037`、`d63f1db` | 按用户裁定发布 44 份 DHF 规则包(生成器与加载器双层校验决定与收据哈希);RDM 层外部超链接回归测试 |
|
||||
| Backend | `1afe164` | Renderer pin `0d1c512`→`31fbe54`;公司默认按渲染器状态报告为已发布,路由不放宽 |
|
||||
| Frontend | `85428b4`、`de65026` | Task 11 文档渲染工作区(结构画布 + 传统阅读器、规则选择、预览诊断、审阅、下载);按服务端真实契约修正 5 处字段与树遍历 |
|
||||
|
||||
## 2. 业务决定(用户,2026-10-16,本聊天)
|
||||
|
||||
- 公司默认规则:采用普查主流值——A4、四边约 2.5cm、宋体 + Times New Roman、正文小四 12pt、标题黑体、暂无 Logo。
|
||||
- 44 份模板发布方式:智能体用 LibreOffice 对照原件与输出,无差异的直接发布,有差异的列清单交用户裁决。
|
||||
- 对照结果:底稿→渲染输出 44/44 PASS(逐页文本 + 像素,阈值 0.005,60 dpi);原件→底稿 44/44 有模板化差异(示例值清空 7、页数不变的页面差异 27、页数变化 10),附逐页对照图与清单。用户裁定:**接受模板化差异,44 份全部发布**。收据 SHA256 `90c768eb240a2b590b0f474a86bf3be9a8a830653809d3ee08c3951b749eb230`,副本入 RDM `docs/records/renderer/`。
|
||||
- 局限:对照基于 LibreOffice 渲染,不代表 Microsoft Word 渲染结果。
|
||||
|
||||
## 3. 评审轨迹(每轮为全新独立会话,仅接收目标、diff 与证据)
|
||||
|
||||
| 对象 | 结论 |
|
||||
|---|---|
|
||||
| Renderer `0d1c512..94d51c2` | PASS 0/0 |
|
||||
| Renderer `94d51c2..44df4cc` | PASS 0/0 |
|
||||
| Renderer `44df4cc..2c18c31` | PASS 0 Critical / 0 Important / 2 Minor |
|
||||
| Renderer `2c18c31..31fbe54` | PASS 0/0 |
|
||||
| RDM Task 11 `..0cb10f0` | PASS 0/0 |
|
||||
| RDM `0cb10f0..f2a5a16` | PASS 0/0 |
|
||||
| RDM `f2a5a16..dcdb1de` | PASS,1 Important(可达性测试只解析单文件)/ 1 Minor |
|
||||
| RDM `dcdb1de..5feca0f` | PASS 0/0(上轮 Important、Minor 关闭)/ 1 Minor(并入下一提交) |
|
||||
| RDM `5feca0f..d63f1db` | PASS 0/0 / 2 Minor(可读性) |
|
||||
| Backend `a2f4978..1afe164` | PASS 0/0/0 |
|
||||
| Frontend `a81e94a..85428b4` | 5 Important(与服务端字段契约不符、树非递归) |
|
||||
| Frontend `85428b4..de65026` | PASS 0/0;5 项全部关闭 |
|
||||
|
||||
## 4. 验证(来源等级)
|
||||
|
||||
- SELF:各实施会话在对应 HEAD 运行 `go test -count=1 ./...`、race、`go vet`、gofmt;RDM `make test && make build`;Backend 全量 `go test ./...`、`go build`;Frontend vitest 359、`npm run build`、knip 棘轮 43≤43、design-guard。
|
||||
- REPLAY:各评审会话重放聚焦测试与 vet(见评审结论);主模型在 Renderer `31fbe54` 运行 `go test -count=1 ./...` 全部通过,并以 RDM 源码副本运行 44 份身份渲染(44/44)与 LibreOffice 对照。
|
||||
- GATE:NOT_RUN。Renderer 仓无 CI;RDM/Backend/Frontend 的 PR 与 CI 留待 Task 13 组合交付。
|
||||
|
||||
## 5. 未执行项
|
||||
|
||||
Task 13:44 份产品矩阵(正常/缺必填/超长/重复块、审阅与批准输出、回读)、真实产品浏览器验收、DOCX 重开、性能容量记录、全量组合测试与独立终审;各仓 PR、CI 与合入;三份安全派生底稿 `safe-bases/manifest.v1.json` 中的视觉状态字段仍为 pending(规则包已按用户裁定发布)。
|
||||
@@ -0,0 +1,93 @@
|
||||
# 01 需求与范围
|
||||
|
||||
## 1. 用户目标
|
||||
|
||||
成员和智能体能够以 Markdown 编制公司项目文档,由系统根据声明式渲染规则生成 Word。文档可使用专用公司模板,也可在未指定专用模板时使用公司通用规则。用户可以下载 Markdown、Word 或包含全部交付物的归档包。
|
||||
|
||||
渲染结果不是一次性文件,而是 2 树 1 网的一部分:文档树保存文档、章节、小节和段落;笔记树保存对话、文件、网络搜索和工具结果等依据;追溯网连接内容节点、来源、修订、批注、审签决定、规则版本和最终文件。
|
||||
|
||||
## 2. 第一阶段范围
|
||||
|
||||
- 统一文档模型和 Markdown 解析。
|
||||
- 声明式 RenderProfile schema、校验器、注册表和版本生命周期。
|
||||
- Word 格式适配器。
|
||||
- 公司通用 Word 规则包。
|
||||
- 44 份现有模板的规则包及受控资产绑定。
|
||||
- 文档实例级规则选择及四级回退策略。
|
||||
- 工作稿、预览稿、批准稿和审阅留痕稿。
|
||||
- Markdown、DOCX、清单及归档包下载。
|
||||
- Word 书签/内容控件与文档树节点的双向锚定。
|
||||
- 规则预览、发布、退役、升级提案和回滚。
|
||||
- SQLite 与 PostgreSQL 的规则、版本和交付物持久化。
|
||||
- 真实浏览器中的选择规则、预览、审阅和下载流程。
|
||||
|
||||
## 3. 后续范围
|
||||
|
||||
后续格式适配器消费同一 `CanonicalDocument`:
|
||||
|
||||
- PDF:固定版式发布和打印交付。
|
||||
- PPT:按幻灯片规则映射章节、图表和演讲者备注。
|
||||
- 用户上传参考文档,智能体分析后生成候选 RenderProfile。
|
||||
|
||||
后续功能必须沿用本阶段的规则审查、预览、发布和权限生命周期。上传参考文档不会直接生成已发布规则。
|
||||
|
||||
## 4. 角色
|
||||
|
||||
| 角色 | 权限与职责 |
|
||||
|---|---|
|
||||
| 文档编制人 | 编辑 Markdown、选择允许的规则、生成工作稿和提交审阅 |
|
||||
| 审阅人 | 查看来源和差异、添加批注、提出修改或通过审阅 |
|
||||
| 批准人 | 对冻结提交作最终决定,批准后生成批准稿 |
|
||||
| 项目创建者/授权管理员 | 管理项目默认规则和项目内可用规则 |
|
||||
| 系统管理员 | 发布公司规则、受控资产和格式适配器 |
|
||||
| 普通项目成员 | 按项目内容权限查看和下载文档;无审计权时不见审计信息 |
|
||||
| 智能体 | 生成 Markdown 候选、提出规则选择和结构映射;不得伪造审签或发布规则 |
|
||||
|
||||
## 5. 功能要求
|
||||
|
||||
### 5.1 规则选择
|
||||
|
||||
选择顺序固定为:
|
||||
|
||||
1. 文档实例显式绑定的 `profileId@version`。
|
||||
2. 文档类型的已发布默认规则。
|
||||
3. 项目已发布默认规则。
|
||||
4. 公司通用 Word 规则。
|
||||
|
||||
受控文档一旦声明专用模板,任何缺包、失配、退役或必填字段缺失都必须阻止生成,不进入第 3 或第 4 级回退。
|
||||
|
||||
### 5.2 双格式与清单
|
||||
|
||||
每次交付至少包含:
|
||||
|
||||
- `document.md`
|
||||
- `preview.docx`、`approved.docx` 或 `review.docx` 中的适用文件
|
||||
- `manifest.json`
|
||||
|
||||
清单记录内容哈希、规则和模板版本、资产哈希、生成主体、生成时间、审签轮次、输出哈希、诊断结果及文档树根节点。
|
||||
|
||||
### 5.3 可追溯性
|
||||
|
||||
每个可渲染内容节点必须有稳定 `nodeId`。Markdown 解析范围、DOCX 书签/内容控件、来源引用、内容版本、批注和交付物均绑定该 ID。仅靠标题或段落顺序不得作为稳定身份。
|
||||
|
||||
### 5.4 审阅和批准
|
||||
|
||||
系统分别保存内容版本、批注和审签决定。批准稿接受已批准修订并隐藏普通批注;审阅留痕稿保留修订、批注、回复及解决状态。签署区只读取可信审签数据。
|
||||
|
||||
## 6. 非功能要求
|
||||
|
||||
- 确定性:同一 Markdown、元数据、规则版本和资产生成相同有效内容;时间戳等非确定字段必须来自冻结提交。
|
||||
- 安全:规则不含脚本、宏、外部 URL 运行、任意 OOXML 或任意文件路径。
|
||||
- 隔离:规则执行无网络,资产只从已验证包读取,输出写入限定目录。
|
||||
- 兼容:未知规则版本、未知节点、旧二进制或新 schema 均 fail-closed。
|
||||
- 性能:普通 100 页以内文档在交互预览预算内完成;大文档进入后台任务并显示进度。
|
||||
- 可解释:失败返回具体字段、规则路径、文档节点和修复建议。
|
||||
|
||||
## 7. 完成判据
|
||||
|
||||
- 44/44 模板在适用项目中完成“Markdown→预览→审阅→批准→批准稿/留痕稿→下载”的逐项验证;当前两个字典阻塞清零。
|
||||
- 公司通用规则可生成无专用模板的普通文档。
|
||||
- Markdown 与所有 Word 输出均可下载,清单中的哈希可复核。
|
||||
- 页眉、页脚、页码、文件控制字段、Logo、标题、表格及签署区符合已批准规范。
|
||||
- 私人来源和无权批注不进入共享文件。
|
||||
- 规则升级不改变旧批准文件,旧版本仍可重放生成或取回冻结字节。
|
||||
@@ -0,0 +1,141 @@
|
||||
# 02 总体架构与方案
|
||||
|
||||
## 1. 推荐架构
|
||||
|
||||
采用“统一内容模型+统一渲染内核+格式适配器+版本化规则包”。第一阶段提供 Word 适配器,后续 PPT/PDF 不改变上游内容和规则生命周期。
|
||||
|
||||
本方案建议把渲染内核放入独立的 `Agent-Document-Renderer` Go 模块。该模块边界是本次待评审的架构决策;在评审通过和任务启动门禁完成前,不创建新仓库、不改变现有模块 pin,也不迁移现有生产路径。若评审决定先以内嵌包落地,公开接口、依赖方向和后续独立化条件仍须保持与本文一致。
|
||||
|
||||
```text
|
||||
Markdown + metadata + source links
|
||||
│
|
||||
▼
|
||||
MarkdownParser
|
||||
│
|
||||
▼
|
||||
CanonicalDocument
|
||||
│
|
||||
ProfileResolver
|
||||
│
|
||||
▼
|
||||
RenderProfile
|
||||
│
|
||||
DocumentRenderer
|
||||
│
|
||||
▼
|
||||
WordAdapter v1
|
||||
│
|
||||
┌───────┼────────┐
|
||||
▼ ▼ ▼
|
||||
DOCX bytes diagnostics manifest
|
||||
```
|
||||
|
||||
## 2. 模块边界
|
||||
|
||||
### 2.1 CanonicalDocument
|
||||
|
||||
格式无关的不可变输入,包括:
|
||||
|
||||
- 文档身份、标题、语言、项目和文档类型。
|
||||
- `section/heading/paragraph/list/table/image/callout/attachment/signature` 节点。
|
||||
- 稳定节点 ID、层级、文本、样式意图和数据类型。
|
||||
- 来源引用、置信度、可见范围和内容版本。
|
||||
- 批注、修订集合和审签快照引用。
|
||||
|
||||
Markdown 只负责表达内容;页面、字体、Word 样式名和 OOXML 不进入内容模型。
|
||||
|
||||
### 2.2 RenderProfileRegistry
|
||||
|
||||
保存规则包元数据、版本、适用范围、状态、资产和 schema 版本。职责:
|
||||
|
||||
- 精确解析 `profileId@version`。
|
||||
- 执行四级规则选择。
|
||||
- 验证文档类型、项目范围、发布状态和资产哈希。
|
||||
- 返回不可变规则快照。
|
||||
|
||||
### 2.3 DocumentRenderer
|
||||
|
||||
格式无关调度器:验证输入、解析规则、构建渲染计划、调用格式适配器、运行输出校验并生成清单。它不读项目数据库、不判断用户权限、不访问网络。
|
||||
|
||||
### 2.4 WordAdapter
|
||||
|
||||
唯一允许操作 Word 包结构的模块。负责样式、编号、分节、表格、页眉页脚、图片、书签、内容控件、批注、修订、签署区和 OPC 完整性。
|
||||
|
||||
### 2.5 RDM 编排层
|
||||
|
||||
RDM 负责项目权限、文档树、审签、规则选择、冻结提交、交付物保存和追溯关系。它把已经授权和冻结的输入交给渲染器,不让渲染器反查项目数据。
|
||||
|
||||
### 2.6 Backend 工作区交付
|
||||
|
||||
普通会话交付使用同一公开渲染入口:先保存 Markdown,再提交受限的 RenderRequest。现有 `house-style` 能力逐步迁移为公司通用规则包和 WordAdapter,不维持第二套独立语义。
|
||||
|
||||
## 3. 关键接口
|
||||
|
||||
```go
|
||||
type RenderRequest struct {
|
||||
Document CanonicalDocument
|
||||
Profile RenderProfileSnapshot
|
||||
Review ReviewSnapshot
|
||||
Mode RenderMode
|
||||
FrozenAt time.Time
|
||||
RequestedBy string
|
||||
}
|
||||
|
||||
type RenderResult struct {
|
||||
Artifact []byte
|
||||
MIME string
|
||||
FileName string
|
||||
Manifest RenderManifest
|
||||
Diagnostics []Diagnostic
|
||||
}
|
||||
|
||||
type Renderer interface {
|
||||
Validate(context.Context, RenderRequest) ([]Diagnostic, error)
|
||||
Render(context.Context, RenderRequest) (RenderResult, error)
|
||||
}
|
||||
```
|
||||
|
||||
`RenderMode` 第一阶段固定为 `working`、`preview`、`review`、`approved`。
|
||||
|
||||
## 4. 生成流程
|
||||
|
||||
1. RDM 冻结 Markdown 版本、节点映射、来源和审签状态。
|
||||
2. ProfileResolver 选择确切规则;受控文档不存在确切规则则失败。
|
||||
3. Parser 生成 CanonicalDocument,并验证稳定节点 ID。
|
||||
4. Renderer 编译声明式规则为 RenderPlan。
|
||||
5. WordAdapter 克隆受控模板包或公司通用底稿。
|
||||
6. 按 RenderPlan 写入内容和受控元数据。
|
||||
7. 运行 OPC、样式、锚点、字段、回读和安全校验。
|
||||
8. 保存字节、清单、诊断和追溯边。
|
||||
|
||||
## 5. 确定性与缓存
|
||||
|
||||
缓存键:
|
||||
|
||||
```text
|
||||
SHA256(
|
||||
canonicalDocumentHash ||
|
||||
renderProfileSnapshotHash ||
|
||||
reviewSnapshotHash ||
|
||||
renderMode ||
|
||||
adapterVersion
|
||||
)
|
||||
```
|
||||
|
||||
相同键返回同一冻结交付物。规则发布、内容修改、审签变化或适配器升级会形成新键,不覆盖旧文件。
|
||||
|
||||
## 6. 失败策略
|
||||
|
||||
- `profile_not_found`:无确切规则。
|
||||
- `profile_not_published`:规则未发布或已退役。
|
||||
- `asset_hash_mismatch`:模板、Logo、字体或图片资产漂移。
|
||||
- `required_field_missing`:文件号、版本或规则必填元数据缺失。
|
||||
- `mapping_unresolved`:Markdown 节点不能映射到模板槽位。
|
||||
- `review_state_invalid`:导出模式与审签状态不匹配。
|
||||
- `word_validation_failed`:DOCX 包、样式、锚点或回读失败。
|
||||
|
||||
错误不得触发受控文档向默认规则回退。
|
||||
|
||||
## 7. 扩展格式
|
||||
|
||||
后续 `PdfAdapter` 和 `PptAdapter` 只消费 CanonicalDocument 与各自 RenderProfile format section。跨格式共用来源、权限、版本、审签和清单;格式特有能力由适配器声明 capability,规则引用未知 capability 时拒绝发布。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user