Compare commits

...
Author SHA1 Message Date
weichen 0b16daf14a Merge Documents main into IAM U4 role authority
governance / governance (pull_request) Successful in 17s
Why: U4 must sync main before stage 7 acceptance; main carries 21 newer commits (renderer, regulations and two-trees documents). Evidence: git merge-tree reported no conflicts; no content resolved by hand. Impact: U4 documents now sit on main 5bb4877. Refs: Dev card feature-iam-u4-role-authority
2026-10-18 14:03:41 +00:00
weichen 5bb487795c Merge the EXT-20 shared regulations extension point proposal
governance / governance (push) Successful in 14s
Why: Register the U9 public contract proposal.
Evidence: CI success on 3a3904fe (governance).
Impact: Documentation only.
Refs: .task/feature-regulations-kb-ext20-proposal.md
2026-10-18 10:04:17 +00:00
weichenandCursor 3a3904fea6 Close the EXT-20 proposal task card before merge
governance / governance (pull_request) Successful in 15s
Why: Card closes in the same PR per delivery rules.
Evidence: Card only.
Impact: None.
Refs: https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/113
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 10:03:29 +00:00
agent-exec-transport 52d77f6834 agent-exec transport 236440f7dd8706d5e75570537e655d7a/1584524c456c
governance / governance (pull_request) Successful in 14s
2026-10-18 09:57:34 +00:00
weichenandCursor e4aa3c6d99 Open the EXT-20 proposal task card
Why: Register the U9 public contract proposal through the governed path.
Evidence: Card only.
Impact: None.
Refs: Agent-System-Dev feature/regulations-kb
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 09:52:14 +00:00
weichen e2f5729e8f Merge pull request 'Record the layered delivery and spec slimming proposal' (#112) from feature/delivery-model-v3-record into main
governance / governance (push) Successful in 13s
Record the layered delivery and spec slimming proposal (#112)
2026-10-17 19:56:44 +00:00
agent-exec-transport c1b0b35352 agent-exec transport c40e652385634327f58e6f1946d49604/5001e4ce8764
governance / governance (pull_request) Successful in 14s
2026-10-17 19:55:36 +00:00
weichen 6c04eb24f4 Merge pull request 'Adopt the shared governance kit (development-governance-v2)' (#110) from feature/governance-adoption into main
governance / governance (push) Successful in 23s
2026-10-17 09:25:26 +00:00
weichen acaaaa67e0 Close and archive the governance adoption card
governance / governance (pull_request) Successful in 20s
Why: the adoption PR is reviewed and its candidate HEAD passed CI; the card closure is folded into the PR so no separate close PR is needed.
Evidence: CI GATE on 9d4582a47f4f4c887afd2fafb3ad507f20716f8d; independent Review REPLAY (cursor-agent-stable --mode ask 全新只读会话(fresh_session=true,session id not-observable)闭合重审 VERDICT: APPROVE(对象 9d4582a,与 HEAD 仅 .task/ 不同)).
Impact: task card only (moved to .task/archive/).
Refs: https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/110
2026-10-17 09:22:10 +00:00
weichen 9d4582a47f docs(task): complete the card for review (sync, CI, results)
governance / governance (pull_request) Successful in 23s
2026-10-17 08:47:52 +00:00
weichen 6a1308c251 docs(task): record review repair run and evidence
governance / governance (pull_request) Successful in 17s
Why: independent Review blocked the adoption; the repair unit ran through the shared executor and was integrated with agent-exec apply.
Evidence: .task/evidence/governance-adoption/ (SELF): governance check and agent-exec validate on the repaired head.
Impact: task card and evidence logs only.
Refs: .task/feature-governance-adoption.md
2026-10-17 08:41:29 +00:00
agent-exec-transport 31daf7f764 agent-exec transport cddbee3518698a94ceaaac4d563e14d9/c95307af4fb6 2026-10-17 08:39:06 +00:00
weichen c51ae06b4d Record the adoption unit run and positive/negative evidence
governance / governance (pull_request) Successful in 18s
Why: Phase 6 requires one positive executor run and the negative cases (missing config, bad receipt, out-of-scope path, unknown side effect) before adoption becomes active.
Evidence: .task/evidence/governance-adoption/ (SELF): governance check, agent-exec validate and adoption cases; this commit passed the generated pre-commit hook (admit).
Impact: task card and evidence logs only.
Refs: .task/feature-governance-adoption.md
2026-10-17 07:40:47 +00:00
agent-exec-transport fd13a26677 agent-exec transport 8348cbe4ac5d7604985d8d0f38187573/1df0d292eafb 2026-10-17 07:40:26 +00:00
weichen cf44b1ed04 Record the failed first attempt and its reconciliation
Why: the r1 attempt ended failed-unknown (invalid terminal record); fail-stop requires reconciliation before a fresh attempt.
Evidence: receipt /tmp/gov-receipt-Agent-System-Documents-r1.json; worktree clean, no transport ref (SELF).
Impact: task card only.
Refs: .task/feature-governance-adoption.md
2026-10-17 07:37:54 +00:00
weichen d259242849 Bootstrap AGENT-EXECUTION.md and the governance adoption card
Why: development-governance-v2 Phase 6 adopts the shared governance kit in every formal repository; the executor needs a valid AGENT-EXECUTION.md before any implementation unit can run.
Evidence: generated by dm-server governance init at Development-Manager bd3a7de57a3a9e1a4495b94c5fa5c08d71e7be8c; dm-server agent-exec validate passes.
Impact: configuration and task card only; no code or CI change yet.
Refs: Agent-System-Dev docs/superpowers/plans/2026-10-16-development-governance-v2-master.md
2026-10-17 07:16:27 +00:00
weichen da4d016ee1 Merge pull request 'Record the layered Python environment proposal'
Reviewed against the layered environment plan. Required CI on the current head passed where this repository runs CI.
2026-10-15 14:24:47 +00:00
weichen 73bbb4cea6 Merge remote-tracking branch 'origin/main' into feature/layered-python-env 2026-10-15 14:01:27 +00:00
weichenandCursor 945db355fc Record the layered Python environment proposal
Why: 8788 could not render docx because the sandbox hides host site-packages and there is no request path for extra packages. The proposal fixes the design before the implementation lands.
Evidence: SELF — proposal written from the cnv_7936c0a799ff transcript and the existing exec-deps-dir code path.
Impact: Documents only. Index lists the proposal as pending review, not approved.
Refs: docs/proposals/2026-10-15-layered-python-env.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 13:29:49 +00:00
weichen f01aefa4eb Merge pull request 'Record the document duty matrix rework' (#108) from feature/rdm-duty-matrix into main 2026-10-15 09:15:11 +00:00
weichen 5f411499c5 Merge remote-tracking branch 'origin/main' into feature/rdm-duty-matrix 2026-10-15 09:14:32 +00:00
weichenandCursor 034faa4021 Record the document duty matrix rework
Why: the duty page needs one record for the four domain rulings, and the earlier settings plan must show which duty-page sections it no longer owns.
Evidence: SELF review of the proposal text against the approved implementation plan.
Impact: r1 section 4 and the duty-page parts of P5 and P7 point at r2. Settings, members, and the permission matrix stay in r1.
Refs: docs/proposals/2026-10-15-rdm-duty-matrix-rework.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 07:20:46 +00:00
weichen c0611814aa Merge remote-tracking branch 'origin/main' into feature/iam-u4-role-authority 2026-10-15 06:03:14 +00:00
weichen d668a3e0ac Merge pull request 'Record the svc plugin compose proposal' (#107) from feature/svc-plugin-compose-design into main
Why: keep the compose proposal in the document set while it remains under review.
Evidence: this repository has no workflow; head 2a8deac89d contains origin/main. Backend CI is already green and merged.
Impact: proposal status stays pending review. Inclusion is not approval.
Refs: #107
2026-10-15 03:58:32 +00:00
weichen bcdb30cc55 Plan IAM U4 acceptance and protected delivery
Why: The approved role and permission implementation needs a focused, reviewable path through browser acceptance, component delivery, and guarded closure.

Evidence: Structural audit confirms DR1-DR21, U1-U9, and KTD1-KTD6; git diff --check passes; six-lens document review findings are incorporated.

Impact: Adds the stage 7-10 plan, records the focused specification approval, and indexes the plan without authorizing production migration or deployment.

Refs: feature/iam-u4-role-authority
2026-10-15 03:53:10 +00:00
weichen e251c4bd62 Merge authoritative main before stage 7 planning
Why: base the IAM delivery plan on the current Documents main.

Evidence: fetched origin/main=87b88018b9236434b97ff6781655d625901d4090.

Impact: integrates documentation-only upstream changes before adding the U4 delivery plan.

Refs: feature/iam-u4-role-authority
2026-10-15 03:26:15 +00:00
weichenandCursor 2a8deac89d Add the svc plugin compose deploy proposal
Why: deploy needs a reviewed design for compiling selected plugins into the base binary before that behavior is treated as approved.
Evidence: the proposal records the throwaway compose build; implementation status stays unreviewed.
Impact: adds a pending proposal and an index link. Inclusion does not approve the design.
Refs: Dev .task/feature-svc-plugin-compose.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 02:03:03 +00:00
weichen 87b88018b9 Merge pull request 'Record U1-U6 completion and owner-blocked exit in the DHF plan' (#106) from feature/dhf-u5u6-progress into main 2026-10-14 18:12:19 +00:00
weichen 136534ce0d Record U1-U6 completion and owner-blocked exit in the DHF plan
Why: the plan's progress annex still described the pre-adjudication
state (44 needs-review, U2-U6 pending); the authoritative record must
reflect the 2026-10-14 landing: batch adjudication, publication flip
(44/44 published), U5 product-loop wiring with pilot pass, U6
per-identity matrix (41 PASS + 2 EXPECTED_BLOCKED + 1 EXPECTED_LIMITED),
and the owner-side exit items (deployment pilot, independent REPLAY,
U4 originals) now blocked on the owner per the handoff checklist.

Evidence: docs-only change in the Documents repo; all referenced RDM
PRs (#377/#381/#383/#385/#387/#389/#391) carry green CI and merged
state; pilot and matrix outputs are recorded in the RDM task cards and
docs/records/dhf/.

Impact: plan annex only; no code or asset change.

Refs: RDM docs/records/dhf/package-review-decision-2026-10-14.md;
RDM docs/records/dhf/u6-acceptance.md; u6-replay-handoff.md
2026-10-14 18:10:20 +00:00
weichen e9ce9a539e Plan the focused role and permission implementation
Why: The approved scope spans Backend authority, RDM project enforcement, and Frontend configuration and needs exact contracts and verification boundaries.

Evidence: The plan was checked against every specification section, fixed interface names, failure cases, and placeholder rules.

Impact: Implementation is limited to one effective role, system and project authorization, and the requested configuration views.

Refs: Focused role and permission system spec
2026-10-14 16:42:24 +00:00
weichen d77c6425bc Define the focused role and permission system
Why: The implementation scope must match the requested single-role position model and three permission layers without carrying unrelated IAM work.

Evidence: The spec was checked for placeholders, internal contradictions, and whitespace errors.

Impact: Backend becomes the role authority while RDM retains project permissions and document duties.

Refs: IAM role and permission system
2026-10-14 16:37:01 +00:00
weichen 19aa34efe6 Merge pull request 'Record approved manual merge queue expansion plan' (#105) from feature/merge-queue-manual-phase2-plan into main 2026-10-14 14:32:01 +00:00
weichen a665c2d0b9 Record approval of manual expansion plan
Why: Preserve the owner’s Stage 5 decision and implementation method on the reviewed plan object.

Evidence: Owner approved plan 28c4ceb in the task conversation; git diff --check and relative links passed (SELF).

Impact: Documentation status only; Dev implementation remains subject to Stage 6 and 7 review.

Refs: Agent-System-Documents #105; Agent-System-Dev #518
2026-10-14 14:31:48 +00:00
weichen 28c4ceb173 Plan controlled manual merge queue expansion
Why: The approved Stage 4 design needs a reviewable Stage 5 implementation and test sequence.

Evidence: git diff --check, relative-link validation, M2-1 through M2-6 coverage, and placeholder scan passed (SELF).

Impact: Documentation only; no Dev queue activation or task takeover.

Refs: Agent-System-Documents #104; Agent-System-Dev #518
2026-10-14 14:29:48 +00:00
weichen 8e3b5b0d28 Merge pull request 'Record approved manual merge queue expansion design' (#104) from feature/merge-queue-manual-phase2-design into main 2026-10-14 14:27:46 +00:00
weichen 77c8cc2548 Record approval of manual merge queue expansion design
Why: Preserve the owner’s Stage 4 conclusion against the reviewed design object.

Evidence: Owner approved Documents PR #104 design aa4d372 in the task conversation; git diff --check passed.

Impact: Design only; Stage 5 implementation and test plan remains unapproved.

Refs: Agent-System-Documents #104; Agent-System-Dev #518
2026-10-14 14:26:28 +00:00
weichen aa4d372f01 Describe controlled manual merge queue expansion
Why: The first trial reduced final CI churn, while later Dev merges exposed gaps in shared window records that must be addressed before broadening manual coordination.

Evidence: SELF Gitea API snapshot for PR #539–#548, current #518 comments, protection and open PR states; fixed first-trial report and current project rules reviewed.

Impact: Add a stage-4 design and evidence snapshot only; no queue activation, platform protection change, production task takeover, or workflow edit.

Refs: Dev issue #518; Documents 2026-10-14 merge queue trial report
2026-10-14 14:20:34 +00:00
weichen 5909cb37cf Merge pull request 'Record merged state of the first U1 increment in the DHF plan note' (#103) from feature/dhf-plan-progress-note into main 2026-10-14 09:53:20 +00:00
weichen 46506aec34 Record merged state of the first U1 increment in the DHF plan note
Why: the progress note still listed Documents #102, RDM #365 and Dev
#540 as WIP and said the stage-8 review was under rectification, but all
three PRs merged on 2026-10-14 and the Dev task card is archived; the
note must state the terminal state instead of stale WIP/GATE caveats.

Evidence: merge SHAs 9062445 (Documents), 57d2214 (RDM), 11aa76a (Dev)
per the archived card .task/archive/feature-dhf-template-pipeline-plan.md
(Dev #542); this change is documentation-only and does not touch the
frozen r0.1 body or its recorded SHA256.

Impact: readers of the plan see the merged terminal state and the
remaining U1/U2-U6 exits; no requirement or scope change.

Refs: Dev task feature/dhf-plan-progress-note
2026-10-14 09:17:45 +00:00
weichen 9062445db8 Merge pull request 'Record the approved DHF plan and asset inventory' (#102) from feature/dhf-template-pipeline-plan into main 2026-10-14 08:03:33 +00:00
weichen 6619835a65 Record approved DHF implementation status in the main plan
Why: The approved plan remained an earlier review snapshot and contradicted the index and task card after U1 implementation began.

Evidence: The pre-decision r0.1 file hash is f99e1424; the additive dated note preserves that text and records owner stage 6/7 decisions, four package reviews and remaining gates.

Impact: Documentation status only; no asset or product behavior change.

Refs: docs/proposals/2026-10-14-dhf-template-generation-plan.md
2026-10-14 07:33:07 +00:00
weichen fdca353097 Merge remote-tracking branch 'origin/main' into feature/dhf-template-pipeline-plan 2026-10-14 06:36:43 +00:00
weichen 2d35cd49c2 Merge pull request 'Record the controlled merge queue trial' (#101) from feature/merge-queue-trial-report into main 2026-10-14 04:51:47 +00:00
weichen 3e0cdae1bf Record the controlled merge queue trial
Why: The approved U6 plan requires a reviewable account of three real serial deliveries, CI costs, recovery paths, and manual adoption limits.

Evidence: Dev #489/#488/#486 fixed-head Actions runs 3038/3050/3067 and main runs 3040/3053/3068; component PRs and Issue #518 preserve raw SELF and independent REPLAY.

Impact: Document observed behavior and untested automatic coordination boundaries without changing product code or declaring rollout authority.

Refs: Dev issue #518; merge queue implementation plan U6
2026-10-14 04:48:22 +00:00
weichen c256558ca8 Record approved DHF implementation progress
Why: Keep the planning index aligned with the approved scope and actual U1 results.

Evidence: The RDM branch saved the 44-asset catalog and E1 receipts; exact candidate fidelity remains under human review.

Impact: Documentation status only; no template is published and no runtime behavior changes here.

Refs: DHF plan r0.1; RDM feature/dhf-template-assets@6af4497
2026-10-14 03:21:21 +00:00
weichen 8e9587ca1d Preserve the approved DHF integration plan
Why: Keep the owner-reviewed scope and asset evidence available for implementation.

Evidence: Plan review and SELF document/source receipts are recorded in the Dev task card.

Impact: Documentation and asset inventory only; no product behavior changes.

Refs: DHF plan r0.1; owner approval to begin implementation
2026-10-14 01:52:56 +00:00
weichen 7bd4e17827 Merge pull request 'Record the approved U8, U7, and export status' (#89) from feature/u8-u7-rdm-export-status into main 2026-10-14 01:15:10 +00:00
36 changed files with 3459 additions and 4 deletions
+150
View File
@@ -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 .
+6
View File
@@ -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,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)逐项核对,无阻塞项。
- 影响与剩余项:仅文档。
+66
View File
@@ -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;放弃路径注明原因>。
+67
View File
@@ -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"
```
+20
View File
@@ -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` 集成。
+5
View File
@@ -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 行。
Vendored Submodule
+1
@@ -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,313 @@
---
title: DHF 模板接入 RDM 文档生成管线 - Plan
type: feat
date: 2026-10-14
artifact_contract: ce-unified-plan/v1
product_contract_source: legacy-requirements
origin: 2026-10-11-rdm-template-dialog-generation.md
execution: code
---
# DHF 模板接入 RDM 文档生成管线 - Plan
## 批准与实施进展(2026-10-14 后续附注)
本节记录批准后的状态;下方 r0.1 主文保留批准前评审快照,原对象 SHA256 为 `f99e1424a9bb86f68ad6de91657102a36004c61fb0f36c8427e913d9e0cf9643`。主文中的“草案”“待批准”“本轮 NOT_RUN”指当时状态,不代表今日仍未获实施授权。
- owner 已批准 r0.1 的需求、方案和实施计划并授权 U1–U6 按阶段推进,另批准 E1-R1 隔离追加试验。U1 当前增量已走完阶段 6–10:阶段 6/7 获 owner 人工结论,独立 Review 闭合整改,最终 HEAD 的 GATE 与独立重放核验记录在案,三份交付 PR 均已合入。
- RDM 已封装 44 个逻辑原件,owner 分别接受项目建议书、F01、F02、DI 四份确切四哈希包(内容与版式接受,正式发布授权仍未给出);全部 44 项仍 `needs-review`,正式发布数 0。E1/E1-R1 使 14 DOC 均有转换候选,但逐项 Word 保真 **NOT_PASSED**;其余 40 项待包级裁定。F01/F02 的正式类型/存量字典升级及 U2–U6 真实产品流程仍未完成。
- U1 当前增量的终态以归档任务卡为准:Dev 仓 `.task/archive/feature-dhf-template-pipeline-plan.md`(随 Dev #542 归档合入)。合入记录:[Documents #102](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/102) merge `9062445db808`、[RDM #365](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/365) merge `57d2214feb0a`、[Dev #540](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/540) merge `11aa76a3bc1c`,三个 main 树各自与受测 head 一致。U1 剩余 40 项包级裁定、14 DOC 保真对照、类型合同与 U2–U6 按本方案顺序继续;此前 WIP/待整改表述与旧 GATE 不再作为放行依据。
- **2026-10-14 收口(本轮)**:批量 1–5 包级裁定获 owner「全部按推荐」批复并落档(RDM `docs/records/dhf/package-review-decision-2026-10-14.md`);其余 DOC 11 份(#377)与 DOCX 17 份(#381)四哈希候选包合入,44/44 具备候选包;owner 同轮授权 catalog 翻转,#383 将 44 项全部置 `published`+confirmed+绑定四哈希+issues 全清。U5 交付命令接线与实例播种随 #385 落地,真实产品二进制全链路试点 PASS;U6 逐项验收矩阵随 #387 完成——44/44 入账=41 PASS+2 EXPECTED_BLOCKED(F01/F02 字典门禁,owner 裁定暂缓)+1 EXPECTED_LIMITED(无槽位确认报告,空填充 fail-closed 拒绝实测),0 FAIL;过程中修复 F05/F06 封面双层嵌套缺陷并补登记 11 个批量裁定 docType。卡片 #379/#382/#384/#386/#388/#390/#392 全部归档,RDM main `c5ea0f5`。交接文档 [u6-replay-handoff.md](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/branch/main/docs/records/dhf/u6-replay-handoff.md) 固化 owner 侧三项动作:①部署发布包+三用户真实试点(回传导出 Word SHA256 与审签元数据);②独立审阅者以一键驱动 `scripts/dhf-u6-replay.sh` 完成 R1–R4 重放并签署(作者 SELF 试运行全绿,审阅者重跑方为 REPLAY);③提供带附件/页眉页脚的真实原件路径以启动 U4。独立 REPLAY 与真实环境试点完成前,本方案 DoD 的「试点交付/全量交付」两项维持 owner 阻塞态。
修订 r0.1;需求负责人 weichen;方案编制 Codex;各仓实施负责人待立项指定。
本文件是 DHF 接入专项的评审草案,授权终点为源码/资产调查、方案和计划文档、记忆归档。
需求取舍、设计、实施和测试计划仍须按 Dev `policy/delivery.md` 逐阶段评审;本文不授予业务实施、转换试验、迁移、发布或部署权限。
文件路径以目标仓为准:`Dev:` 为 Agent-System-Dev,`RDM:` 为 Agent-System-RDM,`Frontend:` 为 Agent-System-Frontend;无前缀为 Documents 仓。
## Goal Capsule
用户能在 RDM 项目对话中,按提供的 DHF 标准模板编制文档,取得内容有依据、格式可核查、审签版本一致的 Word 文件。
采用现有 RDM 模板、两树一网、持久提案和三权流程,补齐 Word 资产解析、固定绑定和模板填充导出。
本批最终覆盖 Dev `.templates/DHF 文件模板/` 全部 44 份逻辑资产;试点成功只代表试点完成。
首选下一步是评审范围及解析试验 E1;E1 的 DOC 保真结果是全量接入的前置条件。
---
## Product Contract
### Summary
将 44 份 Word 原件转为可审核发布的模板包,使其内容结构、填写规则和原始版式共同约束文档生成。
先用真实 DHF 项目建议书完成一条用户闭环,再按文档族接入全部资产;设计输入规格书和验证确认报告同时作为结构与示例语义的压力样本。
登录恢复为已收官基线;本专项不把部署增强或账户恢复重新列作遗留实现项。
### Problem Frame
RDM 当前注册量不能代表标准模板可用量。
已有模板选择、章节实例化和导出器缺少共同的模板身份,新增 Word 文件后仍可能生成错误用途的正文,或者丢失原件的表格与排版。
模板中的示例测试结果和签署意见还可能被误当作本项目已经发生的事实。
### Current State
本轮源码/资产观察为 SELF,业务测试、DOC 转换、真实模型、浏览器验收、CI 和部署均为 NOT_RUN。
调查对象:Dev R0 `add097d06137c4912a4ed9279e98ca353e4e4cf1`;RDM `6fcb256205c2384abed35d3b6ab96ca7216e9297`;Documents 草案从本轮 SSH/API 同值的 main `7bd4e17827d4c7c88647bf3c9199c495b60cb107` 建立。
RDM 正式产品的 Frontend gitlink 与实际检出均为 `eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b`;该源码基线用于定位当前预览行为,不代表组合浏览器验收。
Dev 固定 Documents 的 `a7ff466…` 与本轮 Documents main 不同;本轮只保存规划,不推进 gitlink,未来集成须处理两条历史及规范差异。
源码/资产原始输出与完整 SHA 由 Dev 任务卡的 evidence 段记录;以下是静态分析,不是运行通过声明。
| 对象 | 当前事实 | 接入含义 |
|---|---|---|
| DHF 原件 | 44 份:30 DOCX、14 DOC,7 阶段;41 个不同 SHA256 | 同内容不同阶段仍保留独立逻辑用途 |
| RDM 目录 | 69 个 docType,73 项 registry:4 定制 Markdown+69 骨架 | 骨架含“内容要求待补”,不算 69 份标准正文已迁入 |
| Word 原件 | RDM 未跟踪 DOC/DOCX 原模板 | 需要可脱离 Dev 工作目录的正式资产包 |
| 现有解析 | DOCX 主要读 document.xml,DOC 不支持 | 不能用文本抽取代替完整内容和版式解析 |
| 模板选择 | Compose 按适用列表首项选 key;rd_proposal 首项为 weekly-report | 必须消除注册顺序决定正文用途 |
| 结构实例化 | 独立 structure YAML 建文档/章节,无公开的按模板实例化命令 | 模板发布、文档创建与生成入口需要接成一条路径 |
| 固定版本 | Doc/Section/Version 未存真实模板绑定;提交的 TemplateVersion 实为字典版本 | 当前快照无法证明 Word 模板身份不漂移 |
| 审签与提案 | 有事务采纳、幂等、持久提案及整文三权 | 扩展既有机制,不重写审批和项目权限 |
| DOCX 导出 | 新建最小 OOXML,不消费原件版式;未按指定整文审批轮次导出 | 需要原模板填充和批准快照再现 |
| 用户入口 | 自然语言写文档 intent 用错 docType 且仅查询模板;正式 Web 使用 Frontend pin | 真实对话、工具 schema 与正式 React 产品均需验证 |
资产阶段分布:商务 1、策划 3、设计输入 15、设计输出 9、设计验证 8、设计转换 3、设计确认 5。
四份输出/验证/转移/确认评审原件字节相同,但不能合并为一份逻辑模板。
候选适配为 32 份映射既有类型、12 份新增或细分用途待评审;不等同于批准新增 12 个类型。
### Requirements
资产与内容约束:
| ID | 要求 | 可判定验收条件 | 来源 |
|---|---|---|---|
| R1 | 44 份原件逐份登记来源、用途、版本和状态 | 每个路径有完整 hash 和处置;重复内容保留逻辑用途;未验证项不可标可用 | 本轮范围;TT-T01/T04 |
| R2 | 保留真实多级结构、表格、填写规则与关键版式 | 对照每份原件无关键静默丢失;DOC 的解析/转换差异有人工裁定 | TT-T01/T02;现有模板方案 R3/R11 |
| R3 | 示例、说明、占位符与固定文本分别处理 | 无真实证据时不预填验证成功、样本量或签署;模板内产品示例不进入项目事实 | 原件填写说明;原方案 R6 |
| R4 | 模板用途和项目适用性明确 | 选择显式正文模板;计划/报告、验证/确认用途不混用;不适用部分注明理由 | TT-T03;原方案 R1/R3 |
生成与受控交付:
| ID | 要求 | 可判定验收条件 | 来源 |
|---|---|---|---|
| R5 | 新实例及历史内容固定实际模板身份 | templateId/version 与原件、结构、渲染包的完整 hash 可复核;升级不改旧版本 | TT-T04;原方案 R3/R9 |
| R6 | 用户能从项目对话创建或更新模板文档 | 真实认证总线到实例化、生成、提案、采纳;歧义先澄清;总结请求不触发写入 | 原方案 R2/R7/R13 |
| R7 | 生成和下载遵守现有项目、资源和文档职责 | 仅指定编制人生成/采纳;检索与模型输入授权;恢复、撤权及下载再次核验 | 原方案 R4/R9/R11 |
| R8 | 模板、正文、依据和审签使用同一冻结对象 | 旧卡片/并发/模板退役均不能覆盖新内容;正式导出读取指定批准快照 | 原方案 R5/R7/R8/R9/R11 |
| R9 | 完成状态以实际 Word 与用户流程验收为准 | 每个发布模板至少一个正常样例及一个空缺/冲突样例;44 份全部有结果 | 原方案 R12;TT-V01–03 |
### Scope Boundaries
本专项承接在途 `feature/rdm-two-trees-latest-templates` 的 TT-T01–04,依赖其 TT-D01–04 的递归结构、结构提案和版本保护。
该任务已形成阶段 2 评估;本轮读取的记录仍待人工评审,不把其文字升级为实施批准。
两个任务只能有一处权威模板/内容块契约和一份 44 资产台账;实施立项前指定契约 owner,按共同 R0 分工,禁止各做一套树或升级机制。
原两树一网任务其余需求继续由其主记录维护,本专项的聚焦不削减那 28 项完整范围。
### Deferred to Follow-Up Work
未提供新标准原件的其余 37 个既有类型保留兼容和明确状态;不以本批 44 份宣称覆盖全部 69 类型。
历史报价 XLSX 不在本批 Word 接入范围;全局项目字典扩展、默认成员工作上下文、完整审计展示继续归原两树专项。
`-open-existing` 修复和 U2/U3 部署增强保持独立新需求。
旧项目批量改绑、运行库迁移和上线需独立方案与授权,本轮不启动。
### User Flow
用户在可信项目对话中提出“按 DHF 模板生成项目建议书”;系统确认目标文档、用途和已发布模板。
已有同类文档时展示更新目标;缺职责时等待负责人分配,由指定编制人接续。
模板不适用、资料不足或用途歧义时保留待处理状态,不能退回任意骨架继续生成。
生成任务使用已固定且有权使用的项目依据,返回逐块内容、来源、差异和缺项;编制人采纳后才形成内部版本。
审核和批准绑定整文快照;草稿与正式版可区分地预览/下载,正式 Word 从指定批准快照和固定模板包生成。
---
## Planning Contract
### Key Technical Decisions
KTD1. 将原件、结构合同、渲染包组成同一个不可变模板发布版本;登记阶段/用途、适用规则和来源谱系。
原件永久保存;DOC 转换产物是派生件,记录转换器版本/配置及产物 hash。
默认模板只能从人工确认的显式绑定取得;语义版本比较替代字符串最大值,骨架显示“待标准模板”,不得混成已发布 DHF。
共享模板/默认绑定治理沿用[原模板方案 KTD1](2026-10-11-rdm-template-dialog-generation.md#ktd1-template-contract-and-authority)的获批仓库发布边界;本专项不开放运行时模板管理权限。
KTD2. Word 在资产准备阶段规范化为 DOCX,运行时不新增 LibreOffice 服务依赖。
先复用在途 E1 的隔离试验,验证 DOC→DOCX 的可行性与损失;不得直接把 DOC 二进制当字符串或重命名扩展名。
建议方法受官方格式与转换接口支持,但本批保真尚未验证:[MS-DOC 格式](https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-doc/ccd7b486-7881-484c-a137-51170af7cc22)、[LibreOffice 转换参数](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)。
E1 先检验用户需求、软件测试用例、采购技术说明三种 DOC 样本,再覆盖全部 14 份;失败项保留未验证,不能降低 R2。
本轮 PATH 未找到 LibreOffice/soffice;固定工具版本、隔离环境和试验授权仍是前置条件。
E1 使用独立转换器 profile、只读原件和隔离临时输出,禁用宏、外部内容加载和网络;转换进程不得访问用户凭证或运行库。
KTD3. 结构合同采用原两树专项的递归内容块,模板只定义其约束和 Word 槽位映射。
块具有稳定 ID、层级、顺序、填写语义、字段/重复行/合并关系、依据需求、适用性和附件引用;显示标题不作为身份。
解析综合样式继承、outlineLvl、自动编号、正文顺序和表格关系,人工确认其业务含义。
蓝字、斜体、黑字只是分类线索;预填的 IQ/OQ/PQ 成功、样本量 22 和“同意”意见必须按 R3 处理。
KTD4. 扩展现有领域对象、事件 payload 和 replay,固定模板绑定及每次生成的内容/依据基线。
增加 RDM 领域的按模板实例化与生成编排入口;既有 compose/propose/adopt 适配到同一约束,不建立第二个提案或审批库。
实例化事务创建文档、内容块和模板绑定;确认/采纳使用预期版本、opId 幂等和事务内复验。
生成任务保存输入清单与候选,失败可恢复;恢复重新验证权限及模板可用性,缺少依赖时返回明确待处理结果。
KTD5. DOCX 采用固定原模板包的槽位填充渲染,结构化内容是业务正文权威。
保留原件的封面、页眉页脚、样式、编号、图片和非填充部件,确定性填充已标记的段落/单元格/重复行。
发布检查识别会自动读取外部内容的关系;派生渲染包禁止保留外链图片加载,普通引用链接保持可审查的文本/超链接语义。
本批《原材料进货检验规范》的图片同时有内嵌 rId11 和外链 rId12;派生包保留内嵌图片,移除 rId12 关系及对应 r:link,原件不变,处置进入差异台账。
只有外链而无可保全本地内容时阻止发布,不能静默删图或自动下载补齐。
原模板包不得直接把示例结论保留为实例结果;签署区域只映射真实审签元数据,不生成手写签名。
提交快照冻结真实模板 binding、内容块/章节版本、依据和渲染器版本;导出明确选择草稿或某一批准快照,不能读取各章当前最新版拼装。
批准 Word 首次生成后,字节、完整 hash、固定输入与精确批准快照持久关联,随批准历史保留;现有短期导出工件的 24 小时寿命不能作为该文件的保留策略。
采用 RDM 自有的受控导出产物仓储,复用现有文件/hash 完整性机制,下载权限使用 `doc_export_visibility.go` 的受控正文授权,区分短期导出和批准历史文件;下载链接可短期失效,批准文件不能因此删除。
批准后排队生成并保存该交付物,生成失败不回滚已批准的文档状态,文件状态保持待生成或失败;固定输入的幂等重试保存完整文件及关联后才可声明文件就绪。
同一快照再次取得文件返回原批准字节;首次生成或获准重建只能使用可执行的固定渲染版本,相关模板包/槽位映射缺失、原件 hash 不符或旧渲染路径不可执行时明确阻塞,禁止自动改用新版渲染器。
软件升级和例行清理必须保全批准文件及关联;结构化内容仍是业务权威,存档 Word 是对应快照的固定交付物。
现有仅含字典版本的历史快照不补造模板身份;继续按旧导出路径提供并标明历史格式,不能宣称新 DHF 保真。
KTD6. RDM 持有领域模板与生成/导出逻辑,Frontend 持有正式用户界面。
对话、工具及工作区消费同一服务端对象和状态;修正错误 intent 参数,并公开合法的模板绑定和提案 schema。
正式产品必须检验 Frontend 发布版本和 RDM pins 的组合;仅修改 RDM `web/app.js` 不算正式产品交付。
按 Dev DESIGN 复用三栏、卡片与唯一文件预览,界面消费令牌和已有原语;文档纸面保留原件自己的字体和颜色。
预览明确区分页式视图、版式降级的内容视图和无法读取;页式渲染失败时显示“版式预览不可用,当前仅展示内容”,保留同一 Word 文件的下载入口供核对,不把内容视图当作格式验收。
仅当已批准路径无法由公开扩展点实现时,向基座提交四要素扩展申请;禁止改 RDM pins 或导入 Backend internal。
### High-Level Technical Design
以下图示规定权威和流向;具体类型名、函数及路径由实施时确定。
```mermaid
flowchart LR
O[44份只读原件] --> N[DOC规范化与差异核对]
N --> T[固定模板包: 原件/结构/槽位]
T --> I[可信项目与按模板实例化]
K[授权知识与原文版本] --> G[逐块生成和校验]
I --> G
G --> P[持久提案和差异]
P --> A[编制人采纳: 事务/CAS]
A --> S[整文提交/审核/批准快照]
T --> E[固定模板填充导出]
S --> E
E --> F[同一文件预览和下载]
```
```mermaid
stateDiagram-v2
[*] --> Imported
Imported --> NeedsReview: 结构/语义/版式待确认
NeedsReview --> Published: 资产评审通过
NeedsReview --> Blocked: 关键丢失或用途不明
Blocked --> NeedsReview: 有依据的修正
Published --> Retired: 受控退役
```
```mermaid
sequenceDiagram
actor A as 编制人
participant C as 对话/工具
participant R as RDM领域服务
participant D as 事务与事件库
participant E as Word导出
A->>C: 指定项目/目标/模板
C->>R: 可信主体与明确绑定
R->>D: 实例化及生成输入快照
R-->>A: 候选、差异、缺项与来源
A->>R: 采纳固定提案
R->>D: 权限/版本复验,原子提交
Note over R,D: 三权审签后冻结整文及真实模板
A->>R: 导出指定批准快照
R->>E: 固定内容与模板包
E-->>A: 经授权的文件预览/下载
```
### Dependencies and Open Questions
实施启动阻塞项:本轮范围与取舍评审、在途两树任务契约 owner、44 份逐项阶段/type/用途映射、E1 授权与 DOC 保真结果、原件内容分类及导出槽位合同。
特别是 F02《验证确认报告》虽位于设计验证目录,正文是过程 IQ/OQ/PQ 确认,须由业务负责人裁定用途,不按目录自动映射。
导出关键版式以 R2 为底线;允许的字体替代和跨 Office 分页差异在 E1/样例评审中逐项确认,不承诺像素一致。
源模板中的企业信息、示例产品名和标识需人工分类为企业固定项或项目替换项;无人确认时保持待发布。
具体 helper 名称、序列化细节和测试夹具目录由实施者确定;不得用这些细节延后上述业务裁定。
---
## Implementation Units
以下 U-ID 只属于本专项;均为待批准工作,不代表 E1 或任何业务实施已启动。
### U1. Asset Contract and Conversion Proof
覆盖 R1–R4;先与 TT-T/TT-D 的 owner 固定共享契约与台账。
Files:RDM `internal/rdmapp/templates/`、`templates.go`、`templates_embed.go`;新增 `docs/records/dhf/` 台账及 `template_asset_contract_test.go`(拟定);Dev 原件保持只读。
产物为 44 份完整谱系、用途/适用性映射、内容分类、保真差异台账和已评审结构/槽位规范。
先用项目建议书 DOCX 完成内容模型;设计输入规格书及 F02 报告校验多级结构与示例语义,复用 E1 覆盖全部 DOC。
验证场景:损坏/加密/不支持对象拒绝发布;重复 hash 不吞用途;混合标题/编号正确;黑字假结论不能成为项目结果;每个 DOC 关键差异有判定;外链图片处置后内嵌图完整且导出无自动外部内容读取。
出口:44 份处置明确,全部 14 DOC 方法可核验;未通过资产保持阻塞,不能进入全量发布。
### U2. Published Template Binding and Instantiation
依赖 U1 共享契约;覆盖 R1/R4/R5/R8。
Files:RDM `templates.go`、`structure.go`、`internal/domain/doctree.go`、`payloads.go`、`replay.go`、`plugins/rdm/plugin.go`;新增 `dhf_template_instance_test.go`(拟定)。
增加发布模板包与明确默认用途,原子创建文档/块/真实模板 binding;内容块复用 TT-D,不按标题去重代替身份。
验证场景:v2/v10 选择、周报与建议书同 docType、缺包/hash 错误、退役、重复创建、跨项目、更名同名章、失败回滚及重启重放;模板升级不会覆盖旧实例。
出口:无 Dev 源码目录的构建制品可实例化试点模板;新对象与历史对象有明确兼容路径。
### U3. Evidence-Based Generation and Confirmed Adoption
依赖 U2;覆盖 R3/R6–R8。
Files:RDM `compose.go`、`draft.go`、`draftproposal.go`、`plugins/rdm/plugin.go`;扩展 `compose_test.go`、`draftproposal_test.go`、`plugins/rdm/intents_test.go`。
修正 intent 和总线 schema;按块要求组织有权依据,结构化生成并校验,复用持久提案/事务采纳;同时落实 Compose 的指定编制人门禁。
验证场景:真实自然语言请求从正确模板到提案;无资料、示例黑字、适用条件冲突均诚实留缺;未分配职责、非编制人和私人未发布资料拒绝;并发采纳、重复点击、取消、断连/恢复及撤权结果可查且不重复生效。
出口:项目建议书有固定来源的完整候选和内部版本;无证据的测试/验证字段仍空缺或注明未执行。
### U4. Approved Snapshot and Word Fidelity
依赖 U2/U3;覆盖 R2/R3/R5/R8/R9。
Files:RDM `docsubmission.go`、`docx.go`、`doc_export_visibility.go`、`export_artifact.go`、领域快照 payload/replay;扩展 `docx_test.go`、`plugins/rdm/doc_submission_test.go`;新增 `dhf_docx_fidelity_test.go`(拟定)。
冻结真实模板及渲染版本,补整文快照选择;实现原 OOXML 槽位填充、重复行和附件映射及批准 Word 持久关联,旧导出语义独立兼容。
验证场景:审核中改正文被拒、提交后模板更新/退役、批准后当前章变化、历史批准轮次重导出、槽位重复/缺失、长表格跨页、合并关系、编号、图片、页眉页脚、中文字体、非法 XML;无真实签署不填意见;下载撤权立即拒绝。
跨版本验收:旧版批准/导出→超过短期工件 TTL→升级并更换渲染实现→取得同一轮次 Word,字节 hash 与原批准文件一致;下载仍按当前权限判断。原批准文件损坏或丢失且固定渲染版本不可执行时明确阻塞,不生成外观相近的新文件冒充历史产物。
故障验收:生成失败不改变审批结论;写文件与关联记录部分失败不发布就绪文件,重启后可查并幂等恢复;文件下载采用正文职责权限,普通审计权不扩大文件读取范围。
出口:三用户完成试点审签,Word 内容/依据与批准快照相同,关键版式对照通过;ZIP 非空或可打开仅为辅助检查。
### U5. Formal Product Path and Offline Package
依赖 U3/U4;覆盖 R6/R7/R9。
Files:RDM `scripts/build-product.sh`、`scripts/pack-release.sh`、`templates_embed.go`、`templates_embed_test.go`;Frontend `src/previewsetup.ts`、真实对话卡片/文件预览/API 与相关浏览器用例(其余路径实施前按当前发布版定位)。
统一包内模板路径、读取路径和 hash 校验;对话与辅助工作区复用同一任务/提案/快照,交付正式 Frontend 版本后由 RDM 正常消费。
验证场景:真实 auth-on 两项目三用户,关闭右栏完成编制,刷新/重启/撤权/旧卡片;脱离源码运行同一制品,资产缺失/摘要错误拒绝;原模板字体/颜色在预览保留;页式渲染失败明确降级,完全无法读取显示错误及下载入口;证明浏览器使用精确 Frontend SHA。
出口:项目建议书在正式产品完成全流程,固定组合 CI 与独立重放齐备;静态工作台或桩测试不能替代。
### U6. Complete All DHF Families
依赖 U1–U5 试点通过;覆盖 R1–R9。
Files:RDM 模板包、registry、映射台账及每文档族的内容/Word 回归样例,复用 U1 的唯一资产台账。
顺序为策划/输入→输出→验证/确认→商务/转换及剩余评审;DOC 规范化与 DOCX 内容整理可在同一契约下并行,发布仍逐批评审。
每份模板至少运行一个有材料的完整样例和一个缺证据/冲突样例;报告类只使用实际提供的验证记录,不能生成执行记录。
出口:44 份逐资产结果齐全,声明可用者通过真实生成/采纳/审签/导出;未解决项显式保留,本目标不能标全量完成。
---
## Verification Contract
验证在后续批准的阶段执行;本轮只能做原件/源码阅读和文档一致性检查。
实施期先补关键链路的行为测试,再扩展原有实现;正式验收遵循 Dev evidence、精确组件 SHA、CI GATE 与独立 REPLAY 门禁。
| 证据层 | 对象与方法 | 硬判据 |
|---|---|---|
| 资产 | 44 份路径、原件/派生/结构/渲染 hash、DOC 差异和业务分类 | 44/44 可追溯;原件不变;关键结构/语义/格式无静默丢失 |
| 领域 | RDM 模板/实例/提案/审签/事件重放测试 | 固定绑定、CAS/幂等、失败全回滚、历史再现,负向越权为零 |
| 真实总线 | 意图→schema→认证主体→实例化/生成/采纳/导出 | 用合法 docType/templateRef;工具暴露参数和处理器一致 |
| 模型行为 | 固定真实素材、原件和任务,人工审核正文与引用 | 不编造事实、样本量、执行记录、结论或签署;缺项明确 |
| Word | OOXML 核对+真实 Office/LibreOffice 打开+人工原件对照+升级后历史文件重取 | 内容/表格/合并/编号/图片/页眉页脚/关键样式与固定快照一致;批准历史文件不受短期 TTL 清理 |
| 正式浏览器 | 真实 auth-on 三用户两项目、对话/卡片/预览/下载、重启/撤权 | 完整用户流程,文件可读可下载,职责/私域隔离有效 |
| 安装制品 | 固定 RDM/Frontend/Backend pins 与模板包,源码外运行 | 无 cwd 依赖;读/打包路径同值;错包拒绝,不回退到骨架 |
RDM 的现有 `make test`、product build、模板/提案/审签测试用于回归;Frontend 使用相关浏览器测试;Dev 有 gitlink 改动时执行组合 `make test` 和 `make build`。
正式以各 PR 当前 HEAD 的必需 CI 为准;原件盘点 SELF、模型自评和历史绿色 CI不能代替当前验收。
生成耗时、费用和人工修订量先建立试点基线,再确认目标;本轮不编造工期或质量评分。
## Definition of Done
规划交付:范围、源码基线、44 资产特点、技术决策、依赖、工作包、验证和阻塞项可审查;未批准及未执行阶段明确。
试点交付:真实 DHF 项目建议书在正式产品,经三用户完成生成/采纳/审签/按快照 Word 导出,精确组合证据齐备。
全量交付:U6 达到 44 份逐资产验收,原两树任务的共同契约和台账同步;试点或 registry 数量不能替代。
上线交付:另行确认实例、制品和迁移范围,按批准窗口部署并运行验收;本方案完成不等于上线。
## Appendix
主要源码:RDM `internal/rdmapp/templates.go`、`templates_gen.go`、`templates_embed.go`、`structure.go`、`parse.go`、`compose.go`、`draftproposal.go`、`docsubmission.go`、`docx.go`、`plugins/rdm/plugin.go`、`scripts/build-product.sh`。
本轮资产证据索引:[44 份原件的路径/hash/结构特征及源文件摘要](../records/2026-10-14-dhf-assets.json);完整命令输出以 Dev 任务卡 evidence 为准。
上游来源:[原模板生成方案](2026-10-11-rdm-template-dialog-generation.md)、[最终目标方案](2026-10-11-rdm-final-target-completion.md)、[两树一网方案](2026-10-11-rdm-two-trees-trace-audit-integration.md)及在途 `feature/rdm-two-trees-latest-templates` 阶段 1/2 记录;旧“四模板”盘点只作历史。
登录收官来源:Dev `docs/svc-deploy/2026-10-13-login-recovery-contract.md` 的最后一项为“完成”,PR #516 已合入;owner 于 2026-10-13 自行在浏览器确认通过,密码不经 Agent。本轮不重做该验收。
@@ -0,0 +1,113 @@
# Dev main 第二轮 manual 合入调度实施与测试计划
> **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:** 让第二轮三个已授权真实任务在同一人工窗口中按序完成最终同步、审核、CI 与智能体合入,同时把所有已知 Dev main 写入及失败退出记录在唯一调度 Issue;正常排队推进不使等待分支反复重跑最终 CI。
**Architecture:** 保留现有 Gitea 分支保护、三项 PR 检查和 `task-sync`;Dev `policy/` 仅说明项目采纳、写者覆盖、记录字段及停止条件。Issue #518 是动态窗口唯一来源,原任务卡保留授权与阶段结论。只读对账从实际 main PR/合入列表反查 #518 的先前领取与事后释放;无原子锁、无自动调度服务。
**Tech Stack:** Git/Gitea 1.27 API、Dev `make precheck`/`make evidence`/`make task-sync`、Markdown 规范与 JSON 收据、现有 `.gitea/workflows/ci.yaml`。
**Spec:** [已批准的阶段 4 设计](2026-10-14-merge-queue-manual-phase2.md),Documents PR #104(合入 `8e3b5b0d2838f89430683ec731a15b32b4fa5eae`);[首轮报告](../records/2026-10-14-merge-queue-trial.md)与 Dev #518 是历史与动态证据,不能以本计划代替实时回读。
## Global Constraints
- 范围仅为 Dev 仓库 ID=29、`refs/heads/main`;普通、闭卡、紧急和机器人目标写入都纳入同一记录。组件仓按自身目标协调。
- 第二轮样本为**随后实际就绪的三个已授权真实任务**;闭卡单列。#482、#512、#537 不因本计划自动取得接管或合入授权。
- 现有 Gitea 保护、必需检查、CI workflow 和 runner 全局配置保持不变;最终 PR HEAD 的 `test`、`test-pg`、`svc-realcombo` 均须取得真实 GATE。
- 采用单一协调者维护的 `manual` 窗口。Issue 编辑、评论、`content_version` 和本地锁都不是平台原子互斥;旧执行者未确认退出时不得接管。
- 无进展 20 分钟、单窗口 90 分钟、已知基础设施失败最多额外重试一次、队列每 30 分钟复核;领取前当场核对 runner 容量。
- 阶段 5–7 依 `policy/delivery.md` 分别取得人工结论;阶段 8–9 由智能体审阅、核验精确 HEAD 与平台准入并合入。阶段 5 批准不等于第二轮已启用。
- 所有通过断言区分 GATE、REPLAY、SELF;本地输出经 `make evidence` 写入,固定后收据置于源码外;未知结果先读回,不盲目重复副作用请求。
## Review Focus
1. **已知写者仍从另一入口推进 main:**任务 2 的对账应查到实际合入但缺先前领取,暂停新领取并标记受影响候选失效。
2. **Issue 中只有事后补记:**任务 2 的对账应区分先前领取与事后释放;#539 不能被算作合格覆盖。
3. **候选固定后内容或 base 变化:**任务 3 的核验应建立新尝试,并拒用旧 Review/CI;同基线重复 `task-sync` 应保持 HEAD 不变。
4. **合入响应未知或协调者失联:**任务 3 应先回读 PR/main 并保持 `reconciling`,确认前执行者退出后才释放/交接。
5. **没有三个已就绪任务:**任务 4 应保持 `waiting`,不接管 #482/#512 或制造生产 PR,不把缺样本写为通过。
| 设计验收 | 计划中的主要验证 |
|---|---|
| M2-1 | 任务 2 入队字段、任务 4 三个真实任务与等待期间最终 CI 清单 |
| M2-2 | 任务 2 的逐合入只读对账、任务 4 每次 main 推进后的覆盖核对 |
| M2-3 | 任务 3 的同基线无变更与变更后新尝试重放 |
| M2-4 | 任务 3 的精确 HEAD 三项 GATE/智能体合入、任务 4 的每任务对象记录 |
| M2-5 | 任务 4 对正常排队造成的最终 CI 废弃数和所有 CI 成本分类 |
| M2-6 | 任务 2/3 的异常决策表与任务 4 的自然退出/`NOT_RUN` 记录 |
---
### Task 1: 固定实施范围与 Dev 规范入口(M2-1、M2-3)
**Files:**
- Modify: Dev `policy/merge-queue.md` 的状态、项目调度记录、启动与同步、采纳顺序及验收表。
- Modify: Dev `policy/adoption.md` 中合入调度采纳行。
- Modify: Dev `policy/tool-adaptation-matrix.md` 的 A10/A11 行。
- Read only: Dev `AGENTS.md`、`policy/delivery.md`、`policy/governance.md`、Guidelines 固定版 `standards/merge-queue.md`。
**Interfaces:** 仅细化已固定通用规范,不改 `task-sync`、`make evidence` 或 CI 接口。规范链接指向 Documents 阶段 4 设计和 #518;`policy/adoption.md` 区分“规范已合入”“第二轮待启用”“manual 能力”;A10 说明 Issue 协作与平台准入的不同强度。
- [ ] 在 Dev 当前 main 创建未占用收据路径,运行下列启动门禁并确认 READY;按输出读必读规范。新任务用同一收据建独立工作区,记录 R0 与写者归属;若任务已登记则在原 worktree 改用 `make task-resume PRECHECK_RECEIPT="$mq_receipt"`,不重复开卡。BUSY、SYNC_REQUIRED、REMOTE_UNVERIFIED 先排除。
```bash
mq_receipt="/tmp/mq-phase2-stage6-precheck-$(date -u +%Y%m%dT%H%M%SZ)-$$.json"
RECEIPT="$mq_receipt" CMD='make precheck' make evidence
make task-start NAME=feature/merge-queue-manual-phase2 PRECHECK_RECEIPT="$mq_receipt"
```
- [ ] 对照当前 Dev main、Guidelines gitlink、#518 与已合入设计。把 `policy/merge-queue.md` 首轮“本轮三个任务待完成”“本分支”等已过期时态改为历史结果,把第二轮规则明确标为 `approved/pending-activation`,并逐项写明 `ready_at`、`queue_entered_at`、`attempt_id`、`initial_base_sha`、`source_head_sha`、`sync_base_sha`、`frozen_head_sha`、组件/检查定义、Review 与 GATE、实际合入/释放。动态值只在 #518,不复制静态队列表。
- [ ] 在 `policy/adoption.md` 与 A10/A11 中指向同一设计及项目规则:保留首轮原始证据范围;第二轮标 `manual`、`pending-activation`,不可升级成 `enforced` 或声称自动互斥;现有源码外收据能力保持原样。
- [ ] 检查 `AGENTS.md` 与 `policy/delivery.md` 对合入窗口及阶段 7–9 的指向。若现有入口已覆盖,只记录无需修改;若确有入口断链,按文档范围补链接并将变化列入 Review。
- [ ] 运行 `git diff --check`、Markdown 相对链接检查和规则一致性检查:阶段 5 批准后尚未启用、缺写者覆盖时必须保持 waiting、三个必需检查没有删减。若动到治理脚本或任务卡模板,另运行 `CMD='make test-governance' make evidence`;纯文档不制造新脚本测试。
- [ ] 将本单元源码与 SELF 检查收据写入原任务卡并提交;阶段 6 人工评审前不把 #518 标为第二轮 active。
### Task 2: 建立 #518 入队模板与只读覆盖对账(M2-1、M2-2、M2-6)
**Files:**
- Modify: Dev `policy/merge-queue.md` 的记录示例、写者覆盖、异常与暂停规则。
- Prepare then update after Stage 6 approval: Gitea Dev Issue #518 正文的第二轮入口与追加式评论模板;不建立第二份队列状态文件。
- Save outside source: 每次只读 Gitea API 对账的原始脱敏 JSON/`make evidence` 收据;必要结论只引用对象和链接。
**Interfaces:** #518 条目至少包含 `entry_id`、目标、PR/任务卡、owner/协调者、授权与阶段版本、依赖、`queue_entered_at`、`ready_at`、状态;领取评论补 Task 1 的 attempt 字段;释放评论补实际 PR/main SHA、合入结果及 GATE 链接。`ready_at` 未知标 `NOT_MEASURED`,不足条件标 `blocked`。
- [ ] 只读查询 Dev 当前 main SHA、开放 PR、仓库协作者、可写工作区 owner、机器人/webhook/workflow 入口、#518 正文与评论,生成带观察时间和对象 SHA 的 SELF 清单;无法查到的写者类别标“未核验”,不推断不存在。
- [ ] 在 Task 1 规范中给出普通、闭卡、紧急、机器人共同的入队/领取/释放字段,规定 `blocked` 不占窗口;跨仓组件未就绪不占 Dev 窗口。未知来源与旧执行者未退出必须暂停或 `reconciling`,不得靠 20 分钟超时接管。
- [ ] 固定只读对账步骤:枚举观察区间内实际合入 Dev main 的 PR/merge SHA;逐个在 #518 找**合入前**同目标同 attempt 的领取和**合入后**释放;同时反查 Issue 中仍占用但 PR 已关闭/合入的窗口。分列“合格、仅事后补记、未找到、结果不明”,保留 API 原始响应与分页范围。
- [ ] 用 [阶段 4 SELF 快照](../records/2026-10-14-manual-phase2-source-audit.json) 回放对账口径:#539 属“仅事后补记”,#540/#542 能找到领取/释放,其余七个仅可记“在该次 #518 观察中未找到”;不得倒推出其他渠道绝无协调。源记录更新后另取实时快照,不用历史快照证明当前覆盖。
- [ ] 将模板与覆盖清单先作为 Dev PR/任务卡可审附件;Stage 6 人工确认后才更新 #518 的**待启用**入口。写入前读回 `content_version` 与活动窗口,遇到别人更新先重算差异;请求结果未知先 GET 对账,不重复 PATCH/POST。
- [ ] 当场向每位**已知目标写者**核实采用同一窗口的确认;未确认类别逐项留记录。没有全体已知写者覆盖,不转 active、不领取三个样本。人工确认不等于 Gitea 执行端隔离。
### Task 3: 用现有门禁交付 Dev 规则并验证异常边界(M2-3、M2-4)
**Files:**
- Modify: Task 1/2 的 Dev 规则差异及原任务卡(仅在候选固定前)。
- Save outside source: 最终 precheck、task-sync、直接相关检查、Review 和 CI 的原始收据及对象索引。
**Interfaces:** 复用 `make task-sync`、`make evidence`、Gitea PR/Actions 与现有分支保护;不新增自动队列或跳过 CI 的入口。
- [ ] 在阶段 6 人工通过后,正式测试前对 Dev 规则 PR 执行一次 `make task-sync`,处理真实冲突、确认组件不回退,先写完任务卡和需提交证据,再固定并推送 PR HEAD。若有脚本/模板改动跑 `make test-governance`,Dev 组合按变更影响跑 `make test`/`make build`,由 `make evidence` 保存完整 SELF 输出。
- [ ] 在临时真实 Git 场景复核同 base/head 重复 `task-sync` 的 HEAD、索引和组件不变;目标前进或候选内容变时,新 attempt 的 base/head 与旧 CI/Review 不同,旧结果不能放行。若本增量未改同步脚本,引用现有治理回归并做最小重放,不重复整个历史试行。
- [ ] 用只读或隔离模拟验证异常决策表:未登记 main 推进→暂停及候选失效;合入 API 超时/断连→`reconciling` 并先读 PR/main;代码/Review 失败→当前条目 blocked 并安全释放;未发生真实生产故障的路径只标模拟或 `NOT_RUN`。
- [ ] 阶段 7 人工审阅固定候选与测试映射后,由智能体完成阶段 8 Review 与影响重放;阶段 9 合入前再次同步核对最新 base/head/组件及当次要求的 GATE 身份、SHA、三项结果。合入请求固定 `head_commit_id` 且 `force_merge=false`,回读 PR/main 树与合入 SHA。若候选改变,重新测试及受影响评审,不沿用旧绿灯。
- [ ] 把实际阶段 6/7/8/9 结果及 GATE/REPLAY/SELF 来源写入原任务记录;规则 PR 合入并不自动启用第二轮任务窗口。
### Task 4: 第二轮启用、三任务试行与收口(M2-1–M2-6)
**Files:**
- Update dynamically: Gitea Dev Issue #518 与每个**原任务**的任务卡/PR。
- Create after actual observation: Documents `docs/records/<实际日期>-merge-queue-manual-phase2-trial.md`;与 #518 互链,不复制动态队列状态。
- Update only after result review: Dev `policy/adoption.md`、`policy/tool-adaptation-matrix.md` 的实际能力和状态(若有变化)。
**Interfaces:** Task 2 的 #518 模板;每个任务原有人工阶段与接管授权;固定 PR HEAD 的三项 GATE;智能体合入入口。此任务不承担其他任务业务代码实现。
- [ ] 在规则 PR 合入、#518 模板已登记、已知目标写者确认覆盖、无活动/未知窗口、runner 容量当场核验后,由负责人审阅启用条件与当前清单,再把第二轮从 `pending-activation` 切为 `manual active`。缺任何条件保持 `waiting`,继续独立局部开发。
- [ ] 只让三个**实际就绪且已有自身实施/合入授权**的任务依 `queue_entered_at`/`ready_at` 顺序入队;协调者在领取前核对原卡阶段结论、PR head、依赖、组件与其他写者退出。#482/#512 只有重新满足这些条件才可参与,不能因本计划自动接管。
- [ ] 每次领取后按 Task 3 固定并通过当前 HEAD 必需检查、Review 与人工阶段结论,智能体串行合入并释放;闭卡 PR 使用独立窗口,成本单列。每 30 分钟复查等待队列,记录 runner 等待与人的依赖/准备等待;时间缺失记 `NOT_MEASURED`。
- [ ] 每次 main 实际推进后运行 Task 2 只读覆盖对账;发现未登记合入、并行窗口、对象不符、旧执行者未退出接管或来源伪造时立即暂停新领取,先核清受影响候选和写者。未知合入结果不重发 POST。已合入成果不自动回退。
- [ ] 三项完成或触发停止条件时,按 M2-1–M2-6 列每个真实任务的最终 base/head、同步/新尝试原因、Review、GATE、合入树、开发/最终/main push/组件/闭卡 CI 次数与耗时、废弃原因;仅正常已登记顺序推进造成的最终 CI 废弃数作为目标指标。没有可比历史基线时不报告节省百分比,未发生的退出路径记 `NOT_RUN`。
- [ ] 用户评审第二轮报告后决定继续 manual、调整预算、停止或另立自动准入;仅实际合入与经核验的能力可更新 Dev 采纳/矩阵。阶段 10 的安全回收按工作区 owner 和 `task-finish` 现场检查执行,任务闭合经有授权的 `task-close` 与智能体 PR 合入;保留所有原始收据。
## Stage 5 decision and stop rule
2026-10-14,负责人 weichen 在本任务会话中对 Documents 草稿 PR #105 的计划稿 `28c4ceb17315e1bb06f8e39c8407eb525effb8fe` 回复“通过阶段 5”,并选择由当前智能体逐项实施。批准覆盖本计划的阶段 6 候选编制与自检,不替代阶段 6–7 的人工结论,也不等于 #518 第二轮 active。任何实施中发现原子互斥、角色隔离或执行端 fencing 被要求为通过条件,应停止扩围并回到阶段 4 重设计,不能靠文字提升 `manual` 能力。
@@ -0,0 +1,74 @@
# Dev main 合入调度第二轮 manual 扩围设计
状态:**阶段 4 方案设计与[阶段 5 实施计划](2026-10-14-merge-queue-manual-phase2-implementation-plan.md)均已通过;阶段 6 实施待评审**。2026-10-14,负责人 weichen 在本任务会话中对 Documents 草稿 PR #104 的规范稿 `aa4d372f01d0473928c570aa69c09ca771f2de45` 明确回复“通过阶段 4”,随后对 PR #105 的计划稿 `28c4ceb17315e1bb06f8e39c8407eb525effb8fe` 回复“通过阶段 5”,选择由当前智能体实施。这些批准不等于启用第二轮窗口或接管其他任务。执行协调者须在每个窗口明确登记。本文只设计 Dev 仓 `refs/heads/main` 的下一轮人工调度,不启用自动队列。
主记录:[Dev 调度 Issue #518](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/issues/518);既有规则:[Development-Guidelines 固定版合入调度](https://git-home.u1680832.nyat.app:30319/weichen/Development-Guidelines/src/commit/2f5b19872be2a4597838a4131ad75d1be089ee5e/standards/merge-queue.md)、[Dev 项目细化](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/src/branch/main/policy/merge-queue.md);首轮结果:[三任务试行报告](../records/2026-10-14-merge-queue-trial.md)。本稿为下一轮范围与验收设计;动态队列状态只维护在 #518,不复制第二份任务进度表。
## 1. 评审结论与问题
首轮 #489、#488、#486 在同一协调者下顺序合入,每个真实任务只有一次最终 PR CI,三项各自合入后的 main CI 另计;没有因首轮正常顺序合入废弃的最终 CI。首轮报告将 MQ1、MQ5–MQ7 的未覆盖部分及自动原子领取、旧执行者拒绝列为部分满足或 `NOT_RUN`,不得据此宣布全仓自动约束已就位。
2026-10-14 22:13(Asia/Shanghai)对 #518 当前正文/评论和 Dev PR #539–#548 的只读 API 对照([SELF 观察快照](../records/2026-10-14-manual-phase2-source-audit.json),原始本机文件 `/tmp/mq-manual-expansion-audit-20261014.json`)显示:这十个 PR 均已合入;[#540](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/540)、[#542](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/542) 有窗口领取与释放记录;#539 只有合入后的事实记录;其余七个在当前 #518 正文与所返回的评论中找不到对应 PR 的窗口记录。这是**记录覆盖缺口**,不等于断言这些合入未经其他人工协调。它使“所有 Dev main 写入者都受同一 manual 窗口控制”的结论无法成立。
[#537](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/537) 曾取得旧候选绿色 GATE,但 Stage 8 审阅判为 `NOT READY`,窗口释放,后由用户取消且 PR 未合入;该例证明 CI 与人工阶段结论须分别核验。[#542](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/542) 的归档文字变化使旧候选作废,run 3100 不能放行新 head,run 3107 才属于实际合入对象。两者是应保留的正常失败/恢复事实,不计为“因正常排队 main 移动而浪费的 CI”。
目前 Dev 开放 PR 只有 #482 与 #512:#482 非草稿但落后 main、平台回读不可合入;#512 为草稿。两者的既有绿色状态均属于旧对象,且未取得本轮写者接管确认。因此**当前没有可直接领取的第二轮任务**,不得为凑满数量生成生产 PR、自动同步它们或把队列扩围理解为接管授权。
平台当前只读回读(SELF):Dev `main` 禁直推/强推,拒绝落后分支,要求三个 PR 检查上下文 `ci / test`、`ci / test-pg`、`ci / svc-realcombo`,管理员不可绕过合入。它仍不能区分共用账号下的人与智能体,也未把 #518 的窗口写入变成原子锁或执行端 fencing。本轮不变更保护、批准数、CI workflow 或 runner 全局设置。
## 2. 目标、范围与非目标
**目标:**在保留人工阶段评审和现有平台准入的前提下,将首轮单一协调者的经验扩展为可供多个已授权任务 owner 依次使用的 **manual** 窗口;在候选固定后减少因正常排队合入而造成的无效同步和完整 CI;准确统计没有节省的成本与退出案例。
**范围:**仅 Dev 仓库 ID=29、托管实例 `git-home.u1680832.nyat.app:30319` 的 `refs/heads/main`。普通 PR、任务卡闭合、紧急和机器人目标写入均须出现在同一调度记录;不同组件仓按各自目标协调。候选任务原卡仍是需求、授权、阶段和证据的主记录。第二轮以随后实际就绪的三个已授权真实任务为观察样本,闭卡 PR 单列成本与窗口,不充作三个业务任务。
**非目标:**自动优先级、合并列车、批量/预测合并、复制旧 CI 状态、降低必需检查、调整分支保护、发布/部署、代替其他任务 owner 编写业务代码。#482、#512 和已取消的 #537 不因本设计自动变为就绪或重新授权。
取舍:立即把所有 PR 宣称为受控 manual,管理成本最低,却与七条找不到 #518 窗口记录的实际合入不符;只点名三个任务而放任其他 main 写入,不能解决等待者因外部推进失效的问题;直接建设自动队列需要真实原子领取和执行端旧代次拒绝,超出用户选择的 manual 范围。本设计选择先确认已知写者覆盖与记录完整性,再接收三个真实就绪任务;覆盖不足时诚实标记并暂停,保留以后另立自动机制的边界。
## 3. 第二轮 manual 协议
### 3.1 入队与覆盖
任务 owner 在最终同步之前登记目标仓库/分支、任务卡与 PR、授权范围及阶段结论、源 HEAD、依赖/组件、现有写者和预计最小重放集。`ready_at` 只在依赖已落主干、必要人工结论与写者排他确认均齐备时记录。尚缺任一条件的条目标 `blocked`,可以继续自己的局部开发,不领取窗口;入队不要求提前合入不断移动的 main。组件仓未交付时不占 Dev 窗口,也不持有一个目标窗口等待另一个目标。
第二轮启用前,协调者核对当时的开放 PR、可推进 main 的工作区 owner、仓库协作者、机器人/webhook 和 workflow 入口,并取得**已知目标写者**采用同一窗口的确认。普通、闭卡、紧急及机器人合入均须走 #518;仍有未接入写者时如实登记其范围,不能声明全写者覆盖,也不能保证等待任务免于外部 main 移动。
协调者按就绪时间与已批准的紧急理由安排顺序,领取前读回 #518、实际 Dev main/PR、分支保护和 runner 资源。#518 的当前窗口字段只写一个目标尝试;评论保留追加式时间线。领取后再读回核对,无匹配或发现另一执行者时停止。Issue 的 `content_version`、本地锁和评论均**不等于平台原子互斥**;本模式依靠明确写者遵约和受保护分支的最终准入。协调者换手时须确认前执行者退出及未知合入结果,不能凭 20 分钟超时自动接管。
### 3.2 固定、检查与合入
一个窗口以 `attempt_id` 标识:`target`, `owner/coordinator`, `claimed_at`, `last_progress_at`, `initial_base_sha`, `source_head_sha`, `sync_base_sha`, `frozen_head_sha`, 组件清单、检查定义、Review 对象、GATE 运行与真实结果。新增 `ready_at` 与 `queue_entered_at`,使任务等待时间和 runner 等待时间分开计算;时间未知时记 `NOT_MEASURED`,不倒推填造。
窗口领取后执行一次真实 `task-sync`,处置冲突、物化已合入组件并完成应提交的任务卡/收据;此时才固定父仓候选。目标未变的验收、Review、合入节点只做同基线核验,不生成记录提交或重复完整 CI。最终 CI 仍由现行 workflow 在**固定 PR HEAD**上运行 `test`、`test-pg`、`svc-realcombo`;独立 Review、人工阶段结论与 CI 分别审查。合入前再次核对最新 base/head、组件、保护和三个 GATE 作业身份与结果;智能体使用固定 `head_commit_id`、`force_merge=false` 经 PR 合入,回读实际 main 树、合入 SHA、组件和后续 main push CI。
源 HEAD、目标 base、组件、检查定义或相关环境改变时建立新尝试,并按影响补测/复审。旧结果保留其对象范围;不为减少 CI 次数制造绿色状态。开发期 CI、最终 PR CI、合入后 main CI、组件 CI 和闭卡 CI 分开统计。
### 3.3 失效、异常与未登记推进
发现 #518 未登记的 main 推进时,协调者先读回目标、PR、运行和活动窗口;将受影响的固定候选标失效,记录缺口来源与对象,暂停本轮新领取,待写者覆盖和影响范围核清后恢复。不得把“记录中没有”推断为平台阻断已生效。代码或 Review 失败、依赖不满足、需要人工决定超时:保存现场与原始证据,受影响条目 `blocked` 并安全释放;其它目标和局部开发继续。合入请求超时、断连或结果不明:保持目标 `reconciling`,查询 PR/main 真实状态;未确认旧执行者退出前不重发有副作用的请求,也不移交窗口。
预算沿用首轮:无进展 20 分钟、单窗口 90 分钟、已知基础设施失败最多额外重试一次、等待队列每 30 分钟复核一次。领取前重新核对当时 runner 容量,不把首轮的 capacity=12 当作永久事实;资源不足先等待,不在窗口中空占名额。预算变化必须在实际成本复盘后另行评审。
## 4. 验收、观察和停止条件
| ID | 可判定条件 | 证据与边界 |
|---|---|---|
| M2-1 | 第二轮的三个真实任务均有原卡授权、阶段结论、owner 确认和先行组件;等待期间不为追 main 重跑最终 CI | 每任务原 R0、入队/就绪/领取时间、固定 base/head、源外收据;缺任务时保持等待,不制造 PR |
| M2-2 | 每次 Dev main 实际合入在 #518 可找到同对象的先前领取和事后释放;闭卡、紧急、机器人同样登记 | 以实际 main merge/PR 列表对照 Issue 正文/时间线;遗漏即覆盖失败,不能声称“全写者受控” |
| M2-3 | 稳定候选同基线重复 `task-sync` 不改 HEAD;对象变化拒用旧 Review/CI | 独立重放及精确运行 SHA;本轮记录每次新尝试原因 |
| M2-4 | 三个真实任务各自取得当前 HEAD 三项必需 GATE 后由智能体合入,实际树与候选一致 | PR/run/job/actor/runner 链接及合入后 main 回读;平台仍是最终准入 |
| M2-5 | 正常已登记任务顺序合入造成的最终 CI 废弃数为 0;候选整改、外部推进和基础设施失败另计 | 完整列出开发、最终、main push、组件、闭卡运行次数/耗时与废弃原因;无可比基线不报告节省百分比 |
| M2-6 | 自然发生的 blocked/withdrawn/reconciling 均如实记录并安全处理;某类未发生则标 `NOT_RUN` | 不制造生产故障凑数;#537 历史可作设计参考,不冒充第二轮执行 |
若有未登记 main 合入、并行窗口、对象不匹配仍合入、伪造来源、旧执行者未退出即接管,立即暂停扩围并先对账;这是试行停止条件,不自动回退已经合入的成果。三个条目及闭卡均核验后形成第二轮报告,人工评审是否保持 manual、调整预算或另立自动准入项目。本轮即使全部满足,也只证明声明范围内的**人工协作**;自动锁、所有角色的执行端隔离和旧代次 fencing 继续 `NOT_RUN`。
## 5. 采纳顺序与阶段 4 决定
1. 阶段 4 已由用户按规范稿 `aa4d372` 批准;智能体完成本设计的 Review 与 Documents PR 合入。阶段 5 计划获批前不改 Dev 规则/Issue 状态,不领取新任务。
2. 另编实施/测试计划:对账 `policy/merge-queue.md`、`policy/adoption.md`、`policy/tool-adaptation-matrix.md` 的首轮历史快照与当前动态入口,确定 #518 第二轮条目模板和只读合入覆盖核对方法;有脚本变更时运行 `make test-governance`。规范源码、项目采纳及 Issue 记录分别标阶段,不把计划写入视作已启用。
3. 经计划阶段评审后,按 Dev 首次 precheck、独立工作区、Review、当前 HEAD CI 与智能体 PR 合入流程交付必要规范更新。高后果保护变更若将来必要,仍由用户亲手执行,本设计不要求该动作。
4. 各真实任务 owner 在自己的授权与阶段下自愿入队;协调者确认全写者覆盖、同目标唯一窗口和资源,再领取。当前 #482/#512 不满足这一步。
5. 第二轮达到三个真实任务或触发停止条件后,按本设计 M2 指标复盘;由用户作继续、调整或回退的阶段决定。
**阶段 4 决定:**用户已批准以“先补全 Dev main 合入记录覆盖、后接收三个真实就绪任务”的受控扩围作为第二轮设计,遗漏目标推进立即暂停、现有预算不变、闭卡单列成本,当前无就绪任务时保持 `waiting`。这一决定只批准设计;#518 与仓库规则的第二轮启用仍受阶段 5–7 评审及实际写者覆盖核验约束。
@@ -0,0 +1,80 @@
# svc 插件组合部署(--with)方案 r1
状态:**待评审**。日期:2026-10-14。负责人:weichen。
任务卡:Dev `.task/feature-svc-plugin-compose.md`。
需求来源:部署时用交互或参数选择把哪些插件与基座编译成同一个二进制服务,并在服务中激活这些插件。
## 1. 范围
做:
- 每次 `svc.sh` 的 agent deploy 可以选择零个或多个已登记插件。
- 被选中的插件与 `--from` 指定的 Dev 基座编译成一个仍名为 `agent-system` 的二进制。
- 部署后校验这些插件已注册且命令面处于启用;失败走现有 release 回退。
- 插件清单来自 Dev 仓 `plugins/registry.json`,不自动发现。
不做:
- 不做 sidecar,不把插件部署成独立服务。
- 不让插件自带基座 pin。基座就是本次 `--from` 的 Dev 提交;对不上就构建失败并报原因。
- 第一版最多一个带静态工作台(`web`)的插件。
- 不删除旧的 `--from rdm`。它仍用 RDM 仓自己的 `pins/` 构建,与 `--with` 互斥。
## 2. 步骤 0 试验结论(不留代码)
2026-10-14 在 `/tmp/svc-compose-spike` 复制当前 Dev 的 backend 模块,空白导入
`agent-system-rdm/plugins/rdm`(指向 `~/.cache/agent-system-svc/rdm-src`),
`go mod edit -require/-replace` 后执行 `CGO_ENABLED=0 go build -mod=mod`。
- 构建成功。产物约 40MB,`version` 仍是基座的 `agent-system 0.1.0-dev`。
- `go version -m` 显示主模块 `agent-system-backend`,依赖 `agent-system-rdm v0.0.0`。
- 二进制内可见 `rdm.project.create` 与 `rdm.ping`。
- 聚焦依赖(`golang.org/x/*`、`github.com/jackc/*`、`modernc.org/sqlite`、`gopkg.in/yaml`)版本无变化。
- 新增模块只有 `agent-system-rdm`、`github.com/kr/text`、`github.com/rogpeppe/go-internal`。
- 默认 `-mod=readonly` 会拒绝更新 `go.mod`/`go.sum`,组合构建必须使用 `-mod=mod`。
- 依赖模块自己的 `replace` 不生效,插件按主模块(Dev 基座)解析 `agent-system-backend`。这正是“基座以 Dev 提交为准”所要的结果。
试验目录是一次性的,不进入任何仓库。
## 3. 行为
### 3.1 选择
- `--with rdm,foo` 选择插件;`--with rdm@<sha>` 钉住单个插件提交;`--with none` 明确不带插件。
- 标准输入是终端且没有 `--with` 时,按登记表给出编号勾选。默认勾选上次 `svc.env` 的 `plugins=`;第一次默认不选。回车接受默认,`none` 清空。
- 非交互且没有 `--with`:沿用上次选择,没有则不带插件。已有脚本和 CI 的行为不变。
- `--dry-run` 打印基座提交和每个插件的提交,不构建。
- `--from rdm` 与 `--with`(除 `none`)互斥。`--from release` 不能再注入插件。
### 3.2 构建
1. 物化 Dev 提交的隔离 worktree,并完成前端构建,使嵌入资源就绪。`--from local` 不改主检出的 `go.mod`:把 backend 模块复制到 `runtime/.worktrees/` 再构建。
2. 每个插件使用独立源仓缓存(`~/.cache/agent-system-svc/plugin-<id>`,`repoEnv` 可覆盖克隆地址)并物化 worktree。
3. 在这份一次性 backend 副本里生成 `cmd/agent-system/zz_plugins_gen.go`(空白导入 `entryPackage`),并用 `go mod edit` 增加 `require` 与 `replace`。
4. `go build -mod=mod` 产出 `agent-system`。基座的 `version`、身份和 `user` 等子命令保持不变。
5. 测试可设 `SVC_COMPOSE_STUB=1`,跳过真实 `go build`,只记录插件选择。这不是生产路径。
### 3.3 激活与记录
- `GET /api/plugins` 与 `GET /api/registry` 的 `compiled` 列表必须包含每个所选插件。
- `GET /api/commands` 中该插件 `commandPrefix` 下至少有一条 `enabled` 命令。
- 插件在而命令全部禁用时,用与设置播种相同的临时管理员 key 调用 `POST /api/plugins/{id}/enabled`,再复查。失败则 `svc_rollback_deploy`。
- `svc.env` 写 `plugins=id@sha,id@sha`。`source` 形如 `dev@<sha>+rdm@<sha>`。release 目录的 `release.json` 带同一 `plugins` 字段。
- `update` 把基座升到远端最新,并原样带上已记录的 `--with`,不再询问。`recover` 只拉起已有二进制,不重新选择。
- 插件 id 集合变化(含从无到有、从有到无)与源种类变化一样,需要 `--allow-source-switch`。只改提交不需要。
### 3.4 工作台
登记表里 `web` 非空的插件,沿用现有伴生 static 服务(`<name>web`)。多于一个带 `web` 的插件直接拒绝。
## 4. 跨仓
- Backend:`extension.InProc` 增加可选 `HostOptions` 与 `CLI`。布尔默认按“任一为 true”合并,不覆盖显式 serve 旗标。`GET /api/registry` 增加 `compiled`。
- RDM:`plugins/rdm` 在 `InProc` 上声明 `HostOptions`(含关闭上传自动索引、会话卡镜像、执行原语)和 `-bootstrap-admin` 钩子。RDM 自己的 `main.go` 继续可用,旧 `--from rdm` 不依赖这次钩子。
- Dev:`scripts/svc.sh`、`plugins/registry.json`、`docs/svc.md`、`help plugins`、`tests/test_svc_plugins.py`,并推进 backend 与 documents 的 gitlink。
## 5. 验收
- 登记、选择、换源门禁、dry-run、stub 部署与激活走 `tests/test_svc_plugins.py`。
- Backend 的合并与 CLI 钩子走 `go test ./pkg/extension/`。
- 真实 `go build` 组合(Dev 提交 + RDM 提交)在步骤 0 已证实可编译。带网络的完整 `svc deploy --with rdm` 与 `make test-lifecycle` 不在本增量的 stub 套件里,未在本机再跑时标 NOT_RUN。
@@ -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)。
+21 -2
View File
@@ -4,8 +4,21 @@
本索引负责导航与差异提示,规划正文、批准范围和验收条件仍以链接的主记录及其批准版本为准。
合入授权不批准新方向、不调整里程碑范围、不启动新的业务任务。
[分层分支交付与规范精简 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 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` 与公开扩展四要素。
@@ -180,7 +193,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 规划补充
@@ -192,7 +209,9 @@ RDM 总案把库分期作为支撑与依赖,不覆盖库分期的原始范围
- [RDM 两树一网集成、完善与追溯审计展示方案 r1](2026-10-11-rdm-two-trees-trace-audit-integration.md):对应 P3/MS3,源码已有部分实现;优先补项目绑定、创建者/管理员读取隔离与历史完整性,再接统一展示。用户确认范围为 RDM 与必要基座能力;r1 已获用户评审通过(2026-10-11,五阶段一并,含 KTD4 双层管理员裁定)。U1–U5 全部实施合入(RDM PR #195/#197/#201/#213;Dev PR #368,2026-10-11;超管槽待基座能力接线,见 RDM 仓 U1 基座扩展申请)。U6 团队存储独立后续;运行验收属部署环境。
- [RDM 模板与两树一网对话文档生成方案 r1.1](2026-10-11-rdm-template-dialog-generation.md):69 类旧资产、4 个当前注册模板的盘点及生成闭环设计;待评审,实施/迁移/模型试验/运行验收 NOT_RUN。与两树一网集成方案共用项目授权、原子事件与历史能力。 首批项目建议书/竞品分析、随后扩展全部文档已确认(2026-10-11),其余方案与实施仍待评审。
- [DHF 模板接入 RDM 文档生成管线 r0.1](2026-10-14-dhf-template-generation-plan.md):用户于 2026-10-14 批准本方案并启动实施。RDM 的首批资产合同与 44 份原件目录已在独立任务分支保存;14 份 DOC 均有自动转换候选,E1 内容与版式保真仍待人工评审,正式模板发布数为 0。真实《项目建议书》的结构/槽位评审候选已形成;U1 整体、U2–U6 用户流程、正式验收与部署尚未完成。与在途两树任务沿用同一 TT-T/TT-D 契约;每阶段仍按既有人工评审门禁推进。
- [RDM 模板与两树一网对话文档生成方案 r1.1](2026-10-11-rdm-template-dialog-generation.md):69 类旧资产、2026-10-11 四个注册模板的历史盘点及生成闭环设计;待评审,实施/迁移/模型试验/运行验收 NOT_RUN。与两树一网集成方案共用项目授权、原子事件与历史能力。 首批项目建议书/竞品分析、随后扩展全部文档已确认(2026-10-11),其余方案与实施仍待评审;2026-10-14 资产和源码刷新见 DHF 专项。
- [RDM 最终目标核对与完整交付方案 r1](2026-10-11-rdm-final-target-completion.md):本轮用户确认系统级唯一项目、管理员上限内覆盖、私域与三权读取边界;覆盖 34 UR/68 SR/10 F、全部69类模板及现有XLSX,当前源复核 RDM d8d7e743。总体方案待评审,实施/迁移/运行验收 NOT_RUN;模板方案为子方案。
+589
View File
@@ -0,0 +1,589 @@
{
"source": "SELF",
"dev_sha": "add097d06137c4912a4ed9279e98ca353e4e4cf1",
"rdm_sha": "6fcb256205c2384abed35d3b6ab96ca7216e9297",
"rdm_frontend_sha": "eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b",
"rdm_frontend_preview_sha256": "0f53735a5b58d4c7c545ceb56ce02d0305af47f379f16d92295323a68dd5f13d",
"summary": {
"count": 44,
"formats": {
"docx": 30,
"doc": 14
},
"unique_content": 41,
"phases": {
"0. 商务阶段": 1,
"1. 策划阶段": 3,
"2. 设计输入阶段": 15,
"3. 设计输出阶段": 9,
"4. 设计验证阶段": 8,
"5. 设计转换阶段": 3,
"6. 设计确认阶段": 5
}
},
"assets": [
{
"source": ".templates/DHF 文件模板/0. 商务阶段/0.1初始要求申请表.docx",
"format": "docx",
"bytes": 17137,
"sha256": "eb9d287014911a18c5589a0b9e7b7f63ad535178cf7cf29a3a269dcf46118391",
"tables": 2,
"gridSpan": 0,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/1. 策划阶段/1.1、731QCP29-F01 项目建议书 02.docx",
"format": "docx",
"bytes": 25114,
"sha256": "3f54f060d9c528e3fd4e7b7c606f352fbabe9488a25ad95a7341fa7901518b29",
"tables": 2,
"gridSpan": 4,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/1. 策划阶段/1.2、731QCP29-F02 设计开发计划任务书 02.docx",
"format": "docx",
"bytes": 36248,
"sha256": "d152b0b4d2bb1aa30c60aaec19e331a05a552d7d119f5a6f4cc4177f163159fb",
"tables": 7,
"gridSpan": 6,
"vMerge": 106,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/1. 策划阶段/1.3、731QCP29-F07 设计开发(策划)评审记录 02.docx",
"format": "docx",
"bytes": 26043,
"sha256": "d6f3cca9c3c1f7ed1ea60322c5435f8410d6cf7ca2096b04a367fc8255ee1330",
"tables": 5,
"gridSpan": 35,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.10.1、731QCP29-F13 配置管理计划 02.docx",
"format": "docx",
"bytes": 58902,
"sha256": "94e8e7fc868d76c62199fdeb30ea0aab7db3c58a36ef94aef15d629f4930b11a",
"tables": 5,
"gridSpan": 4,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.10.2、软件维护计划模板.docx",
"format": "docx",
"bytes": 166962,
"sha256": "76fc4d4fddecc04e533aceb930aab9b82f4956c6bf5fb3d04f19150003c7932e",
"tables": 2,
"gridSpan": 4,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/footer2.xml",
"word/footer3.xml",
"word/footer4.xml",
"word/footer5.xml",
"word/footer6.xml",
"word/header1.xml",
"word/header2.xml",
"word/header3.xml",
"word/header4.xml",
"word/header5.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.11.1、731QCP29-F16设计输入规格书模版.docx",
"format": "docx",
"bytes": 68678,
"sha256": "3fef2ed7d0aa5e0ac8c01b92571b0ce9dbe3a8191a06d7a79d799fb62fe5e613",
"tables": 17,
"gridSpan": 4,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.12、731QCP29-F05 设计开发输入清单 02.docx",
"format": "docx",
"bytes": 20681,
"sha256": "de990de6bf13e4c692a9664719f508cf2d34765b14ddd77fbb58879c99dee6da",
"tables": 2,
"gridSpan": 4,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.13、RDDHF0213-xxxx产品系统设计方案.doc",
"format": "doc",
"bytes": 419499,
"sha256": "8168ea37c7ca5f32f5d57527d0c8ff5c2d583998167e30ed713937c95e9e82d4",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.14、731QCP29-F07 设计输入评审记录.docx",
"format": "docx",
"bytes": 28675,
"sha256": "a3677cb06a3946769e501f906669f57c4cd21769109ad5e27697d76320fa8686",
"tables": 5,
"gridSpan": 35,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.1、731QCP29-F14 用户需求模板.doc",
"format": "doc",
"bytes": 115712,
"sha256": "2f9c6795f81188797018ef7e2ba4c7e693db0f3fabaa2eb5a9478fb2e2b1a6ac",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.2、RDDHF0202-xxxx 医疗器械法规和标准清单.docx",
"format": "docx",
"bytes": 29384,
"sha256": "2b36daeedc8c54a7975ece49102d279584bb80a5ff262912db2941edf009feec",
"tables": 3,
"gridSpan": 5,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.3、RDDHF0203-xxxx 同类产品不良事件信息.docx",
"format": "docx",
"bytes": 29958,
"sha256": "f7cd69b08c1ec1bea04ec8a30aaa54f6d8bed90a6e9544c3b9264341ac299edc",
"tables": 3,
"gridSpan": 4,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml",
"word/header2.xml",
"word/header3.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.4、731QCP29-F15 系统需求规格书模板.doc",
"format": "doc",
"bytes": 119296,
"sha256": "b58d1b900c951f8c20b5f301cb75e072a91c98ab3d71b172128b51dc84c8bff3",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.5、731QCP29-F07 需求评审记录表.docx",
"format": "docx",
"bytes": 27823,
"sha256": "102ed2b6418b51b383de97a735b8a183d025af9da139152d92715e44ba860b1b",
"tables": 6,
"gridSpan": 42,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.6、731QCP29-F03 风险管理计划 02.docx",
"format": "docx",
"bytes": 31626,
"sha256": "0c1484d6b29595077c9b60e08a69c73d008216744e7df59f83c0e7054f1e51c9",
"tables": 7,
"gridSpan": 8,
"vMerge": 13,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.7.3、731QCP29-F04 风险管理报告 02.docx",
"format": "docx",
"bytes": 29910,
"sha256": "d4f18eb817dae8b655715c6832b591299d0e5c7c1196e777cf9e48e79b4f3544",
"tables": 6,
"gridSpan": 8,
"vMerge": 13,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.8、731QCP29-Fxx 软件开发计划-模板.doc",
"format": "doc",
"bytes": 300544,
"sha256": "2dee0e085113adc4868546b2469eab89c076b6c8613417b3897e975a2adb4e29",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/2. 设计输入阶段/2.9、软件需求规格书模板.docx",
"format": "docx",
"bytes": 48903,
"sha256": "aa12be2b8158439c91b77df5a90fd2d71aa658186e37332c54a6766b572b4a30",
"tables": 10,
"gridSpan": 4,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.12、原材料进货检验规范-模版.docx",
"format": "docx",
"bytes": 995696,
"sha256": "34608b520ebff384cdb613818271a04d3e7fc9a71da693cdd51550ab0b38bf0c",
"tables": 18,
"gridSpan": 124,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/footer2.xml",
"word/header1.xml",
"word/header2.xml"
],
"linked_images": [
{
"part": "word/document.xml",
"link": "rId12",
"embed": "rId11"
}
]
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.15、产品技术要求.doc",
"format": "doc",
"bytes": 16896,
"sha256": "b787295c6c66089cb0895a1f9ebd77058091bb85355910f84d014613470b2512",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.17、731QCP29-F06 设计开发输出清单 02.docx",
"format": "docx",
"bytes": 22792,
"sha256": "f53a2f271bf2782ab12cba1f26a141d5560e7e7aa905a0a74b46b10bbf43e84b",
"tables": 1,
"gridSpan": 4,
"vMerge": 0,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.18、731QCP29-F07 设计输出评审记录.docx",
"format": "docx",
"bytes": 28214,
"sha256": "e37ab2828e647ffee84068d8c4ce6520c70b3a3849d37d946cb7bd52bd28efe9",
"tables": 5,
"gridSpan": 35,
"vMerge": 0,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.6.2、软件详细设计模板.docx",
"format": "docx",
"bytes": 51735,
"sha256": "e1089b1de6d2c06e5468adfa7f28b9cfaa13b3382f299e9e0af204543d221c20",
"tables": 30,
"gridSpan": 0,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.8、RDDHF0213-xxx采购技术说明-结构&硬件.doc",
"format": "doc",
"bytes": 7791188,
"sha256": "77fd422be6f37632052d47a05490312a8e36098eceb6d529653f59dde8fe51ef",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.9.1、731QCP29-Fxx 工艺流程图模板.doc",
"format": "doc",
"bytes": 199173,
"sha256": "1d702e1cdbdca52fe7957b01d13f15f77d447d78498a78e332d4646e27ee014c",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/3.9.2、RDSOP00xx-00xx xxx作业指导书.docx",
"format": "docx",
"bytes": 6312572,
"sha256": "e2d5e596ee1fa24ddd4166f41575167ed054451beb6fdbd1d1bccd15a709ef48",
"tables": 7,
"gridSpan": 1,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/footer2.xml",
"word/footer3.xml",
"word/header1.xml",
"word/header2.xml",
"word/header3.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/3. 设计输出阶段/731QCP33-F01 软件可追溯性分析报告 02.docx",
"format": "docx",
"bytes": 24006,
"sha256": "23d6402dc8511a1ed7815082cc00822f9d62e3b74509bd75302987bfdf538f8a",
"tables": 3,
"gridSpan": 4,
"vMerge": 10,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/24.产品有效期验证.doc",
"format": "doc",
"bytes": 144292,
"sha256": "425e993090eb84c5a88fbc6fe2d664d788d4879a7e173bd8a235b6aa0589311d",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/41.软件单元测试用例-模板.doc",
"format": "doc",
"bytes": 57249,
"sha256": "02f41e0770380332105851d620fbcfc470dbef93d2e7fa55c4b1dad441a7fcc0",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/42.软件集成测试用例-模板.doc",
"format": "doc",
"bytes": 60369,
"sha256": "1a373f9bec235d6771fceec15341c858412737298fad696dd68cb9bf262a5dec",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/43.软件系统测试用例-模板.doc",
"format": "doc",
"bytes": 60915,
"sha256": "22b211453d734668bd8b6a5948a5612ec93bde41838ee0fe0535551124566062",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/49. 软件配置管理报告-模板.doc",
"format": "doc",
"bytes": 63121,
"sha256": "243993a6ab53b475139afbeef04c9be0d593956bb2ae4e90f77c22b2e38b0063",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/731QCP29-F07 设计验证评审记录.docx",
"format": "docx",
"bytes": 28214,
"sha256": "e37ab2828e647ffee84068d8c4ce6520c70b3a3849d37d946cb7bd52bd28efe9",
"tables": 5,
"gridSpan": 35,
"vMerge": 0,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/731QCP29-F08 设计开发验证记录 02.docx",
"format": "docx",
"bytes": 24111,
"sha256": "c5b84546e647259f25b9445358ff93ecf61e047075d83a87b1f0f928df32f69a",
"tables": 1,
"gridSpan": 14,
"vMerge": 0,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/4. 设计验证阶段/756QCP26-F02 验证确认报告 V03-.docx",
"format": "docx",
"bytes": 42712,
"sha256": "f5bbe7816e79a62e7bbbf297014be98a63b9ec306999a09723bef1a78d60b3fd",
"tables": 12,
"gridSpan": 2,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/footer2.xml",
"word/header1.xml",
"word/header2.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/5. 设计转换阶段/731QCP29-F04 风险管理报告 02.docx",
"format": "docx",
"bytes": 31234,
"sha256": "8a17e5b4cff1d4a7d51a8ee5d4cc6b5e4da9c91f3a501cbe91bc3409d3f7b0b9",
"tables": 6,
"gridSpan": 8,
"vMerge": 13,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/5. 设计转换阶段/731QCP29-F07 设计转移评审记录.docx",
"format": "docx",
"bytes": 28214,
"sha256": "e37ab2828e647ffee84068d8c4ce6520c70b3a3849d37d946cb7bd52bd28efe9",
"tables": 5,
"gridSpan": 35,
"vMerge": 0,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/5. 设计转换阶段/731QCP29-F09+试产总结报告+03-20250730.docx",
"format": "docx",
"bytes": 31901,
"sha256": "7600083fa8675a95f2365267801cb3d712bcb0d0534b49371bf12c2abda9a66b",
"tables": 4,
"gridSpan": 23,
"vMerge": 30,
"headers_footers": [
"word/footer1.xml",
"word/header1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/6. 设计确认阶段/53. 使用错误评估报告-模板zlx.doc",
"format": "doc",
"bytes": 136224,
"sha256": "75cafe0c4c26edb2d9430f3c9839c5217106acdb5f205f12dcf3d728a67f5ed8",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/6. 设计确认阶段/731QCP29-F07 设计确认评审记录.docx",
"format": "docx",
"bytes": 28214,
"sha256": "e37ab2828e647ffee84068d8c4ce6520c70b3a3849d37d946cb7bd52bd28efe9",
"tables": 5,
"gridSpan": 35,
"vMerge": 0,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/6. 设计确认阶段/731QCP29-F11 设计开发确认记录 02.docx",
"format": "docx",
"bytes": 23026,
"sha256": "d01ff3c568416c81d7729fe35c4fe0820513dcbf74e2e33c3a6bf7db1453d609",
"tables": 1,
"gridSpan": 9,
"vMerge": 0,
"headers_footers": [
"word/header1.xml",
"word/footer1.xml"
],
"linked_images": []
},
{
"source": ".templates/DHF 文件模板/6. 设计确认阶段/756QCP20-F01 计算机软件确认报告 02.doc",
"format": "doc",
"bytes": 114176,
"sha256": "45e57b363abf14a19e6ef26af23f33b42095e68c1516f1af13f7b73f1f21050d",
"header_hex": "d0cf11e0a1b11ae1"
},
{
"source": ".templates/DHF 文件模板/6. 设计确认阶段/756QCP26-F01 验证确认方案 V03-.docx",
"format": "docx",
"bytes": 44029,
"sha256": "525b2c40d74e09318188216b1cbc3d62ca410cdb55008fa7996ed9bdbc36e3f0",
"tables": 14,
"gridSpan": 33,
"vMerge": 0,
"headers_footers": [
"word/footer1.xml",
"word/footer2.xml",
"word/header1.xml",
"word/header2.xml"
],
"linked_images": []
}
],
"rdm_source_sha256": {
"internal/rdmapp/templates.go": "3defc58f0e20dc15d8cee9d846da0d998ca3caf659af2cca2603b6d8f1741419",
"internal/rdmapp/templates_gen.go": "8d4a68a31b69ab1834e66acc583211614d8177d23e1844bd4aa61c98ff57547c",
"internal/rdmapp/templates_embed.go": "26c940d94639b283fec2add2f2312931321d0bc0cd5e6ebb95c3c3b1c4f188c1",
"internal/rdmapp/compose.go": "b2da219785cbf44ee53d1408e56628f44619c8dd93fb4415f2daa9013b591349",
"internal/rdmapp/structure.go": "116a25bf5e76f940f54ba67b87b855c5953b944a4ca4f088953766a35563fa86",
"internal/rdmapp/parse.go": "9db5e576496b60f54b6be1c6601df14b776075edefd1f712bc78d22d86bb4dc3",
"internal/rdmapp/draftproposal.go": "85c638e9ac5b8c9c81974af6eb33b8e86053d3997ab718169a64cd987d1376a6",
"internal/rdmapp/docsubmission.go": "e8070350ad794b46d226cba3acb9ff78bfed58113f766cf845d194bb6f3d686f",
"internal/rdmapp/docx.go": "7ed609f658cc31ad216464fcea5dbdaa4e25cb56b3de205bc464e9848964db3d",
"internal/rdmapp/export_artifact.go": "07a1a4fe537674e1413e38425a36af3c02e29c9e041f6478f96c45769328b2ce",
"internal/rdmapp/doc_export_visibility.go": "e4fd051ffb643ae3f002b797ee4175b8b3b2a698012c411021492cab372e7580",
"plugins/rdm/plugin.go": "25382894886fef7e9015d254fc416766d9cd7ce355671c088d2c34b0870a2eb8",
"scripts/build-product.sh": "70041237df111f064257a8ba95e463de1db6c734d71a77f0f20efa3fa812de97",
"scripts/pack-release.sh": "ebeb2b6728fb964aa9983c07e022b52e11be7d2efb76c5bbb6941ce13547d360"
},
"business_test": "NOT_RUN",
"doc_conversion": "NOT_RUN"
}
@@ -0,0 +1,210 @@
{
"source": "SELF",
"observed_at_utc": "2026-10-14T14:13:54.776253+00:00",
"repo": "weichen/Agent-System-Dev",
"main_sha": "e1bc2602e18a89e4d75a4bf6cd80bc7f9b4d2164",
"queue_issue": 518,
"issue_content_version": 34,
"issue_updated_at": "2026-10-14T13:41:21Z",
"active_window": "- 当前窗口:无(mq-dev-20261014-537-01 因独立 Stage 8 Review 的三项 Important 整改与安全设计重审,于 2026-10-14T06:06:23.872984+00:00 主动释放)。旧固定 head=6a2f7cd3e610a263b6348efe9084e386dc88f30c / base=4f84c2e1630cd0311643529fae1c3a99f1dd5d64 的 GATE run3076/3077、阶段7人工批准均只对应旧对象;PR #537 已按用户撤销指示关闭,迁移专用远端与本地分支已删除;该任务不再排队。旧 GATE 和阶段结论仅为历史记录。",
"branch_protection": {
"enable_push": false,
"enable_force_push": false,
"block_on_outdated_branch": true,
"enable_status_check": true,
"status_check_contexts": [
"ci / test (pull_request)",
"ci / test-pg (pull_request)",
"ci / svc-realcombo (pull_request)"
],
"required_approvals": 0,
"block_admin_merge_override": true
},
"post_trial_prs": [
{
"number": 539,
"merged": true,
"merge_sha": "d40579ed7fe3bbca68d3c6fcd1bce6707688d59e",
"merged_at": "2026-10-14T06:40:54Z",
"head_sha": "3b0e100fba149dbb29066c2ca3d2a74bbe1d4443",
"issue_body_ref": false,
"issue_comment_refs": [
{
"id": 6017,
"created_at": "2026-10-14T06:42:12Z",
"head": "<!-- facts-539-merge-record-20261014T0700Z -->"
}
]
},
{
"number": 540,
"merged": true,
"merge_sha": "11aa76a3bc1c5047791f9a2de154e451634b6567",
"merged_at": "2026-10-14T08:08:07Z",
"head_sha": "889f64f88167a5314ebfa42a41f9c7a57f91b404",
"issue_body_ref": false,
"issue_comment_refs": [
{
"id": 6025,
"created_at": "2026-10-14T07:02:56Z",
"head": "<!-- dhf-u1-stage7-wip-20261014-01a137f8 -->"
},
{
"id": 6059,
"created_at": "2026-10-14T08:04:24Z",
"head": "<!-- mq-dev-20261014-dhf-u1-01-claim -->"
},
{
"id": 6066,
"created_at": "2026-10-14T08:09:12Z",
"head": "<!-- mq-dev-20261014-dhf-u1-01-release -->"
},
{
"id": 6097,
"created_at": "2026-10-14T08:32:38Z",
"head": "<!-- mq-dev-20261014-dhf-cardclose-01-claim -->"
}
]
},
{
"number": 541,
"merged": true,
"merge_sha": "d23fb4363dcc0a206e71e47f9cd23a644c7e1c70",
"merged_at": "2026-10-14T07:33:18Z",
"head_sha": "221afaeb169b826ecd38567296319c20c0e94b18",
"issue_body_ref": false,
"issue_comment_refs": []
},
{
"number": 542,
"merged": true,
"merge_sha": "7e9ebdea5055a63c713ccc0fb1f938ffe35a6b9d",
"merged_at": "2026-10-14T08:46:12Z",
"head_sha": "60d48e0580a36b2e6f93c77bb1edbe9bd0be342e",
"issue_body_ref": false,
"issue_comment_refs": [
{
"id": 6097,
"created_at": "2026-10-14T08:32:38Z",
"head": "<!-- mq-dev-20261014-dhf-cardclose-01-claim -->"
},
{
"id": 6106,
"created_at": "2026-10-14T08:35:39Z",
"head": "<!-- mq-dev-20261014-dhf-cardclose-02-replacement -->"
},
{
"id": 6117,
"created_at": "2026-10-14T08:47:12Z",
"head": "<!-- mq-dev-20261014-dhf-cardclose-02-release -->"
}
]
},
{
"number": 543,
"merged": true,
"merge_sha": "da93edf23408ca871ae489ac2123e10734c24413",
"merged_at": "2026-10-14T09:24:42Z",
"head_sha": "deac1025f1810d7a535c44a16dd6368eb652c979",
"issue_body_ref": false,
"issue_comment_refs": []
},
{
"number": 544,
"merged": true,
"merge_sha": "2dbe11c5d970e7d6a71d0ce1a00eb399bfbbd427",
"merged_at": "2026-10-14T09:00:43Z",
"head_sha": "b926c701f261995b6e1acabf277bbfdfa47829ca",
"issue_body_ref": false,
"issue_comment_refs": []
},
{
"number": 545,
"merged": true,
"merge_sha": "c8eead49c5e68b2e295927c0e82cc57bcb04bad5",
"merged_at": "2026-10-14T09:10:29Z",
"head_sha": "00b35c5e6f5e0a0bc8072ff5c8c56378e6641d85",
"issue_body_ref": false,
"issue_comment_refs": []
},
{
"number": 546,
"merged": true,
"merge_sha": "3538d40f45ad5a7c779426eb3322f79751db380c",
"merged_at": "2026-10-14T09:40:57Z",
"head_sha": "4a15fa0ceadf716fb93cc2966f099f3915b5f9d9",
"issue_body_ref": false,
"issue_comment_refs": []
},
{
"number": 547,
"merged": true,
"merge_sha": "bcf225d0b981dcd69f8c736010c69b6a92d04341",
"merged_at": "2026-10-14T09:53:34Z",
"head_sha": "8522502e6e6db7a438a8f6fd391e1aa334c7a161",
"issue_body_ref": false,
"issue_comment_refs": []
},
{
"number": 548,
"merged": true,
"merge_sha": "e1bc2602e18a89e4d75a4bf6cd80bc7f9b4d2164",
"merged_at": "2026-10-14T10:05:47Z",
"head_sha": "b89dd1c20ef4aa5c93a144f00e722a81dee87a50",
"issue_body_ref": false,
"issue_comment_refs": []
}
],
"open_prs": [
{
"number": 512,
"draft": true,
"mergeable": false,
"head_sha": "89125b8dda5f8f988a8a760ed64bf00827e1de5c",
"base_sha": "e1bc2602e18a89e4d75a4bf6cd80bc7f9b4d2164",
"title": "[WIP] Deliver progressive U2/U3 work with reliable sourced checkpoints"
},
{
"number": 482,
"draft": false,
"mergeable": false,
"head_sha": "d5e8d6ab7a368f08b29e968b6f65f8898f2b28f5",
"base_sha": "e1bc2602e18a89e4d75a4bf6cd80bc7f9b4d2164",
"title": "Pin the SQLite activity guard and document its refusals"
}
],
"selected_runs": [
{
"run": 3088,
"head_sha": "6463ef430640c56940b82776adb504ee272f030c",
"status": "completed",
"conclusion": "success",
"started_at": "2026-10-14T07:02:04Z",
"completed_at": "2026-10-14T07:09:41Z"
},
{
"run": 3092,
"head_sha": "889f64f88167a5314ebfa42a41f9c7a57f91b404",
"status": "completed",
"conclusion": "success",
"started_at": "2026-10-14T07:49:37Z",
"completed_at": "2026-10-14T07:58:00Z"
},
{
"run": 3100,
"head_sha": "7dd8d0f52ed930fbcabc05f5c4b1fb2b41b10bc5",
"status": "completed",
"conclusion": "success",
"started_at": "2026-10-14T08:28:25Z",
"completed_at": "2026-10-14T08:43:31Z"
},
{
"run": 3107,
"head_sha": "60d48e0580a36b2e6f93c77bb1edbe9bd0be342e",
"status": "completed",
"conclusion": "success",
"started_at": "2026-10-14T08:33:36Z",
"completed_at": "2026-10-14T08:45:31Z"
}
]
}
@@ -0,0 +1,51 @@
# 合入调度首轮受控试行(2026-10-14)
状态:三个真实任务已由智能体依次合入;本报告记录 **manual** 模式的实际观察。是否扩大试行、调整预算或建设自动领取,仍待用户评审。依据为[已批准的实施计划](../proposals/2026-10-13-merge-queue-implementation-plan.md) U5–U6、[Dev 项目规则](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/src/branch/main/policy/merge-queue.md)和[唯一调度记录 #518](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/issues/518)。本报告不代表发布、部署或运行服务验收。
## 范围与证据口径
用户授权由当前智能体接管已有的 Dev #489、#488、#486,确认三者没有其他活动写者;所有实际 PR 合入由智能体执行。Dev `refs/heads/main` 的仓库 ID=29,协调者和窗口在 #518 登记。原任务 R0 各自不同,未伪称共同启动 SHA。组件先按自身目标交付,再固定 Dev 父仓组合;等待的 Dev 源分支没有随前一个正常合入反复同步、推最终候选或跑最终 CI。
证据分层:本机 `make evidence`、API 读取及隔离夹具输出是 **SELF**;`/root/merge_queue_review` 或 `/root/docs_delivery_review` 对固定对象的独立重放另记 **REPLAY**;Gitea Actions 的实际运行链接、作业身份和精确 SHA 才作为 **GATE**。原始 SELF 收据保存在各任务卡、#518 所指 `/tmp/mq-*` 路径及本轮私人状态目录;本文件只列对象、结论和索引,不转写命令输出。未执行的负例继续标 `NOT_RUN`。
平台前置使用用户亲手设置的私有夹具仓库 repoID38 `main` 保护规则。用户修正字段后,Root 只读回读六字段;隔离实测缺检查、失败检查、陈旧绿色候选、匿名请求及已认证绿色候选直推拒绝,合法固定候选由智能体合入。原始 SELF 收据和独立 REPLAY 索引在 #518。该夹具证明所测入口的拒绝/合法路径,不证明 Dev 所有角色、全部写者的机器隔离或旧执行者 fencing。Dev 三项业务检查仍须逐候选运行。
## 三个真实条目
| 顺序 | 原任务 R0 | 先行组件 | Dev 最终 base → head | 独立 Review 与当前 HEAD GATE | 实际合入 main |
|---|---|---|---|---|---|
| [#489](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489) | `cd61bbb112eea6a210a64e84f2cef00b0d64bfc1` | [Documents #89](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89) → `7bd4e17827d4c7c88647bf3c9199c495b60cb107` | `add097d06137c4912a4ed9279e98ca353e4e4cf1` → `5e6bf4aa0546d68fb3f872158f22b2791c301a60` | `/root/docs_delivery_review` PASS;[run 3038](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3038) 三作业成功 | `f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60` |
| [#488](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488) | `99048dda1f48bccb3d5d798050d7beeea2907177` | [Frontend #73](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73) → `5313cfad4e633d0909ed40dcdfa28a11bc1902c0`;[RDM #301](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301) → `ef5100a020abdd8ba8712c3d15c04c28bcac6e84` | `f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60` → `a70de2c54a74e175ad12c8d52ac29d0bafce9491` | `/root/merge_queue_review` PASS、隔离浏览器 7/7;[run 3050](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3050) 三作业成功 | `d852c159b6b3387a2f418a42ab6d3696ac873d01` |
| [#486](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/486) | `4d362537d0e8755a03b1757b5bad92779a064b33` | [Backend #185](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/185) → `8e80e2618eb7471dd12d5f172ff3cd23622b7d2f` | `d852c159b6b3387a2f418a42ab6d3696ac873d01` → `d805cc1697ae7f49d371a56a6a55191f00897b8c` | `/root/merge_queue_review` PASS;[run 3067](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3067) 三作业成功 | `05b997b84db26c517604c48d12676f0eb2b86e18` |
三个 Dev 合入都用固定 `head_commit_id`、`force_merge=false`,合入后从远端重新读取 PR/main 并核对完整 tree 与已审候选一致;组件 gitlink 没有回退。#489 首个合入响应后的本地指针统计出错,Root 先从 PR/main 重新对账再释放窗口,未重发合入请求。#488 的独立浏览器验收使用临时二进制/私有环境,未操作 live 服务。#486 的 U7 安全审阅先发现 B1–B7,Backend 在推最终源 HEAD 前修复并以隔离 PostgreSQL 真实交叠、跨进程、SIGTERM/SIGKILL 重放;Dev 最终组合继续通过本地 `make test`、隔离 PostgreSQL/Redis `make test-backend-pg` 和 `make build` 的 SELF 检查,GATE 另见表内 run 3067。
## 同步、CI、等待与恢复
每条 Dev 任务对其本轮最新目标仅发生一次真实纳入;固定后同基线 `task-sync` 核验不生成提交。#489 为纠正旧启动状态,在正式窗口前完成源码/组件整改与目标纳入;这与理想的“领取窗口后才第一次纳入”不同,不能抹去。#488、#486 都在领取最终窗口后才执行 `changed=1`,随后成功的固定 HEAD 检查为 `changed=0`。#486 一次无变更检查被嵌套 Git 的短暂 `index.lock` 拒绝,未删锁;持锁操作结束后原对象复核通过。原始失败和成功收据都在 #518。
| Dev PR | 目标纳入次数 | 固定后成功的无变更核验 | 本轮最终 PR CI | 作业运行时长(test / test-pg / svc-realcombo) | runner 等待 |
|---|---:|---:|---|---|---|
| #489 | 1(启动整改期) | 至少 3 次,均未改 HEAD | [3038](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3038):1 次、3/3 成功 | 5:10 / 7:22 / 1:46 | 每作业 3 秒 |
| #488 | 1(最终窗口) | 2 次,均未改 HEAD | [3050](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3050):1 次、3/3 成功 | 5:12 / 8:42 / 1:54 | 每作业 3 秒 |
| #486 | 1(最终窗口) | 1 次成功;另 1 次锁拒绝未推进 | [3067](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3067):1 次、3/3 成功 | 5:01 / 7:19 / 1:54 | 每作业 3 秒 |
三次最终 PR CI 共 3 个 run、9 个必需作业,**因本轮正常排队任务移动 main 而废弃的最终 run 为 0**;没有拿旧绿色检查放行新 HEAD。合入后 main push CI 单列:[run 3040](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3040) 对 #489 合入树、[run 3053](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3053) 对 #488 合入树、[run 3068](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3068) 对 #486 合入树,各自另有 3/3 作业成功;共 3 个 push run、9 个作业,不能省略这部分实际 CI 成本。3068 在 04:43:55Z 完成,精确对象为 `05b997b84db26c517604c48d12676f0eb2b86e18`。组件仓的 GATE/N/A 与 RDM #301 任务卡闭合 [PR #364](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/364) 的 CI 不计入上述 Dev 目标 run。
自 2026-10-12 起查询到三个 PR 另有 13 次**试行前开发** Actions run(#489 2、#488 7、#486 4;6 成功、7 失败),其对象与本轮最终候选不同;原始只读清单 `/tmp/mq-trial-ci-history-20261014.json`。这些运行既不能当本轮最终准入,也不能归因于本轮 main 移动。runner 作业等待时间以各 GATE job 的 `created_at`→`started_at` 计算;人的准备/依赖等待没有统一的入队就绪时间戳,本轮不填造净等待时长。仅可复核首次最终同步到合入的可观测下界:#489 19:49、#488 24:20、#486 18:46;它们含测试、Review 和平台等待,不等同完整窗口耗时。三条目均未重新领取最终目标窗口;启动整改、#488 的 E2E 夹具失败、#486 的一次锁拒绝分别保留,不计成 CI 废弃或窗口接管成功。
## 验收与下一步边界
| 验收 | 本轮结论 | 依据及限制 |
|---|---|---|
| MQ1 | 部分满足 | 三任务顺序合入且后继未提前最终同步;最终 CI 0 次因正常排队合入废弃。#489 的目标纳入发生在启动整改期,严格“领取后首同步”未由该例满足。 |
| MQ2 | manual 已登记;原子互斥 `NOT_RUN` | 单协调者与目标窗口记录有效;重复领取的执行端拒绝及旧代次 fencing 未实现/未测。 |
| MQ3 | 本轮通过 | 三个固定对象有同基线无变更核验;#486 短暂锁失败被拒绝且重验不改 HEAD。 |
| MQ4 | 本轮通过 | 三个最终 HEAD 各跑实际新 CI;隔离夹具的陈旧绿色候选被拒。没有把组件/旧分支检查当父仓 GATE。 |
| MQ5 | 部分满足 | #486 活动锁阻断并自行恢复,#489/#488 源码和夹具问题在固定前整改;人工超时释放及无依赖任务并行负例 `NOT_RUN`。 |
| MQ6 | 部分满足 | 组件先合入,后继父仓保留其他能力;紧急插队导致候选失效的真实路径 `NOT_RUN`。 |
| MQ7 | 部分满足 | #489 合入后本地异常先对账,未重复 POST;未知请求结果与旧执行者失联接管 `NOT_RUN`。 |
| MQ8 | manual 范围通过 | 私有夹具正负例、Dev 精确 GATE 和合法智能体合入均有对象证据;全部角色/自动 fencing `NOT_RUN`。 |
| MQ9 | 待文档 PR Review | 权威规范、Dev 采纳、调度记录、实际 PR/运行互相链接;本报告的最终交叉检查需随文档 PR 完成。 |
建议维持单协调者的 **manual** 模式,按目标串行领取,把组件准备与父仓最终 CI 分开。首次试行证明“等待分支不因正常合入反复重跑最终 CI”在这三项中成立;没有可比历史基线,**不报告节省百分比**。自动模式须另行建设并验证原子持久领取、执行端旧代次拒绝、角色覆盖和异常接管,不能从本轮人工遵约推导已具备。扩大试行与预算调整留待用户阶段评审决定;本报告不替代该决定。
+38
View File
@@ -0,0 +1,38 @@
# 通用规范采纳记录
- 项目/负责人:Agent-System-Documents / weichen
- 状态:active
- 规范位置:`deps/development-guidelines`(gitlink,见下方版本权威)
- 规范性文档目录:`policy/`(本仓当前仅含本采纳记录,无其他规范性文档;项目规则与制度放此处)
- 过程文档位置:过程记录保存在本仓 `docs/` 固定目录,不另设独立过程仓库:实施记录 `docs/records/`、设计方案与计划 `docs/proposals/`(索引 `docs/proposals/INDEX.md`)、测试报告 `docs/reports/`、使用报告与插件开发指南 `docs/guides/`,目录入口见 `README.md`(仓内固定目录的登记见下方项目差异表);`.task/` 仅为治理交付流程的任务卡与证据位置(随 PR 维护),任务主记录在 PR 描述中
- 版本权威:本仓 gitlink `deps/development-guidelines` @ `2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb`(可读标签:无,固定提交的 VERSION 为 0.1.0-draft.12)
- 批准/生效依据:`feature/governance-adoption` PR(Agent-System-Documents)
- 替代范围和迁移说明:无。既有 AGENTS.md、PROJECT.md、AGENT-EXECUTION.md、docs/ 与 .task/ 全部保留,不替代、不迁移历史记录。
| 规范/工作流 | 适用条件与范围 | 采纳或不适用理由 | 执行方式/证据 |
|---|---|---|---|
| core/baseline.md | 本仓全部工作(文档、治理与任务交付) | 适用:所有变更遵循其强度与授权定义 | manual;AGENTS.md 入口 |
| workflows/delivery.md、debugging.md、handoff.md | 交付(任务卡 + PR)、排障、跨会话交接 | 适用:交付经 `.task/` 任务卡与 PR 进行;交接状态写入任务主记录 | manual;AGENTS.md 与 `.task/feature-governance-adoption.md` |
| standards/collaboration.md | 并行共同起点、两级分支、节点同步与陈旧候选拒绝 | 适用:AGENTS.md 启动门禁要求从权威 origin/main 固定起点并同步 | manual;AGENTS.md 启动门禁与任务卡同步记录 |
| standards/merge-queue.md | 多个就绪任务同一目标分支的串行交付调度 | 不适用:本仓不单独维护同一目标分支的多任务交付队列,本仓自身的交付不经队列调度。本仓存放的合入调度试行记录 [docs/records/2026-10-14-merge-queue-trial.md](../docs/records/2026-10-14-merge-queue-trial.md) 与实施计划 [docs/proposals/2026-10-13-merge-queue-implementation-plan.md](../docs/proposals/2026-10-13-merge-queue-implementation-plan.md) 记录的是 Agent-System-Dev 的调度(依据 Dev 仓 `policy/merge-queue.md` 与 Dev #518),本仓仅以文档形式保存 | 不适用 |
| standards/agent-execution.md | 工程 Agent CLI 执行路由、会话隔离与受控集成 | 适用:允许 AI 协助文档与治理变更,必须采纳;配置见 AGENT-EXECUTION.md | AGENT-EXECUTION.md + scripts/agent-exec(validate / admit);证据:governance check 与 CLI 正负例(`.task/feature-governance-adoption.md`) |
| standards/verification.md | 验证与结论 | 适用:本仓无可编译程序,验证以文档检查与治理检查为主 | `git diff --check`、`scripts/dm governance check --repo .`、`scripts/agent-exec validate --repo .`(PROJECT.md 验证节);`.gitea/workflows/governance.yml` |
| standards/documentation.md | 文档结构、相对链接、版本与引用一致性 | 适用:本仓即系统文档仓(docs/ 与 README 目录) | manual;PROJECT.md 验证节 |
| standards/multi-repo.md | 跨仓 gitlink 与组合验证 | 适用:Development-Guidelines 与 Development-Manager 以 gitlink 挂载,gitlink 变更须经 Dev 仓组合验证后推进 | manual;AGENTS.md 仓内规则 |
| standards/security.md | 凭证与秘密不入仓 | 适用:AGENTS.md 规定 token 不入仓、不回显、不写入产出物 | manual;AGENTS.md Gitea 访问事实节 |
| workflows/design-verification.md、standards/testability.md、standards/failure-containment.md | 功能增量的设计/验证、模块测试与故障控制 | 不适用:本仓不含产品代码、运行服务或业务测试套件(见 PROJECT.md 验证节) | 不适用 |
| standards/module-contracts.md、observability.md、data-reliability.md、release-operations.md、configuration.md、tool-adaptation.md | 业务模块契约、观测、数据可靠性、发布运维、运行配置、工具适配 | 不适用:本仓无业务模块、运行服务、发布制品或运行配置;模块边界如出现时再启用 | 不适用 |
## 项目差异
| 原规则/章节 | 项目采用方式 | 原因与风险 | 负责人/复查条件 |
|---|---|---|---|
| standards/documentation.md 过程记录位置 | 登记为仓内固定目录豁免:过程记录保存于 `docs/records/`、`docs/proposals/`、`docs/reports/`、`docs/guides/`(按 `README.md` 目录),任务卡与证据保存于 `.task/`;不另设独立过程仓库 | 本仓即系统文档与过程记录仓(见 `README.md`),过程记录本身是其内容,拆出独立仓会使文档与其引用的实施记录分离。风险:规范文档与过程记录同仓,需依靠目录边界与 `docs/proposals/INDEX.md` 区分 | weichen;复查条件:建立独立过程仓库,或 Development-Guidelines 固定版本变更过程记录位置规则时复查 |
默认做法差异说明理由;硬边界冲突须有明确有效决策,不能用此表自授权。建议不采用无需登记。
## 本次升级或首次接入验证
本次为首次接入,采用 `governance init --adopt` 固定 Development-Guidelines `2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb` 与 Development-Manager `bd3a7de57a3a9e1a4495b94c5fa5c08d71e7be8c`。既有 AGENTS.md、PROJECT.md、AGENT-EXECUTION.md 保留,新增治理文件见 `scripts/`、`.gitea/workflows/governance.yml`、`.task/templates/task-card.md`。正负例与 `governance check`、`agent-exec validate` 的输出证据记录于 `.task/feature-governance-adoption.md`。
回退方式:删除两个 gitlink(`deps/development-guidelines`、`deps/development-manager`)、`.gitmodules`、`scripts/`、`.gitea/workflows/governance.yml`、`.task/templates/task-card.md` 与本记录,并撤销 AGENTS.md 与 PROJECT.md 中新增的段落。回退前须确认不再有任务依赖 `scripts/agent-exec` 路由。
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# 共享 Agent 执行器薄入口:转调 scripts/dm 的 agent-exec 子命令(validate / run / apply / admit / cleanup)。
set -euo pipefail
exec "$(dirname "$0")/dm" agent-exec "$@"
Executable
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# 共享 dm-server 薄入口:读取 deps/development-manager 的 gitlink 钉住提交,
# 按该提交构建并缓存 dm-server,再 exec 其子命令(agent-exec、task、governance)。执行语义与退出码以该二进制为准。
set -euo pipefail
root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)
dm="$root/deps/development-manager"
die() { echo "dm: $*" >&2; exit 2; }
# git 钩子会导出仓库本地变量(GIT_DIR、GIT_INDEX_FILE 等),它们会让 `git -C "$dm"` 解析到外层仓库。
# 所有针对 DM 检出的 git 与 go 调用都在清除这些变量后执行;读取外层 gitlink 与最终 exec 仍保留继承环境。
dm_local_env="GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_PREFIX GIT_OBJECT_DIRECTORY GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_GRAFT_FILE GIT_NAMESPACE GIT_CONFIG GIT_CONFIG_PARAMETERS GIT_CONFIG_COUNT GIT_SHALLOW_FILE GIT_IMPLICIT_WORK_TREE $(git rev-parse --local-env-vars 2>/dev/null || true)"
dm_clean_env() { for v in $dm_local_env; do unset "$v"; done; }
dmgit() ( dm_clean_env; git -C "$dm" "$@" )
# 1. 钉住版本只来自索引中的 gitlink(mode 160000),不读取工作区文件。
entry=$(git -C "$root" ls-files -s -- deps/development-manager 2>/dev/null || true)
[ -n "$entry" ] || die "索引中缺少 deps/development-manager 的 gitlink,无法确定钉住的 DM 版本"
read -r mode pin _stage _path <<<"$entry"
[ "$mode" = 160000 ] || die "deps/development-manager 不是 gitlink(mode=$mode)"
[[ "$pin" =~ ^[0-9a-f]{40}$ ]] || die "gitlink 提交格式无效:$pin"
# 2. 检出必须存在且确为 DM 独立仓库(避免 git -C 误解析到外层仓库),HEAD 必须等于钉住提交。
[ -e "$dm/.git" ] || die "deps/development-manager 未检出;请按钉住提交 $pin 检出该 gitlink"
top=$(dmgit rev-parse --show-toplevel 2>/dev/null || true)
[ -n "$top" ] && [ "$top" = "$(cd "$dm" && pwd -P)" ] \
|| die "deps/development-manager 不是独立检出;请按钉住提交 $pin 检出该 gitlink"
head=$(dmgit rev-parse HEAD 2>/dev/null || true)
[ "$head" = "$pin" ] \
|| die "deps/development-manager HEAD(${head:-未知})与钉住提交 $pin 不一致;请按钉住提交检出"
# 3. 检出工作树必须干净(忽略嵌套 submodule 状态)。
dirty=$(dmgit status --porcelain --ignore-submodules=all) \
|| die "无法读取 deps/development-manager 的工作树状态"
[ -z "$dirty" ] || die "deps/development-manager 存在未提交改动,拒绝运行(请先清理该检出)"
# 4. 二进制按钉住提交缓存;缺失时在缓存目录内临时构建,完成后原子改名,避免留下半成品。
cache="${DM_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/development-manager/dm-server}"
bin="$cache/dm-server-$pin"
if [ ! -x "$bin" ]; then
command -v go >/dev/null 2>&1 || die "缺少 go,无法构建 dm-server($pin)"
mkdir -p "$cache"
cache=$(cd "$cache" && pwd -P)
bin="$cache/dm-server-$pin"
work=$(mktemp -d "$cache/build-$pin.XXXXXX")
if ! (dm_clean_env; cd "$dm" && GOWORK=off go build -trimpath -o "$work/dm-server" ./cmd/dm-server); then
rm -rf "$work"
die "构建 dm-server 失败($pin)"
fi
mv -f "$work/dm-server" "$bin"
rm -rf "$work"
fi
exec "$bin" "$@"
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# 本地检查(pre-commit):集成分支直提拒绝 + 分支命名 + 本地完整性核对。权威准入在 PR(baseline.md:26)。
branch=$(git rev-parse --abbrev-ref HEAD)
case "$branch" in
main|master)
echo "pre-commit: 拒绝——集成分支 ${branch} 不得直接提交,走 feature 分支 + PR(collaboration.md)" >&2
exit 1 ;;
esac
echo "$branch" | grep -qE '^(feature|fix|hotfix|release)/[A-Za-z0-9._-]+$' || {
echo "pre-commit: 拒绝——分支名须为 feature|fix|hotfix|release/<slug>,当前:${branch}" >&2
exit 1
}
root=$(git rev-parse --show-toplevel)
# admit 只是本地完整性/篡改证据(SELF):同一 OS 用户可读取本地 HMAC 密钥并绕过本钩子,
# 它不是 GATE,也不是可信身份。缺失或无效的本地记录仍拒绝;交付信任来自精确 HEAD 的 CI 或独立 REPLAY。
"$root/scripts/agent-exec" admit --repo "$root"
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# 通用任务入口:转调 scripts/dm 的 task 子命令(triage / start / pr-check)。
set -euo pipefail
exec "$(dirname "$0")/dm" task "$@"