Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d73d2e8633 | ||
|
|
111f25c9a8 | ||
|
|
e5e09560c7 | ||
|
|
b67816a898 | ||
|
|
56eb0ed4fe | ||
|
|
8c9a12d996 | ||
|
|
dd30e061d8 | ||
|
|
2e826e7f58 |
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"hooks": {
|
||||
"beforeShellExecution": [
|
||||
{
|
||||
"command": ".cursor/hooks/guard-git.sh",
|
||||
"matcher": "^git ",
|
||||
"timeout": 10,
|
||||
"failClosed": true
|
||||
},
|
||||
{
|
||||
"command": ".cursor/hooks/guard-pi-shell.sh",
|
||||
"matcher": "pi_subagents\\.py|pkill",
|
||||
"timeout": 10,
|
||||
"failClosed": true
|
||||
}
|
||||
],
|
||||
"beforeMCPExecution": [
|
||||
{
|
||||
"command": ".cursor/hooks/guard-pi-dispatch.sh",
|
||||
"matcher": "pi-subagents|pi_subagent_",
|
||||
"timeout": 10,
|
||||
"failClosed": true
|
||||
}
|
||||
],
|
||||
"postToolUse": [
|
||||
{
|
||||
"command": ".cursor/hooks/pi-receipt-context.sh",
|
||||
"matcher": "MCP: pi-subagents|pi_subagent_",
|
||||
"timeout": 10,
|
||||
"failClosed": false
|
||||
}
|
||||
],
|
||||
"sessionStart": [
|
||||
{
|
||||
"command": ".cursor/hooks/audit-session.sh",
|
||||
"timeout": 20,
|
||||
"failClosed": false
|
||||
}
|
||||
],
|
||||
"stop": [
|
||||
{
|
||||
"command": ".cursor/hooks/audit-session.sh",
|
||||
"timeout": 10,
|
||||
"failClosed": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Shared helpers for project Cursor hooks (advisory gates + audit/probe)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
KNOWN_ROLES = frozenset(
|
||||
{
|
||||
"research",
|
||||
"planning",
|
||||
"requirements_review",
|
||||
"plan_review",
|
||||
"code_review",
|
||||
"diagnosis",
|
||||
"test_run",
|
||||
"acceptance_check",
|
||||
"stage_notes",
|
||||
"report",
|
||||
"auxiliary",
|
||||
}
|
||||
)
|
||||
TEST_ROLES = frozenset({"test_run", "acceptance_check"})
|
||||
FULL_SHA = re.compile(r"^[0-9a-fA-F]{40}$")
|
||||
REQUEST_ID = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$")
|
||||
|
||||
|
||||
def repo_root() -> Path:
|
||||
env = os.environ.get("CURSOR_PROJECT_DIR") or os.environ.get("CURSOR_WORKSPACE_ROOT")
|
||||
if env:
|
||||
return Path(env).resolve()
|
||||
# hooks run with cwd = project root
|
||||
return Path.cwd().resolve()
|
||||
|
||||
|
||||
def audit_path() -> Path:
|
||||
return repo_root() / ".cursor" / "hook-audit.jsonl"
|
||||
|
||||
|
||||
def probe_path() -> Path:
|
||||
return repo_root() / ".cursor" / "hook-probe.jsonl"
|
||||
|
||||
|
||||
def inventory_dir() -> Path:
|
||||
return repo_root() / ".cursor" / "hook-audit"
|
||||
|
||||
|
||||
def append_jsonl(path: Path, record: dict[str, Any]) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
record = dict(record)
|
||||
record.setdefault("ts", datetime.now(timezone.utc).isoformat())
|
||||
with path.open("a", encoding="utf-8") as fh:
|
||||
fh.write(json.dumps(record, ensure_ascii=False) + "\n")
|
||||
|
||||
|
||||
def read_stdin() -> str:
|
||||
return sys.stdin.read()
|
||||
|
||||
|
||||
def maybe_probe(raw: str, hook: str) -> None:
|
||||
if os.environ.get("CURSOR_HOOKS_PROBE", "").strip() not in ("1", "true", "TRUE", "yes"):
|
||||
return
|
||||
append_jsonl(
|
||||
probe_path(),
|
||||
{"hook": hook, "raw": raw[:65536], "raw_len": len(raw)},
|
||||
)
|
||||
|
||||
|
||||
def parse_json_loose(raw: str) -> dict[str, Any] | None:
|
||||
raw = (raw or "").strip()
|
||||
if not raw:
|
||||
return None
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
return data if isinstance(data, dict) else None
|
||||
|
||||
|
||||
def first_key(data: dict[str, Any], *names: str) -> Any:
|
||||
for name in names:
|
||||
if name in data and data[name] is not None:
|
||||
return data[name]
|
||||
return None
|
||||
|
||||
|
||||
def normalize_tool_name(name: str | None) -> str | None:
|
||||
"""Strip Cursor MCP prefixes such as 'MCP:' / 'MCP: pi-subagents/'."""
|
||||
if name is None:
|
||||
return None
|
||||
n = str(name).strip()
|
||||
# Observed IDE postToolUse: tool_name == "MCP:pi_subagent_roles"
|
||||
if n.upper().startswith("MCP:"):
|
||||
n = n[4:].lstrip()
|
||||
# Rare: "MCP: pi-subagents/pi_subagent_run"
|
||||
if "/" in n and n.rsplit("/", 1)[-1].startswith("pi_subagent_"):
|
||||
n = n.rsplit("/", 1)[-1]
|
||||
return n or None
|
||||
|
||||
|
||||
def tool_name(data: dict[str, Any]) -> str | None:
|
||||
v = first_key(data, "tool_name", "mcp_tool_name", "name", "toolName")
|
||||
return normalize_tool_name(str(v) if v is not None else None)
|
||||
|
||||
|
||||
def mcp_server(data: dict[str, Any]) -> str | None:
|
||||
v = first_key(data, "mcp_server_name", "server", "mcpServer", "server_name")
|
||||
return str(v) if v is not None else None
|
||||
|
||||
|
||||
def tool_input(data: dict[str, Any]) -> dict[str, Any] | None:
|
||||
v = first_key(data, "tool_input", "arguments", "input", "toolInput", "params")
|
||||
if isinstance(v, dict):
|
||||
return v
|
||||
if isinstance(v, str):
|
||||
try:
|
||||
parsed = json.loads(v)
|
||||
return parsed if isinstance(parsed, dict) else None
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
def shell_command(data: dict[str, Any]) -> str:
|
||||
v = first_key(data, "command", "shell_command", "cmd")
|
||||
return str(v) if v is not None else ""
|
||||
|
||||
|
||||
def emit(obj: dict[str, Any]) -> None:
|
||||
sys.stdout.write(json.dumps(obj, ensure_ascii=False))
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def allow() -> None:
|
||||
emit({"permission": "allow"})
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
def ask(user_message: str, agent_message: str) -> None:
|
||||
emit(
|
||||
{
|
||||
"permission": "ask",
|
||||
"user_message": user_message,
|
||||
"agent_message": agent_message,
|
||||
}
|
||||
)
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
def additional_context(text: str) -> None:
|
||||
emit({"additional_context": text})
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
def audit(hook: str, code: str, **extra: Any) -> None:
|
||||
rec = {"hook": hook, "code": code}
|
||||
rec.update(extra)
|
||||
try:
|
||||
append_jsonl(audit_path(), rec)
|
||||
except OSError:
|
||||
pass
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/audit_session.py"
|
||||
@@ -1,101 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""sessionStart / stop: audit + optional fail-open inventory (no context injection)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "audit-session"
|
||||
INVENTORY_TIMEOUT = 15
|
||||
|
||||
|
||||
def _run_inventory(root: Path) -> dict:
|
||||
out: dict = {"cleanup_report": None, "docs_drift": None, "errors": []}
|
||||
if os.environ.get("CURSOR_HOOKS_NO_INVENTORY", "").strip() in ("1", "true", "TRUE", "yes"):
|
||||
out["skipped"] = "CURSOR_HOOKS_NO_INVENTORY"
|
||||
return out
|
||||
agentctl = root / "scripts" / "agentctl.py"
|
||||
if not agentctl.is_file():
|
||||
out["errors"].append("agentctl.py missing")
|
||||
return out
|
||||
for label, args in (
|
||||
("cleanup_report", ["cleanup", "report"]),
|
||||
("docs_drift", ["docs", "drift"]),
|
||||
):
|
||||
try:
|
||||
r = subprocess.run(
|
||||
["python3", "-B", str(agentctl), *args],
|
||||
cwd=str(root),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=INVENTORY_TIMEOUT,
|
||||
check=False,
|
||||
)
|
||||
payload = None
|
||||
for stream in (r.stdout, r.stderr):
|
||||
for line in (stream or "").splitlines():
|
||||
line = line.strip()
|
||||
if line.startswith("{"):
|
||||
try:
|
||||
payload = json.loads(line)
|
||||
break
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
if payload is not None:
|
||||
break
|
||||
out[label] = {
|
||||
"exit_code": r.returncode,
|
||||
"payload": payload,
|
||||
"stdout_tail": (r.stdout or "")[-2000:],
|
||||
"stderr_tail": (r.stderr or "")[-1000:],
|
||||
}
|
||||
except subprocess.TimeoutExpired:
|
||||
out["errors"].append(f"{label}: timeout>{INVENTORY_TIMEOUT}s")
|
||||
except OSError as exc:
|
||||
out["errors"].append(f"{label}: {exc}")
|
||||
return out
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw) or {}
|
||||
event = str(
|
||||
lib.first_key(data, "hook_event_name", "event", "event_name", "type") or "unknown"
|
||||
)
|
||||
root = lib.repo_root()
|
||||
if "start" in event.lower() or event == "unknown":
|
||||
inv = _run_inventory(root)
|
||||
inv_path = None
|
||||
try:
|
||||
inv_dir = lib.inventory_dir()
|
||||
inv_dir.mkdir(parents=True, exist_ok=True)
|
||||
ts = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
|
||||
path = inv_dir / f"inventory-{ts}.json"
|
||||
path.write_text(json.dumps(inv, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
inv_path = str(path)
|
||||
except OSError:
|
||||
pass
|
||||
lib.audit(
|
||||
HOOK,
|
||||
"SESSION_AUDIT",
|
||||
event=event,
|
||||
inventory_path=inv_path,
|
||||
inventory_errors=inv.get("errors"),
|
||||
)
|
||||
else:
|
||||
lib.audit(HOOK, "SESSION_AUDIT", event=event)
|
||||
|
||||
lib.emit({})
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fail-closed red-line gate for destructive / unauthorized git. Does not replace agentctl leases.
|
||||
set -euo pipefail
|
||||
input=$(cat)
|
||||
command=$(printf '%s' "$input" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("command") or "")')
|
||||
|
||||
ask() {
|
||||
local user_msg="$1"
|
||||
local agent_msg="$2"
|
||||
python3 -c 'import json,sys; print(json.dumps({"permission":"ask","user_message":sys.argv[1],"agent_message":sys.argv[2]}))' "$user_msg" "$agent_msg"
|
||||
exit 0
|
||||
}
|
||||
|
||||
allow() {
|
||||
echo '{"permission":"allow"}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Normalize whitespace for matching
|
||||
cmd=$(printf '%s' "$command" | tr '\n' ' ')
|
||||
|
||||
# Unauthorized push (user must confirm)
|
||||
if printf '%s' "$cmd" | grep -Eq '(^|[[:space:]])git([[:space:]]+-[^[:space:]]+)*[[:space:]]+push([[:space:]]|$)'; then
|
||||
ask "git push 需要显式用户授权(AGENTS remote_sync)。请确认后再继续。" \
|
||||
"Hook blocked git push pending user authorization."
|
||||
fi
|
||||
|
||||
# Destructive / force operations
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+.*(--force|-f)([[:space:]]|$)' \
|
||||
|| printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+push[[:space:]].*\+'; then
|
||||
ask "检测到 git --force / 强推。破坏性操作须用户明确授权。" \
|
||||
"Hook requires confirmation for force git operation."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+reset[[:space:]]+.*--hard'; then
|
||||
ask "git reset --hard 会丢弃工作区。须用户明确授权。" \
|
||||
"Hook requires confirmation for git reset --hard."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+clean[[:space:]]+.*-[a-zA-Z]*f'; then
|
||||
ask "git clean -f 会删除未跟踪文件。须用户明确授权。" \
|
||||
"Hook requires confirmation for git clean -f."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+branch[[:space:]]+(-D|--delete[[:space:]]+--force)'; then
|
||||
ask "强制删分支 (-D) 须用户明确授权;优先 git branch -d。" \
|
||||
"Hook requires confirmation for git branch -D."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+worktree[[:space:]]+remove[[:space:]]+.*--force'; then
|
||||
ask "git worktree remove --force 被 AGENTS 禁止升级。须用户明确授权。" \
|
||||
"Hook requires confirmation for forced worktree remove."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+checkout[[:space:]]+--\.($|[[:space:]])'; then
|
||||
ask "git checkout -- . 会丢弃全部本地修改。须用户明确授权。" \
|
||||
"Hook requires confirmation for discarding all local changes."
|
||||
fi
|
||||
|
||||
allow
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Thin wrapper: preserve stdin for Cursor hook JSON (do not use heredoc).
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/guard_pi_dispatch.py"
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/guard_pi_shell.py"
|
||||
@@ -1,113 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Advisory beforeMCPExecution gate for pi-subagents MCP tools."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "guard-pi-dispatch"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw)
|
||||
if data is None:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
|
||||
lib.allow()
|
||||
|
||||
name = lib.tool_name(data)
|
||||
server = lib.mcp_server(data)
|
||||
if not name:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_tool_name", keys=sorted(data.keys())[:40])
|
||||
lib.allow()
|
||||
|
||||
if server and "pi-subagents" not in server and not name.startswith("pi_subagent_"):
|
||||
if not name.startswith("pi_subagent_"):
|
||||
lib.allow()
|
||||
|
||||
if name in ("pi_subagent_roles", "pi_subagent_result"):
|
||||
lib.allow()
|
||||
|
||||
if name != "pi_subagent_run":
|
||||
if name.startswith("pi_subagent_"):
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="unknown_pi_tool", tool=name)
|
||||
lib.allow()
|
||||
|
||||
args = lib.tool_input(data) or {}
|
||||
req = args.get("request") if isinstance(args.get("request"), dict) else args
|
||||
if not isinstance(req, dict):
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_request")
|
||||
lib.ask(
|
||||
"pi_subagent_run 缺少可识别的 request 对象。请核对 MCP 参数后再继续。",
|
||||
"Hook: unrecognized request shape for pi_subagent_run.",
|
||||
)
|
||||
|
||||
role = req.get("role_id")
|
||||
request_id = req.get("request_id")
|
||||
goal = req.get("goal")
|
||||
auth = req.get("authorization_ref")
|
||||
source_sha = req.get("source_sha")
|
||||
input_files = req.get("input_files")
|
||||
timeout = req.get("timeout_seconds")
|
||||
|
||||
problems: list[str] = []
|
||||
|
||||
if not role or not isinstance(role, str):
|
||||
problems.append("role_id 缺失")
|
||||
elif role not in lib.KNOWN_ROLES:
|
||||
problems.append(f"role_id={role!r} 不在已知角色表")
|
||||
|
||||
if not request_id or not isinstance(request_id, str) or not lib.REQUEST_ID.match(request_id):
|
||||
problems.append("request_id 非法(需字母数字开头,长度≤128)")
|
||||
|
||||
if not goal or not isinstance(goal, str) or not goal.strip():
|
||||
problems.append("goal 为空")
|
||||
|
||||
if not auth or not isinstance(auth, str) or not auth.strip():
|
||||
problems.append("authorization_ref 为空")
|
||||
|
||||
if not isinstance(source_sha, str) or not lib.FULL_SHA.match(source_sha):
|
||||
problems.append("source_sha 必须是完整 40-hex 提交(禁止 HEAD/分支名/短 hash)")
|
||||
|
||||
if not isinstance(input_files, list):
|
||||
problems.append("input_files 必须是数组")
|
||||
|
||||
if not isinstance(timeout, int) or isinstance(timeout, bool) or timeout <= 0:
|
||||
if isinstance(timeout, float) and timeout.is_integer() and timeout > 0:
|
||||
pass
|
||||
else:
|
||||
problems.append("timeout_seconds 必须是正整数")
|
||||
|
||||
if isinstance(role, str) and role in lib.TEST_ROLES:
|
||||
cmds = req.get("approved_commands")
|
||||
digest = req.get("plan_digest")
|
||||
if not isinstance(cmds, list) or not cmds:
|
||||
problems.append("test 角色需要 approved_commands(argv 数组的数组)")
|
||||
elif any(not isinstance(c, list) or not all(isinstance(x, str) for x in c) for c in cmds):
|
||||
problems.append("approved_commands 形状错误(应为字符串数组的数组)")
|
||||
if not isinstance(digest, str) or len(digest) != 64 or any(
|
||||
c not in "0123456789abcdefABCDEF" for c in digest
|
||||
):
|
||||
problems.append("plan_digest 必须是 64-hex SHA-256")
|
||||
|
||||
if "model_override" in req and req.get("model_override") is not None:
|
||||
problems.append("出现 model_override(禁止静默换模型;请用任务 override)")
|
||||
|
||||
if problems:
|
||||
detail = ";".join(problems)
|
||||
lib.audit(HOOK, "SHAPE_ASK", tool=name, problems=problems, role=role, request_id=request_id)
|
||||
lib.ask(
|
||||
f"pi_subagent_run 形状检查未通过:{detail}。执行器仍会硬校验;确认后继续或修正参数。",
|
||||
f"Hook advisory: {detail}",
|
||||
)
|
||||
|
||||
lib.audit(HOOK, "ALLOW", tool=name, role=role, request_id=request_id)
|
||||
lib.allow()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Advisory beforeShellExecution: bare pi_subagents.py run / broad pkill."""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "guard-pi-shell"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw)
|
||||
if data is None:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
|
||||
lib.allow()
|
||||
|
||||
cmd = lib.shell_command(data)
|
||||
if not cmd:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_command", keys=sorted(data.keys())[:40])
|
||||
lib.allow()
|
||||
|
||||
compact = re.sub(r"\s+", " ", cmd).strip()
|
||||
|
||||
if re.search(r"(^|[;&|]\s*)pkill(\s|$)", compact) and re.search(r"\s-f(\s|$)", compact):
|
||||
lib.audit(HOOK, "PKILL_ASK", command=compact[:500])
|
||||
lib.ask(
|
||||
"检测到 pkill -f(广谱杀进程)。AGENTS/PI 规则禁止广谱杀;请确认范围后再继续。",
|
||||
"Hook requires confirmation for pkill -f.",
|
||||
)
|
||||
|
||||
if re.search(r"pi_subagents\.py(\s|$)", compact) and re.search(r"(^|\s)run(\s|$)", compact):
|
||||
has_lease = (
|
||||
re.search(r"agentctl(\.py)?\s+with\b", compact) is not None
|
||||
and re.search(r"--resource\s+path:", compact) is not None
|
||||
)
|
||||
if re.search(r"pi_subagents\.py\s+(roles|result|status|config)\b", compact):
|
||||
lib.allow()
|
||||
if not has_lease:
|
||||
lib.audit(HOOK, "BARE_RUN_ASK", command=compact[:500])
|
||||
lib.ask(
|
||||
"裸调 pi_subagents.py run 缺少 agentctl with --resource path:… 租约。"
|
||||
"报告路径须在 path:.doc/test-reports/assets/pi-subagents/<task>/<request> 租约内。",
|
||||
"Hook: bare PI run without lease resource.",
|
||||
)
|
||||
|
||||
lib.allow()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/pi_receipt_context.py"
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""postToolUse: inject receipt-check reminders after pi-subagents tools."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "pi-receipt-context"
|
||||
|
||||
REMINDER = """[PI subagent receipt checklist]
|
||||
- 核对 report/receipt 路径:.doc/test-reports/assets/pi-subagents/<task_id>/<request_id>/
|
||||
- 记录 config_revision / config_sha256 / configured vs actual_model(不可观察填 unknown)
|
||||
- run_status=succeeded 不等于阶段 PASS;review_state 仍可为 pending
|
||||
- 测试 pass 只来自批准命令证据(approved_commands),不能用模型叙事冒充
|
||||
- 推进门禁前用 subagent-stage-record skill 写回传与阶段收据
|
||||
"""
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw)
|
||||
if data is None:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
|
||||
lib.emit({})
|
||||
raise SystemExit(0)
|
||||
|
||||
name = lib.tool_name(data) or ""
|
||||
server = lib.mcp_server(data) or ""
|
||||
blob = raw
|
||||
is_pi = (
|
||||
name.startswith("pi_subagent_")
|
||||
or "pi-subagents" in server
|
||||
or "pi_subagent_" in blob
|
||||
)
|
||||
if not is_pi:
|
||||
lib.emit({})
|
||||
raise SystemExit(0)
|
||||
|
||||
lib.audit(HOOK, "CONTEXT_INJECT", tool=name or "unknown")
|
||||
lib.additional_context(REMINDER)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"agentctl": {
|
||||
"type": "stdio",
|
||||
"command": "node",
|
||||
"args": ["scripts/mcp/agentctl-mcp.mjs"]
|
||||
},
|
||||
"jev": {
|
||||
"type": "stdio",
|
||||
"command": "node",
|
||||
"args": ["scripts/mcp/jev-mcp.mjs"]
|
||||
},
|
||||
"codegraph": {
|
||||
"type": "stdio",
|
||||
"command": "codegraph",
|
||||
"args": ["serve", "--mcp", "--path", "${workspaceFolder}"]
|
||||
},
|
||||
"pi-subagents": {
|
||||
"type": "stdio",
|
||||
"command": "node",
|
||||
"args": ["scripts/mcp/pi-subagents-mcp.mjs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,25 @@
|
||||
---
|
||||
description: 任务分级、授权、文档与收口入口
|
||||
description: 强制 Agent 文档同步与 ops 协作纪律;详情见 AGENTS.md
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
遵循 [AGENTS](../../AGENTS.md) 的启动、任务分级与收口规则。写入文档前读 [文档地图](../../.doc/README.md);创建、集成、环境操作、清理前读 [操作规范](../../.doc/ops/2026-09-21-agent-worktree-workflow.md)。
|
||||
# Agent 文档同步(强制)
|
||||
|
||||
完整规范见 [AGENTS.md](../../AGENTS.md) 与 [PROJECT.md](../../PROJECT.md)。
|
||||
|
||||
## 开场必读
|
||||
|
||||
1. `AGENTS.md` → `PROJECT.md` → `.doc/README.md` → `.doc/ops/CURRENT.md` → `FEATURE-MATRIX` → short-term / handoff
|
||||
|
||||
## 红线
|
||||
|
||||
- 任务开始前:short-term/long-term + CURRENT 并行认领(mutex)
|
||||
- 合 dev + 容器测:占用 CURRENT 集成槽位;他人 queue 等待
|
||||
- 多 Agent 并行:worktree(`.worktrees/`);禁止 worktree 内 env-service start
|
||||
- 禁止只改代码;done 任务 → `archive/ops/`
|
||||
- 验收报告 → `.doc/test-reports/`;运行产物 → `test-reports/assets/`
|
||||
- 禁止在 `.doc/` 根或 `docs/` 随意新建文档
|
||||
|
||||
## 状态
|
||||
|
||||
`planned | in_progress | blocked | done | cancelled`
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
description: Cursor 对话自动生成的会话名称使用简体中文
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# 会话名称(中文)
|
||||
|
||||
Cursor 为本对话自动生成或建议的**会话名称 / 聊天标题**必须使用**简体中文**。
|
||||
|
||||
## 要求
|
||||
|
||||
- 用简短中文概括当前任务主题(约 6–16 字)
|
||||
- 优先动词/对象:如「创建会话中文命名规则」「修复登录超时」
|
||||
- 禁止默认英文标题(专有名词、命令、路径可保留原文,整体仍以中文为主)
|
||||
|
||||
## 示例
|
||||
|
||||
| 场景 | 可用标题 |
|
||||
|---|---|
|
||||
| 新建 Cursor 规则 | 创建会话中文命名规则 |
|
||||
| 排查 hook | 排查 pi-dispatch hook |
|
||||
| 合入 feature | 合入治理目录库变更 |
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
description: Cursor hooks are client-side advisories only. Remote authority is Gitea native protection (2026-09-29); agentctl gates are retired for coding flow.
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Cursor hooks(客户端门禁)
|
||||
|
||||
配置:`.cursor/hooks.json`;脚本:`.cursor/hooks/`。规范登记修订 `cursor-governance-2026-09-24-r1`。
|
||||
|
||||
## 分层
|
||||
|
||||
| 层 | 能力 | 说明 |
|
||||
|---|---|---|
|
||||
| Gitea 服务端 | **enforced** | 受保护分支、必需 CI、非作者批准(2026-09-29 起) |
|
||||
| 本地 agentctl | 已退役(仅维护场景可选) | pre-commit/租约等本地硬拒绝已停用 |
|
||||
| hook 脚本行为 | **enforced**(有单元回归) | stdin→stdout 契约可测 |
|
||||
| hook ↔ Cursor 接线 | **advisory / manual** | 官方事件字段未完全文档化;待 probe 采样后收紧 |
|
||||
|
||||
命中策略:与 `guard-git.sh` 一致,一律 `permission: ask`(不静默 deny)。
|
||||
|
||||
## 事件与脚本
|
||||
|
||||
- `beforeShellExecution`:`guard-git.sh`(破坏性 git);`guard-pi-shell.sh`(裸调 `pi_subagents.py run`、`pkill -f`)
|
||||
- `beforeMCPExecution`:`guard-pi-dispatch.sh`(`pi_subagent_run` 形状)
|
||||
- `postToolUse`:`pi-receipt-context.sh`(注入收据核对提醒)
|
||||
- `sessionStart` / `stop`:`audit-session.sh`(审计 + 可选只读盘点;**不注入上下文**)
|
||||
|
||||
IDE 实测(2026-09-24):`postToolUse` 的 `tool_name` 形如 `MCP:pi_subagent_roles`;hooks 须剥 `MCP:` 前缀后再匹配角色工具名。
|
||||
|
||||
## 审计与 probe
|
||||
|
||||
- 审计:`.cursor/hook-audit.jsonl`(gitignore;勿提交)
|
||||
- 盘点:`.cursor/hook-audit/inventory-*.json`
|
||||
- 采样:`CURSOR_HOOKS_PROBE=1` → `.cursor/hook-probe.jsonl`
|
||||
- 关闭盘点:`CURSOR_HOOKS_NO_INVENTORY=1`
|
||||
|
||||
异形/未知字段:**fail-open + 审计 `UNRECOGNIZED_INPUT`**,不因契约未知卡死会话。
|
||||
|
||||
## 红线
|
||||
|
||||
- 不把 hook 复刻成第二套执行器门禁
|
||||
- 脚本存在 ≠ Cursor 已加载;改 hooks 后检查 Hooks 设置页或通道
|
||||
- 审计日志不得放进被 git 跟踪的 `.cursor/hooks/` 目录
|
||||
@@ -1,6 +1,24 @@
|
||||
---
|
||||
description: 凭证与推送授权入口
|
||||
description: Git push 凭证自主读取;禁止向用户索要 token;详情见 AGENTS.md §8
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
遵循 [AGENTS 安全与证据](../../AGENTS.md#5-安全与证据);授权推送的凭证和脚本入口见 [PROJECT](../../PROJECT.md#凭证与推送)。
|
||||
# Git Secrets 自主(禁止索要)
|
||||
|
||||
完整规范见 [AGENTS.md](../../AGENTS.md) §8 与 [PROJECT.md](../../PROJECT.md) §7。
|
||||
|
||||
## 本仓约定
|
||||
|
||||
- 凭证:`${HOME}/.secrets/gitea`
|
||||
- 字段:`- ACCESS_TOKEN=`、`- URL_PREFIX=`
|
||||
- 推送:优先 `./scripts/git-push-dev.sh <branch>`
|
||||
|
||||
## 禁止
|
||||
|
||||
- 向用户索要或要求粘贴 token
|
||||
- 在聊天/文档/commit 中展示 secret
|
||||
- 写入 git config 或提交到仓库
|
||||
|
||||
## 缺失时
|
||||
|
||||
在 `.doc/ops` 记 blocker(路径 + 缺字段),提示用户本机补齐后重试;**仍不索要内容**。
|
||||
|
||||
@@ -1,6 +1,60 @@
|
||||
---
|
||||
description: 分支、原子提交与环境操作入口
|
||||
description: 项目固定3分支模型(dev/test/main)、逐步渐进式提交规范与三套独立服务(知识库共享+对话与DB隔离)准则
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
分支/原子提交边界见 [AGENTS](../../AGENTS.md),环境拓扑见 [PROJECT](../../PROJECT.md)。创建、集成、环境写操作及清理按 [操作规范](../../.doc/ops/2026-09-21-agent-worktree-workflow.md) 执行。
|
||||
# Git 三分支流转与三套服务环境架构准则
|
||||
|
||||
本仓库严格遵循以下固定分支体系、提交拆分规范与多套独立服务运行准则:
|
||||
|
||||
## 一、 Git 固定三分支体系
|
||||
|
||||
1. **开发分支 (`dev`)**:
|
||||
- **合入基线**,不是日常 commit 目标。
|
||||
- **禁止**在 `dev` 上直接开发提交(含 docs/chore)。
|
||||
- 一律从最新 `dev` 检出 `feature/<name>` 或 `fix/<name>`,在 feature 分支上渐进式提交;自测后占集成槽位,`--no-ff` 合回 `dev`,并删除临时子分支(见 [AGENTS.md](../../AGENTS.md) §6.2)。
|
||||
|
||||
2. **测试分支 (`test`)**:
|
||||
- 当 `dev` 积累了一定的功能阶段后,合并至 `test` 分支,创建阶段候选节点 Tag(如 `rc-vX.Y.Z-beta.1`)。
|
||||
- 用于较长时间的真实环境部署、全链路集成测试、运维稳定性检验。
|
||||
- **严禁**在 `test` 分支进行开发或直接 commit。
|
||||
|
||||
3. **主分支 (`main`)**:
|
||||
- 生产发布分支(Release)。
|
||||
- **严禁**直接在 `main` 上开发或 commit!
|
||||
- 只有 `test` 分支的代码经过实际运维和测试充分验证达到发布标准后,方可将对应验证节点合并回 `main` 分支,并打正式发布 Tag(如 `v1.0.0`)。
|
||||
|
||||
---
|
||||
|
||||
## 二、 任务拆分与渐进式提交规范 (Progressive Commits)
|
||||
|
||||
- **原子性拆分**:严禁把整个任务的大量改动揉合成一次庞大的提交。
|
||||
- **阶段逐步提交**:一个任务必须按功能逻辑分层逐步提交:
|
||||
1. `feat(db)` / `refactor(db)`: 数据表、模型、迁移脚本
|
||||
2. `feat(agent)` / `feat(service)`: 业务逻辑、智能体执行流程
|
||||
3. `feat(api)`: 接口路由与交互
|
||||
4. `test(...)`: 单元测试与集成测试用例
|
||||
5. `docs(...)` / `chore(...)`: 配置、运维脚本与文档同步
|
||||
- **提交规范**:遵循 Conventional Commits (`feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `ci`)。
|
||||
|
||||
---
|
||||
|
||||
## 三、 三套环境独立运行准则 (知识库共享 + 对话与DB隔离)
|
||||
|
||||
三套独立服务对应三个分支的运行态:
|
||||
|
||||
| 环境 | 分支 | Compose 项目 | HTTP 端口 | DB 端口 | 数据/对话路径 |
|
||||
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||
| **共享知识库** | 跨环境 | `agent-infra` | - | `5432` | `data/shared/kb` |
|
||||
| **开发环境** | `dev` | `agent-dev` | `8080` | `5433` | `data/dev` |
|
||||
| **测试环境** | `test` | `agent-test` | `8081` | `5434` | `data/test` |
|
||||
| **生产环境** | `main` | `agent-main` | `8000` | `5435` | `data/main` |
|
||||
|
||||
### 核心约束:
|
||||
1. **知识库共享**:
|
||||
- 三套环境服务均通过共享网络或内网连接同一个知识库数据库(`shuimu-kb-shared:5432`)。
|
||||
- 知识库法规、向量索引保持全局一致。
|
||||
2. **对话数据与数据库隔离(红线)**:
|
||||
- 各环境对话记录(Chat History)、Agent 思考工作区、审计事件及 SQLite/Postgres 业务库必须严格隔离!
|
||||
- 严禁任何环境读取或写入其他环境的对话数据与业务库。
|
||||
- 宿主机挂载目录严格区分:`data/dev/`、`data/test/`、`data/main/`。
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
description: Route PI analysis/review/test subagent work through scripts/pi_subagents.py (not Cursor native agents).
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# PI subagents(工程工具)
|
||||
|
||||
本机 PI 子任务走 `scripts/pi_subagents.py` + 模型配置 `.doc/ops/2026-09-24-subagent-model-config.md`。可执行步骤见 skill `pi-subagent-dispatch`;阶段记录见 `subagent-stage-record`。
|
||||
|
||||
## 自动派发(主 Agent)
|
||||
|
||||
1. **预览配置**:`pi_subagent_roles` / CLI `roles`(不调模型)。
|
||||
2. **按阶段选角色**:research → planning → reviews → diagnosis → test_run / acceptance_check → report;实施/修复仍由 Cursor Auto。
|
||||
3. **派发 `run`**:携带 task_id、role_id、唯一 request_id、goal、authorization_ref、冻结 source_sha、input_files、timeout;test 角色另附 approved_commands + plan_digest。
|
||||
4. **租约**:报告路径 `path:.doc/test-reports/assets/pi-subagents/<task>/<request>`;裸调拒绝。
|
||||
5. **取回**:`pi_subagent_result` / CLI `result`;`run_status` 与 `verdict`/`review_state` 分离——模型成功仅 `pending`,测试 pass 仅来自批准命令证据。
|
||||
6. **门禁**:审查/测试结论须带回报告路径与 receipt 字段;不得用模型叙事冒充 PASS。
|
||||
|
||||
## 边界
|
||||
|
||||
- **Cursor Auto**:唯一代码实施车道;本规则不把 implementation 派给 PI。
|
||||
- **禁止**:自动换模型、M3 关键角色、伪造 lease、递归把本修复任务再派给 PI worker、`pkill -f` 广谱杀进程。
|
||||
- **MCP**:`.cursor/mcp.json` → `pi-subagents`(roles/run/result);executor 来自 MCP 安装根。
|
||||
- **Hook(advisory)**:`.cursor/hooks/guard-pi-dispatch.sh` / `guard-pi-shell.sh` 可在形状错误时 `ask`;**硬拒绝以执行器为准**,见规则 `cursor-hooks`。
|
||||
@@ -1,13 +1,12 @@
|
||||
---
|
||||
description: Cursor-side test report path/naming conventions; validation scope comes from the validation contract.
|
||||
description: 规定项目中所有自动化测试、功能测试、集成测试报告的存放路径与结构标准规范
|
||||
globs: ["**/*test*.go", ".doc/test-reports/**/*.md"]
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# 测试报告规范准则 (Test Reports Standard)
|
||||
|
||||
本仓库严格遵循标准化、可追溯的质量测试管理体系。**验证范围、套件选择与模型证据的唯一来源**为 [验证契约](../../.doc/ops/2026-09-21-validation-contract.md);本规则只约定 Cursor 侧的报告路径、命名与结构提醒,不另设第二套测试门禁。
|
||||
|
||||
**范围判定**:纯工程规范/文档变更按 [PROJECT.md 验证入口](../../PROJECT.md#验证入口) 与 [worktree 工作规范](../../.doc/ops/2026-09-21-agent-worktree-workflow.md) 检查链接、规则一致性及 Git 差异;不适用产品 PI 全链路。报告注明 NOT REQUIRED 及依据,不能记成产品测试 PASS。运行模板、提示词和业务变更不属于此例外——按验证契约选层级。
|
||||
本仓库严格遵循标准化、可追溯的质量测试管理体系。所有测试报告必须归档于指定的文档目录下,并遵循固定结构。
|
||||
|
||||
## 一、 测试报告归档路径规范
|
||||
|
||||
@@ -16,9 +15,11 @@ alwaysApply: true
|
||||
- 例如:`.doc/test-reports/2026-09-07-three-branch-intent-framework-test-report.md`
|
||||
- **证据附件**:运行产物(json/jsonl、workspace 快照、截图)放 `.doc/test-reports/assets/<report-slug>/`,**不得**与 `*-test-report.md` 混放在同一层级目录。
|
||||
|
||||
---
|
||||
|
||||
## 二、 测试报告固定结构模板
|
||||
|
||||
每份独立测试报告应包含以下核心板块(小型文档/脚本任务可在任务主文档设验证节,无需机械拆报告):
|
||||
每份测试报告必须包含以下核心板块:
|
||||
|
||||
```markdown
|
||||
# [功能/模块名称] 测试报告
|
||||
@@ -27,37 +28,38 @@ alwaysApply: true
|
||||
- 简述被测功能/特性的产生背景、业务痛点或上一轮测试中发现的缺陷与瓶颈。
|
||||
|
||||
## 二、 测试目标 (Test Objectives)
|
||||
- 列举本次测试需要验证的核心功能点、质量指标。
|
||||
- 列举本次测试需要验证的核心功能点、质量指标(如通过率 100%、无流程卡点、非阻塞人机协同等)。
|
||||
|
||||
## 三、 测试方案与环境 (Test Plan & Environment)
|
||||
- 测试环境(OS、工具版本、目标环境批准配置);
|
||||
- 测试层级分层(按验证契约矩阵选行);
|
||||
- 测试环境(OS、Go 版本、后端 Stub/Real 模型);
|
||||
- 测试层级分层(单元测试、协同集成测试、CLI 真实交互测试);
|
||||
- 核心测试用例矩阵设计。
|
||||
|
||||
## 四、 预期结果 (Expected Results)
|
||||
- 明确给出各用例输入下的理论判定。
|
||||
- 明确给出各用例输入下的理论判定分支、目标意图、提取槽位、参谋回复风格与状态机流转。
|
||||
|
||||
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
|
||||
- 必须包含针对每一个典型测试用例的真实记录:
|
||||
- **测试输入 (Input)**
|
||||
- **实际输出 (Actual Output)**:贴出真实的终端/日志输出文本(可脱敏)
|
||||
- **评价判定 (Evaluation / Verdict)**:PASS / FAIL / SKIP / 未运行
|
||||
- **实际输出 (Actual Output)**:贴出真实的终端/日志输出文本
|
||||
- **评价判定 (Evaluation / Verdict)**:PASS / FAIL 标志及判定依据
|
||||
- **性能与耗时 (Duration & Latency)**
|
||||
|
||||
## 六、 自动化测试套件汇总 (Test Suite Execution)
|
||||
- 只列本次适用并**实际运行**的检查与通过率;不无条件要求全量 `go test`。
|
||||
- 工程工具改动优先 `python3 -B -m unittest discover -s scripts/tests -p 'test_*.py' -v`(见验证契约「工程工具验收补充」)。
|
||||
- 附带 `go test -v ./...` 全量回归测试输出与通过率统计。
|
||||
|
||||
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
|
||||
- 总结测试是否达到授权交付终点,提出后续演进或强化点。
|
||||
- 总结测试是否达到上线/合并标准,提出后续演进或强化点。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、 执行要求与真实 Agent 交付铁律
|
||||
|
||||
1. **真实 Agent 交付铁律(红线)**:
|
||||
- **开发实现阶段**:可以快速使用 stub 验证状态机、协议分流、数据落盘与逻辑契约,加速反馈;
|
||||
- **交付前验收与测试报告生成**:涉及产品 Agent/工作流时,必须按验证契约「产品 PI 基线」在获授权环境用真实产品 PI Agent Runner 全链路实测;模型以目标环境批准配置为准,不得在本规则中硬编码模型名;
|
||||
- **严禁**使用 stub、SKIP、未运行输出作为最终交付报告的验收数据。
|
||||
2. **严禁散落存放**:测试报告统一归档至 `.doc/test-reports/`,禁止散落在根目录或临时沙箱中。
|
||||
- **开发实现阶段**:可以快速使用 `stub` 验证状态机、协议分流、数据落盘与逻辑契约,加速反馈;
|
||||
- **交付前验收与测试报告生成**:**必须切回真实环境与真实 Agent(`pi-agent` + 实际运行的 `MiniMax-M2.7-highspeed` 容器)进行全链路端到端实测**;
|
||||
- **严禁**使用 stub 的测试输出作为最终交付报告的验收数据。
|
||||
2. **严禁散落存放**:测试报告统一归档至 `.doc/test-reports/` 目录下,禁止散落在根目录或临时沙箱中。
|
||||
3. **真实控制台取样**:测试报告中的输入、输出、耗时与判定必须取自实际环境运行的真实控制台输出与日志。
|
||||
4. **Git 规范管理**:测试报告伴随对应阶段的 `docs(test)` 或 `test(...)` 规范提交入库。
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
---
|
||||
name: agentctl-integrate-closeout
|
||||
description: Validate a merge candidate, enqueue for daemon ff-only integrate, and close out five-state. Use when ready to land a task on local dev.
|
||||
---
|
||||
|
||||
# agentctl 集成与收口
|
||||
|
||||
权威:[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)、[验证契约](../../../.doc/ops/2026-09-21-validation-contract.md)。常驻 daemon 已装载时走 **enqueue**,勿手动 `integrate`(除非 daemon 停)。
|
||||
|
||||
## 候选
|
||||
|
||||
优先一层封装(创建 integrate worktree、`task register`、`--no-ff` merge;**不** validate/enqueue):
|
||||
|
||||
```bash
|
||||
D=$(git -C /path/to/Agent-System rev-parse HEAD) # 冻结 expected-dev
|
||||
python3 scripts/agentctl.py integrate prepare \
|
||||
--task <feature-task-id> --expected-dev "$D" \
|
||||
[--integrate-id integrate-<task>-YYYY-MM-DD]
|
||||
# 进入返回的 worktree 继续 validate → enqueue
|
||||
cd .worktrees/integrate-<task>-YYYY-MM-DD # 或 emit 中的 worktree
|
||||
```
|
||||
|
||||
第一父必须等于 `$D`。手工 `worktree add` + `with` + `merge --no-ff` 仍可用。
|
||||
|
||||
## validate → enqueue(daemon ff)
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py validate --task "$ID" -- <验收命令>
|
||||
python3 ../../scripts/agentctl.py queue enqueue \
|
||||
--task "$ID" --expected-dev "$D" --head "$(git rev-parse HEAD)"
|
||||
# 在任务 worktree 内 enqueue;数秒内 daemon 合入
|
||||
python3 ../../scripts/agentctl.py queue list
|
||||
python3 ../../scripts/agentctl.py daemon status
|
||||
```
|
||||
|
||||
验收按验证契约选行;治理脚本用 `unittest discover`。
|
||||
|
||||
## 五态收口
|
||||
|
||||
| 字段 | 典型值 |
|
||||
|---|---|
|
||||
| review_state | accepted |
|
||||
| integration_state | merged_local_dev |
|
||||
| deployment | not_required 或 loaded_local_launchd |
|
||||
| cleanup | pending(独立维护者;禁止 `--force`) |
|
||||
| remote_sync | not_requested |
|
||||
|
||||
CURRENT 行 → `done`(`docs apply`);`task close --status done`。
|
||||
|
||||
## 清理前
|
||||
|
||||
确认 tip 为 local_dev 祖先、证据已持久化、无 tracked/untracked 遗留、无进程占用。唯一日志/对话归档进 `.doc/ops/evidence/` 后再 `worktree remove`。
|
||||
|
||||
只读盘点(不自动删除、不自动写 MATRIX):
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py cleanup report # 主目录或任意同仓 cwd
|
||||
python3 ../../scripts/agentctl.py docs drift
|
||||
```
|
||||
|
||||
对 `verdict=ready` 的 worktree 由独立维护者执行 `agent-worktree.sh remove … --delete-branch`;拒绝则保留 cleanup_pending。daemon 未装载时用 `queue schedule --drain`(主目录 + 分支 dev)。
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
name: agentctl-lease-write
|
||||
description: Write under agentctl leases and docs apply CAS. Use before any git write, shared-doc edit, or when hitting UNMANAGED_DOCUMENT_CHANGE / EVIDENCE_REQUIRED.
|
||||
---
|
||||
|
||||
# agentctl 租约写回
|
||||
|
||||
权威:[AGENTS §3–5](../../../AGENTS.md)、[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)。
|
||||
|
||||
## 原则
|
||||
|
||||
- **任何仓库写**(含 `git add/commit`)必须在 `agentctl with` / MCP `lease_run` 租约内
|
||||
- CURRENT / FEATURE-MATRIX **只能** `docs apply`(行级 CAS;MATRIX 键为 `record_id`)
|
||||
- 直接 `git commit` 会被 agentctl-managed pre-commit hook 拒绝
|
||||
|
||||
## lease_run(CLI)
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py with \
|
||||
--task "$ID" \
|
||||
--resource path:scripts --resource path:.doc --resource git:index \
|
||||
-- bash -lc 'git add … && git commit -m "…"'
|
||||
```
|
||||
|
||||
MCP:`lease_run` 的 `command` 为 **argv 数组**(无额外 shell)。
|
||||
|
||||
## docs apply(行级)
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py docs snapshot --file .doc/ops/CURRENT.md --record "$RID"
|
||||
# expected_sha256 = snapshot.sha256;改 replacement 后:
|
||||
python3 scripts/agentctl.py docs apply --task "$ID" --request /tmp/req.json
|
||||
```
|
||||
|
||||
FEATURE-MATRIX 升 `done` 需要 `docs:approve` + 可核验 evidence(`git cat-file -e`),否则 `EVIDENCE_REQUIRED`。
|
||||
收口或合入含 MATRIX 的变更后跑 `python3 scripts/agentctl.py docs drift`:硬告警仅 `done→非 done`;不因任务结束自动升 done。
|
||||
|
||||
## 常见拒绝
|
||||
|
||||
| 码 | 处置 |
|
||||
|---|---|
|
||||
| `UNMANAGED_DOCUMENT_CHANGE` | 保留现场,先 snapshot/reconcile,勿覆盖 |
|
||||
| `BASE_CHANGED` | 重新 snapshot,基于新 sha 再 apply |
|
||||
| `AMBIGUOUS_RECORD` | 修重复 record_id / 模块名 |
|
||||
| `CAPABILITY_REQUIRED` | 任务缺 docs:admin / docs:approve |
|
||||
| `DOCUMENT_RECEIPT_REQUIRED` | 共享文档须经 apply 收据后再 commit |
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
name: agentctl-session-start
|
||||
description: Start an Agent-System session under agentctl governance. Use at session start, when opening a worktree, or before any write to this repo.
|
||||
---
|
||||
|
||||
# agentctl 会话启动
|
||||
|
||||
权威规范:[AGENTS.md](../../../AGENTS.md)、[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)、[CURRENT](../../../.doc/ops/CURRENT.md)。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. 读 `AGENTS.md`、`PROJECT.md`、`.doc/ops/CURRENT.md` 活跃摘要(勿跳过)。
|
||||
2. 核对管理面:
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py daemon status
|
||||
# 期望:status=ok;launchd 已装载时 manager.lock.held=true
|
||||
```
|
||||
|
||||
或 MCP 工具 `status`。
|
||||
|
||||
3. 刷新 CodeGraph 索引(fail-open;CLI 缺失可跳过):
|
||||
|
||||
```bash
|
||||
codegraph sync -q
|
||||
# 或:python3 scripts/agentctl.py hooks codegraph-sync
|
||||
```
|
||||
|
||||
跨文件定位优先用 CodeGraph MCP/`explore`;**grep 仍是完整性唯一权威**(假阴性时以 grep 为准)。
|
||||
|
||||
4. 若任务已存在:在注册 worktree 内工作,确认 `tasks.state=active`。
|
||||
5. **开工前需求重叠探测**(治理目录库):新设计或可能与其他对话重叠时:
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py catalog search --query '<关键词>'
|
||||
python3 scripts/agentctl.py catalog overlap --task "$ID" --statement '<设计原文>' [--requirement R-xxx] [--feature <record_id>] [--mutex <key>]
|
||||
# soft 命中须显式裁决后才可编码:
|
||||
python3 scripts/agentctl.py catalog overlap ack --task "$ID" --overlap <oid> --decision proceed|merge_into|supersede|defer --reason '...'
|
||||
```
|
||||
|
||||
硬重叠(同 mutex/feature/scope/R-ID)直接拒绝;向量层失败自动降级到 FTS5,不阻断。
|
||||
|
||||
6. 若新任务:跟 [agentctl-worktree-setup](../agentctl-worktree-setup/SKILL.md)。
|
||||
7. 任何仓库写 → [agentctl-lease-write](../agentctl-lease-write/SKILL.md);合入 → [agentctl-integrate-closeout](../agentctl-integrate-closeout/SKILL.md)。
|
||||
|
||||
## 禁止
|
||||
|
||||
- 主目录直接开发提交;未授权 `git push` / 晋升 test/main
|
||||
- 绕过 `docs apply` 改 CURRENT / FEATURE-MATRIX
|
||||
- 卸载或重启 launchd coordinator(除非用户明示)
|
||||
- 未执行 `catalog overlap` / 未裁决 soft 命中即编码(有 `--requirement`/`--intent`/`--feature`/`--mutex` 绑定时机器强制)
|
||||
@@ -1,65 +0,0 @@
|
||||
---
|
||||
name: agentctl-worktree-setup
|
||||
description: Create an agentctl task worktree, register scopes/capabilities, and claim CURRENT. Use when starting a new feature/fix task in Agent-System.
|
||||
---
|
||||
|
||||
# agentctl 建场
|
||||
|
||||
权威:[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)。
|
||||
|
||||
## 命令序列
|
||||
|
||||
```bash
|
||||
cd /path/to/Agent-System # 主目录(dev)
|
||||
D=$(git rev-parse HEAD)
|
||||
ID=<task-id-YYYY-MM-DD>
|
||||
WT=.worktrees/$ID
|
||||
# 推荐入口:自动 best-effort codegraph init(后台;CLI 缺失不阻断)
|
||||
./scripts/agent-worktree.sh create feature/$ID
|
||||
# 等价:git worktree add -b feature/$ID "$WT" "$D"
|
||||
cd "$WT"
|
||||
python3 ../../scripts/agentctl.py task register \
|
||||
--id "$ID" --owner <Owner> \
|
||||
--scope scripts --scope .doc \
|
||||
--capability docs:publish
|
||||
# 需要整文/行级 admin 时再加 --capability docs:admin;证据升 done 加 docs:approve
|
||||
# 若已知需求/功能绑定,追加:
|
||||
# --requirement R-<slug> --intent '<设计原文>' --feature <record_id> --mutex <key>
|
||||
# 有 soft 重叠时 register 会 OVERLAP_ACK_REQUIRED:先 catalog overlap + ack 再重试 register
|
||||
codegraph sync -q # 若建场已 init,此处只需 sync;缺失 CLI 可跳过
|
||||
```
|
||||
|
||||
## 开工前重叠裁决(catalog)
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py catalog overlap \
|
||||
--task "$ID" --statement '<新设计原文>' \
|
||||
[--requirement R-xxx] [--feature <record_id>] [--mutex <key>]
|
||||
# hard → 换 mutex/合并到持有者任务;soft → ack 留痕
|
||||
python3 ../../scripts/agentctl.py catalog ack \
|
||||
--task "$ID" --overlap <oid> \
|
||||
--decision proceed|merge_into|supersede|defer \
|
||||
--reason '<理由>'
|
||||
```
|
||||
|
||||
## CURRENT 认领
|
||||
|
||||
优先用一层封装(内部仍走 `docs apply` CAS):
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py claim new \
|
||||
--task "$ID" --owner <Owner> --mutex <mutex> \
|
||||
[--branch feature/$ID] [--worktree "$WT"] [--replace]
|
||||
```
|
||||
|
||||
手工 `docs snapshot` + `docs apply` 仍可用;行已存在且内容不同时需 `--replace`。
|
||||
|
||||
## short-term 模板字段
|
||||
|
||||
`status`、`write_scope`、`mutex`、`base_dev_sha`、`review_state`/`integration_state`/`deployment`/`cleanup`/`remote_sync`。命名 `.doc/ops/short-term/YYYY-MM-DD-<slug>.md`。
|
||||
|
||||
## 注意
|
||||
|
||||
- 从确切 `dev` SHA 创建,不从他人 feature 分支启动
|
||||
- 重叠 path/mutex 只允许一个写者
|
||||
- CodeGraph 索引是加速器:有假阴性;穷举调用方仍用 grep
|
||||
@@ -1,52 +0,0 @@
|
||||
---
|
||||
name: jev-decide
|
||||
description: Use jev-service typed decisions (choice/noul/numeric with probabilities) for Agent-System governance classification. Use when choosing task tier, validation level, reject-code routing, or other closed-enum judgments.
|
||||
---
|
||||
|
||||
# jev-decide(治理决策)
|
||||
|
||||
依赖 MCP 服务器 `jev`([`scripts/mcp/jev-mcp.mjs`](../../../scripts/mcp/jev-mcp.mjs))。凭证在本机 `~/.secrets/jev/`(`api.key`、`base-url`),**禁止**写入仓库、commit 或聊天。
|
||||
|
||||
## 何时用
|
||||
|
||||
输入是情境文本、输出是**封闭枚举 / yes-no / 分桶数值**时调用 `jev_decide`,例如:
|
||||
|
||||
| 决策点 | 建议 questions |
|
||||
|---|---|
|
||||
| 任务分级(是否开 worktree) | `choice`:`info_reply` / `single_task` / `cross_module` |
|
||||
| 验证层级(验证契约) | `choice`(可多题):`doc` / `script` / `go` / `frontend` / `migration` / `product_pi` |
|
||||
| 拒绝码处置 | `choice`:`reconcile` / `re_snapshot` / `fix_record_id` / `request_capability` / `abort` |
|
||||
| 是否 blocker / 是否触碰重验面 | `noul` |
|
||||
|
||||
不适合:需要解释链、多步规划、自由文本生成——那些走大模型或 agentctl 确定性门禁。
|
||||
|
||||
## 调用约定
|
||||
|
||||
1. 可选先 `jev_health`;失败则本机判断,勿阻塞写路径。
|
||||
2. `jev_decide`:同一情境的多问合成一次请求。
|
||||
3. 问句**正向措辞**,避免双重否定。
|
||||
4. 置信度路由:
|
||||
- `confidence >= 0.9` 且 top1−top2 ≥ 0.15 → 可采用
|
||||
- 否则 → agent 自行按规范裁定,把 jev 结果当参考
|
||||
5. 401/超时/`answers.*.error` → 降级到本机判断;勿把决策失败变成业务失败。
|
||||
|
||||
## 示例(任务分级)
|
||||
|
||||
```json
|
||||
{
|
||||
"context": "用户请求:给 CURRENT 加一行认领说明,不改代码",
|
||||
"questions": {
|
||||
"tier": {
|
||||
"type": "choice",
|
||||
"question": "This request matches which AGENTS task tier?",
|
||||
"options": ["info_reply", "single_task", "cross_module"]
|
||||
},
|
||||
"needs_worktree": {
|
||||
"type": "noul",
|
||||
"question": "Does this require a new feature/fix worktree?"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
权威矩阵仍以 [AGENTS.md](../../../AGENTS.md)、[验证契约](../../../.doc/ops/2026-09-21-validation-contract.md) 为准;jev 只加速封闭枚举分类,不替代机器门禁(admit/hooks/docs apply)。
|
||||
@@ -1,87 +0,0 @@
|
||||
---
|
||||
name: pi-subagent-dispatch
|
||||
description: Dispatch gmktec PI analysis/review/test subagents via project MCP pi-subagents (roles/run/result). Use when delegating research, planning, reviews, diagnosis, test_run, acceptance_check, or report work—not for code implementation.
|
||||
---
|
||||
|
||||
# PI Subagent 派发
|
||||
|
||||
权威:[模型配置](../../../.doc/ops/2026-09-24-subagent-model-config.md)、[执行器说明](../../../.doc/ops/2026-09-24-pi-subagent-executor.md)、[流程规范](../../../.doc/ops/2026-09-24-subagent-workflow-standard.md)。客户端规则:[pi-subagents](../../rules/pi-subagents.mdc)。阶段落盘:[subagent-stage-record](../subagent-stage-record/SKILL.md)。
|
||||
|
||||
**Cursor Auto 独占代码实施与修复**;本 skill 只走本机 PI 子任务。
|
||||
|
||||
## 调用序列
|
||||
|
||||
1. `pi_subagent_roles` — 只读预览角色/模型(不调 PI)。
|
||||
2. 选 `role_id`(research → planning → reviews → diagnosis → test_run / acceptance_check → report)。
|
||||
3. (推荐)`agentctl pi packet` 生成派发包;**不**触发 run:
|
||||
```bash
|
||||
python3 -B scripts/agentctl.py pi packet \
|
||||
--task "$ID" --role research \
|
||||
--goal '…' --authorization-ref 'user:…' \
|
||||
--source-sha "$(git rev-parse HEAD)" \
|
||||
[--input-file …] [--approved-command '…']… \
|
||||
--request-id "$RID" --write
|
||||
# → .doc/test-reports/assets/pi-subagents/<task>/<request>/packet.json
|
||||
```
|
||||
4. `pi_subagent_run` — 按 packet 字段在 agentctl 租约下异步启动。
|
||||
5. `pi_subagent_result` — 取回收据;轮询至终态。
|
||||
|
||||
CLI 等价:`python3 -B scripts/pi_subagents.py roles|run|result`;`run` 必须包在 `agentctl with --resource path:.doc/test-reports/assets/pi-subagents/<task>/<request>` 内。
|
||||
|
||||
## 请求字段(MCP `pi_subagent_run`)
|
||||
|
||||
外层:`worktree`(已登记任务工作区绝对路径)、`task_id`、`request` 对象。
|
||||
|
||||
`request` 必填:
|
||||
|
||||
| 字段 | 约束 |
|
||||
|---|---|
|
||||
| `role_id` | 配置 §3 中 enabled 角色 |
|
||||
| `request_id` | 任务内稳定唯一;同参重放不重复调模型 |
|
||||
| `goal` | 具体目标;子任务不依赖主会话未传入历史 |
|
||||
| `authorization_ref` | 可回链真实用户授权,禁止日志自授 |
|
||||
| `source_sha` | **完整** 40-hex 提交;禁止 `HEAD`/分支名/短 hash |
|
||||
| `input_files` | 已跟踪 UTF-8 普通文件相对路径数组 |
|
||||
| `timeout_seconds` | 正整数 |
|
||||
|
||||
测试角色(`test_run` / `acceptance_check`)另需:
|
||||
|
||||
- `approved_commands`:argv 数组的数组(如 `[["go","test","-short","./"]]`)
|
||||
- `plan_digest`:外部已批准计划的 SHA-256 hex
|
||||
|
||||
禁止静默 `model_override`;临时改模型写任务 override 并说明用户来源。
|
||||
|
||||
## 租约与输出
|
||||
|
||||
- 资源:`path:.doc/test-reports/assets/pi-subagents/<task_id>/<request_id>`
|
||||
- 产物:`receipt.json`、`report.md`、命令日志(同目录)
|
||||
- 裸调 `run`(无租约)被拒绝
|
||||
|
||||
## 状态分离(红线)
|
||||
|
||||
| 字段 | 含义 |
|
||||
|---|---|
|
||||
| `run_status` | running / succeeded / failed / cancelled / unknown |
|
||||
| `verdict` | pass / changes_required / blocked / not_applicable |
|
||||
| `review_state` | 阶段门禁;模型 succeeded **仅** pending |
|
||||
|
||||
测试 `commands_passed`/`pass` 只针对批准命令证据,不能直接赋给任务 `acceptance`。
|
||||
|
||||
## 常见拒绝码(执行器权威)
|
||||
|
||||
| 码 | 处置 |
|
||||
|---|---|
|
||||
| `INVALID_SOURCE_SHA` | 换完整提交 hash |
|
||||
| `APPROVED_COMMANDS_REQUIRED` | 补 approved_commands + plan_digest |
|
||||
| `MINIMAX_ROLE_FORBIDDEN` | 不把 M3 用于关键角色 |
|
||||
| `INPUT_NOT_TRACKED` / `PATH_OUT_OF_SCOPE` | 收窄 input_files |
|
||||
| `CONCURRENCY_LIMIT` | 串行或等空闲槽 |
|
||||
| `ORPHAN_RUNNING` | 先核进程/副作用,勿盲目重派 |
|
||||
|
||||
Cursor hooks 对形状错误可能 `permission=ask`(advisory);**硬拒绝以执行器为准**。
|
||||
|
||||
## 禁止
|
||||
|
||||
- 把 implementation 派给 PI
|
||||
- 自动换模型 / 伪造 lease / 递归把本修复再派给 PI worker
|
||||
- 用模型叙事冒充 PASS;审查结论须带回报告路径与 receipt 字段
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
name: subagent-stage-record
|
||||
description: Record PI/Cursor stage handoffs using the subagent stage template (dispatch packet, return, S0–S9 receipt, R-AC-T mapping). Use after PI results, before gate advances, or when closing a multi-stage task.
|
||||
---
|
||||
|
||||
# Subagent 阶段记录
|
||||
|
||||
权威模板:[subagent-stage-record.md](../../../.doc/ops/templates/subagent-stage-record.md);流程:[协作规范](../../../.doc/ops/2026-09-24-subagent-workflow-standard.md)。派发入口:[pi-subagent-dispatch](../pi-subagent-dispatch/SKILL.md)。
|
||||
|
||||
原则:**一步一记录,不必一步一文件**。小任务可把适用段落并入任务主文档;跨模块才拆独立审查/测试/验收证据。
|
||||
|
||||
## 何时写
|
||||
|
||||
- 每次 `pi_subagent_run` 前后:派发包 + 回传
|
||||
- 阶段门禁推进前:S0–S9 收据行
|
||||
- 收口前:R→AC→改动→审查→T→运行验收映射
|
||||
|
||||
## 派发包(最小字段)
|
||||
|
||||
复制到任务文档并填实值:
|
||||
|
||||
- `parent_task_id` / `subtask_id` / `stage_id` / `role_id`
|
||||
- 配置路径 / `config_revision` / `config_sha256`(来自 roles 或 receipt)
|
||||
- 解析后的 provider/model;任务 override 与用户来源
|
||||
- 目标、非目标、授权来源、交付终点
|
||||
- 输入版本:R-ID / AC-ID / 方案版本 / `base_sha` / `head_sha` 或 `source_sha`
|
||||
- cwd / branch / allowed_paths / 只读或写入 / mutex
|
||||
- 完成条件、输出路径、预算与异常处理
|
||||
|
||||
## 子任务回传
|
||||
|
||||
- PI `run_id` / producer / 起止时间
|
||||
- `configured_model` / `actual_model`(不可观察填 `unknown`)
|
||||
- `run_status` 与 `verdict` **分列**(不得把退出成功当质量通过)
|
||||
- 结论与依据、证据链接、脱敏范围
|
||||
- 未覆盖项、风险、遗留进程/产物、接管建议
|
||||
|
||||
只读子 Agent 结论由主 Agent 转存时:保留 `agent_id` 与原结论,注明「由主 Agent 转存」。
|
||||
|
||||
## 阶段收据表
|
||||
|
||||
| 阶段 | 输入版本 | 产物/证据 | producer | reviewer/独立性 | 决定 | 下一步 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| S0–S9 适用项 | | | | independent / self_review / not_required | pass / changes_required / blocked / not_applicable | |
|
||||
|
||||
未执行阶段写 `not_applicable` + 原因。报告存在不自动满足门禁。
|
||||
|
||||
## 需求追踪
|
||||
|
||||
| R-ID | AC-ID | 改动/版本 | 审查 | T-ID / 结果 | 运行验收 | acceptance_owner |
|
||||
|---|---|---|---|---|---|---|
|
||||
| | | | | | | |
|
||||
|
||||
## 与任务五态
|
||||
|
||||
继续用任务模板的 `status`、`review_state`、`integration_state`、`deployment`、`cleanup`、`remote_sync`;额外记 `phase`、`acceptance`、待回收 `subtask_id`。`done` 取决于授权交付终点,不因会话结束自动完成。
|
||||
+4
-15
@@ -11,10 +11,10 @@
|
||||
.doc/
|
||||
README.md ← 本文件(总地图)
|
||||
status/ ← 模块/功能完成度 SSOT
|
||||
audit/ ← 问题发现与分析、ISSUES.md 问题/修复台账
|
||||
audit/ ← 问题发现与分析
|
||||
remediation/ ← 整改方案与发布缺口
|
||||
archive/ ← 历史(只增不删)
|
||||
ops/ ← 活协作(任务、交接、调研;lessons/ 开发经验)
|
||||
ops/ ← 活协作(任务、交接、调研)
|
||||
system-design/ ← 模块架构深读
|
||||
adr/ ← 架构决策
|
||||
backlog/ ← 产品 backlog(非阻塞)
|
||||
@@ -33,23 +33,16 @@
|
||||
|
||||
| 我要… | 读这里 |
|
||||
|--------|--------|
|
||||
| Subagent 模型配置 / 流程 | [可调整模型配置](ops/2026-09-24-subagent-model-config.md) · [PI 执行器](ops/2026-09-24-pi-subagent-executor.md) · [流程草案](ops/2026-09-24-subagent-workflow-standard.md) · [研究依据](audit/2026-09-24-subagent-workflow-research.md) |
|
||||
| 规则来源/生效版本 | [规范登记](ops/2026-09-21-policy-registry.md) |
|
||||
| 选择测试/报告范围 | [验证契约](ops/2026-09-21-validation-contract.md) |
|
||||
| 任务模板与会话收口 | [任务模板](ops/templates/short-term-task.md) · [收口清单](ops/templates/session-close-checklist.md) |
|
||||
| 创建任务、集成、部署、清理 | [worktree 工作规范](ops/2026-09-21-agent-worktree-workflow.md) |
|
||||
| 当前在做什么 | [ops/CURRENT.md](ops/CURRENT.md) |
|
||||
| 模块完成度 | [status/FEATURE-MATRIX.md](status/FEATURE-MATRIX.md) |
|
||||
| 发布 blocker | [remediation/gap-matrix.md](remediation/gap-matrix.md) |
|
||||
| 问题历史、修复经过 | [问题台账](audit/ISSUES.md) · [闭环规范](ops/2026-09-23-issue-learning-workflow.md) |
|
||||
| 开发注意事项与经验检索 | [经验索引](ops/lessons/INDEX.md) |
|
||||
| 审计/问题分析 | [audit/INDEX.md](audit/INDEX.md) |
|
||||
| 整改方案 | [remediation/INDEX.md](remediation/INDEX.md) |
|
||||
| 历史归档 | [archive/README.md](archive/README.md) |
|
||||
| 架构设计 | [system-design/README.md](system-design/README.md) |
|
||||
| 用错误码定位失败 | [错误码目录](system-design/2026-09-28-error-code-catalog.md) |
|
||||
| 测试报告 | [test-reports/](test-reports/) |
|
||||
| 历史功能设计 | [archive/design/superpowers/](archive/design/superpowers/) |
|
||||
| Herdr 角色、审批与备援 | [ops/2026-09-13-herdr-agent-roster.md](ops/2026-09-13-herdr-agent-roster.md) |
|
||||
|
||||
---
|
||||
|
||||
@@ -64,13 +57,9 @@
|
||||
|
||||
## 文档生命周期
|
||||
|
||||
按 [AGENTS 任务分级](../AGENTS.md#2-任务分级与授权) 选择最小产物。下图是可选信息流,不要求每任务创建所有文件;小任务/有价值的只读审查可由一个主文档承载范围、结论、验证与交接。主文档先明确 task_id、owner、授权来源、状态和证据;跨阶段信息确需独立时才拆分并回链。
|
||||
|
||||
```text
|
||||
audit(问题)→ remediation(方案)→ ops/short-term(任务)
|
||||
→ test-reports(验收)→ archive(关闭证据)
|
||||
```
|
||||
|
||||
任务状态字段:`planned | in_progress | blocked | done | cancelled`。问题以 issue_state、经验以 lesson_state 独立记录,取值与转换见 [闭环规范](ops/2026-09-23-issue-learning-workflow.md);研究任务完成不关闭待修问题。
|
||||
|
||||
会话结束不等于任务完成;只有 done/cancelled 任务归档。CURRENT 保留最多 3 项焦点及活跃/阻塞/待集成/待清理事项,完成认领和长证据迁入 [历史快照](archive/ops/2026-09-21-current-history.md)。移动文档同步修复相对链接,保留证据与来源。规范生命周期另用 proposed/approved/active/deprecated;工具能力另用 manual/enforced。
|
||||
状态字段:`planned | in_progress | blocked | done | cancelled`
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# ADR:最终成果保险库(FAV)
|
||||
|
||||
## 状态
|
||||
|
||||
已接受(2026-09-14,落地计划 V0–V6)
|
||||
|
||||
## 背景
|
||||
|
||||
运行库 PostgreSQL 与 workspace 投影会一起丢失或错挂。需要独立保存**已确认终态**的精确字节,但不能成为第三套完整业务真相源,也不能用目录扫描猜测“最终文件”。
|
||||
|
||||
## 决策
|
||||
|
||||
1. **三层权威**:PostgreSQL 管项目/权限/工作流/版本关系;workspace 是可清理投影;FAV 只对已归档 payload、manifest、来源证据和删除状态权威。
|
||||
2. **无 tenant_id**:安全边界沿用 `environment + project_members + role-admin`。未来组织层另立 ADR。
|
||||
3. **事件准入**:只接受方案准入表中的数据库事实。显式 publish/pin 不能绕过终态 allowlist。禁止扫描 workspace。
|
||||
4. **同事务冻结**:终态事务把精确 payload/SHA 写入 staging 并写 unpublished outbox;publisher 不得重读可变消息行。
|
||||
5. **union-deny 删除**:运行库删除账本或 vault tombstone 任一侧删除即拒绝读取/恢复。
|
||||
6. **恢复**:只进 scratch 库,默认 `recover-as-collection`。禁止 GET 自动写回或覆盖现有 head。
|
||||
7. **互补**:FAV、migration corpus、完整 DB backup/PITR 互相不能替代。不作为 409/split-brain 绕行。
|
||||
|
||||
## 后果
|
||||
|
||||
- 实现从 `feature/final-artifact-vault` 推进;mutex=`artifact-vault`。
|
||||
- Goose 从 **00034** 增加 FAV 表(00033 已被 task-run 治理占用)。
|
||||
- 降级读取默认关闭(`FAV_DEGRADED_READ`),Unit A 纠挂完成前不得对现网开启。
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
已接受(2026-09-14 提议;2026-09-18 确认——Phase 1 纵向绞杀与 Phase 2 持久事件交付已落地并验收,见 gap-matrix `DOC-RELIABILITY-PILOT` PASS、[Phase 1 计划](../remediation/2026-09-14-module-decoupling-refactor-plan.md)、[Phase 2 修订计划](../remediation/2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md)、[Track E 复盘](../ops/research/2026-09-15-track-e-retrospective.md))
|
||||
提议(2026-09-14;架构与实施计划已修订,等待用户确认后进入首个实现里程碑)
|
||||
|
||||
## 背景
|
||||
|
||||
|
||||
@@ -1,609 +0,0 @@
|
||||
---
|
||||
title: "个人工程中控台:实时项目看板与离线 HTML 快照"
|
||||
type: feat
|
||||
date: 2026-09-17
|
||||
artifact_contract: ce-unified-plan/v1
|
||||
product_contract_source: ce-plan-bootstrap
|
||||
execution: code
|
||||
---
|
||||
|
||||
> **已废弃(2026-09-17;2026-09-19 更新)**:旧版只读工程中控台代码已移除。后来短暂合入的 Control Center 也已移出本仓库,进度管理由独立项目承担。本文仅作历史证据保留。
|
||||
|
||||
# 个人工程中控台:实时项目看板与离线 HTML 快照
|
||||
|
||||
## Goal Capsule
|
||||
|
||||
为仓库所有者提供一个独立于产品后台的本地只读中控台。打开一个页面即可判断当前系统由什么组成、哪些任务正在计划或实施、真实分支和 worktree 在哪里、各环境实际运行了什么,并能在两次点击内到达对应的设计、审计、整改、任务和测试材料。
|
||||
|
||||
中控台同时提供两种输出:
|
||||
|
||||
1. `serve`:持续采集本地仓库、Git 和运行环境,提供自动刷新的 HTML 页面与机器可读 JSON;
|
||||
2. `export`:基于同一份不可变快照生成单文件 HTML,便于归档、离线查看和交接。
|
||||
|
||||
这不是产品功能,不接入产品后台、产品数据库或产品权限体系;它也不是发布系统,不执行 Git、Docker、部署或文档写操作。
|
||||
|
||||
### 成功标准
|
||||
|
||||
- 在当前仓库规模下,首次可用页面目标为 2 秒内出现;慢数据源可随后标记为 `degraded`,不得拖垮整页。
|
||||
- 正常情况下,本地文件、Git 或运行态变化在 5 秒内反映到新快照。
|
||||
- 页面分别展示“文档声明、Git 实施、验证证据、环境实装”,不把任务文档的 `done` 翻译为已合并或已部署。
|
||||
- 每个关键结论均显示来源、采集时间、新鲜度和可信类型;冲突保留双方证据,不静默选边。
|
||||
- 在线模式检索 allowlist 内未截断的 Markdown 正文;离线导出同时给出 included、truncated 和 metadata-only 清单,二进制附件只索引路径、类型、大小和归属。
|
||||
- 单文件 HTML 默认权限为 `0600`,可脱离仓库阅读已纳入 inclusion manifest 的 Markdown 正文,并醒目标出截断或仅元数据条目;不打包 `.doc/**/assets`。
|
||||
- 任一采集源失败时仍可查看最近成功数据,并明确显示 `stale/error/last_success_at`。
|
||||
|
||||
---
|
||||
|
||||
## Product Contract
|
||||
|
||||
### 用户与使用场景
|
||||
|
||||
唯一主要用户是仓库所有者。典型使用包括:
|
||||
|
||||
- 每天开始工作时查看焦点任务、阻塞、集成槽和环境异常;
|
||||
- 从模块进入设计、任务、测试和部署证据链;
|
||||
- 判断某项工作究竟只是有计划、正在实现、已经验证,还是已在某环境实装;
|
||||
- 查看本地分支、远端跟踪引用、ahead/behind、worktree 和未提交变更;
|
||||
- 发现 `CURRENT`、功能矩阵、发布门禁、Git 与 Docker 之间的漂移;
|
||||
- 导出一个自包含 HTML,作为某一时点的项目快照。
|
||||
|
||||
### 已确定的产品决策
|
||||
|
||||
#### PKD-1:独立本地工具
|
||||
|
||||
采用独立 Go CLI 和本地 Web 页面,不加入现有产品后台。
|
||||
|
||||
(session-settled: user-approved — chosen over product-admin integration: the console is for the repository owner’s local engineering management and the production image excludes `.doc` and `.git`)
|
||||
|
||||
#### PKD-2:只读实时页与离线快照共用数据模型
|
||||
|
||||
实时服务和导出文件必须由同一份版本化快照生成,避免在线页面与离线报告出现两套口径。
|
||||
|
||||
(session-settled: user-approved — chosen over a static-only report: the requested console must follow agent tasks and project state as they change)
|
||||
|
||||
### 核心需求
|
||||
|
||||
| ID | 需求 |
|
||||
|---|---|
|
||||
| R1 | CLI 默认解析当前 Git 仓库根,也接受显式 `--repo`;页面始终显示绝对根路径、当前分支、HEAD 和采集时间。 |
|
||||
| R2 | 仅监听 `127.0.0.1`,不依赖产品容器、产品数据库或产品登录。 |
|
||||
| R3 | 架构与模块页聚合 `module-boundaries.yaml`、系统设计索引和 `FEATURE-MATRIX`,展示模块、能力、依赖和证据链。 |
|
||||
| R4 | 任务状态至少拆为 `doc_status`、Git facets、`verification_result`/`verification_freshness`、deployment facets;可并存事实不得压成单值枚举。 |
|
||||
| R5 | Git 页展示本地/跟踪分支、ahead/behind、最近提交、worktree、dirty/untracked 和任务声明匹配情况;不得隐式 `fetch`。 |
|
||||
| R6 | 部署页按 shared/dev/test/main 分别展示容器状态、应用 readiness、服务完整性、schema、镜像与 promotion receipt;不得计算未经定义的综合绿灯。 |
|
||||
| R7 | 文档页支持按 taxonomy、状态、模块和关键词筛选,展示正文、正向链接、反向链接、broken、orphan 与 unindexed 状态;查询状态可通过 URL 恢复。 |
|
||||
| R8 | 一个不可变快照包含 `schema_version`、`generation_id`、`revision_id`、`generated_at`、仓库/提交身份、来源状态、事实与冲突。 |
|
||||
| R9 | 自动刷新采用完整快照原子切换;每个来源独立超时,失败时保留最近成功数据并标注过期。 |
|
||||
| R10 | 每条关键事实标注 `declared`、`observed`、`verified` 或 `inferred`,并保留来源路径和采集时间。 |
|
||||
| R11 | 单 HTML 内嵌结构化模型、页面资源和允许导出的 Markdown 正文;附件只保留元数据及相对链接,并显示内容覆盖清单。 |
|
||||
| R12 | 对 Agent 暴露稳定的只读 JSON,而不是让 Agent 解析 HTML;JSON 与页面引用同一 `generation_id` 和 `revision_id`。 |
|
||||
| R13 | TaskState 显示声明的 owner/Agent 类型/认领/mutex 与基于 Git 的最近活动证据;Herdr 工程 Agent 和产品 PI Agent Runner 使用不同类型。没有运行态来源时必须显示 unknown,不得把“已认领”写成“正在执行”。 |
|
||||
| R14 | 文件、命令和 HTTP 均采用 allowlist;拒绝路径穿越、symlink 越界、原始 HTML 执行、远程资源加载和凭证读取。 |
|
||||
|
||||
### 事实源与权威边界
|
||||
|
||||
| 领域 | 权威来源 | 中控台处理方式 |
|
||||
|---|---|---|
|
||||
| 发布门禁 | `.doc/remediation/gap-matrix.md` | 只解释发布 blocker,不替代能力完成度。 |
|
||||
| 能力成熟度 | `.doc/status/FEATURE-MATRIX.md` | 显示功能完成度,不据此推断是否部署。 |
|
||||
| 当前焦点、认领、集成槽 | `.doc/ops/CURRENT.md` | 作为团队声明,与 Git 和运行态对账。 |
|
||||
| 任务计划 | `ops/short-term`、`ops/long-term`、backlog front matter | 作为计划状态,不据此推断实现。 |
|
||||
| 分支与 worktree | Git plumbing | 作为本地观测;远端状态注明“基于本地 refs,未联网刷新”。 |
|
||||
| 环境运行态 | Docker/Compose 元数据与 `/ready` | 分开展示容器、应用与服务完整性。 |
|
||||
| 验收证据 | `.doc/test-reports` 及 promotion receipts | 显示证据存在性与身份,不以文件名替代内容校验。 |
|
||||
|
||||
来源之间不设全局覆盖顺序。各来源回答自己的问题;值不一致时生成 drift,并并列展示原值、时间和来源。
|
||||
|
||||
### 用户流程
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Start[启动 serve 或 export] --> Root[解析显式 repo root]
|
||||
Root --> Collect[并行采集文档 Git 运行态]
|
||||
Collect --> Snapshot[构建不可变快照]
|
||||
Snapshot --> Reconcile[按领域对账]
|
||||
Reconcile --> Live[本地实时页面和 JSON]
|
||||
Reconcile --> Export[单文件 HTML]
|
||||
Live --> Refresh[定时生成下一快照]
|
||||
Refresh --> Snapshot
|
||||
```
|
||||
|
||||
总览默认优先显示 `in_progress`、`blocked`、`planned`、`partial/deferred`、drift 和 degraded。`done` 与 archive 默认收起,避免历史材料淹没当前工作。
|
||||
|
||||
任务详情按照以下证据链导航:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Audit[audit 问题] --> Remediation[remediation 方案]
|
||||
Remediation --> Task[任务声明]
|
||||
Task --> Git[分支 worktree commit merge]
|
||||
Git --> Test[测试与验收报告]
|
||||
Test --> Deploy[环境 artifact 与 readiness]
|
||||
```
|
||||
|
||||
显式 Markdown 链接和既定 taxonomy 属于强关系;仅由文件名或 slug 推断的关系标为“候选”,不得参与完成度计算。
|
||||
|
||||
### 状态模型
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
D[doc_status: planned/in_progress/blocked/done] --> View[并列状态视图]
|
||||
G[Git facets: branch/worktree/merge/cleanliness/ahead-behind] --> View
|
||||
V[Verification: result + freshness + bound identity] --> View
|
||||
P[Deployment facets: container/readiness/services/artifact identity] --> View
|
||||
View --> Drift{来源是否一致}
|
||||
Drift -->|是| Consistent[consistent]
|
||||
Drift -->|否| Conflict[drift + 双方证据]
|
||||
```
|
||||
|
||||
“实装”定义为存在可核对的环境观测证据,而不是任务文档为 `done`。容器可达但 artifact identity 无法核对时显示“运行可见、版本未验证”,不得提升为 verified deployment。当文档声明 healthy、Docker 显示异常而 `/ready` 为 ok 时,页面保留多值并标记 drift,不输出统一绿灯。
|
||||
|
||||
### 真实验收样本
|
||||
|
||||
1. rdev:存在调研、设计、任务与 backlog,但若没有 CURRENT 认领和真实分支,应显示“已计划、未认领、未实施、未实装”。
|
||||
2. main 环境:若 CURRENT 声明整体 healthy,而 events 容器实际 restarting、应用 `/ready` 仍为 ok,应同时显示三项证据与 drift。
|
||||
3. 本地 dev:若分支领先 `origin/dev`,必须显示“本地已具备、远端未确认可用”,不得写成已远程发布。
|
||||
4. `system-admin-console`:作为产品管理后台能力,与本计划的个人工程中控台分开展示,名称和边界不得混淆。
|
||||
|
||||
### 安全与非目标
|
||||
|
||||
一期明确不做:
|
||||
|
||||
- 不写文档,不修改任务状态,不占用集成槽;
|
||||
- 不创建、切换、合并、删除或推送 Git 分支;
|
||||
- 不执行 `git fetch`,不调用远端托管平台 API;
|
||||
- 不启动、停止、重建或部署容器;
|
||||
- 不控制 Herdr 或向 Agent 派发任务;
|
||||
- 不读取 `.env`、`.secrets`、Docker `Config.Env`、数据库数据或 `.git` 内部文件正文;
|
||||
- 不加入产品 API、产品前端、产品数据库或生产镜像;
|
||||
- 不执行 Markdown 原始 HTML、脚本、Mermaid 或远程资源。
|
||||
|
||||
后续候选包括跨快照历史、远端 CI/Gitea 聚合、受限 Markdown/Mermaid 渲染、Agent 查询 API 和修复建议。任何写操作继续保持在本工具之外。
|
||||
|
||||
---
|
||||
|
||||
## Planning Contract
|
||||
|
||||
### High-Level Technical Design
|
||||
|
||||
以下图示冻结边界和协议,不规定具体函数签名。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Docs[.doc sources] --> DC[Document collector]
|
||||
Git[Git/worktrees] --> GC[Git collector]
|
||||
Run[Docker/ready/receipts] --> RC[Runtime collector]
|
||||
DC --> Build[Snapshot builder]
|
||||
GC --> Build
|
||||
RC --> Build
|
||||
Build --> Rec[Reconcile facts and conflicts]
|
||||
Rec --> JSON[Read-only JSON]
|
||||
Rec --> Web[Local HTML]
|
||||
Rec --> File[Offline HTML]
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as Browser
|
||||
participant C as Collection coordinator
|
||||
participant S as Sources
|
||||
participant P as Snapshot publisher
|
||||
UI->>C: poll with revision_id
|
||||
C-->>UI: current snapshot immediately
|
||||
C->>S: singleflight collection with deadlines
|
||||
S-->>C: facts or source error
|
||||
C->>P: publish complete generation atomically
|
||||
P-->>UI: new revision or not-modified
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Loading
|
||||
Loading --> Fresh: first collection succeeds
|
||||
Loading --> ErrorUnknown: first collection fails
|
||||
Fresh --> Refreshing: TTL expires
|
||||
Refreshing --> Fresh: new generation succeeds
|
||||
Refreshing --> Stale: source fails and last-known exists
|
||||
Stale --> Fresh: source recovers
|
||||
ErrorUnknown --> Fresh: source first succeeds
|
||||
```
|
||||
|
||||
### 技术决策
|
||||
|
||||
#### KTD-1:采用仓库内独立 Go CLI
|
||||
|
||||
新增 `cmd/engineering-dashboard` 与 `internal/engineeringdashboard`,复用仓库 Go 工具链但不导入产品业务包。Go 标准库足以提供本地 HTTP、资源嵌入、JSON、并发和原子文件输出;现有 `yaml.v3` 可用于已定义的 YAML 契约。
|
||||
|
||||
#### KTD-2:快照是唯一交付模型
|
||||
|
||||
采集器只生产事实,reconcile 层只生产派生状态和冲突,HTTP/API/export 只消费已完成的不可变快照。快照至少包含:
|
||||
|
||||
```text
|
||||
schema_version, generation_id, revision_id, generated_at, collection_duration
|
||||
repository { root, branch, head, dirty }
|
||||
sources[] { name, status, observed_at, last_success_at, error }
|
||||
facts[] { subject, field, value, provenance, source_ref, observed_at, confidence }
|
||||
conflicts[] { subject, field, kind, fact_refs[] }
|
||||
documents[], modules[], tasks[], git[], environments[]
|
||||
```
|
||||
|
||||
`generation_id` 唯一标识一次采集,包含采集批次语义;`revision_id` 只由 schema、仓库身份和规范化的非易变事实、冲突、来源状态确定,明确排除 `generated_at`、`observed_at` 和采集耗时。HTML 与 JSON 必须展示同一对标识,HTTP ETag 和前端是否重绘使用 `revision_id`。一期不读取旧 schema 的外部 JSON;离线 HTML 自带对应 renderer,因此不依赖未来二进制迁移。
|
||||
|
||||
#### KTD-3:专用解析器与容错索引并存
|
||||
|
||||
对 CURRENT、FEATURE-MATRIX、gap-matrix、任务 front matter 和 module boundaries 编写契约化解析器。文档层只索引 promotion receipt 的路径与链接,结构化部署凭证由运行态采集器唯一负责。对其余 Markdown 只提取安全元数据、标题、正文与链接。专用解析器失败时保留原文入口并标记 degraded,不凭模糊规则编造状态。
|
||||
|
||||
#### KTD-4:命令执行采用固定 argv 和超时
|
||||
|
||||
Git 与 Docker 采集通过注入式 command runner 执行固定程序和分离 argv,不通过 shell 拼接。`--repo` 先转为绝对、symlink-resolved 的 Git 根并作为单个参数传递。每个来源默认 2 秒超时;错误输出做长度限制和敏感字段清理。Git 使用 porcelain/plumbing 输出,例如 `status --porcelain=v2`、`worktree list --porcelain`、`for-each-ref`、`rev-list`、`merge-base`。
|
||||
|
||||
#### KTD-5:一期采用短轮询,不引入持久数据库
|
||||
|
||||
服务端由单一采集协调器按 TTL 触发完整重采集,2–5 秒刷新;同一仓库最多一轮采集在途,请求只读取当前快照,不直接叠加扫描。每轮带单调 generation 序号和整轮 deadline,只有当前有效轮次能原子发布。页面使用 ETag/`revision_id` 避免重复传输。last-known 只在同一 `serve` 进程内有效;冷启动或单次 export 首次采集失败时显示 unknown/error,不伪造历史值。文件监听、SSE 通知、持久缓存和历史数据库均后置。
|
||||
|
||||
#### KTD-6:安全阅读优先于富渲染
|
||||
|
||||
在线详情页一期将 Markdown 全部作为纯文本安全转义,并保留换行和空白;标题、列表、链接、代码、图片和 Mermaid 均显示源码,不生成 HTML 节点或发起资源请求。静态导出内嵌同一正文和内部导航。所有文档 ID 都是规范化仓库相对路径,只允许 `.doc/**/*.md` 及明确列入 allowlist 的根 Markdown;读取前后都校验解析路径,直接拒绝 symlink,并对 `.git`、`.env*`、`.secrets`、`data` 等敏感路径执行最终目标 denylist。
|
||||
|
||||
#### KTD-7:导出为自包含、有限尺寸的证据快照
|
||||
|
||||
导出将模型、CSS、JS 和允许的 Markdown 正文写入单 HTML,采用临时文件加 rename 原子落盘,默认 `0600`。数据使用 HTML-safe JSON 或等价编码封装,正文只通过 `textContent`/DOM API 写入;CSP 禁止网络、外部资源和内联事件执行。默认只嵌入 Git tracked、allowlist 内的 Markdown;untracked Markdown 只列元数据,除非用户显式选择。导出前输出 inclusion manifest 与敏感模式告警;`.doc/**/assets`、数据库、构建产物和二进制报告不嵌入。
|
||||
|
||||
### 建议目录
|
||||
|
||||
```text
|
||||
cmd/engineering-dashboard/
|
||||
main.go
|
||||
internal/engineeringdashboard/
|
||||
model.go
|
||||
collector.go
|
||||
source_docs.go
|
||||
source_git.go
|
||||
source_runtime.go
|
||||
reconcile.go
|
||||
server.go
|
||||
export.go
|
||||
assets/
|
||||
index.html
|
||||
app.js
|
||||
app.css
|
||||
testdata/
|
||||
docs/
|
||||
git/
|
||||
runtime/
|
||||
scripts/
|
||||
engineering-dashboard.sh
|
||||
.doc/test-reports/
|
||||
YYYY-MM-DD-engineering-dashboard-test-report.md
|
||||
```
|
||||
|
||||
### 风险与缓解
|
||||
|
||||
| 风险 | 缓解 |
|
||||
|---|---|
|
||||
| 文档结构并不完全统一 | 只对 SSOT 和任务 front matter 使用严格契约;其余文档容错索引并暴露解析告警。 |
|
||||
| 看板制造“假完成” | 多轴 facets、事实 provenance、验证身份绑定、冲突不覆盖、真实反例测试。 |
|
||||
| Docker/Git 卡住或不可用 | 独立超时、并行采集、last-known 状态、degraded 页面。 |
|
||||
| 文档 XSS 或路径穿越 | 纯文本渲染、HTML-safe 数据封装、CSP、路径 allowlist、拒绝 symlink、最终目标敏感路径 denylist。 |
|
||||
| `.doc` 附件导致扫描/导出失控 | 默认跳过 assets 内容,只采集元数据;设置单文档和总正文上限并报告截断。 |
|
||||
| 导出副本离开本机后 `0600` 不再提供保护 | 页面首部标明敏感快照、仓库身份和生成时间;输出 inclusion manifest,交接者自行控制接收者、保留期与删除。 |
|
||||
| worktree 与主 checkout 混淆 | 只管理 `--repo` 指定/解析出的根,页面常驻显示根与 HEAD;其他 worktree 仅作为 Git 元数据。 |
|
||||
| 本地 remote refs 被误认为远端实时状态 | 显示 refs 观测时间和“未联网刷新”,不自动 fetch。 |
|
||||
| 与产品 `system-admin-console` 命名冲突 | CLI、包和文档统一使用 `engineering-dashboard` / “个人工程中控台”。 |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Units
|
||||
|
||||
### U1:冻结快照、事实与状态契约
|
||||
|
||||
**目标**:先建立不会把计划、实现、验证、部署混为一谈的模型与测试夹具。
|
||||
|
||||
**覆盖需求**:R4、R8、R10、R12、R13;承接 PKD-2 的同源快照决策。
|
||||
|
||||
**依赖**:无。
|
||||
|
||||
**文件**:
|
||||
|
||||
- `internal/engineeringdashboard/model.go`
|
||||
- `internal/engineeringdashboard/model_test.go`
|
||||
- `internal/engineeringdashboard/testdata/**`
|
||||
|
||||
**实施要点**:
|
||||
|
||||
1. 定义版本化 `Snapshot`、`SourceState`、`Fact`、`Conflict`、`TaskState`、`AgentClaim`、`EnvironmentState`。
|
||||
2. provenance 固定为 `declared|observed|verified|inferred`;freshness 固定为 `fresh|stale|error|unknown`。
|
||||
3. 状态使用可组合 facets:Git 分为 branch/worktree/merge/cleanliness/ahead-behind;验证分为 result/freshness/subject identity;部署分为 container/readiness/services/artifact identity。
|
||||
4. TaskState 保留 owner、agent kind、claim、mutex、声明分支、观测 worktree、最近活动时间及证据;声明与观测不可互相提升。
|
||||
5. 建立 rdev、dev ahead、main events restarting、CURRENT/worktree 不匹配等夹具。
|
||||
|
||||
**测试场景**:
|
||||
|
||||
- 文档 `done` 但无 merge/deploy 时,Git 与部署 facets 不改变;
|
||||
- `claimed` 但无可观测运行信号时,Agent 活动保持 unknown;Herdr 与产品 PI Runner 不共享类型;
|
||||
- 同字段多来源不一致时生成 conflict 并保留所有 fact 引用;
|
||||
- JSON round-trip 保留 schema 与 snapshot identity;
|
||||
- 枚举未知值失败且错误可定位。
|
||||
|
||||
**完成证据**:模型测试通过,schema 示例落入 Go fixture,不存在页面专用的第二套状态类型。
|
||||
|
||||
### U2:实现文档图谱与领域解析器
|
||||
|
||||
**目标**:将 `.doc` taxonomy、模块、任务、测试和链接转换为可追溯文档图谱。
|
||||
|
||||
**覆盖需求**:R3、R7、R10、R11、R14。
|
||||
|
||||
**依赖**:U1。
|
||||
|
||||
**文件**:
|
||||
|
||||
- `internal/engineeringdashboard/source_docs.go`
|
||||
- `internal/engineeringdashboard/docs_test.go`
|
||||
|
||||
**实施要点**:
|
||||
|
||||
1. 扫描 allowlist 内 Markdown,默认跳过任何 `assets` 目录正文;记录附件元数据。
|
||||
2. 解析 front matter、标题、显式 Markdown 链接和反向链接。
|
||||
3. 为 CURRENT、FEATURE-MATRIX、gap-matrix、任务文、module boundaries 和 test report 建立专用适配器;receipt 只在文档图谱中作为文档与链接,结构化解析归 U4。
|
||||
4. 区分 `broken`、`orphan`、`unindexed`;slug 相似只形成候选关系。
|
||||
5. 规范化路径并阻止 `..`、绝对路径和任何 symlink;最终目标再次应用扩展名 allowlist 与敏感路径 denylist。
|
||||
|
||||
**测试场景**:
|
||||
|
||||
- taxonomy 内文档可检索且反向链接正确;
|
||||
- broken link 不导致整个索引失败;
|
||||
- front matter 缺失或非标准时产生告警并仍可阅读;
|
||||
- assets 不读正文,越界 symlink 被拒绝;
|
||||
- rdev 文档链被发现,但没有被推断为已实现。
|
||||
|
||||
**完成证据**:文档索引能从 fixture 生成稳定 JSON,路径安全负例通过。
|
||||
|
||||
### U3:实现 Git 与 worktree 采集
|
||||
|
||||
**目标**:以只读 Git plumbing 形成可复现的分支、提交和 worktree 观测。
|
||||
|
||||
**覆盖需求**:R1、R4、R5、R10、R14。
|
||||
|
||||
**依赖**:U1。
|
||||
|
||||
**文件**:
|
||||
|
||||
- `internal/engineeringdashboard/source_git.go`
|
||||
- `internal/engineeringdashboard/git_test.go`
|
||||
|
||||
**实施要点**:
|
||||
|
||||
1. 抽象 command runner,固定 argv、工作目录、超时和输出上限。
|
||||
2. 收集当前分支/HEAD、dirty/untracked、local/remote-tracking refs、ahead/behind、merge-base 和 worktree。
|
||||
3. 不执行 fetch;remote tracking ref 始终带本地观测时间与免责声明。
|
||||
4. 对账任务声明的 branch/worktree,但不因路径名相似而认定一致。
|
||||
|
||||
**测试场景**:
|
||||
|
||||
- 本地分支领先 origin 时显示 ahead 且不显示“远端可用”;
|
||||
- worktree 目录名与真实检出分支不一致时生成 drift;
|
||||
- 命令超时、Git 不存在、非 Git 目录时单源 degraded;
|
||||
- runner 记录中不存在 shell、fetch、push 或写命令。
|
||||
|
||||
**完成证据**:临时 Git 仓库集成测试和 fake runner 单元测试通过。
|
||||
|
||||
### U4:实现运行态与部署证据采集
|
||||
|
||||
**目标**:按环境独立呈现容器、应用 readiness、服务完整性、schema、镜像和晋升凭证。
|
||||
|
||||
**覆盖需求**:R4、R6、R10、R14。
|
||||
|
||||
**依赖**:U1。
|
||||
|
||||
**文件**:
|
||||
|
||||
- `internal/engineeringdashboard/source_runtime.go`
|
||||
- `internal/engineeringdashboard/runtime_test.go`
|
||||
|
||||
**实施要点**:
|
||||
|
||||
1. 从仓库内批准的 Compose 静态配置和 allowlist labels 映射环境与服务;无法明确映射时显示 unknown,不用名称猜测。容器 JSON 只提取容器名、image/digest、状态、restart count、health,以及 allowlist 内的 Compose project/service labels;不复制 Env、Mounts、完整 NetworkSettings 或任意 labels。
|
||||
2. 对 allowlist 中的本地 `/ready` 端点执行短超时、响应大小受限的请求;禁用重定向,或对每一跳重新校验 scheme、解析后 IP、端口和 host。
|
||||
3. 解析 promotion receipt/candidate image 等仓库证据,保留 artifact identity。
|
||||
4. 将 container health、app readiness、required-service completeness 分开建模。
|
||||
|
||||
**测试场景**:
|
||||
|
||||
- app ready 且 events restarting 时同时保留两项状态;
|
||||
- Docker 不可用或 HTTP 超时时,其他数据源仍可输出;
|
||||
- receipt 与容器 image 不一致时生成 deployment drift;容器可达但 identity 缺失时标记“运行可见、版本未验证”;
|
||||
- readiness 重定向到外网或非 allowlist 本地端口时拒绝访问;
|
||||
- 输出中不存在容器环境变量或凭证。
|
||||
|
||||
**完成证据**:fixture 和 fake HTTP/Docker runner 测试通过,main 分叉场景被覆盖。
|
||||
|
||||
### U5:实现对账、派生视图与新鲜度
|
||||
|
||||
**目标**:把来源事实组合成用户可判断的视图,但不替来源做未经定义的裁决。
|
||||
|
||||
**覆盖需求**:R3、R4、R6、R8、R9、R10、R13。
|
||||
|
||||
**依赖**:U2、U3、U4。
|
||||
|
||||
**文件**:
|
||||
|
||||
- `internal/engineeringdashboard/reconcile.go`
|
||||
- `internal/engineeringdashboard/reconcile_test.go`
|
||||
|
||||
**实施要点**:
|
||||
|
||||
1. 按领域 SSOT 规则构建 module、task、environment 和 evidence-chain 视图。
|
||||
2. 实现 conflict 分类:declared-vs-observed、task-vs-git、test-vs-subject、receipt-vs-runtime、stale-source、missing-evidence。
|
||||
3. 快照构建期间每个来源独立记录 `observed_at`、持续时间和错误;成功后一次性发布。
|
||||
4. 失败源只可复用同一 serve 进程的 last-known,并标注 stale、age 与 last-success;冷启动无缓存时为 unknown/error。过期数据不隐藏,但按年龄提升告警级别。
|
||||
5. 测试报告只有在 commit/artifact identity 与当前 subject 对齐时才能派生 pass;身份缺失为 unbound,身份不匹配为 stale/drift。
|
||||
|
||||
**测试场景**:
|
||||
|
||||
- 三个真实样本得到预期多轴状态;
|
||||
- 同一组输入顺序变化不改变规范化快照;
|
||||
- 单源失败不会删除其他源,也不会重写 last-known 的观测时间;冷启动失败没有伪造 last-known;
|
||||
- 旧测试报告、新 HEAD 与不同 image 不会派生当前验证通过;
|
||||
- 恢复后 stale 自动清除并产生新 snapshot ID。
|
||||
|
||||
**完成证据**:reconcile table tests 覆盖一致、漂移、缺失、过期和恢复。
|
||||
|
||||
### U6:实现本地服务、总览与文档导航
|
||||
|
||||
**目标**:提供能快速判断异常并下钻证据的本地只读页面和 JSON。
|
||||
|
||||
**覆盖需求**:R1、R2、R3、R7–R10、R12–R14;承接 PKD-1 和 PKD-2。
|
||||
|
||||
**依赖**:U5。
|
||||
|
||||
**文件**:
|
||||
|
||||
- `internal/engineeringdashboard/server.go`
|
||||
- `internal/engineeringdashboard/server_test.go`
|
||||
- `internal/engineeringdashboard/assets/index.html`
|
||||
- `internal/engineeringdashboard/assets/app.js`
|
||||
- `internal/engineeringdashboard/assets/app.css`
|
||||
- `cmd/engineering-dashboard/main.go`
|
||||
|
||||
**实施要点**:
|
||||
|
||||
1. `serve --repo <path> --addr 127.0.0.1:<port>`;一期无条件拒绝所有非 loopback 地址,包括通配、IPv6 非 loopback 和显式传入值。
|
||||
2. 暴露 `/api/v1/snapshot`、`/api/v1/doc/<id>`、`/healthz`;所有接口只读。严格校验 Host/Origin/Fetch Metadata,不信任代理转发头;页面和 API 使用每次启动生成的不可预测访问令牌,降低 DNS rebinding 与跨站读取风险。
|
||||
3. 页面分为总览、架构/模块、任务、Git、部署、文档和证据链。
|
||||
4. 自动刷新完整快照,保留当前筛选、滚动位置、焦点和选中文档;ETag 未变化时不重绘。
|
||||
5. 明确一级视图状态:initial loading、fresh empty、fresh success、partial/degraded with last-known、hard error without cache、refreshing、recovered。刷新中继续展示上一完整快照,直到下一版本原子替换。
|
||||
6. 搜索覆盖标题、仓库相对路径、front matter 和未截断正文;不同维度用 AND、同一维度多选用 OR,默认先排当前任务和异常证据,再按匹配度与路径稳定排序。筛选、查询和选中文档写入 URL 参数,支持浏览器前进/后退与深链。
|
||||
7. 桌面优先;窄屏下侧栏变为可关闭抽屉,宽表格保留可横向滚动的语义表头,详情区单列。所有功能可键盘完成,使用 landmark/标题/表格语义,drift/degraded 不只靠颜色表达,自动刷新通过非打断式 live region 报告且不抢焦点。
|
||||
8. Markdown 正文只进入文本节点;在线页与导出页均设置限制性 CSP,不执行 HTML、脚本、SVG、远程 URL 或事件属性。
|
||||
|
||||
**测试场景**:
|
||||
|
||||
- 只监听 loopback,方法 allowlist 拒绝写请求;Host/Origin/token、DNS rebinding 和跨 Origin 负例被拒绝;
|
||||
- HTML 与 JSON 的 generation/revision identity 一致;
|
||||
- 文档 ID 越界、symlink 越界、未知 ID 返回安全错误;
|
||||
- degraded source 在总览可见且页面仍可导航;
|
||||
- 任务状态四轴、drift 和来源时间在浏览器中可见。
|
||||
- 首次加载、空数据、无缓存错误、刷新、恢复状态可区分;键盘、焦点、语义结构、窄屏和非颜色告警验收通过。
|
||||
- 搜索组合逻辑、排序、无结果、URL 深链和刷新后的视图保持通过。
|
||||
|
||||
**完成证据**:HTTP tests、基本无障碍检查和真实浏览器验收通过。
|
||||
|
||||
### U7:实现离线导出、启动脚本与治理文档
|
||||
|
||||
**目标**:生成安全、可携带、可追踪的单文件快照,并完成仓库治理接线。
|
||||
|
||||
**覆盖需求**:R1、R8、R9、R11、R14;承接 PKD-1 和 PKD-2。
|
||||
|
||||
**依赖**:U6。
|
||||
|
||||
**文件**:
|
||||
|
||||
- `internal/engineeringdashboard/export.go`
|
||||
- `internal/engineeringdashboard/export_test.go`
|
||||
- `scripts/engineering-dashboard.sh`
|
||||
- `.doc/status/FEATURE-MATRIX.md`
|
||||
- `.doc/ops/CURRENT.md`
|
||||
- `.doc/test-reports/YYYY-MM-DD-engineering-dashboard-test-report.md`
|
||||
|
||||
**实施要点**:
|
||||
|
||||
1. `export --repo <path> --output <file>` 构建一次不可变快照并原子写入;首次采集失败的来源显示 unknown/error。
|
||||
2. 以 HTML-safe JSON/等价编码内嵌允许的 Markdown 正文、索引和页面资源;附件保持元数据与相对链接,所有正文只写入文本节点。
|
||||
3. 默认权限 `0600`,输出页显示生成时间、repo、HEAD、snapshot ID 和 degraded/drift。
|
||||
4. 薄脚本只负责定位仓库与调用 Go CLI,不隐藏参数或执行安装/部署副作用。
|
||||
5. 实施期间按仓库规范更新 CURRENT、FEATURE-MATRIX 和 test report;完成后再迁移任务生命周期状态。
|
||||
|
||||
**测试场景**:
|
||||
|
||||
- 导出文件脱离仓库后仍能搜索和阅读 Markdown;
|
||||
- 导出中不含附件字节、绝对凭证路径、env 值或远程请求;`</script>`、事件属性、SVG、危险 URL scheme 和 Unicode 边界载荷不能逃逸数据上下文;
|
||||
- 默认 tracked/untracked 与敏感模式策略、inclusion manifest 和覆盖清单符合契约;
|
||||
- 采集部分失败时仍能导出并保留错误;
|
||||
- 输出中 JSON/HTML snapshot identity 一致,权限符合预期;
|
||||
- 大文档和总正文上限触发时明确标记截断。
|
||||
|
||||
**完成证据**:export tests、离线浏览器验收和治理文档回链完整。
|
||||
|
||||
---
|
||||
|
||||
## Verification Contract
|
||||
|
||||
### 自动验证
|
||||
|
||||
实施阶段至少运行:
|
||||
|
||||
```bash
|
||||
go test ./internal/engineeringdashboard/...
|
||||
go test ./cmd/engineering-dashboard/...
|
||||
go vet ./...
|
||||
go test -short ./...
|
||||
git diff --check
|
||||
```
|
||||
|
||||
涉及共享容器的只读验收也必须遵守 CURRENT 集成槽规则;中控台本身不得为测试启动、停止或重建共享容器。
|
||||
|
||||
### 契约验证矩阵
|
||||
|
||||
| 领域 | 必须证明 |
|
||||
|---|---|
|
||||
| 模型 | 计划、Git facets、验证、部署 facets 互不覆盖;Agent 声明和运行观测分离;所有派生结论可追溯到 facts。 |
|
||||
| 文档 | taxonomy、全文检索、反链、broken/unindexed、路径安全与 assets 排除。 |
|
||||
| Git | ahead/behind、worktree、dirty、local refs 新鲜度和无隐式 fetch。 |
|
||||
| 部署 | container/app/service 三类信号分离,receipt/artifact 身份可核对。 |
|
||||
| 降级 | 每个源超时、错误、stale、恢复都不会让整页不可用。 |
|
||||
| 实时 | 变化在目标时间内形成完整新快照,不出现半新半旧卡片。 |
|
||||
| 导出 | 单文件离线可读、默认 `0600`、不嵌 assets、不产生网络请求。 |
|
||||
| 安全 | loopback、Host/Origin/startup token、read-only methods、命令 allowlist、路径边界、Docker 字段 allowlist、CSP 与输出脱敏。 |
|
||||
|
||||
### 浏览器验收
|
||||
|
||||
1. 从总览进入 rdev,确认“计划/实施/验证/实装”四轴与源文档链接均可见。
|
||||
2. 在仓库外复制导出 HTML,断网打开并全文搜索、阅读至少一份设计与一份测试报告。
|
||||
3. 制造 fixture 中的 CURRENT/Docker/readiness 冲突,确认页面保留多值且不出现综合绿灯。
|
||||
4. 切换 fixture 快照,确认页面刷新后筛选条件和当前文档保持不变。
|
||||
5. 尝试路径穿越、未知文档、POST、DNS rebinding、跨 Origin、readiness 重定向和含原始 HTML/脚本逃逸载荷的 Markdown,确认均不能越界、外联或执行。
|
||||
|
||||
### 性能与容量验证
|
||||
|
||||
- 记录当前 `.doc` 规模下的冷启动、增量刷新、JSON 大小和 HTML 导出大小。
|
||||
- 建议一期门槛:UI shell 与来源状态在 2 秒内可交互,P95 完整快照重建不超过 5 秒,单源超时不超过 2 秒;基线不达标时必须记录实测并拆分后台正文索引,不能伪造 PASS。
|
||||
- 导出达到配置上限时必须显式列出被截断文档,不允许静默丢失。
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] `serve` 和 `export` 在显式仓库根下可重复运行,且没有产品后台依赖。
|
||||
- [ ] 实时 HTML、离线 HTML 与 JSON 使用同一版本化快照契约。
|
||||
- [ ] `generation_id` 标识采集实例,`revision_id` 标识内容版本并驱动 ETag;无内容变化不会触发重绘。
|
||||
- [ ] 架构、模块、功能、任务、Git、部署、文档和证据链均可从页面访问。
|
||||
- [ ] 计划、实施、验证、实装四轴独立,rdev、dev ahead、main events 分叉样本通过。
|
||||
- [ ] Agent 认领与可观测活动分开,Herdr 工程 Agent 与产品 PI Agent Runner 不混称。
|
||||
- [ ] 所有 drift、degraded、stale 都带来源和时间,不存在未经定义的综合绿灯。
|
||||
- [ ] 默认 loopback、Host/Origin/startup token、只读命令、路径边界、脱敏、CSP 和 Markdown 安全测试通过。
|
||||
- [ ] 首次加载、空数据、部分失败、无缓存失败、恢复、键盘、窄屏和 URL 深链验收通过。
|
||||
- [ ] 导出 HTML 脱离仓库可读 Markdown,且不包含二进制 assets 或凭证数据。
|
||||
- [ ] 单元、集成、全仓短测、浏览器验收和 `git diff --check` 均有真实输出。
|
||||
- [ ] `.doc/test-reports` 报告回链任务文,FEATURE-MATRIX 与 CURRENT 按实际状态更新。
|
||||
- [ ] 没有遗留调试入口、写操作按钮、未使用的替代模型或与产品后台重名的组件。
|
||||
|
||||
---
|
||||
|
||||
## Appendix
|
||||
|
||||
### 一期交付边界
|
||||
|
||||
一期交付:本地只读服务、版本化快照 JSON、架构/任务/Git/部署/文档视图、四轴状态、drift/degraded、全文搜索、安全文档阅读和单 HTML 导出。
|
||||
|
||||
后续评估:跨快照历史趋势、远端托管/CI 聚合、受限富文本与 Mermaid、跨仓库聚合、面向 Agent 的筛选查询 API。
|
||||
|
||||
永久排除:在页面中修改文档、切换或推送分支、控制 Agent、执行部署、读取密钥、成为产品后台模块。
|
||||
|
||||
### 方案依据
|
||||
|
||||
- `.doc/README.md` 定义的文档 taxonomy 与生命周期;
|
||||
- `.doc/ops/CURRENT.md` 的焦点、认领、集成槽与环境声明;
|
||||
- `.doc/status/FEATURE-MATRIX.md` 的模块完成度口径;
|
||||
- `.doc/remediation/gap-matrix.md` 的发布门禁口径;
|
||||
- `.doc/system-design/README.md` 与模块边界清单;
|
||||
- Git/worktree、Docker/Compose、`/ready` 和 promotion receipts 的当前可观测能力。
|
||||
@@ -1,110 +0,0 @@
|
||||
# Herdr 多 Agent 编排 v1.2
|
||||
|
||||
更新:2026-09-21;owner:Herdr 任务协调者;本轮规范修订 `herdr-v1.2`。本文件是 Herdr 角色、额度、审批与备援的唯一来源,取代原 2026-09-13 路由。实现/核验见[任务记录](../archive/ops/2026-09-21-herdr-orchestration-v12.md)。
|
||||
|
||||
## 1. 生效范围与前提
|
||||
|
||||
**仅在明确使用 Herdr 编排、启动或派发任务时适用本表分工。** 普通 Codex、Claude Code、Cursor 独立会话,以及仅研究/编辑本规范的任务,不自动套用 Cursor 唯一实施通道,也不自动启动多 Agent。通用授权、分支、锁、验证、清理始终遵循 [AGENTS](../../AGENTS.md) 与 [worktree 操作规范](./2026-09-21-agent-worktree-workflow.md)。
|
||||
|
||||
只有 `HERDR_ENV=1` 才能查看/控制当前 Herdr 会话;外部会话可读规范、跑 dry-run 与隔离测试。用户已授权这些客户端自动通过工具请求;不为已授权步骤再等待人工批准。自动审批不产生额外环境、外部写入或破坏性操作授权。
|
||||
|
||||
Herdr 中的 PI CLI(例如 `context_pi`)是工程协作客户端;Compose 中“产品 PI Agent Runner”是业务执行器。二者不共享验收结论,不修改产品模型配置来满足本表。
|
||||
|
||||
## 2. 资源与取舍
|
||||
|
||||
订阅价格与个人额度优先级来自用户本次说明,是预算输入,不是实测余额或供应商无限量承诺。
|
||||
|
||||
| 资源 | 用户预算 | Herdr 纪律 |
|
||||
|---|---|---|
|
||||
| Cursor Ultra | $200/月,实施优先 | 默认唯一产品代码实施通道;高额度仍监测限流/余额,不自动开启额外付费 |
|
||||
| Qwen 3.8 max/flash | 百炼最高档,充裕 | max 分析、报告、监督判断;flash 例行检查和执行已有测试 |
|
||||
| GLM 5.3/flash | 高档 token plan,充裕 | 规划、执行跟踪、代码审查;模型额度共享时不把两个客户端当两份预算 |
|
||||
| MiniMax M3 | ¥119/月,中等 | 失败归因、二线审查;每个失败问题至多两轮归因,重复失败转交带证据复核 |
|
||||
| Kimi Code | ¥699/月,个人调研/报告优先 | Herdr 默认不用;仅可选正式报告终稿检查,或有理由的应急借用;合计每逻辑任务最多一次 |
|
||||
| Codex / GPT-6 | 稀缺 | 终审仲裁、高歧义与两轮审查仍未解决的争议;不作日常监督/机械实施 |
|
||||
| agy / Antigravity | 最低档,极少 | 轻量杂活与测试想法;耗尽转 flash,不做高频轮询或安全终审 |
|
||||
|
||||
修正“Cursor 订阅不限量”:官方[用量说明](https://prod.cursor.com/help/models-and-usage/usage-limits)仍描述用量池/限制。其他“充裕”也只是调度优先级,任务开始记录 available/low/exhausted/unknown;unknown 不等于无限。价格不写进程序阈值。
|
||||
|
||||
## 3. 角色、客户端与路由
|
||||
|
||||
模型路由基于本机帮助和已配置别名,启动后还须确认实际模型。`pi --list-models` 只证明配置目录可识别,不证明账户余额、远端可用或本任务真实输出质量。
|
||||
|
||||
| 角色 / lane | 默认 → 备援 | 交付边界 |
|
||||
|---|---|---|
|
||||
| 例行监督 `supervision` | qwen_flash → qwen_max → verifier_antigravity | 读任务/测试/锁状态;阻塞判断交 max,僵局显式 critical-review |
|
||||
| 需求分析 `analysis` | qwen_max → qwen_flash | 可验收需求、歧义、边界;高歧义显式终审升级 |
|
||||
| 规划 `planning` | reviewer_glm → qwen_max → glm_pi | 步骤、依赖、允许写范围、测试计划 |
|
||||
| 执行计划 `execution` | reviewer_glm → qwen_max | 调度、跟踪、核对产物;不与实施者同时改产品代码 |
|
||||
| 实施 `implementation` / `ui` | implementer_cursor | 可运行改动、回归测试;仅明确写入接管理由时追加 reviewer_glm → qwen_max |
|
||||
| 代码审查 `code-review` | reviewer_glm → context_pi | 对冻结 diff 独立审查;两轮未过显式 critical-review |
|
||||
| 系统测试 `test` | qwen_flash → verifier_antigravity | 执行确定性测试命令;不能以“模型判断通过”替代进程退出码与断言 |
|
||||
| 失败归因 `test-analysis` | context_pi → reviewer_glm | 可重现输入、原因、最小修复建议;修复回实施通道 |
|
||||
| 报告 `report` | qwen_max → qwen_flash | max 写交付稿;flash 仅草稿,须回 max 定稿 |
|
||||
| 报告二审 `report-review` | reviewer_glm | max 自审后,GLM 独立查来源/逻辑/未验收声明 |
|
||||
| 可选终稿 `report-final-check` | context_kimi | max 完成正式交付稿后,至多一次,非每任务必经 |
|
||||
| 终审 `critical-review` | orchestrator_codex → reviewer_glm | GPT-6 仲裁;GLM 若是原作者/审查者须独立上下文并补跨模型复核,未解决风险保留 blocked |
|
||||
| 轻量杂活 `fast-check` | verifier_antigravity → qwen_flash | 小范围静态核对和整理 |
|
||||
| 长材料 `long-context` | qwen_max → glm_pi | 相关证据扫描,不默认占 Kimi |
|
||||
| 特例借用 `quota-emergency` | context_kimi | 百炼等故障、任务确需借个人额度;与终稿入口共用一次计数 |
|
||||
|
||||
兼容旧 lane `governance` 转到规划 GLM → max,已移除日常 Codex/Kimi 路由。Cline、Devin 和旧 `reserve_claude` 不在 v1.2 活跃路由;Claude Code 是客户端名称,本机路由到 GLM,不把它算作另一份 Claude 高端模型额度。
|
||||
|
||||
| profile | 标准逻辑名 | 启动选择 |
|
||||
|---|---|---|
|
||||
| claude | reviewer_glm | Claude Code `--model opus`,本机 Opus 别名配置为 GLM 5.3;不修改全局配置 |
|
||||
| codex | orchestrator_codex | 默认已配置 GPT-6;仅角色名称兼容旧脚本,其职责收窄为终审 |
|
||||
| cursor | implementer_cursor | cursor-agent 的已配置模型 |
|
||||
| pi-max | qwen_max | qwen-token-plan-cn / qwen3.8-max |
|
||||
| pi-flash | qwen_flash | qwen-token-plan-cn / qwen3.8-flash |
|
||||
| pi-glm | glm_pi | zai-coding-cn / glm-5.3 |
|
||||
| pi | context_pi | minimax-cn / MiniMax-M3 |
|
||||
| kimi | context_kimi | Kimi Code 已配置模型 |
|
||||
| antigravity | verifier_antigravity | agy 已配置模型 |
|
||||
|
||||
独立上下文审查有价值,但规划和审查都用 GLM 仍可能同源盲点;高风险争议增加 MiniMax/GPT-6 跨模型意见。简单任务采用“实施 → 验证/审查 → 收口”最短路径,不强制走九个角色;大任务按依赖拆分,最多一个产品代码写者/重叠范围,独立 worktree 可并行。
|
||||
|
||||
## 4. 预算闸门
|
||||
|
||||
- 每任务记录一个不可随子任务/重试变化的 task_id、角色调用、升级原因、审查/归因轮次、实际来源与结果。轮询优先直接读机器状态,只在状态改变或阻塞时调用模型。
|
||||
- Kimi 默认不进入普通分析、代码审查、测试归因或报告撰写备援。协调者在既有授权内判断是否值得调用,显式填 `--kimi-reason`,不用再向用户索取工具批准。
|
||||
- 派发器在发送前向主仓 `.locks/state.sqlite` 的 `herdr_kimi_uses` 原子登记;同一 task_id 两个入口合计 ≤1。发送失败/结果未知也占用,不自动退款,不通过新 task_id 重置。此计数是一次投递,不是模型内部工具轮数或真实账单 token 上限;输入只含最终稿/必要来源,禁止继续发多轮 Kimi。
|
||||
- 个人调研额度告急时,协调者在主仓 `.locks/herdr-kimi.disabled` 留停用标记,所有后续受管 Kimi 派发拒绝;确认恢复后移除此标记。它不控制个人在 Herdr 之外的 Kimi 主业,也不能自动读取个人用量。
|
||||
- Kimi 停用:max 自审 + GLM 二审。GPT-6 耗尽:GLM 复核;仅交付文档可以用尚未使用的 Kimi 终稿检查,不能拿文稿检查顶替代码安全/发布终审。百炼故障先用 GLM/MiniMax 支撑,确需 Kimi 才借用;故障消除即回原通道,不形成新默认。
|
||||
- 机器强制范围是统一派发入口的一次计数;直接在 Kimi pane 手工发问可绕过,禁止据此声称全账户硬限额已完成。MiniMax 轮次/GPT 升级由任务记录管理,尚无跨供应商余额 API。
|
||||
|
||||
## 5. 自动通过请求与实际启动
|
||||
|
||||
所有 Herdr 启动均走 [start](../../scripts/herdr-agent-start.sh);仅影响该次进程参数,**不改个人客户端的全局审批设置**。以下来自本轮安装 CLI `--help`,不是猜测同名产品能力。
|
||||
|
||||
| 客户端 | 参数 | 说明 |
|
||||
|---|---|---|
|
||||
| Claude Code | `--dangerously-skip-permissions --model opus` | 自动通过工具权限,使用用户已配置 GLM 别名 |
|
||||
| Codex | `--ask-for-approval never --sandbox danger-full-access` | 不再等待批准;授权内操作仍须 agentctl/Git 门禁 |
|
||||
| Cursor | `--force --sandbox disabled --approve-mcps --trust` | Run Everything + MCP 自动批准 + workspace trust;显式 deny 仍有效 |
|
||||
| agy | `--dangerously-skip-permissions` | 自动通过工具请求,不再添加旧脚本的限制性 sandbox |
|
||||
| PI CLI | `--approve` + 明确 provider/model | 内置工具本就无逐工具弹窗;该参数处理项目文件信任,不能说它关闭了不存在的权限系统 |
|
||||
| Kimi | `--auto` | Never Ask;`--yolo` 仍可能询问,不替代 auto |
|
||||
|
||||
[Cursor 参数](https://cursor.com/docs/cli/reference/parameters)、[Kimi 参数](https://www.kimi.com/code/docs/en/kimi-code-cli/reference/kimi-command)、[Claude 参数](https://code.claude.com/docs/en/cli-reference)与本机帮助一起核对。CLI 升级后先重新核验 flags;外部认证、显式 deny、企业策略或扩展交互无法由统一参数保证消失,失败写 blocker,不反复向用户弹批准,不擅自清除已有安全规则。
|
||||
|
||||
```bash
|
||||
# 先用 agentctl 注册 task-id。名称可用 base__短任务后缀,完整长度最多 32。
|
||||
./scripts/herdr-agent-start.sh --dry-run pi-max qwen_max__demo w1:p2
|
||||
./scripts/herdr-agent-start.sh --task task-id pi-max qwen_max__demo w1:p2
|
||||
./scripts/herdr-agent-dispatch.sh --explain report
|
||||
./scripts/herdr-agent-dispatch.sh --task task-id report '根据已提交证据撰写报告'
|
||||
./scripts/herdr-agent-dispatch.sh --task task-id --kimi-reason '正式报告的一次终稿核验' report-final-check '核验最终稿与来源'
|
||||
./scripts/herdr-agent-dispatch.sh --task task-id --implementation-fallback 'Cursor 额度已耗尽,已核对无在途写入' implementation '接续已登记范围'
|
||||
```
|
||||
|
||||
启动/派发仅接受注册任务的直接 `.worktrees` 工作区;目标 pane/agent cwd 必须匹配。标准名后缀支持不同任务同时有自己的同角色 Agent;同任务同角色出现多个可用实例时拒绝歧义。旧命名实例先由其 owner 完成/交接,不自动抢占、改名或停止。
|
||||
|
||||
## 6. 监督、失败、恢复与交接
|
||||
|
||||
1. 协调者读取任务与本规范,确认预算、角色、分支、允许写路径、实际客户端/模型和精确 head。启动后核验身份;标准名字只能表达意图,不能证明客户端模型没被手工切换。
|
||||
2. Herdr 的新 pane 不是 `agentctl with` supervisor 的子进程;禁止把短命令租约凭据复制进去。worker 按每条写命令取自己的任务 path 租约,提交另取 git:index;共享 CURRENT/MATRIX 用 docs apply。监督者不长期持有所有资源锁。
|
||||
3. 只投递同任务的 idle/done Agent;已工作/blocked/unknown 不发第二份。等待最多 60 秒;超时只观察,不把超时当未执行或自动终止任务。
|
||||
4. 已选实例的 prompt RPC 出错统一视为可能已发送,不根据输出里出现 quota/auth 字样自动转发。只有已 settled 且返回本轮唯一 HERDR_RETRY 标记、明确未写入/无副作用时才可备援;仍是合作协议,不是任意工具副作用的机器证明。
|
||||
5. 不抢主目录、不切他人分支、不覆盖旧 CURRENT;合入/环境验收由独立协调者按机器锁串行处理。模型返回“完成”不等于测试通过或 dev 已部署。
|
||||
6. 每次交接含冻结 SHA、改动范围、实际验证/缺项、未完成副作用、下一执行者与预算用量。owner 退出并确认文件/进程/祖先证据后再清理;异常现场保留 cleanup_pending,不强删。
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: "docgov 变更提案 HTTP + 前端接线"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/docgov-modification-proposal-http
|
||||
worktree: .worktrees/feature-docgov-modification-proposal-http
|
||||
mutex: docgov
|
||||
---
|
||||
|
||||
# docgov 变更提案 HTTP + 前端接线
|
||||
|
||||
## 目标
|
||||
|
||||
暴露 `POST /api/v1/docgov/proposal`,前端「修改」快捷分支与 `ProposalConfirmCard` 走真实 propose/decide,不再本地假装成功。
|
||||
|
||||
## 范围
|
||||
|
||||
- API:`ProposeModification` 路由;decide 补 404/403 映射
|
||||
- 前端:`docgov.ts` + `App.tsx` 接线
|
||||
- 单测 + 真实 HTTP 证据
|
||||
- 关闭 audit 缺口;dev 试点总开关证据归档
|
||||
|
||||
## 非目标
|
||||
|
||||
- 晋升 test/main
|
||||
- 变更提案自动改写受控正文(批准后仍为 UI 演示增补)
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 实现 propose handler + 路由
|
||||
2. [x] 前端 client + App 接线
|
||||
3. [x] handler/client 单测
|
||||
4. [x] 合入 dev + rebuild + 真实 HTTP
|
||||
5. [x] push origin/dev;清理 author-only worktree
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] `POST /api/v1/docgov/proposal` 可写库(单测)
|
||||
- [x] 真实 HTTP claim → propose → decide PASS
|
||||
- [x] audit 缺口 resolved;CURRENT 认领收敛
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Audit: [../../audit/2026-09-17-docgov-modification-proposal-http-gap.md](../../audit/2026-09-17-docgov-modification-proposal-http-gap.md)
|
||||
- Pilot: [../../test-reports/assets/2026-09-17-author-only-pilot/](../../test-reports/assets/2026-09-17-author-only-pilot/)
|
||||
- Closeout: [../handoffs/2026-09-17-document-author-only-closeout.md](../handoffs/2026-09-17-document-author-only-closeout.md)
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
title: 文档编制人兼任审核批准方案
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Codex
|
||||
branch: feature/document-author-only-plan
|
||||
worktree: .worktrees/feature-document-author-only-plan
|
||||
mutex: document-duty-policy-plan
|
||||
---
|
||||
|
||||
# 文档编制人兼任审核批准方案
|
||||
|
||||
## 目标
|
||||
|
||||
基于当前源码形成管理员总授权、项目创建者逐文档选择的详细实施方案,交用户审核。
|
||||
|
||||
## 范围
|
||||
|
||||
权限、系统设置、工作流规划和冻结、文档三职、动作鉴权、状态机、前端、迁移与验收。
|
||||
|
||||
## 非目标
|
||||
|
||||
本次不修改业务代码、不变更数据库或共享容器、不推送。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 阅读启动链并从本地 dev 建立隔离分支。
|
||||
2. [x] 核查实现并记录证据。
|
||||
3. [x] 编写方案、检查边界与验收覆盖。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 方案覆盖用户两个权限层级及逐文档持久化。
|
||||
- [x] 当前事实与拟议行为分开,列明实施单元与测试场景。
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
基线 dev adb48c8。已 fetch origin/dev,本地 dev 领先 44、落后 0,保留未推送集成成果;主工作区 feature/control-center-server 未切换。worktree 脚本默认从当前 HEAD 创建,故直接指定 dev 创建本 worktree,避免引入他人分支。
|
||||
|
||||
## 交付
|
||||
|
||||
- 方案:`.doc/remediation/2026-09-17-document-author-only-plan.md`
|
||||
- 核查:`.doc/audit/2026-09-17-document-author-only-analysis.md`
|
||||
- 本任务完成仅指方案交付,业务实现为 planned;R9/R10 待用户审核。
|
||||
- 未合入 dev:方案保留在独立分支供审核;未推送、未修改业务代码或容器。
|
||||
- 验证:源码与文档一致性检查、git diff --check;未执行业务测试。
|
||||
@@ -1,57 +0,0 @@
|
||||
---
|
||||
title: "文档编制人兼任:U1 策略存储与总授权"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/document-author-only-plan
|
||||
worktree: ".worktrees/feature-document-author-only-plan"
|
||||
mutex: sysadmin + document-duty-policy
|
||||
---
|
||||
|
||||
# 文档编制人兼任:U1 策略存储与总授权
|
||||
|
||||
## 目标
|
||||
|
||||
落地 `workflow.allow_author_only_approval` 管理员总开关:默认关闭、严格 bool、revision CAS、事务内审计,并向 projectinstance 提供可参与激活事务的窄读取接口。
|
||||
|
||||
## 范围
|
||||
|
||||
- Goose 增量迁移(revision 列、种子行、策略审计表)
|
||||
- `internal/sysadmin` 存储/服务/窄 Policy 接口
|
||||
- `admin_system_handlers` 对本 key 的 `expected_revision` 协议
|
||||
- 单元 / PG / HTTP 负例测试
|
||||
|
||||
## 非目标
|
||||
|
||||
- 逐文档 duty_policy(U2)
|
||||
- 前端设置页文案(U5)
|
||||
- 已激活实例紧急熔断
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 认领 CURRENT
|
||||
2. [x] 迁移 00050
|
||||
3. [x] sysadmin CAS + 审计 + PolicySource
|
||||
4. [x] admin handler
|
||||
5. [x] 测试与提交
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 管理员可开关;非管理员 403
|
||||
- [x] null/字符串布尔拒绝
|
||||
- [x] 并发 CAS 仅一版成功
|
||||
- [x] 审计失败回滚设置
|
||||
- [x] 窄接口可读 allowed+revision;缺行默认 false;DB 故障不伪装
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: `.doc/remediation/2026-09-17-document-author-only-plan.md` U1
|
||||
- Checklist:
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- `go test ./internal/sysadmin/ ./internal/server/ -run 'Settings|AuthorOnly|PGSettings|AdminSystem'` PASS
|
||||
- `go test -short ./internal/sysadmin/ ./internal/server/` PASS
|
||||
- Key: `workflow.allow_author_only_approval`
|
||||
- 窄接口: `sysadmin.AuthorOnlyPolicySource`
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
title: "文档编制人兼任:U2 逐文档模式与激活"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/document-author-only-plan
|
||||
worktree: ".worktrees/feature-document-author-only-plan"
|
||||
mutex: projectinstance + document-duty-policy
|
||||
---
|
||||
|
||||
# 文档编制人兼任:U2 逐文档模式与激活
|
||||
|
||||
## 目标
|
||||
|
||||
落地逐文档 `duty_policy=author_only`:规划校验、预览摘要、激活 token 绑定策略 revision,激活事务内行锁串行化关闭总开关。
|
||||
|
||||
## 范围
|
||||
|
||||
- DocTaskPlan / PreviewSummary / ProjectSettings 扩展
|
||||
- ResolveDocTaskDuty、Save/Preview/Activate 消费 U1 策略
|
||||
- Goose 00051 token revision 列
|
||||
- app 适配器装配、HTTP 错误码映射
|
||||
- 单元测试
|
||||
|
||||
## 非目标
|
||||
|
||||
- Heal/文档投影(U3)
|
||||
- 前端 UI(U5)
|
||||
- 运行时动作多职责(U4/U6)
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 类型与解析器
|
||||
2. [x] service/store/迁移
|
||||
3. [x] app 装配与 handler
|
||||
4. [x] 测试与提交
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 一位成员兼任可存/预览/激活(总开关开)
|
||||
- [x] 总开关关时 Save 拒绝
|
||||
- [x] 预览后 revision 变化旧 token 409
|
||||
- [x] 未开模式只填作者仍 partial 拒绝
|
||||
- [x] 旧快照缺 duty_policy 时 hash 稳定
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: `.doc/remediation/2026-09-17-document-author-only-plan.md` U2
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- `go vet ./internal/projectinstance/ ./internal/app/ ./internal/server/`
|
||||
- `go test -short ./internal/projectinstance/ ./internal/server/ ./internal/app/` PASS
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
title: "文档编制人兼任:U3 文档绑定与职责投影"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/document-author-only-plan
|
||||
worktree: ".worktrees/feature-document-author-only-plan"
|
||||
mutex: docgov + docduty + bizdev + document-duty-policy
|
||||
---
|
||||
|
||||
# 文档编制人兼任:U3 文档绑定与职责投影
|
||||
|
||||
## 目标
|
||||
|
||||
生成时写入实例治理职责并 `duty_locked`;heal/revoke 跳过锁定行;读侧投影 `duty_policy`。
|
||||
|
||||
## 范围
|
||||
|
||||
- Goose 00052:`document_records.duty_locked` / `duty_policy`
|
||||
- `docgov.LockDocumentDuty` + 列表投影
|
||||
- `docduty` heal/revoke `AND NOT duty_locked`
|
||||
- `bizdev.InstanceDutySource` + `resolveTaskDocumentDuties` 治理分支;跳过 governed 内存 heal
|
||||
- `app/instance_duty_adapter.go` 装配
|
||||
|
||||
## 非目标
|
||||
|
||||
- U4 动作鉴权 / allowed_actions
|
||||
- U5/U6 前端
|
||||
- 合入 `dev`
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 迁移
|
||||
2. [x] docgov / docduty
|
||||
3. [x] bizdev + app 适配器
|
||||
4. [x] 测试与提交
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 受治理文档创建后 `duty_locked=true` 且三职来自实例
|
||||
- [x] heal/revoke 不清锁定行(SQL 过滤 + 单测/PG 可选)
|
||||
- [x] 生成后 governed 路径不再用项目默认覆盖内存态
|
||||
- [x] 模块边界:bizdev/docduty/docgov 不导入 projectinstance
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: U3(文档绑定与职责投影一致性)
|
||||
- 依赖:U1 `3b6def2`、U2 `c03d0a3`
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- `go vet ./internal/docgov/ ./internal/docduty/ ./internal/bizdev/ ./internal/app/ ./internal/projectinstance/`
|
||||
- `go test -short` 上述包 PASS
|
||||
- PG:`TEST_DATABASE_URL` 未配置时 `Heal/Revoke SkipsDutyLocked` 自动跳过
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
title: "文档编制人兼任:U4 动作鉴权与审计"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/document-author-only-plan
|
||||
worktree: ".worktrees/feature-document-author-only-plan"
|
||||
mutex: projectinstance + docgov + document-duty-policy
|
||||
---
|
||||
|
||||
# 文档编制人兼任:U4 动作鉴权与审计
|
||||
|
||||
## 目标
|
||||
|
||||
ABAC 门禁识别 `duty_policy=author_only` 派生职责;审计 Details 携带 duty_policy。
|
||||
|
||||
## 范围
|
||||
|
||||
- `duty_action` / `stage_access` / `gate` 改用 `ResolveDocTaskDuty`
|
||||
- `state_machine` Transition* Details 补 `duty_policy`
|
||||
- author_only 动作矩阵与阶段可见性测试
|
||||
|
||||
## 非目标
|
||||
|
||||
- U5 UI / U6 浏览器闭环
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] ABAC 三文件
|
||||
2. [x] 审计详情
|
||||
3. [x] 测试与提交
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] author_only 规范存储(仅 Author ID)下 A 可 run/edit/submit/review/approve
|
||||
- [x] 非 A 拒绝;阶段门禁将 author_only 视为 approvalManaged
|
||||
- [x] 审计 Details 含 duty_policy
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: U4+U5 实施计划
|
||||
- 依赖:U1–U3
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- `go test -short ./internal/projectinstance/ ./internal/docgov/ ./internal/app/ ./internal/server/` PASS
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: "文档编制人兼任:U5 系统设置与逐文档 UI"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/document-author-only-plan
|
||||
worktree: ".worktrees/feature-document-author-only-plan"
|
||||
mutex: web + document-duty-policy
|
||||
---
|
||||
|
||||
# 文档编制人兼任:U5 系统设置与逐文档 UI
|
||||
|
||||
## 目标
|
||||
|
||||
前端识别 `duty_policy` / `author_only_policy`;项目设置可逐文档开启兼任。
|
||||
|
||||
## 范围
|
||||
|
||||
- `projectSettings.ts` 类型
|
||||
- `projectSettingsDuties.ts` resolveClientDocTaskDuty + 校验
|
||||
- `ProjectSettingsModal` 兼任勾选与预览
|
||||
- SettingsSection 不改(白名单通用渲染)
|
||||
|
||||
## 非目标
|
||||
|
||||
- U6 多职责动作栏 / 浏览器 E2E
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 类型与 lib
|
||||
2. [x] UI
|
||||
3. [x] 测试与提交
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] author_only 客户端校验通过且不计三人门槛
|
||||
- [x] 总开关关闭时兼任勾选禁用并提示
|
||||
- [x] 预览展示兼任文档计数
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: U4+U5 实施计划
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- `npx tsc --noEmit` PASS
|
||||
- `npm test` PASS(含 projectSettingsDuties author_only 用例)
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
title: "文档编制人兼任:U6 多职责动作与真实闭环"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/document-author-only-plan
|
||||
worktree: ".worktrees/feature-document-author-only-plan"
|
||||
mutex: web + document-duty-policy
|
||||
---
|
||||
|
||||
# 文档编制人兼任:U6 多职责动作与真实闭环
|
||||
|
||||
## 目标
|
||||
|
||||
去掉 author-first 动作短路,把认领/送审/审核/批准接到真实 docgov HTTP,完成 author_only 端到端验收。
|
||||
|
||||
## 范围
|
||||
|
||||
- `web/src/api/docgov.ts` 四接口客户端
|
||||
- `docGovActionVisibility` / `holdsDocDuty`
|
||||
- `App.tsx` 真实 handler + 快捷指令
|
||||
- `duty_policy` 透传与「编制人兼任」徽标
|
||||
- 单测 + 真实闭环报告
|
||||
|
||||
## 非目标
|
||||
|
||||
- 变更提案 HTTP 路由(另记 audit)
|
||||
- 合入 `dev` / 推送远端(未授权不推)
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] API 客户端
|
||||
2. [x] ID 直判可见性
|
||||
3. [x] App 接线 + 驳回批准修正
|
||||
4. [x] duty_policy 徽标透传
|
||||
5. [x] 单测 / tsc
|
||||
6. [x] 真实闭环与报告
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] author_only 下 A 可见三动作;非 A 403
|
||||
- [x] 真实 API 闭环写库与审计含 duty_policy
|
||||
- [x] 浏览器可见「编制人兼任」徽标
|
||||
- [x] 测试报告归档
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Test report: [../../test-reports/2026-09-17-document-author-only-u6-test-report.md](../../test-reports/2026-09-17-document-author-only-u6-test-report.md)
|
||||
- Remediation U6: [../../remediation/2026-09-17-document-author-only-plan.md](../../remediation/2026-09-17-document-author-only-plan.md)
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- `npm test` 390 pass;`tsc --noEmit` clean
|
||||
- assets: `test-reports/assets/2026-09-17-document-author-only-u6/`
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
title: "首次加载性能诊断与改进方案"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Codex
|
||||
branch: feature/initial-load-performance-plan
|
||||
worktree: .worktrees/feature-initial-load-performance-plan
|
||||
mutex: loading-performance-audit
|
||||
---
|
||||
|
||||
# 首次加载性能诊断与改进方案
|
||||
|
||||
## 目标
|
||||
以源码、现有容器静态资源和只读浏览器测量定位首次加载瓶颈,输出可审核的分期改进方案。
|
||||
|
||||
## 范围
|
||||
登录前首屏、登录后初始化、项目/文档首次打开、静态资源交付;区分事实与待验证假设。
|
||||
|
||||
## 非目标
|
||||
不修改业务代码,不重启/重建共享服务,不触发真实对话或文档写任务,不提交或推送其他人的工作。
|
||||
|
||||
## 步骤
|
||||
1. [x] 阅读仓库启动链;独立 dev 基线 worktree,主仓保留其他 Agent 分支。
|
||||
2. [x] 采集数值基线和源码证据。
|
||||
3. [x] 写 audit 和 remediation,同步 CURRENT,归档任务。
|
||||
|
||||
## 验收标准
|
||||
- [x] 原因有文件位置或运行时测量支持,未覆盖环境明确标注。
|
||||
- [x] 方案包含优先级、改动边界、性能预算、回归门禁和回滚。
|
||||
|
||||
## 证据 / 备注
|
||||
仅诊断与方案,不代表优化已实施。fetch 后 origin/dev 落后本地 dev;不拉回或覆盖本地工作。worktree 从创建瞬间的 dev 建立。
|
||||
|
||||
## 交付
|
||||
|
||||
- 诊断:`.doc/audit/2026-09-17-initial-load-performance-audit.md`
|
||||
- 方案:`.doc/remediation/2026-09-17-initial-load-performance-plan.md`
|
||||
- 报告:`.doc/test-reports/2026-09-17-initial-load-performance-baseline.md`
|
||||
- 本轮仅方案;没有业务代码、没有部署、未提交、未合dev、未推送。主仓仅同步本任务认领。
|
||||
- 临时3199 Vite已停止;既有3100/8080/8081未重启。未占集成槽。
|
||||
@@ -1,57 +0,0 @@
|
||||
---
|
||||
title: "rdev 模板深度补强 S1 续批(剩余 46 份)"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/rdev-template-depth-s1-continued
|
||||
worktree: ".worktrees/feature-rdev-template-depth-s1-continued"
|
||||
mutex: rdev-templates
|
||||
---
|
||||
|
||||
# rdev 模板深度补强 S1 续批(剩余 46 份)
|
||||
|
||||
## 目标
|
||||
|
||||
将剩余 46 份 `rd_*` 模板按写作规范做同等深度补强,lint allowlist 扩至全 60 份,抽样真 PI 打样收口。
|
||||
|
||||
## 范围
|
||||
|
||||
- 批1:6 份评审记录
|
||||
- 批2:阶段06 硬件/工艺 8 份
|
||||
- 批3:阶段06 软件/检验/技术要求+清单 9 份
|
||||
- 批4:阶段08 验证 12 份
|
||||
- 批5:阶段10–13 转换/确认 11 份
|
||||
- lint allowlist + 抽样真 PI + 文档同步
|
||||
|
||||
## 非目标
|
||||
|
||||
- S2/S3、P2 前端、P3 三样本全量 E2E、P4 键名空间化
|
||||
- 晋升 test/main
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 批1 评审记录 6 份
|
||||
2. [x] 批2 硬件/工艺 8 份
|
||||
3. [x] 批3 软件/检验/清单 9 份
|
||||
4. [x] 批4 验证 12 份
|
||||
5. [x] 批5 转换/确认 11 份
|
||||
6. [x] 抽样真 PI + 文档同步(合入 push 见 merge 步骤)
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 46 份无「按本阶段专业结构写」;lint allowlist 60/60
|
||||
- [x] 抽样 1–2 份真 PI PASS(`rd_planning_review` + `rd_design_vv`,项目 6446)
|
||||
- [x] FEATURE-MATRIX / 写作规范 / backlog 已更新
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Backlog: [.doc/backlog/2026-09-17-rdev-phase2-backlog.md](../../backlog/2026-09-17-rdev-phase2-backlog.md)
|
||||
- 写作规范: [.doc/system-design/project-workflow/08-rdev模板写作规范.md](../../system-design/project-workflow/08-rdev模板写作规范.md)
|
||||
- 首批报告: [.doc/test-reports/2026-09-17-rdev-template-depth-test-report.md](../../test-reports/2026-09-17-rdev-template-depth-test-report.md)
|
||||
- 续批报告: [.doc/test-reports/2026-09-17-rdev-template-depth-s1-continued-test-report.md](../../test-reports/2026-09-17-rdev-template-depth-s1-continued-test-report.md)
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- 资产:`.doc/test-reports/assets/2026-09-17-rdev-template-depth-s1-continued/`
|
||||
- 附带:`fix(projectinstance): allocate next instance_no for planning drafts`
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
title: "rdev 模板深度补强 S0 + S1 首批"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: feature/rdev-template-depth
|
||||
worktree: ".worktrees/feature-rdev-template-depth"
|
||||
mutex: rdev-templates
|
||||
---
|
||||
|
||||
# rdev 模板深度补强 S0 + S1 首批
|
||||
|
||||
## 目标
|
||||
|
||||
修复 rdev leader prompt 错配,并为阶段 01–05 的 14 份 rdev 模板补齐 ISO 13485 专业章节与逐节写作指令,以 dev 真实 PI 打样验证收口。
|
||||
|
||||
## 范围
|
||||
|
||||
- S0.1 B1:`rdev_leader.md` + InstructionsFile 注入链
|
||||
- S0.2:`rd_design_input_spec` 样例 + 写作规范 + lint
|
||||
- S0.3:dev 真实 PI 打样
|
||||
- S1 首批:阶段 01–05 共 14 份模板(分 3 批)
|
||||
|
||||
## 非目标
|
||||
|
||||
- overlay 机制本体、R1–R7 二期、per-stage 步骤定制、模型配置化、manifest 元数据、前端(P2)、键名空间化(P4)、阶段 06–13 模板
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] S0.1 leader prompt 注入链(`6a09062`)
|
||||
2. [x] S0.2 样例模板 + 规范 + lint(含于 `eb09b21`)
|
||||
3. [x] S0.3 真实 PI 打样(项目 6424 intake + 6425 `rd_design_input_spec`)
|
||||
4. [x] S1 批 1–3(`eb09b21`)
|
||||
5. [x] 文档与门禁
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] rdev leader AGENTS.md 含「设计控制」且不含「商务对接负责人」「CDO」
|
||||
- [x] intake leader 回归仍含「商务对接负责人」
|
||||
- [x] 14 份模板 lint 绿灯;真 PI 终稿五节实质论证
|
||||
- [x] `go vet` + `go test -short` 全绿
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Test report: [.doc/test-reports/2026-09-17-rdev-template-depth-test-report.md](../../test-reports/2026-09-17-rdev-template-depth-test-report.md)
|
||||
- Assets: [.doc/test-reports/assets/2026-09-17-rdev-template-depth/](../../test-reports/assets/2026-09-17-rdev-template-depth/)
|
||||
- Backlog: [.doc/backlog/2026-09-17-rdev-phase2-backlog.md](../../backlog/2026-09-17-rdev-phase2-backlog.md)
|
||||
- 写作规范: [.doc/system-design/project-workflow/08-rdev模板写作规范.md](../../system-design/project-workflow/08-rdev模板写作规范.md)
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- 依赖 `feature/rdev-core`(尚未合 dev);合入前需 rebase 丢弃已进 dev 的 engineering-dashboard 重复提交。
|
||||
- 真 PI:`run_1789635054471569201`(intake ~220s);`run_1789635960880707641`(DI ~450s,`stage=RD03_design_input`)。
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
title: "研发工作流(rdev)接入:13 阶段 / 60 文档任务"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor
|
||||
branch: fix/docgov-stage-dynamic → feature/rdev-core
|
||||
worktree: "-"
|
||||
mutex: workflow-def
|
||||
---
|
||||
|
||||
# 研发工作流(rdev)接入:13 阶段 / 60 文档任务
|
||||
|
||||
## 目标
|
||||
|
||||
在现有 5 个正式工作流外新增医疗第 4 工作流「研发设计控制流程」(key: `rdev`),完整承载参考项目 13 phase / 60 文档任务的 ISO 13485 DHF 设计控制链,并通过真实 PI 验收;随后完成全工作流任务键命名空间化(P4)。
|
||||
|
||||
## 范围
|
||||
|
||||
- 方案:[07-研发工作流rdev接入-设计与实施计划](../../system-design/project-workflow/07-研发工作流rdev接入-设计与实施计划.md)(P0–P4 五期;§8 四项决策已确认)
|
||||
- P0:docgov Stage 去硬编码 + stage key 透传
|
||||
- P1:rdev.v2.json manifest(13×60 一次到位)+ 60 份 rd_ 前缀模板 + catalog/seed/registry + squad kind 编排 + main-completed precheck + 齐套测试 + stub PG 全链路
|
||||
- P2:前端激活规划/切换/前置 Banner + intent 文档名匹配 + prior docs 注入与血缘
|
||||
- P3:真实 PI Agent E2E(rd_proposal / rd_planning_review / rd_sw_plan 三样本)+ CI 门禁扩四
|
||||
- P4:现有工作流(main/pm/tm + 软件两盘点)任务键 `bd_`/`pm_`/`tm_`(`sw_`)空间化,alias 兼容式改名(D12),独立分支独立验收
|
||||
|
||||
## 非目标
|
||||
|
||||
- 二期增强全部移入 backlog:[2026-09-17-rdev-phase2-backlog](../../backlog/2026-09-17-rdev-phase2-backlog.md)(N/A 不适用页生成、UR/RS 结构化门禁、kind 专用门禁、depends_on 精确血缘、DMR 归档、sw_ 键盘点、complexity regulatory 注入)
|
||||
- 云盘 canonical DHF/DMR 归档(本仓库无云盘模块)
|
||||
- 软件域(non_medical_software)开放 rdev
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 用户确认方案 §8 四项决策(2026-09-17:名称「研发设计控制流程」/ 60 任务一次到位 / N/A 规划期关闭 + backlog / rd_ 前缀并扩展到现有工作流键名空间化)
|
||||
2. [x] P0 分支 `fix/docgov-stage-dynamic`(StageKey 透传;已叠入 `feature/rdev-core`)
|
||||
3. [x] P1 分支 `feature/rdev-core`(manifest/模板/seed/编排/precheck/齐套测试)
|
||||
4. [ ] P2 分支 `feature/rdev-web-governance`(前端 + intent + 血缘)— **骨架已定,待独立认领**
|
||||
5. [ ] P3 真实 PI 验收 + 报告归档 + FEATURE-MATRIX 更新 — **骨架已定,待独立认领**
|
||||
6. [ ] P4 分支 `feature/workflow-key-namespace`(D12 alias 兼容式改名 + 双路径回归)— **骨架已定,待独立认领**
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] `go vet ./...` && `go test -short` 相关包 PASS(P0+P1)
|
||||
- [x] 齐套断言:manifest 60 任务 ↔ `templates/docs/rd_*.md` 存在非空;rd_ 键与既有任务键不相交
|
||||
- [x] precheck:main 未 completed 时 rd 任务启动被拒且文案含 CDO
|
||||
- [ ] PG 集成:rdev 实例 planning→live→推进(`TestPG_RDevActivateWithNAClose`,需 `TEST_DATABASE_URL`)
|
||||
- [ ] web `npm test && npm run build` PASS;Playwright 抽检激活/推进(P2)
|
||||
- [ ] 真实 PI + MiniMax 三样本 E2E 报告归档 `.doc/test-reports/`(P3)
|
||||
- [ ] P4:旧 live 实例(旧键)+ 新实例(新键)双路径回归 PASS;全工作流任务键集合无交集
|
||||
|
||||
## 相关链接
|
||||
|
||||
- 设计方案: [07-研发工作流rdev接入-设计与实施计划](../../system-design/project-workflow/07-研发工作流rdev接入-设计与实施计划.md)
|
||||
- 参考调研: [2026-09-17-rdev-workflow-reference-analysis](../research/2026-09-17-rdev-workflow-reference-analysis.md)
|
||||
- 二期 backlog: [2026-09-17-rdev-phase2-backlog](../../backlog/2026-09-17-rdev-phase2-backlog.md)
|
||||
- Checklist: -
|
||||
- Handoff: -
|
||||
- Test report: -
|
||||
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- 参考项目:`.refs/weichen-agent-system`(configs/workflows/rdev.yaml 60 stage、templates/docs 60 模板、squads/overlays 配套)
|
||||
- 关键约束:WF-DEF-06(无流程级依赖,precheck 先例 test_manager);doc_id `doc_proj{pid}_{taskKey}` 平铺命名 → rd_ 前缀
|
||||
|
||||
## 合入说明(2026-09-17)
|
||||
|
||||
- P0+P1 已 `--no-ff` 合入本地 `dev`(含 template-depth S0+S1)。
|
||||
- P2/P3/P4 仍 planned,待独立认领。
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
title: "功能启用与文档修改影响分析调研"
|
||||
status: done
|
||||
created: 2026-09-20
|
||||
updated: 2026-09-20
|
||||
owner: Codex
|
||||
branch: feature/capability-enablement-impact-plan
|
||||
worktree: "-"
|
||||
mutex: capability-impact-research
|
||||
---
|
||||
|
||||
# 功能启用与文档修改影响分析调研
|
||||
|
||||
## 目标
|
||||
核实已实现功能的有效启用状态,形成分阶段启用方案及需求追踪、增量影响分析设计。
|
||||
|
||||
## 范围
|
||||
源码、配置、只读运行态、已有证据;研究报告与整改方案落盘。
|
||||
|
||||
## 非目标
|
||||
本轮不修改业务代码、不启用开关、不改变共享容器或真实项目数据。
|
||||
|
||||
## 步骤
|
||||
1. [x] 核实功能状态和接线。
|
||||
2. [x] 调研已有修改报告、依赖与需求追踪模型。
|
||||
3. [x] 编写详细报告和可实施方案,完成文档核查。
|
||||
|
||||
## 验收标准
|
||||
- [x] 当前事实与历史验收分开;每项启用方案有前置条件、验收、回退。
|
||||
- [x] 影响分析有版本、权限、增量更新、一致性和用户交互契约。
|
||||
|
||||
## 证据 / 备注
|
||||
开始时 dev=8fdcd98,工作区干净;git pull --ff-only 返回 Already up to date。无集成槽占用、无 push 授权。
|
||||
|
||||
产物:
|
||||
|
||||
- [调研报告](../../ops/research/2026-09-20-capability-enablement-impact-research.md)
|
||||
- [整改方案](../../remediation/2026-09-20-capability-enablement-impact-plan.md)
|
||||
- [FEATURE-MATRIX 校准](../../status/FEATURE-MATRIX.md)
|
||||
- [方案审阅记录](../../ops/research/2026-09-20-capability-enablement-impact-plan-review.md)
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
title: "2026-09-20 P0 热修(迁移 / 越权 / 稳定性 / 凭证)"
|
||||
status: done
|
||||
created: 2026-09-20
|
||||
updated: 2026-09-20
|
||||
owner: Cursor-Auto
|
||||
branch: docs/p0-closeout-2026-09-20
|
||||
worktree: "-"
|
||||
mutex: docs
|
||||
---
|
||||
|
||||
# 2026-09-20 P0 热修
|
||||
|
||||
## 目标
|
||||
|
||||
关闭系统体检发现的 P0 critical:迁移断链、三项 IDOR、进程 panic/race、凭证泄漏与生产口令轮换。
|
||||
|
||||
## 范围
|
||||
|
||||
- Wave 0–4(见 [整改方案](../../remediation/2026-09-20-p0-remediation-plan.md))
|
||||
- 后续实现分支:`fix/capability-merge-00058-2026-09-20`、`fix/authz-idor-hotfixes-2026-09-20`、`fix/runtime-panic-races-2026-09-20`、`fix/credential-hardening-2026-09-20`、`docs/p0-closeout-2026-09-20`
|
||||
|
||||
## 非目标
|
||||
|
||||
- main 分支对齐晋升
|
||||
- FAV / SWBOOT-10 / D7 / MULTI_INTENT full
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] Wave 0:审计与整改文档、CURRENT 认领、long-term 增补
|
||||
2. [x] Wave 1:capability 合入 + 00058 + rebuild
|
||||
3. [x] Wave 2:三项越权
|
||||
4. [x] Wave 2b:panic/race/recover/XSS
|
||||
5. [x] Wave 3:凭证 + 口令轮换
|
||||
6. [x] Wave 4:测试报告与收口
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 见 [测试报告](../../test-reports/2026-09-20-p0-hotfixes-test-report.md)
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Audit: [../../audit/2026-09-20-system-triage-audit.md](../../audit/2026-09-20-system-triage-audit.md)
|
||||
- Remediation: [../../remediation/2026-09-20-p0-remediation-plan.md](../../remediation/2026-09-20-p0-remediation-plan.md)
|
||||
- Test report: [../../test-reports/2026-09-20-p0-hotfixes-test-report.md](../../test-reports/2026-09-20-p0-hotfixes-test-report.md)
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
(各波次合入 commit 与健康输出)
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
title: "落实 Agent 规范与 L1 操作门禁"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Codex
|
||||
branch: feature/agent-governance-implementation
|
||||
worktree: .worktrees/agent-governance-implementation
|
||||
base_dev_sha: a241e838150f218f3a09d3523f93291b847d45fd
|
||||
mutex: agent-governance
|
||||
review_state: passed
|
||||
integration_state: integrated
|
||||
deployment: not_required
|
||||
cleanup: pending
|
||||
cleanup_owner: independent-maintainer-after-owner-exit
|
||||
remote_sync: not_requested
|
||||
---
|
||||
|
||||
# 落实 Agent 规范与 L1 操作门禁
|
||||
|
||||
用户已授权“按照方案实现这些规范”。范围:审查 R01–R10、两项安全补充、两个共享文档与 dev 操作的 L1 管理入口。所有修改在本任务 worktree;不改产品业务代码、数据库、模型配置,不升级 test/main,不 push。Python 标准库 sqlite3/fcntl 实现本机协调,不增加产品 Go 依赖。
|
||||
|
||||
## 实施单元与所有权
|
||||
|
||||
- 规范 Agent:AGENTS/PROJECT/客户端薄入口/模板/测试规范/CURRENT 归档,互斥 policy-docs。
|
||||
- 工具 Agent:worktree helper、env-service、candidate-images-build 与对应测试,互斥 ops-scripts。
|
||||
- 根 Agent:agentctl/SQLite/lease/CAS/提交与集成门禁、runbook、报告、FEATURE-MATRIX、ignore,互斥 coordination-core。
|
||||
- 测试 Agent:核心独立行为测试,仅写自己的测试文件,使用临时 Git 仓库。
|
||||
|
||||
## 验收
|
||||
|
||||
- [x] 新规范一致、轻量入口和真实状态可用;历史迁移不丢失。
|
||||
- [x] 主仓唯一 .locks;原子资源集合、父子冲突、活跃/失效身份、幂等及保守恢复。
|
||||
- [x] CURRENT/MATRIX 受控增量/CAS 更新,旧基线不覆盖,记录恢复证据。
|
||||
- [x] 错误工作区/无租约服务写入被拒;候选镜像源码 SHA 不符被拒。
|
||||
- [x] 安全 create/remove、commit/ref 门禁正反例通过。
|
||||
- [x] 独立代码审查及真实临时仓库并发验收;本地 dev 接收验证后的候选;安全清理。
|
||||
|
||||
## 交付边界
|
||||
|
||||
L1 对统一入口与 Git hooks 防误改,不能阻止任意同 UID shell 绕过。OS 沙箱、跨机锁、产品 PI 镜像交付等独立运行架构变更不在本次规范/最小门禁改动内。纯工程代码与文档不触发产品重建;将验证主目录运行挂载和就绪未因本轮改变。
|
||||
|
||||
## 验证与集成结果
|
||||
|
||||
- 76 项 Python 工程测试通过;最终候选复跑同样 76 PASS。20 个真实进程/独立 Git worktree 争同一资源:1 个执行、19 个 LOCK_BUSY。
|
||||
- ce-simplify-code 三视角完成;ce-code-review `20260921-133611-5e4781e6` 的 5 个确认问题全部修复并经独立复核关闭。详见[报告](../../test-reports/2026-09-21-agent-governance-test-report.md)。
|
||||
- 源码实现提交 `fed87ad1`;保留并行 Cursor 材料切块任务后任务 HEAD 为 `578a96440da56717582ec5ab267a094ceea3d941`。dev 从 `a5ea469ca44171a5c3e6419b1757852270fb991d` 接收完整验证候选 `7e9317b849e0696e110bac5b27749861178d7e3d`,这是规则 effective_commit。
|
||||
- 主仓 `.locks` 初始化、旧/新 dev flock 同 inode 和三个 hooks 已启用;doctor 正常,无租约 env guard 返回 LEASE_REQUIRED。收口文档使用已生效入口完成 CAS、提交与后续候选集成。
|
||||
- 真实 dev 合入前后 ready=ok/schema61、容器镜像和主目录 data/dev 挂载一致。本轮 deployment=not_required;未 push、未操作 test/main、无产品数据库或模型配置改动。
|
||||
- cleanup=pending:实际普通 remove 因部分同 UID 进程 cwd 不可读拒绝。保留本任务及 integrate-agent-governance-implementation 两个工作区,不使用 force/-D。独立维护者在 owner 退出并解决/核实进程可见性后重跑全部门禁;仅含可再生 pycache 的文件先明确删除。其他任务现场不在清理范围。
|
||||
- 文档链接检查 356 个目标中,唯一已存在的 `FEATURE-MATRIX` 历史 promotion receipt 断链不由本轮引入;本轮新增/修改链接全部有效。
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
title: "Agent 规范整体审查"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Codex
|
||||
branch: feature/agent-policy-review
|
||||
worktree: .worktrees/agent-policy-review
|
||||
base_dev_sha: a241e838150f218f3a09d3523f93291b847d45fd
|
||||
write_scope: [.doc/ops/short-term/2026-09-21-agent-policy-review.md, .doc/archive/ops/2026-09-21-agent-policy-review.md, .doc/audit/2026-09-21-agent-policy-review.md, .doc/ops/CURRENT.md]
|
||||
mutex: agent-policy-review
|
||||
deployment: not_required
|
||||
cleanup: retained-with-reason
|
||||
---
|
||||
|
||||
# Agent 规范整体审查
|
||||
|
||||
## 目标与范围
|
||||
|
||||
评估生效规范的可完善之处,形成有依据的新增、删除、修改清单。本轮使用 ce-doc-review 的只读审查流程;不修改 AGENTS/PROJECT/客户端规则,不实现锁管理或改业务代码。
|
||||
|
||||
## 已确定约束
|
||||
|
||||
- 全部新增修改使用 .worktrees;主目录留给 dev 集成与运行。
|
||||
- 锁先统一入口/提交门禁防误改,OS 权限隔离后续实施。
|
||||
- 审查不等于实现或部署授权;已有未合入规范收口和 .locks 方案保留原分支。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 启动链、当前 Git、规范与模板盘点。
|
||||
2. [x] 一致性、可执行性、范围、安全及故障场景复核。
|
||||
3. [x] 核实保留发现,形成增删改建议与实施优先级。
|
||||
4. [x] 文档校验、归档、本地提交。
|
||||
|
||||
## 验收
|
||||
|
||||
- 每条保留发现有当前源文件或明确缺失证据、实际后果和建议修改。
|
||||
- 区分已生效规则、尚待实现工具和未合入草案;不把建议当现状。
|
||||
- 未修改主目录跟踪文件、运行锁、服务或用户数据。
|
||||
|
||||
## 结果与交接
|
||||
|
||||
- [整体审查](../../audit/2026-09-21-agent-policy-review.md):10 组增删改建议、2 项安全观察;保留已确定的 worktree 与 L1-first 选择。
|
||||
- 五个独立会话内视角已返回;主审核对引用与实际命令/脚本。文档原规则未改,自动化未实施。
|
||||
- 检查项:新增文档相对链接、git diff --check;未运行产品测试,不作运行验收声明。
|
||||
- 本任务 CURRENT 快照标 done,未占共享集成槽位;本地分支保留供审核,未合入 dev、未 push。
|
||||
- 需要执行修改时先按第一批消除冲突,再处理减负及既有工具实现;不要将本报告直接视为已生效规则。
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
title: "采纳 Agent worktree 工作规范"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Codex
|
||||
branch: feature/agent-workflow-governance-plan
|
||||
worktree: .worktrees/feature-agent-workflow-governance-plan
|
||||
mutex: agent-workflow-governance
|
||||
---
|
||||
|
||||
# 采纳 Agent worktree 工作规范
|
||||
|
||||
## 授权与范围
|
||||
|
||||
用户于 2026-09-21 确认“提交吧,之后按这套执行”。延续原治理任务,在原 dev 派生的独立 worktree 内将方案采纳为生效规则,提交并合入本地 dev。仅修改规范、模板和治理记录。
|
||||
|
||||
本次不将 W1–W4 的自动化开发宣称已完成;它们保留在实施任务中。主目录仍有其他任务未提交改动,使用临时集成 worktree 合入纯文档,不迁移原任务、不改变业务运行态、不 push。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 核对主目录现场、原方案提交与集成槽位。
|
||||
2. [x] 同步 AGENTS、PROJECT、Cursor 规则、操作规范与模板。
|
||||
3. [x] 文档检查、提交、独立 worktree 合入 dev。
|
||||
4. [x] 更新验收/交接及清理状态。
|
||||
|
||||
## 验收
|
||||
|
||||
- [x] 单 Agent 主目录开发例外已移除,生效规则可从启动链发现。
|
||||
- [x] 创建明确来自 dev;测试提交、共享服务串行、部署及安全清理条件可执行。
|
||||
- [x] 自动化能力保持 planned;主目录其他任务未提交改动不被纳入提交。
|
||||
- [x] 本地 dev 含本次规范提交;未 push,未重建服务。
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [方案](../../remediation/2026-09-21-agent-workflow-governance-plan.md)
|
||||
|
||||
## 结果
|
||||
|
||||
- 规则提交 `048bbe4a`,验证的合并候选及首次 dev 合入 `83e22a70`。
|
||||
- [文档验收](../../test-reports/2026-09-21-agent-workflow-governance-adoption-test-report.md)。
|
||||
- 主目录旧任务保留;临时 dev 集成工作区保留到原 owner 可安全切回 dev,见 [交接](../../ops/handoffs/2026-09-21-agent-workflow-governance-plan.md)。
|
||||
- 收口提交合入后普通清理本任务和候选工作区,实际结果记录共同 Git 目录的治理操作收据。未 push;deployment=not_required。
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: "Agent 工作规范与 worktree 并行治理方案"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Codex
|
||||
branch: feature/agent-workflow-governance-plan
|
||||
worktree: .worktrees/feature-agent-workflow-governance-plan
|
||||
mutex: agent-workflow-governance-plan
|
||||
---
|
||||
|
||||
# Agent 工作规范与 worktree 并行治理方案
|
||||
|
||||
## 目标
|
||||
|
||||
基于当前仓库规范、脚本和现场,评估主目录保护、强制 worktree、串行集成与清理机制,交付可审核方案。
|
||||
|
||||
## 范围
|
||||
|
||||
- 只读检查 Git、脚本、Compose、测试入口和协作记录。
|
||||
- 形成调研、治理方案及交接文档;仅在本任务 worktree 写文档。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不修改业务代码、Agent 规则或运维脚本;不切换主目录分支、不干预其他任务、不重建服务、不清理既有 worktree、不 push。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 阅读启动链并盘点现场。
|
||||
2. [x] 显式从本地 dev@15b8a4a8 创建独立 worktree。
|
||||
3. [x] 完成机制核验、方案和边界审查。
|
||||
4. [x] 写交接并核查文档差异。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 有现状证据、方案比较、操作流程、并行边界、恢复与验收标准。
|
||||
- [x] 区分已存在机制与拟实现机制;不将方案宣称为已落地。
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
初始主目录为 fix/intent-workflow-scoping-2026-09-21,有其他任务未提交变更。为保护现场,未执行 checkout dev / pull;从显式本地 dev 创建 worktree。origin/dev...dev 为 0/309,仅为本地远端跟踪引用快照,本轮未 fetch。认领仅登记本 worktree 的 CURRENT,尚无跨 worktree 实时协调入口;本任务只读代码且使用独立文档路径。
|
||||
|
||||
## 交付
|
||||
|
||||
- [调研](../../ops/research/2026-09-21-agent-workflow-governance-research.md)
|
||||
- [方案](../../remediation/2026-09-21-agent-workflow-governance-plan.md)
|
||||
- [交接](../../ops/handoffs/2026-09-21-agent-workflow-governance-plan.md)
|
||||
- 仅文档核验,未执行产品测试;治理能力在 FEATURE-MATRIX 保持 planned。
|
||||
@@ -1,286 +0,0 @@
|
||||
# CURRENT 历史快照(2026-09-21)
|
||||
|
||||
归档来源:实施基线 `eb4dbdca5baae8dd5f3ddefc0f5510ac2978dcd3` 的 `.doc/ops/CURRENT.md`。以下保留原始认领、环境断言、焦点和证据索引;只调整移动后的 Markdown 相对链接。历史状态不是当前锁、环境或授权依据,活跃协调见 [CURRENT](../../ops/CURRENT.md)。基线内已失效的旧链接另在本次验证记录中说明,不把历史声明改写成新结论。
|
||||
|
||||
---
|
||||
|
||||
# 当前焦点
|
||||
|
||||
**更新**: 2026-09-21
|
||||
**production_ready**: yes(门禁 B1–B4 已签;dev schema **61**,test/main 仍为 **58**。P0 热修 done;rdev 种子热修 done,见 [报告](../../test-reports/2026-09-20-rdev-seed-hotfix-test-report.md))
|
||||
|
||||
## 焦点
|
||||
|
||||
1. **工作流作用域权重**:`WORKFLOW_SCOPE_MODE` 默认 `strict`;`weighted` 按关系权重打分,只读跨流注明归属,写动作仍拦截。见 [报告](../../test-reports/2026-09-21-workflow-scope-weighting-test-report.md)。test/main 未晋升。
|
||||
2. **意图确认优先与阶段感知**:弱写「整理需求」→ intake 确认卡片。见 [报告](../../test-reports/2026-09-21-intent-confirm-stage-aware-test-report.md)。test/main 未晋升。
|
||||
3. **上传解析提示 / 去重 / CoW 收口**:MinerU 解析状态轮询闭环(pending→running→done)、重复文件「已复用」提示、失败原因+重新解析、CAS 不可变 CoW 契约测试,已合入 `dev`(代码 `99905571`、证据 `74587ccf`、收口 `a0464eb5`)。见 [报告](../../test-reports/2026-09-21-upload-parse-ux-dedup-test-report.md)。test/main 未晋升。前序任务执行状态卡收口见 [报告](../../test-reports/2026-09-21-taskrun-status-card-persistence-test-report.md)(含二轮修复:completed 步骤 label 冻结为"正在…(NN%)"的收口归一化 + dev 历史回填,已合入 `dev@4b303247` 并真实 PI 验收)。
|
||||
4. **MinerU 真实 PDF 二轮验收**:用户反馈「PDF 内容未被理解」由两因叠加——(A) 首轮在 worktree 内跑 `env-service dev rebuild` 令挂载漂到 worktree `data/dev`,真实历史 blob 全部读不到;(B) Agent 轻量 API 硬限 20 页,28 页真实文件失败。首轮结论作废。二轮从**主目录** rebuild 修复挂载,`internal/mineru` 在 `-30003` 时按 20 页窗分块解析并重编全局页锚;`ReadRefBytes` 失败改为 `slog.Warn`。已合入 `dev@362b68a0`。真实 `bd_intake`(项目 6532)`completed`,工作区 `materials_text` 注入 29152 字节中文正文。见 [报告](../../test-reports/2026-09-21-mineru-doc-parsing-test-report.md) 第八节。
|
||||
5. **红线**:禁止整支 merge FAV;不默认升 `MULTI_INTENT_PLAN_TIER=full`;`SEMANTIC_SUMMARY_REPLACE` 不随 W2 开启;FAV live 观察窗证据驱动;`FAV_DEGRADED_READ=false`;项目 143 只读;SWBOOT-10 保持 fail-closed stub;D7 对话 ADR 仍待合规签字(追踪表留存类别已定为 `record`,不授权物理删除);**不改 `production_ready`**;模块解耦批次 A–G 与回溯实施切片未单独认领前保持 `planned`;**合入 dev 后必须回主目录跑 `env-service.sh dev rebuild`,禁止任何 worktree 内运行 `env-service`**(脚本 ROOT_DIR 取自脚本所在目录树,会带走 bind mount,导致 `/app/data` 漂到 worktree 空目录)。
|
||||
|
||||
## 并行认领
|
||||
|
||||
| owner | task | branch | worktree | mutex | status |
|
||||
|-------|------|--------|----------|-------|--------|
|
||||
| Codex | 2026-09-21-agent-governance-implementation | feature/agent-governance-implementation | .worktrees/agent-governance-implementation | agent-governance | in_progress |
|
||||
| Cursor | 2026-09-21-workflow-scope-weighting | feature/workflow-scope-weighting-2026-09-21 | .worktrees/workflow-scope-weighting-2026-09-21 | intent+web+docgov | done |
|
||||
| Cursor | 2026-09-21-upload-parse-ux-dedup | feature/upload-parse-ux-2026-09-21 | .worktrees/upload-parse-ux-2026-09-21 | server+web+storage | done |
|
||||
| Cursor | 2026-09-21-mineru-doc-parsing | feature/mineru-doc-parsing-2026-09-21 | .worktrees/mineru-doc-parsing-2026-09-21 | storage+bizdev+kb | done |
|
||||
| Cursor | 2026-09-21-intent-confirm-stage-aware | fix/intent-confirm-stage-aware-2026-09-21 | .worktrees/intent-confirm-stage-aware-2026-09-21 | intent+web+docgov | done |
|
||||
| Cursor | 2026-09-21-taskrun-status-card | feature/taskrun-status-card-2026-09-21 | .worktrees/feature-taskrun-status-card-2026-09-21 | chat+web+taskrun | done |
|
||||
| Cursor | 2026-09-21-intent-workflow-scoping | fix/intent-workflow-scoping-2026-09-21 | - | intent+web+docgov | done |
|
||||
| Codex | 2026-09-21-agent-workflow-governance-adoption | feature/agent-workflow-governance-plan | .worktrees/feature-agent-workflow-governance-plan | agent-workflow-governance | in_progress |
|
||||
| Codex | 2026-09-21-agent-workflow-governance-plan | feature/agent-workflow-governance-plan | .worktrees/feature-agent-workflow-governance-plan | agent-workflow-governance-plan | done |
|
||||
| Cursor | 2026-09-21-workflow-doc-key-unification | fix/workflow-doc-key-unification-2026-09-21 | .worktrees/fix-workflow-doc-key-unification-2026-09-21 | docgov+web | done |
|
||||
| Cursor | 2026-09-21-dev-deep-test-four-issues | fix/dev-deep-test-four-issues-2026-09-21 | - | web+intent+taskrun | done |
|
||||
| Cursor | 2026-09-21-trace-panel-to-chat | feature/trace-panel-to-chat-2026-09-21 | - | trace-impact+web | done |
|
||||
| Cursor | 2026-09-21-taskrun-scope-persist | fix/taskrun-scope-persist-2026-09-21 | - | projectinstance+taskrun | done |
|
||||
| Cursor | 2026-09-21-dev-multiuser-four-issues | fix/dev-multiuser-four-issues-2026-09-21 | .worktrees/fix-dev-multiuser-four-issues | projectinstance+docgov | done |
|
||||
| Cursor | 2026-09-21-taskrun-error-transparency | fix/taskrun-error-transparency-2026-09-21 | - | chat+web | done |
|
||||
| Cursor | 2026-09-21-trace-panel-null-crash | fix/trace-panel-null-crash-2026-09-21 | - | trace-index+web | done |
|
||||
| Cursor-Auto | 2026-09-20-stage-backtrack-design | feature/stage-backtrack-design | - | trace-impact-design | done |
|
||||
| Cursor-Auto | 2026-09-20-impact-loop-t1 至 T3/B1–B3 | feature/stage-backtrack-impl | - | trace-index | done |
|
||||
| Cursor | 2026-09-20-rdev-seed-hotfix | fix/workflow-seed-bootstrap-2026-09-20 | - | workflow-def | done |
|
||||
| Cursor-Auto | 2026-09-20-module-decoupling-spec-audit | docs/module-decoupling-spec-2026-09-20 | - | module-decoupling-spec | done |
|
||||
| Cursor-Auto | 2026-09-20-p0-closeout | docs/p0-closeout-2026-09-20 | - | docs | done |
|
||||
| Cursor-Auto | 2026-09-20-p0-hotfixes(Wave 0 文档) | docs/p0-triage-2026-09-20 | - | docs | done |
|
||||
| Cursor-Auto | 2026-09-20-p0-capability-00058 | fix/capability-merge-00058-2026-09-20 | - | infra+chat | done |
|
||||
| Cursor-Auto | 2026-09-20-p0-idor | fix/authz-idor-hotfixes-2026-09-20 | - | authz | done |
|
||||
| Cursor-Auto | 2026-09-20-p0-runtime-stability | fix/runtime-panic-races-2026-09-20 | - | taskrun+chat+web | done |
|
||||
| Cursor-Auto | 2026-09-20-p0-credentials | fix/credential-hardening-2026-09-20 | - | ops+infra | done |
|
||||
| Cursor-Auto | 2026-09-20-proposed-authoritative-reports | feature/capability-enablement-impact-plan | - | docgov | done |
|
||||
| Cursor-Auto | 2026-09-20-pi-narrative-clipped-diff | feature/capability-enablement-impact-plan | - | docgov | done |
|
||||
| Cursor-Auto | 2026-09-20-pi-reasoning-profile | feature/capability-enablement-impact-plan | - | pi-agent | done |
|
||||
| Cursor-Auto | 2026-09-20-semantic-summary-persistence | feature/capability-enablement-impact-plan | - | chat+lineage-version | done |
|
||||
| Cursor-Auto | 2026-09-20-feature-readiness-and-lineage-authz | feature/capability-enablement-impact-plan | - | sysadmin+lineage | done |
|
||||
| Codex | 2026-09-20-capability-enablement-impact-plan | feature/capability-enablement-impact-plan | - | capability-impact-research | done |
|
||||
| Cursor-Auto | 2026-09-20-post-activation-duty-reassign-member-chat | fix/post-activation-duty-reassign-member-chat | - | projectworkflow+authz+web | done |
|
||||
| Cursor-Auto | 2026-09-20-test-env-triage-fixes | fix/test-env-triage-2026-09-20 | - | projectworkflow+chat+assets | done |
|
||||
| Cursor-Auto | 2026-09-20-test-env-beta6-verification | docs/test-env-beta6-verification | - | infra+docs | done |
|
||||
| Cursor-Auto | 2026-09-20-bug-hunt-permissions-uploads | fix/bug-hunt-2026-09-20-permissions-and-uploads | - | authz+web+projectworkflow | done |
|
||||
| Cursor | audit-b1-data-consistency | fix/audit-b1-data-consistency | - | docgov+workflow+chat | done |
|
||||
| Cursor | audit-b2-authz-hardening | fix/audit-b2-authz-hardening | - | authz | done |
|
||||
| Cursor | audit-b3-sse-events | fix/audit-b3-sse-events | - | chat+events | done |
|
||||
| Cursor | audit-b4-frontend | fix/audit-b4-frontend | - | web | done |
|
||||
| Cursor-Auto | 2026-09-19-audit-remainder-closeout | fix/audit-remainder-closeout | - | audit-remainder | done |
|
||||
| Antigravity | 2026-09-20-dev-deep-test-and-promotion | feature/dev-deep-test-and-promotion | - | integration | done |
|
||||
| Cursor-Auto | 2026-09-19-remove-control-center | fix/remove-control-center | - | controlcenter | done |
|
||||
| Cursor-Auto | 2026-09-17-control-center-server | feature/control-center-server | - | controlcenter | cancelled |
|
||||
| Kimi | 2026-09-18-user-manual | feature/user-manual | .worktrees/feature-user-manual | docs | done |
|
||||
| Cursor-Auto | 2026-09-18-wave7-roadmap-orchestration | docs/wave7-roadmap-orchestration | - | roadmap-orchestration | done |
|
||||
| Cursor-Auto | 2026-09-18-wave6-doc-drift | docs/wave6-doc-drift | - | doc-drift | done |
|
||||
| Cursor-Auto | 2026-09-18-wave5-deadcode-decisions | fix/wave5-deadcode-decisions | - | deadcode-cleanup | done |
|
||||
| Cursor-Auto | 2026-09-18-wave4-hardening-r1-r8 | fix/wave4-hardening-r1-r8 | - | hardening | done |
|
||||
| Cursor-Auto | 2026-09-18-wave3-test-debt-blindspots | fix/wave3-test-debt-blindspots | - | test-debt | done |
|
||||
| Cursor-Auto | 2026-09-18-wave2-config-flag-align | fix/wave2-config-flag-align | - | infra | done |
|
||||
| Cursor | 2026-09-18-wave1-main-env-fix | fix/wave1-main-env-fix | - | infra | done |
|
||||
| Cursor | 2026-09-18-wave0-p0-bug-fixes | fix/wave0-p0-sse-chat-cache-bugs | - | chat + web | done |
|
||||
| Kimi | 2026-09-17-system-health-check(只读审计,未实施) | - | - | audit | done |
|
||||
| Cursor | 2026-09-17-docgov-modification-proposal-http | feature/docgov-modification-proposal-http | - | docgov | done |
|
||||
| Cursor | 2026-09-17-document-author-only-closeout | feature/document-author-only-plan | - | document-duty-policy | done |
|
||||
| Cursor | 2026-09-17-rdev-template-depth-s1-continued | feature/rdev-template-depth-s1-continued | .worktrees/feature-rdev-template-depth-s1-continued | rdev-templates | done |
|
||||
| Cursor | 2026-09-17-rdev-workflow-integration | feature/rdev-core | - | workflow-def | done |
|
||||
| Cursor | 2026-09-17-rdev-template-depth | feature/rdev-template-depth | .worktrees/feature-rdev-template-depth | rdev-templates | done |
|
||||
| Codex | 2026-09-17-document-author-only-plan | feature/document-author-only-plan | - | document-duty-policy-plan | done |
|
||||
| Cursor | 2026-09-17-initial-load-perf-u2 | feature/initial-load-perf-u2 | - | web + static-delivery | done |
|
||||
| Codex | 2026-09-17-initial-load-performance-plan | feature/initial-load-performance-plan | .worktrees/feature-initial-load-performance-plan | loading-performance-audit | done |
|
||||
| Kimi | 2026-09-17-system-admin-console | feature/system-admin-console | - | web + sysadmin | done |
|
||||
| Cursor-Auto | 2026-09-17-engineering-dashboard | feature/engineering-dashboard | .worktrees/feature-engineering-dashboard | engineering-dashboard | done |
|
||||
| Cursor | 2026-09-17-promote-null-fk-to-test | feature/promote-null-fk-to-test | - | infra | done |
|
||||
| Cursor | 2026-09-17-docgov-optional-duty-null-fk | fix/docgov-optional-duty-null-fk | - | docgov | done |
|
||||
| Cursor | 2026-09-17-leftover-hygiene | chore/leftover-hygiene-2026-09-17 | - | ops | done |
|
||||
| Cursor | 2026-09-17-w2-semantic-summary-shadow | feature/w2-semantic-summary-shadow-live | - | chat | done |
|
||||
| Cursor | 2026-09-17-w3-pi-change-report-narrative | feature/w3-pi-change-report-narrative-live | - | docgov | done |
|
||||
| Cursor | 2026-09-17-w4-multi-intent-u9-u12 | feature/w4-u9-segment-live | - | intent-plan | done |
|
||||
| Cursor | 2026-09-17-w5a-software-bootstrap-ui | feature/w5a-software-bootstrap-ui-pi | - | workflow-design | done |
|
||||
| Cursor | 2026-09-17-w6-fav-subscriber-shadow | feature/w6-fav-subscriber-shadow | - | events | done |
|
||||
| Cursor | 2026-09-17-w7-d7-inventory | feature/w7-d7-data-inventory | - | chat | done |
|
||||
| Cursor | 2026-09-17-promote-dev-to-test | feature/promote-dev-to-test-2026-09-17 | - | infra | done |
|
||||
| Cursor | 2026-09-17-kb-host-auth-fix | fix/kb-host-auth-layered-load | - | infra | done |
|
||||
| Cursor | 2026-09-17-w1-ci-e2e-green-nightly | feature/w1-ci-e2e-green-nightly | - | ci | done |
|
||||
| Cline | 2026-09-16-partial-deferred-completion | docs/partial-deferred-completion-plan | - | architecture-docs | in_progress |
|
||||
| Cursor | 2026-09-16-intent-plan-playwright-dual-tab | feature/intent-plan-cards-playwright | .worktrees/feature-intent-plan-cards-playwright | web | done |
|
||||
| Cursor | 2026-09-16-full-backlog-override | docs/override-nogo-full-backlog | - | architecture-docs | done |
|
||||
| Cursor | 2026-09-16-gitea-nightly-docker-datadir | fix/gitea-nightly-docker-datadir | - | ci | done |
|
||||
| Cursor | 2026-09-16-gitea-nightly-host-tools | fix/gitea-nightly-host-tools | - | ci | done |
|
||||
| Cursor | 2026-09-21-test-env-lazy-doc-verification | docs/lazy-doc-verification-2026-09-21 | - | infra+docs | done |
|
||||
| Cursor | 2026-09-16-wave-leftovers | fix/wave-leftovers-n7-playwright-dod | - | ci | done |
|
||||
| Cursor | 2026-09-16-wave3-pu6-pu8-go-no-go | feature/wave3-pu6-pu8-go-no-go | - | architecture-docs | done |
|
||||
| Cursor | 2026-09-16-wave2c-same-image-digest | feature/wave2c-same-image-digest | - | infra | done |
|
||||
| Cursor | 2026-09-16-wave2b-nightly-promotion-receipt | feature/wave2b-nightly-promotion-receipt | - | ci | done |
|
||||
| Cursor | 2026-09-16-wave2-real-pi-evidence | feature/wave2-real-pi-evidence | - | intent-plan | done |
|
||||
| Cursor | 2026-09-16-wave1-race-tempdir-cleanup | fix/race-tempdir-cleanup | - | ci | done |
|
||||
| Cursor | 2026-09-16-wave1-iam-fail-closed | fix/iam-store-fail-closed | - | authz | done |
|
||||
| Cursor | 2026-09-16-feature-matrix-wave0-calibration | feature/feature-matrix-production-readiness-plan | .worktrees/feature-matrix-production-readiness-plan | architecture-docs | done |
|
||||
| Codex | 2026-09-16-feature-matrix-production-readiness-plan | feature/feature-matrix-production-readiness-plan | .worktrees/feature-matrix-production-readiness-plan | architecture-docs | done |
|
||||
| Cursor-Auto | 2026-09-16-matrix-deep-test-promote-test | feature/matrix-deep-test-promote-test | - | infra | done |
|
||||
| Cursor-Auto | 2026-09-16-production-ready-gates | docs/production-ready-flip | - | ci | done |
|
||||
| Cursor-Auto | 2026-09-16-demo-seed-pollution | fix/demo-data-pollution-web | - | web | done |
|
||||
| Cursor | 2026-09-16-multi-intent-u8-task-generate | feature/multi-intent-u8-task-generate | - | intent-plan | done |
|
||||
| Cursor | 2026-09-16-multi-intent-u7-auto-read | feature/multi-intent-u7-auto-read | - | intent-plan | done |
|
||||
| Cursor | 2026-09-16-multi-intent-u6-web-cards | feature/multi-intent-u6-web-cards | - | web | done |
|
||||
| Cursor | 2026-09-16-multi-intent-u5-decision-api | feature/multi-intent-u5-decision-api | - | intent-plan | done |
|
||||
| Cursor | 2026-09-16-multi-intent-u4-outbox-projection | feature/multi-intent-u4-outbox-projection | - | events | done |
|
||||
| Cursor | 2026-09-15-multi-intent-u3-intentflow-pg | feature/multi-intent-u3-intentflow-pg | - | intent-plan | done |
|
||||
| Cursor | 2026-09-15-multi-intent-u2-segmenter | feature/multi-intent-u2-segmenter | - | intent | done |
|
||||
| Cursor | 2026-09-15-multi-intent-u1-contracts | feature/multi-intent-u1-contracts | - | architecture-docs | done |
|
||||
| Cursor | app-composition-u11-u12 | feature/app-composition-u11-u12 | - | app | done |
|
||||
| Cursor | chatlog-contextasm-u10 | feature/chatlog-contextasm-u10 | - | chat | done |
|
||||
| Cursor | chat-history-refresh-remediation | fix/chat-history-refresh | - | chat | done |
|
||||
| Cursor | dataset-lifecycle-u9 | feature/dataset-lifecycle-u9 | - | dataset | done |
|
||||
| Cursor | taskrun-runmanifest-u8 | feature/taskrun-runmanifest | - | taskrun | done |
|
||||
| Cursor | document-reliability-m1-live-and-m2 | refactor/document-reliability-pilot | - | workspace | done |
|
||||
| Codex | module-decoupling-remediation-plan | feature/module-decoupling-remediation | - | architecture-docs | done |
|
||||
| Codex | module-decoupling-phase2-plan-review | docs/module-decoupling-ipc-assessment | - | architecture-docs | done |
|
||||
| Cursor | module-decoupling-phase2-docs | feature/module-decoupling-phase2-docs | - | architecture-docs | done |
|
||||
| verifier_antigravity | controlled-content-ui-acceptance | fix/controlled-content-ui-acceptance | - | document-content-ui-acceptance | done |
|
||||
| implementer_cursor | controlled-content-canonical-hash | fix/controlled-content-canonical-hash | - | docgov | done |
|
||||
| Codex | project143-controlled-content-404-diagnosis | fix/project143-controlled-content-404-diagnosis | - | docgov-content-diagnosis | done |
|
||||
| Codex | software-project-bootstrap-plan | feature/software-project-bootstrap-plan | - | workflow-design | done |
|
||||
| Codex | conversation-intent-runtime-state | fix/conversation-intent-state | - | intent | done |
|
||||
| Cursor | conversation-intent-runtime-state | docs/conversation-intent-dual-tab | - | intent | done |
|
||||
| Cursor | document-revision-wave1-6-implementation | feature/document-revision-management | - | docgov | done |
|
||||
| Cursor-Auto | document-revision-runtime-ui03 | fix/document-revision-runtime-ui03 | - | docgov | done |
|
||||
| Cursor-Auto | document-revision-sse-idempotency | fix/document-revision-sse-idempotency | - | docgov | done |
|
||||
| Cursor-Auto | document-revision-active-doc-routing | fix/document-revision-active-doc-routing | - | docgov | done |
|
||||
| Cursor-Auto | document-revision-quality-context | fix/document-revision-quality-context | - | docgov | done |
|
||||
| Cursor-Auto | document-revision-e2e-pending-flow | fix/document-revision-e2e-pending-flow | - | pending-report-ui | done |
|
||||
| Cursor-Auto | document-revision-e2e-reject-routing | fix/document-revision-e2e-reject-routing | - | document-revision-runtime-ui | done |
|
||||
| Cursor-Auto | document-revision-e2e-block-selector | fix/document-revision-e2e-block-selector | - | document-revision-block-selector | done |
|
||||
| Cursor-Auto | document-revision-e2e-save-selector | fix/document-revision-e2e-save-selector | - | document-revision-save-selector | done |
|
||||
| Cursor-Auto | document-revision-e2e-overlay-selector | fix/document-revision-e2e-overlay-selector | - | document-revision-overlay-selector | done |
|
||||
| Cursor-Auto | document-revision-e2e-overlay-transition | fix/document-revision-e2e-overlay-transition | - | document-revision-overlay-transition | done |
|
||||
| Cursor-Auto | document-revision-second-doc-routing-lease | fix/document-revision-second-doc-routing-lease | - | document-revision-second-doc-routing-lease | done |
|
||||
| Cursor-Auto | document-revision-prelim-output | fix/document-revision-pi-runner-module | - | document-revision-prelim-output | done |
|
||||
| Cursor-Auto | document-revision-editor-hydration-race | fix/document-revision-editor-hydration-race | - | document-revision-editor-hydration-race | done |
|
||||
| Cursor-Auto | document-revision-quality-repair-workspace-contract | fix/document-revision-quality-repair-workspace-contract | - | document-revision-quality-repair-workspace-contract | done |
|
||||
| Cursor-Auto | document-revision-fast-completion-observation | fix/document-revision-fast-completion-observation | - | document-revision-fast-completion-observation | done |
|
||||
| Cursor-Auto | document-revision-workflow-category-navigation | fix/document-revision-workflow-category-navigation | - | document-revision-workflow-category-navigation | done |
|
||||
| Cursor-Auto | document-revision-duty-cell-assertion | fix/document-revision-duty-cell-assertion | - | document-revision-duty-cell-assertion | done |
|
||||
| Cursor-Auto | document-revision-reviewer-duty-sync | fix/document-revision-reviewer-duty-sync | - | document-revision-reviewer-duty-sync | done |
|
||||
| Cursor-Auto | document-revision-post-restart-selector | fix/document-revision-post-restart-selector | - | document-revision-post-restart-selector | done |
|
||||
| Cursor-Auto | document-revision-post-restart-final-snippet | fix/document-revision-post-restart-final-snippet | - | document-revision-post-restart-final-snippet | done |
|
||||
| Cursor-Auto | document-revision-pg-id-remap | fix/document-revision-pg-id-remap | - | document-revision | done |
|
||||
| Cursor-Auto | document-revision-runtime | fix/document-revision-runtime-ui03 | - | docgov | done |
|
||||
| Cursor-Auto | document-revision-runtime-ui-final-report | feature/document-revision-runtime-ui-final-report | - | document-revision-runtime-ui | done |
|
||||
| Cursor-Auto | document-revision-evidence-count | fix/document-revision-evidence-count | - | document-revision-evidence-count | done |
|
||||
| Cursor-Auto | document-revision-session-close | feature/document-revision-session-close | - | document-revision-session-close | done |
|
||||
| Cursor-Auto | vite-frp-allowed-hosts | fix/vite-frp-allowed-hosts | - | web-devserver | done |
|
||||
| implementer_cursor | workflow-plan-409-frozen-and-optional-duties | fix/workflow-plan-409-frozen-and-optional-duties | - | workflow | done |
|
||||
| implementer_cursor | governance-action-level-authz | fix/governance-action-level-authz | - | workflow | done |
|
||||
| Cursor | leftover-branch-cleanup | chore/leftover-branch-cleanup | - | ops | done |
|
||||
| Cursor | event-e0a-production-scope-contract | fix/event-production-scope-contract | - | events | done |
|
||||
| Cursor | event-e0b-dispatcher-pg | feature/events-dispatcher-pg | - | events | done |
|
||||
| Cursor | event-e1a-notify-cutover | fix/event-notify-cutover | - | events | done |
|
||||
| Cursor | event-e1b-workflow-advance | fix/event-workflow-advance | - | events | done |
|
||||
| Cursor | event-e1c-projection-cutover | fix/event-projection-cutover | - | events | done |
|
||||
| Cursor | event-e2-hook-guard | fix/event-e2-hook-guard | - | events | done |
|
||||
| Cursor | doccontent-canonical-boundary | fix/doccontent-canonical-boundary | - | docgov | done |
|
||||
| Cursor | intent-bizdev-boundary | fix/intent-bizdev-boundary | - | intent | done |
|
||||
| Cursor | stageflow-type-ownership | fix/stageflow-type-ownership | - | stageflow | done |
|
||||
| Cursor | bizdev-locator-removal | fix/bizdev-locator-removal | - | bizdev | done |
|
||||
| Cursor | chatflow-orchestration-boundary | fix/chatflow-orchestration-boundary | - | chat | done |
|
||||
| Cursor | phase2-closeout-inventories | feature/phase2-closeout-inventories | - | architecture-docs | done |
|
||||
| Cursor | event-shared-live-cutover | feature/event-shared-live-cutover | - | events | done |
|
||||
| Cursor | pi-typed-result | feature/pi-typed-result | - | pi-agent | done |
|
||||
| Cursor | promote-dev-to-test-2026-09-15 | feature/promote-dev-to-test-2026-09-15 | - | infra | done |
|
||||
|
||||
> 新任务开始前登记。`branch` 必须为 `feature/<slug>` 或 `fix/<slug>`,**禁止** `dev` / `test` / `main`。同一 `mutex` 同时仅一个 `in_progress`。
|
||||
|
||||
> workflow-plan 409 与治理鉴权 G1–G5 已收口(见 [test-report](../../test-reports/2026-09-14-governance-action-level-authz-test-report.md))。禁止终止或改写项目 143。
|
||||
> `document-reliability-pilot` U11–U12 已合入 `dev@bf59cce` 并 rebuild。`CHAT-INTENT-STATE` 双标签 busy 已 PASS(项目 6275)。禁止 worktree 内 `env-service`。项目 143 只读,禁止终止。
|
||||
> 2026-09-17 leftover 二次收口:[报告](../../test-reports/2026-09-17-leftover-hygiene-test-report.md)。已合入 leftover worktree/旁支再拆一轮;`feature/software-project-bootstrap` L1 已在 `dev`(残留关闭 commit 已丢弃)。`fix/clean-test-env-baseline` **不 merge**(前端 demo 清理已放弃;仅保留已挑拣的 `SEED_DEMO_USERS=false`)。extra worktree 仅余 `.worktrees/fix-dev-runtime-data-root-guard`(目录名是 guard,检出的是 `feature/final-artifact-vault`)。**故意不合入、不删**:`feature/final-artifact-vault`、`feature/remove-herdr-agent-settings`、`fix/project143-controlled-content-404-diagnosis`、`fix/dev-runtime-data-root-guard`、`dev-old-linear`。不删 `origin/*`。不整支 merge FAV;不启用 `FAV_DEGRADED_READ`。
|
||||
|
||||
## 集成槽位
|
||||
|
||||
| holder | phase | since | scope | queue |
|
||||
|--------|-------|-------|-------|-------|
|
||||
| - | idle | 2026-09-21 | taskrun-status-card label 修复已合入 dev@4b303247 并真实 PI 验收(round2 docs 随后合入);mineru 二轮文档已合入;schema=61 | - |
|
||||
|
||||
**phase**: `idle` | `merging` | `smoke` | `e2e`
|
||||
|
||||
> 合入 `dev` + 共享容器验证必须串行。详见 [AGENTS.md](../../../AGENTS.md) §6.3。
|
||||
|
||||
## 环境快照
|
||||
|
||||
| 环境 | 端口 | schema | 状态 |
|
||||
|------|------|--------|------|
|
||||
| dev | 8080 | **61** | healthy(mineru `00061`;intent-confirm 真实 PI PASS;`/health` schema_version=61;`pi-agent`;events `:8088`) |
|
||||
| test | 8081 | **58** | healthy(`rc-v1.0.0-beta.7`;rdev v1 active;`published_by` 回落到用户 4;events `:8089`) |
|
||||
| main | 8000 | **58** | healthy(P0 Wave3 rebuild 已追平 schema;分支树对齐仍记 backlog;口令已轮换;events `:8090`) |
|
||||
|
||||
## SSOT
|
||||
|
||||
| 类型 | 路径 |
|
||||
|------|------|
|
||||
| 2026-09-21 Agent worktree 工作规范 | [方案](../../remediation/2026-09-21-agent-workflow-governance-plan.md) · [调研](../../ops/research/2026-09-21-agent-workflow-governance-research.md) · [交接](../../ops/handoffs/2026-09-21-agent-workflow-governance-plan.md);规范已采纳,自动化另列 planned |
|
||||
| 2026-09-20 rdev 种子 | [short-term](../../ops/short-term/2026-09-20-rdev-seed-hotfix.md) · [报告](../../test-reports/2026-09-20-rdev-seed-hotfix-test-report.md) |
|
||||
| 2026-09-20 模块解耦 | [审计](../../audit/2026-09-20-module-coupling-audit.md) · [规范](../../system-design/2026-09-20-module-development-standards.md) · [批次 A–G](../../remediation/2026-09-20-module-decoupling-batch-plan.md) · [short-term](../../ops/short-term/2026-09-20-module-decoupling-spec-audit.md) |
|
||||
| 文档总地图 | [../README.md](../../README.md) |
|
||||
| 模块完成度 | [FEATURE-MATRIX](../../status/FEATURE-MATRIX.md)(Wave 0 已校准契约与冻结边界) |
|
||||
| 发布缺口 | [gap-matrix](../../remediation/gap-matrix.md)(`production_ready=yes`;Wave 0 IAM 只读未发现旁路) |
|
||||
| 2026-09-20 系统体检 | [audit](../../audit/2026-09-20-system-triage-audit.md) · [P0 整改](../../remediation/2026-09-20-p0-remediation-plan.md) · [short-term](../../ops/short-term/2026-09-20-p0-hotfixes.md) |
|
||||
| 连续性审计/计划 | [audit](../../audit/2026-09-16-feature-matrix-production-readiness-audit.md) · [remediation](../../remediation/2026-09-16-feature-matrix-production-readiness-plan.md) · [Wave 0 任务](../../ops/short-term/2026-09-16-feature-matrix-wave0-calibration.md) |
|
||||
| 测试报告 | [test-reports/](../../test-reports) |
|
||||
| dev→test 晋升前复核 | [research](../../ops/research/2026-09-19-pre-test-promotion-review.md)(2026-09-19 只读;静态门禁过,容器未 rebuild,暂不合并) |
|
||||
| D7 盘点(W7) | [audit](../../audit/2026-09-17-d7-data-inventory.md) · [报告](../../test-reports/2026-09-17-w7-d7-inventory-test-report.md) · ADR 仍 `pending-compliance-signoff` |
|
||||
| 功能启用与文档影响分析 | [调研](../../ops/research/2026-09-20-capability-enablement-impact-research.md) · [整改方案](../../remediation/2026-09-20-capability-enablement-impact-plan.md) · [方案审阅](../../ops/research/2026-09-20-capability-enablement-impact-plan-review.md)(2026-09-20;未启用开关、未改业务代码) |
|
||||
| 阶段回溯与影响闭环 | [设计](../../system-design/2026-09-20-stage-backtrack-and-impact-loop-design.md) · [short-term](../../ops/short-term/2026-09-20-stage-backtrack-design.md)(2026-09-20;仅设计。切片 T1/T2/B1/B2/B3/T3 均为 planned) |
|
||||
| Wave 7 编排确认 | [决策记录](../../ops/short-term/2026-09-18-wave7-roadmap-orchestration.md) |
|
||||
| Agent 手册 | [AGENTS.md](../../../AGENTS.md) |
|
||||
| 意图双标签 busy 交接 | [./handoffs/2026-09-15-conversation-intent-dual-tab.md](../../ops/handoffs/2026-09-15-conversation-intent-dual-tab.md) |
|
||||
| 受控正文 hash 漂移 W1–W6 | [../ops/handoffs/2026-09-14-controlled-content-canonical-hash.md](../../ops/handoffs/2026-09-14-controlled-content-canonical-hash.md) |
|
||||
| DOCREV ADR | [../adr/2026-09-13-document-version-boundary.md](../../adr/2026-09-13-document-version-boundary.md) |
|
||||
| DOCREV 管理测试 | [../test-reports/2026-09-13-document-revision-management-test-report.md](../../test-reports/2026-09-13-document-revision-management-test-report.md) |
|
||||
| DOCREV 运行时 UI Round20 | [../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md) |
|
||||
| 纯软件项目自举设计 | [../system-design/2026-09-14-software-project-bootstrap-workflow.md](../../system-design/2026-09-14-software-project-bootstrap-workflow.md) |
|
||||
| 模块化单体解耦架构 | [../system-design/2026-09-14-module-decoupling-architecture.md](../../system-design/2026-09-14-module-decoupling-architecture.md) |
|
||||
| 模块解耦整改计划 | [../remediation/2026-09-14-module-decoupling-refactor-plan.md](../../remediation/2026-09-14-module-decoupling-refactor-plan.md) |
|
||||
| Phase 2 方案审阅 | [../audit/2026-09-15-module-decoupling-phase2-plan-review.md](../../audit/2026-09-15-module-decoupling-phase2-plan-review.md) |
|
||||
| Phase 2 修订计划 | [../remediation/2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md](../../remediation/2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md) |
|
||||
| 多意图 HITL 复核方案 | [../system-design/2026-09-15-multi-intent-hitl-plan.md](../../system-design/2026-09-15-multi-intent-hitl-plan.md) |
|
||||
| 多意图 HITL U1 契约 | [../test-reports/2026-09-15-multi-intent-u1-contracts-test-report.md](../../test-reports/2026-09-15-multi-intent-u1-contracts-test-report.md) |
|
||||
| 多意图 HITL U2 分段 | [../test-reports/2026-09-15-multi-intent-u2-segmenter-test-report.md](../../test-reports/2026-09-15-multi-intent-u2-segmenter-test-report.md) |
|
||||
| 多意图 HITL U3 PG | [../test-reports/2026-09-15-multi-intent-u3-intentflow-pg-test-report.md](../../test-reports/2026-09-15-multi-intent-u3-intentflow-pg-test-report.md) |
|
||||
| 多意图 HITL U4 投影 | [../test-reports/2026-09-16-multi-intent-u4-outbox-projection-test-report.md](../../test-reports/2026-09-16-multi-intent-u4-outbox-projection-test-report.md) |
|
||||
| 多意图 HITL U5 API | [../test-reports/2026-09-16-multi-intent-u5-decision-api-test-report.md](../../test-reports/2026-09-16-multi-intent-u5-decision-api-test-report.md) |
|
||||
| 多意图 HITL U6 Web | [../test-reports/2026-09-16-multi-intent-u6-web-cards-test-report.md](../../test-reports/2026-09-16-multi-intent-u6-web-cards-test-report.md) |
|
||||
| 多意图 HITL U8 generate | [../test-reports/2026-09-16-multi-intent-u8-task-generate-test-report.md](../../test-reports/2026-09-16-multi-intent-u8-task-generate-test-report.md) |
|
||||
| 多意图 HITL U7 只读 | [../test-reports/2026-09-16-multi-intent-u7-auto-read-test-report.md](../../test-reports/2026-09-16-multi-intent-u7-auto-read-test-report.md) |
|
||||
| 文档可靠性 M1 报告 | [../test-reports/2026-09-14-document-reliability-pilot-test-report.md](../../test-reports/2026-09-14-document-reliability-pilot-test-report.md) |
|
||||
| 文档可靠性 M1 活验 | [../test-reports/2026-09-14-document-reliability-pilot-live-test-report.md](../../test-reports/2026-09-14-document-reliability-pilot-live-test-report.md) |
|
||||
| 文档可靠性 M2 | [../test-reports/2026-09-14-document-reliability-m2-test-report.md](../../test-reports/2026-09-14-document-reliability-m2-test-report.md) |
|
||||
| 文档可靠性 M3 U8 | [../test-reports/2026-09-15-taskrun-runmanifest-u8-test-report.md](../../test-reports/2026-09-15-taskrun-runmanifest-u8-test-report.md) |
|
||||
| 文档可靠性 M3 U9 | [../test-reports/2026-09-15-dataset-lifecycle-u9-test-report.md](../../test-reports/2026-09-15-dataset-lifecycle-u9-test-report.md) |
|
||||
| 文档可靠性 M4 U10 | [../test-reports/2026-09-15-chatlog-contextasm-u10-test-report.md](../../test-reports/2026-09-15-chatlog-contextasm-u10-test-report.md) |
|
||||
| 文档可靠性 M5/M6 U11–U12 | [../test-reports/2026-09-15-app-composition-u11-u12-test-report.md](../../test-reports/2026-09-15-app-composition-u11-u12-test-report.md) |
|
||||
| Track E E2 闭包守卫 | [../test-reports/2026-09-15-event-e2-hook-guard-test-report.md](../../test-reports/2026-09-15-event-e2-hook-guard-test-report.md) |
|
||||
| Track E 复盘 | [./research/2026-09-15-track-e-retrospective.md](../../ops/research/2026-09-15-track-e-retrospective.md) |
|
||||
| 旁支清点收口 | [../test-reports/2026-09-15-leftover-branch-cleanup-test-report.md](../../test-reports/2026-09-15-leftover-branch-cleanup-test-report.md) · [二次收口](../../test-reports/2026-09-17-leftover-hygiene-test-report.md) |
|
||||
| SSE/幂等审计 | [../audit/2026-09-13-document-revision-sse-idempotency.md](../../audit/2026-09-13-document-revision-sse-idempotency.md) |
|
||||
| 质量门禁自污染审计 | [../audit/2026-09-13-document-revision-quality-gate-self-pollution.md](../../audit/2026-09-13-document-revision-quality-gate-self-pollution.md) |
|
||||
| 当前文档路由审计 | [../audit/2026-09-13-document-revision-active-doc-routing.md](../../audit/2026-09-13-document-revision-active-doc-routing.md) |
|
||||
| 行动表状态假阳性审计 | [../audit/2026-09-13-document-revision-quality-status-false-positive.md](../../audit/2026-09-13-document-revision-quality-status-false-positive.md) |
|
||||
| 待确认报告选择失败审计 | [../audit/2026-09-13-document-revision-pending-report-selection.md](../../audit/2026-09-13-document-revision-pending-report-selection.md) |
|
||||
| UI-05b 拒绝路由失败审计 | [../audit/2026-09-13-document-revision-e2e-reject-routing.md](../../audit/2026-09-13-document-revision-e2e-reject-routing.md) |
|
||||
| 职责伪造与 ETag 覆盖审计 | [../audit/2026-09-13-document-revision-duty-etag-overwrite.md](../../audit/2026-09-13-document-revision-duty-etag-overwrite.md) |
|
||||
| UI-06 块选择器失败审计 | [../audit/2026-09-13-document-revision-block-selector.md](../../audit/2026-09-13-document-revision-block-selector.md) |
|
||||
| UI-06 保存选择器失败审计 | [../audit/2026-09-13-document-revision-save-selector.md](../../audit/2026-09-13-document-revision-save-selector.md) |
|
||||
| UI-07 纯净阅读取样失败审计 | [../audit/2026-09-13-document-revision-overlay-selector.md](../../audit/2026-09-13-document-revision-overlay-selector.md) |
|
||||
| UI-07 transition 中间帧取样审计 | [../audit/2026-09-13-document-revision-overlay-transition.md](../../audit/2026-09-13-document-revision-overlay-transition.md) |
|
||||
| UI-11 第二份文档路由与 lease 审计 | [../audit/2026-09-13-document-revision-second-doc-routing-lease.md](../../audit/2026-09-13-document-revision-second-doc-routing-lease.md) |
|
||||
| UI-11 prelim_design 缺 output.md 审计 | [../audit/2026-09-13-document-revision-prelim-output.md](../../audit/2026-09-13-document-revision-prelim-output.md) |
|
||||
| UI-06 编辑弹窗 hydration 竞态审计 | [../audit/2026-09-13-document-revision-editor-hydration-race.md](../../audit/2026-09-13-document-revision-editor-hydration-race.md) |
|
||||
| UI-03 质量修复子工作区契约审计 | [../audit/2026-09-13-document-revision-quality-repair-workspace-contract.md](../../audit/2026-09-13-document-revision-quality-repair-workspace-contract.md) |
|
||||
| UI-11 快速完成观测误判审计 | [../audit/2026-09-13-document-revision-fast-completion-observation.md](../../audit/2026-09-13-document-revision-fast-completion-observation.md) |
|
||||
| UI-13a 私密分类导航失败审计 | [../audit/2026-09-13-document-revision-workflow-category-navigation.md](../../audit/2026-09-13-document-revision-workflow-category-navigation.md) |
|
||||
| UI-13a 职责单元格误判审计 | [../audit/2026-09-13-document-revision-duty-cell-assertion.md](../../audit/2026-09-13-document-revision-duty-cell-assertion.md) |
|
||||
| UI-13a reviewer 职责未同步审计 | [../audit/2026-09-13-document-revision-reviewer-duty-sync.md](../../audit/2026-09-13-document-revision-reviewer-duty-sync.md) |
|
||||
| UI-03 首次生成 PG ID 误删 baseline | [../audit/2026-09-13-document-revision-pg-id-remap.md](../../audit/2026-09-13-document-revision-pg-id-remap.md) |
|
||||
| UI-06 刷新后缓存竞争死锁审计 | [../audit/2026-09-14-document-revision-refresh-cache-race.md](../../audit/2026-09-14-document-revision-refresh-cache-race.md) |
|
||||
| 受控正文真实 UI 验收报告 | [../test-reports/2026-09-14-controlled-content-ui-acceptance.md](../../test-reports/2026-09-14-controlled-content-ui-acceptance.md) |
|
||||
|
||||
## 并行集成补录
|
||||
|
||||
来源:dev@a5ea469c 的 CURRENT 增量。保留材料切块任务的新结论;活跃 CURRENT 保留其认领和最新槽位。
|
||||
|
||||
5. **材料切块不再看体积**:项目 6579 `doc_proj6579_bd_intake` 已确认候选 535,正式正文不再含「二进制压缩流」。成功解析的材料一律写入 `material_chunks`,≤60KB 仍全文注入。见 [报告](../../test-reports/2026-09-21-force-material-chunk-index-test-report.md)。已合入 `dev` 并从主目录 rebuild。test/main 未晋升。
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
task_id: herdr-orchestration-v12
|
||||
status: done
|
||||
owner: Codex
|
||||
branch: feature/herdr-orchestration-v12
|
||||
base_dev_sha: d919e06a73f7a4e18ed9d0cc26728f9cb32f8d97
|
||||
policy_revision: agent-governance-2026-09-21-r1
|
||||
deployment: not_required
|
||||
remote_sync: not_requested
|
||||
integration_state: merged
|
||||
review_state: passed
|
||||
cleanup: pending
|
||||
cleanup_owner: independent-maintainer-after-owner-exit
|
||||
effective_commit: 8c5e3477585fe27a485343dac97a670d95cf8905
|
||||
---
|
||||
# Herdr v1.2 分工与自动审批
|
||||
|
||||
授权:用户要求研究所给方案、纳入仅 Herdr 生效规范,并让已准备客户端自动通过工具请求。本轮修改规则与对应本地入口,提交/合入 dev;不改个人全局配置,不花费模型额度做探针,不操作产品/test/main,不 push。
|
||||
|
||||
本会话 HERDR_ENV 检查失败;依 Herdr 技能不查看/操作现有会话。以本机帮助/非敏感模型别名、官方文档及真实临时 Git/SQLite 配合模拟 Herdr 边界验收,不能声称真实 pane 已启动。
|
||||
|
||||
范围:AGENTS/PROJECT 条件入口、roster、两个启动/派发脚本及共享模块/测试。写入通过任务 path 租约;共享 CURRENT 用 CAS。保留其他任务与已存在 cleanup_pending。
|
||||
|
||||
结论与验收见下文。交付后的原 task_id 继续用于 Kimi 总次数;不得以拆子任务重置预算。
|
||||
|
||||
## 研究与验证结果
|
||||
|
||||
总体采纳。修正 Cursor“无限量”前提、执行跟踪与代码实施边界、默认唯一实施与显式故障接管的矛盾;Kimi 应急/终稿共用上限,GPT 耗尽不以文稿审核代替代码安全终审;普通会话不套用本分工。
|
||||
|
||||
本机配置只读核验:Claude Opus/Sonnet 别名为 glm-5.3[1m],Haiku 为 glm-5.3-flash[1m];Codex 默认 gpt-6-astra;PI 默认 minimax-cn/MiniMax-M3,模型目录可列出 qwen-token-plan-cn/qwen3.8-max、qwen3.8-flash 与 zai-coding-cn/glm-5.3。未读取或输出凭证;未修改这些全局设置;未实际调用远端模型。
|
||||
|
||||
- 11 项专用行为测试 PASS(4.664s),包含九个 profile 的自动审批 flags、Herdr 外/错工作区拒绝、目标 pane 检查、报告路由、显式实施备援、不确定发送不重投、唯一重试标记、同角色歧义、Kimi 关停/跨入口计数/未知结果不退款;八进程竞争只有一次真实模拟发送。
|
||||
- [测试输出](../../test-reports/assets/2026-09-21-herdr-v12/focused-tests.txt);[九种启动命令](../../test-reports/assets/2026-09-21-herdr-v12/launch-commands.json)。Git/SQLite 是真实临时仓库,Herdr transport 为 fake,绝不将其声明为实际 pane 启动/模型 E2E。
|
||||
- PI 安装版本 0.85.1 的本机 README 明确内置工具无权限弹窗,`--approve` 是项目文件信任;扩展仍可自建交互。Cursor force 保留显式 deny,Kimi 使用 auto 而非 yolo。其他本机帮助与[官方出处](../../ops/2026-09-13-herdr-agent-roster.md#5-自动通过请求与实际启动)相互核对。
|
||||
- 本地复核:路由/参数集中于一个 Python 模块,两个 shell 薄入口不复制策略;保留 task 与主仓 `.locks` 身份校验;Kimi 占用在投递前事务提交。没有后台队列/全账户计费控制,MiniMax/GPT 预算轮次由任务记录管理。
|
||||
- 代码不涉及产品 Go/前端/数据库业务;无需产品重建。提交后的候选将按工程测试全集验证,再受控合入 dev;真实 Herdr 会话核验留给下一次在 Herdr 内的实际任务,不在外部强行接入。
|
||||
|
||||
## 收口
|
||||
|
||||
实现提交 `8bc7940e`;生效 dev 候选 `8c5e3477585fe27a485343dac97a670d95cf8905`,其第一父节点 `d919e06a`,主目录持锁快进接收同一已验证节点。[候选完整输出](../../test-reports/assets/2026-09-21-herdr-v12/candidate-tests.txt):87 tests PASS,36.216s,含原门禁与本轮 11 项测试。语法、diff 与本轮链接检查均通过。收口附加提交仅文档,按文档契约另验。
|
||||
|
||||
运行边界:未启动真实 Herdr/pane/模型请求,未改全局配置、产品服务或数据库;deployment=not_required,无远端 push。不会把模拟 transport 的通过当作实际账户、余额或审批 UI 已消失的证明。
|
||||
|
||||
清理:[进程可见性预检](../../test-reports/assets/2026-09-21-herdr-v12/cleanup-preflight.json)拒绝,部分同 UID cwd 不可读。保留 `.worktrees/herdr-orchestration-v12` 与 `.worktrees/integrate-herdr-orchestration-v12`;独立维护者在 owner 退出和进程可见性核实后重跑普通 remove/-d 的全部门禁,不强删,不接管其他任务。
|
||||
|
||||
影响:Herdr roster、条件入口、规范登记、启动/派发脚本一致;不改变 FEATURE-MATRIX 的产品状态或治理完整自动化 partial,也不改变 gap-matrix。下一次实际 Herdr 任务先核验模型/自动审批启动状态,再按既有任务范围调度;Kimi 仅有必要时调用一次。
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
title: "意图确认优先与阶段感知消解"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Cursor
|
||||
branch: fix/intent-confirm-stage-aware-2026-09-21
|
||||
worktree: .worktrees/intent-confirm-stage-aware-2026-09-21
|
||||
base_dev_sha: 49fb68fec1ea56f00616c23d08efb15950c2300d
|
||||
mutex: intent+web+docgov
|
||||
---
|
||||
|
||||
# 意图确认优先与阶段感知消解
|
||||
|
||||
## 目标
|
||||
|
||||
商务流初期「整理一下需求」等弱写表述 → 阶段感知消解为 intake,经确认卡片拍板后再执行;不强指令误伤。扩展已合入的工作流作用域修复。
|
||||
|
||||
## 范围
|
||||
|
||||
- 批次5 `feat(intent)`:弱写动词 + `stageAwareRequirementsTask` + `needs_confirmation`
|
||||
- 批次6 `feat(coordinator)`:智能确认门禁(PendingExpectation)
|
||||
- 批次7 `feat(web)`:阶段错误降级聊天一次
|
||||
- 批次8:验收报告 + 合回 `dev` + 真实 PI 抽样
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 批次5–7 实现与单元门禁
|
||||
2. [x] 批次8:合入 `dev@0c401904` + rebuild + 真实链路抽样(陈威项目 6579)
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] V0.1「整理一下需求」→ 确认 →「好」→ intake(单元 + 真实 PI)
|
||||
- [x] 强指令不强制确认;「编写用户需求表」无 rdev 误拦
|
||||
- [x] 合入后真实 PI 抽样(见测试报告)
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: `~/.cursor/plans/意图确认优先与阶段感知_7ab2c4d5.plan.md`
|
||||
- Prior (done): `.doc/archive/ops/2026-09-21-intent-workflow-scoping.md`
|
||||
- Test report: `.doc/test-reports/2026-09-21-intent-confirm-stage-aware-test-report.md`
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
title: "意图填槽工作流作用域修复"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Cursor
|
||||
branch: fix/intent-workflow-scoping-2026-09-21
|
||||
worktree: "-"
|
||||
mutex: intent+web+docgov
|
||||
---
|
||||
|
||||
# 意图填槽工作流作用域修复
|
||||
|
||||
## 目标
|
||||
|
||||
意图识别填槽(target_doc / target_task)只命中当前激活工作流的文档与任务;显式点名其他工作流的文档时拦截并引导切换工作流,不误触、不执行。
|
||||
|
||||
## 背景
|
||||
|
||||
用户反馈:填「要修改的文档」等槽位时可能命中其他工作流的文档。根因链(2026-09-21 调研):
|
||||
|
||||
1. `intent.ContextSnapshot` 无 workflow 字段,`ToSnapshot()` 丢弃 `Project.ActiveWorkflowKey`;server 默认上下文硬编码 `CurrentWorkflow: "intake"`
|
||||
2. `extractDocName` 词表全是 main(bd_)流文档名,无按流归属约束
|
||||
3. 消费端匹配池 `ListWorkflowDocumentsByProject` 仅按 project_id 过滤(跨工作流全量),`selectReadableWorkflowDocument` 双向 contains 模糊匹配取首个命中
|
||||
4. 前端 `resolveTaskTemplateForMessage` 匹配池 `currentProjectDeliverables` 仅按 projectId 过滤;`activeWorkflowKey` 只用于徽标展示
|
||||
|
||||
## 范围
|
||||
|
||||
- 批次1 `feat(intent)`:`ContextSnapshot` 增加 `ActiveWorkflowKey`;`ToSnapshot` 下传;docgov 命中他流文档名时打 `workflow_scope_mismatch` 标记不误填
|
||||
- 批次2 `feat(coordinator+server+projectinstance)`:`ActiveWorkflowTaskKeys` 辅助查询;文档匹配池收窄到激活流;`ErrDocWrongWorkflow` 拦截引导;TRIGGER_TASK 任务键归属校验;enrich 时注入真实 `active_workflow_key`
|
||||
- 批次3 `feat(web)`:`DeliverableItem.workflowKey`;文档列表 API 附带 `workflow_key` 与 `active_workflow_key`;templateMatch 匹配池按激活流过滤,他流点名返回 wrongWorkflow 提示
|
||||
- 批次4:真实环境验收 + 测试报告 + 合回 dev
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不迁移 `document_records` 表(不加 workflow_instance_id 列)
|
||||
- 不改 `production_ready`、不晋升 test/main、不动项目 143
|
||||
- 不改 SWITCH_WORKFLOW 意图本身行为
|
||||
- UI 文档展示列表保持全量(仅匹配池收窄)
|
||||
|
||||
## 渐进安全策略
|
||||
|
||||
`active_workflow_key` 为空或查不到激活实例(存量单流项目、planning 态)→ 不过滤,保持现状行为。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 批次1:intent 快照与工作流词表归属
|
||||
2. [x] 批次2:服务端匹配池收窄与拦截引导
|
||||
3. [x] 批次3:前端模板匹配池收窄
|
||||
4. [x] 批次4:真实环境验收、报告归档、合回 dev
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 激活 main 流说「查看调研报告」→ 命中 main 流文档(正例;修改/生成话术另记路由噪声)
|
||||
- [x] 激活 main 流说「编写项目建议书」(rdev 流文档)→ 拦截 + 引导切换(反例;tasks/run 409 ERR_DOC_WRONG_WORKFLOW)
|
||||
- [ ] 激活 rdev 流后同名操作 → 正常执行(切换后正例;本轮 SWITCH 落库未兑现,记 deferred)
|
||||
- [x] 存量无 active_workflow_key 项目 → 行为不变(回归)
|
||||
- [x] 相关包 `go vet` / scoped `go test -short`、`web: npm test && npm run build` 全绿
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: `~/.cursor/plans/意图填槽工作流作用域修复_dba2ab4c.plan.md`
|
||||
- Handoff:
|
||||
- Test report: `.doc/test-reports/2026-09-21-intent-workflow-scoping-test-report.md`
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
用户在 dev 商务对接实测发现跨工作流误命中。用户在方案确认时选定:严格拦截 + 引导切换;等四问题修复 mutex 释放后独立分支推进。
|
||||
|
||||
- 2026-09-21 收口:已合入 `dev@e0665ca4`,验收报告见 `.doc/test-reports/2026-09-21-intent-workflow-scoping-test-report.md`。
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
title: "工作流作用域权重化"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Cursor
|
||||
branch: feature/workflow-scope-weighting-2026-09-21
|
||||
worktree: .worktrees/workflow-scope-weighting-2026-09-21
|
||||
base_dev_sha: 10aee3feb478c550adc9959f2d3a8d17cd5b48a0
|
||||
write_scope: [internal/workflowscope, internal/intent, internal/server, internal/coordinator, internal/config, internal/sysadmin, web/src, docker-compose.dev.yml, docker-compose.test.yml, docker-compose.main.yml, .env.example, .doc]
|
||||
head_sha: 7723a5515948788602b342cdda1137c90fee311b
|
||||
deployment: deployed
|
||||
cleanup: pending
|
||||
mutex: intent+web+docgov
|
||||
---
|
||||
|
||||
# 工作流作用域权重化
|
||||
|
||||
## 目标
|
||||
|
||||
把「句子里出现他流文档短语就硬拦截」改为「匹配质量 × 工作流关系权重」裁决。激活流优先;只有他流精确命中明显压过激活流时才跨流。只读跨流在查看权限通过后放行并注明归属;写动作仍引导到项目设置切换(跨流写在现架构下不可执行)。`WORKFLOW_SCOPE_MODE` 默认 `strict`,保持现状。
|
||||
|
||||
## 范围
|
||||
|
||||
- 新建 `internal/workflowscope`(开关、关系权重、打分裁决)
|
||||
- 服务端文档读取、意图填槽、前端模板匹配改用同一裁决
|
||||
- compose / `.env.example` / sysadmin 登记开关
|
||||
- dev 真实环境验收与测试报告
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不迁移 `document_records`,不加 `workflow_instance_id`
|
||||
- 不改工作流切换 / 激活接口
|
||||
- 不改 `production_ready`,不晋升 test/main,不动项目 143
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 打分内核与开关
|
||||
2. [x] 服务端只读跨流放行与查看权限
|
||||
3. [x] 意图填槽改打分
|
||||
4. [x] 前端模板匹配改打分
|
||||
5. [x] 开关声明、真实验收、报告、合回 dev
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] strict 模式与现有跨流拦截断言一致
|
||||
- [x] weighted 下激活流精确名压过他流短语,不再误拦
|
||||
- [x] weighted 下只读精确点名他流文档可放行并注明归属;写动作仍拦截
|
||||
- [x] 无查看权限 / 实例已关闭时跨流只读拒绝
|
||||
- [x] 空激活键不过滤
|
||||
|
||||
## 相关链接
|
||||
|
||||
- Plan: `~/.cursor/plans/工作流作用域权重化_411b5e35.plan.md`
|
||||
- Test report: `.doc/test-reports/2026-09-21-workflow-scope-weighting-test-report.md`
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
查看权限:治理实例 `ViewableTaskKeys` 只含当前实例已启用文档。他流任务键不在快照内,不能把它当成「显式隐藏」。判定为:解析失败按 `failClosedAuthz` 拒绝;`ViewableTaskKeys` 为空(实例已关闭)拒绝;键落在当前实例但不可见则拒绝;键不属于当前实例、且调用方已能查看该实例文档时允许只读。
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
title: "个人工程中控台:实时项目看板与离线 HTML 快照"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
owner: Cursor-Auto
|
||||
branch: feature/engineering-dashboard
|
||||
worktree: .worktrees/feature-engineering-dashboard
|
||||
mutex: engineering-dashboard
|
||||
---
|
||||
|
||||
# 个人工程中控台:实时项目看板与离线 HTML 快照
|
||||
|
||||
## 目标
|
||||
|
||||
实现一个独立于产品后台的本地只读中控台,以同一不可变快照驱动实时页面、机器可读 JSON 与单文件 HTML 导出。
|
||||
|
||||
## 范围
|
||||
|
||||
- 聚合 `.doc`、Git/worktree、Docker/Compose、`/ready` 和晋升凭证。
|
||||
- 展示架构、模块、功能、任务、分支、验证和环境实装证据。
|
||||
- 提供 Markdown 搜索、阅读、正反向链接和证据链导航。
|
||||
- 显示来源、新鲜度、degraded 与 drift,不把声明状态当作观测状态。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不接入产品后台、产品数据库或产品权限体系。
|
||||
- 不写文档,不操作 Git、Docker、部署或 Herdr。
|
||||
- 不隐式联网或执行 `git fetch`。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] U1:冻结快照、事实与四轴状态契约。
|
||||
2. [x] U2:实现文档图谱与领域解析器。
|
||||
3. [x] U3:实现 Git 与 worktree 采集。
|
||||
4. [x] U4:实现运行态与部署证据采集。
|
||||
5. [x] U5:实现对账、派生视图与新鲜度。
|
||||
6. [x] U6:实现本地服务、总览与文档导航。
|
||||
7. [x] U7:实现离线导出、脚本、浏览器验收和治理文档同步。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 实时 HTML、离线 HTML 和 JSON 引用同一 `generation_id` 与 `revision_id`。
|
||||
- [x] 计划、实施、验证、实装四轴独立展示。
|
||||
- [x] rdev、dev ahead、main events 分叉三个真实样本按方案输出。
|
||||
- [x] 单源失败时页面仍可用,且显示 stale/error/last-success。
|
||||
- [x] 默认仅监听 loopback,无写操作、凭证暴露、路径越界和远程资源执行。
|
||||
- [x] 导出 HTML 离开仓库后仍可阅读 Markdown,且不嵌入 assets。
|
||||
|
||||
## 相关链接
|
||||
|
||||
- 设计与实施方案:[../../archive/design/2026-09-17-personal-engineering-control-center-plan.md](../../archive/design/2026-09-17-personal-engineering-control-center-plan.md)
|
||||
- Test report: [../../test-reports/2026-09-17-engineering-dashboard-test-report.md](../../test-reports/2026-09-17-engineering-dashboard-test-report.md)
|
||||
|
||||
## 证据 / 备注
|
||||
|
||||
- 实现提交序列见 `feature/engineering-dashboard`(U1→U7)。
|
||||
- 启动:`./scripts/engineering-dashboard.sh serve --repo . --addr 127.0.0.1:8787`
|
||||
- 导出:`./scripts/engineering-dashboard.sh export --repo . --output /tmp/engdash.html`
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "当前受控文档改写被领域关键词改路由到另一交付物"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 当前受控文档改写被领域关键词改路由到另一交付物
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第二轮真实 UI(schema 30)**UI-05 首个失败**:
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-06 用 overlay/p/h 选择器找不到真实文档块"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-06 用 overlay/p/h 选择器找不到真实文档块
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第六轮真实 UI(schema 30):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-13a 用整行 option 文案误判编制负责人"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-13a 用整行 option 文案误判编制负责人
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第16轮真实 UI(schema 30,`dev@dd5671e`):UI-00 至 UI-12 PASS;分类导航修复已实证,UI-13a 已能从「我的私密」切回「流程受控」并打开 reviewer B 权限矩阵。
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "文档职责伪造与保存时重取 ETag 可覆盖并发正文"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: critical
|
||||
---
|
||||
|
||||
# 文档职责伪造与保存时重取 ETag 可覆盖并发正文
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
静态审查与 E2E UI-13 路径暴露两类产品缺陷:
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-05b 缺当前受控文档指示语被路由到 feasibility_reg"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-05b 缺当前受控文档指示语被路由到 feasibility_reg
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第五轮真实 UI(schema 30)**UI-05b 首个失败**:
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-06 编辑弹窗打开期间 hydration 换块 ID 导致保存静默丢稿"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-06 编辑弹窗打开期间 hydration 换块 ID 导致保存静默丢稿
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第十二轮真实 UI(schema 30,dev@4c465d2 基线):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-11 快速 completed 被验收脚本误判为失败"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-11 快速 completed 被验收脚本误判为失败
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第14轮真实 UI(schema 30,`dev@339e871`)在 **UI-11** 失败:页面上传附件并发送「请将此附件归档」后,相邻助手卡片已快速处于 `completed`(文案:已收录补充材料并关联黑板)。
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-07 纯净阅读用 overlay/class*block 找不到真实块"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-07 纯净阅读用 overlay/class*block 找不到真实块
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第八轮真实 UI(schema 30):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-07 在 CSS transition 中间帧采样纯净阅读"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-07 在 CSS transition 中间帧采样纯净阅读
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第九轮真实 UI(schema 30):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-05a 未打开待确认报告导致确认按钮缺失"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-05a 未打开待确认报告导致确认按钮缺失
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第四轮真实 UI(schema 30)**UI-05a 首个失败**:
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "post-restart 项目名同时命中顶栏与侧栏"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# post-restart 项目名同时命中顶栏与侧栏
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第18轮真实 UI(schema 31):main **18 PASS / 0 FAIL**。宿主重启 app 后 `UI_PHASE=post-restart` 在页面**已经恢复项目**时失败,尚未走到 `revision-state`。
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-11 prelim_design 缺 output.md 导致 TASK_INTERRUPTED"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-11 prelim_design 缺 output.md 导致 TASK_INTERRUPTED
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第11轮真实 UI(schema 30,`dev@2a58674`):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "质量门禁自污染与 auto_repair 未启用导致 quality_failed"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 质量门禁自污染与 auto_repair 未启用导致 quality_failed
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
同一整改范围真实 run(与 SSE/幂等现场同源):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-03 质量修复子工作区越界改写根 output.md"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-03 质量修复子工作区越界改写根 output.md
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第13轮 Antigravity 完整 UI(schema 30,dev@8b1a531 基线):UI00–02 PASS,UI-03 真实 PI 终态 `quality_failed`,页面 70 分、缺少必填章节「阻塞信息 / 非阻塞信息」。
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "行动计划表状态列「待续」被质量门禁误判为敷衍"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 行动计划表状态列「待续」被质量门禁误判为敷衍
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第三轮真实 UI(新用户 `mtzzliz5`,新项目,真实 MiniMax):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "项目 reviewer 未同步到受控文档职责"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: critical
|
||||
---
|
||||
|
||||
# 项目 reviewer 未同步到受控文档职责
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第17轮真实 UI(schema 30,`dev@639969f`):UI-00 至 UI-12 PASS。UI-13a 精确职责断言首次暴露产品缺陷:
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-06 全页模糊保存按钮未发出 PATCH"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-06 全页模糊保存按钮未发出 PATCH
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第七轮真实 UI(schema 30):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-11 第二份文档路由到 intake 且 human lease 残留"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-11 第二份文档路由到 intake 且 human lease 残留
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第十轮真实 UI(schema 30):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "任务 run SSE 超时断线后同 turn 误击 DOC_BUSY"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: critical
|
||||
---
|
||||
|
||||
# 任务 run SSE 超时断线后同 turn 误击 DOC_BUSY
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
真实 Antigravity UI-03(dev schema 30):
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
title: "UI-13a 在私密分类下打不开受控工作流文档"
|
||||
status: done
|
||||
status: in_progress
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-22
|
||||
updated: 2026-09-13
|
||||
severity: high
|
||||
---
|
||||
|
||||
# UI-13a 在私密分类下打不开受控工作流文档
|
||||
|
||||
> **W3 UI-rerun 关闭(2026-09-22)**:`status=done`。真实 Playwright 账本 PASS:[`ui-acceptance-results.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results.json)(main UI-00..16)+ [`ui-acceptance-results-post-restart.json`](../test-reports/assets/2026-09-22-docrev-ui-rerun/ui-acceptance-results-post-restart.json)(UI-15)。任务 tip 已合入本地 `dev`;详见 [short-term](../ops/short-term/2026-09-22-docrev-ui-rerun.md) 与 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md)。
|
||||
|
||||
|
||||
## 现象
|
||||
|
||||
第15轮真实 UI(schema 30,`dev@48a4dcb`):UI-00 至 UI-12 全部 PASS,UI-11 快速完成修复已实证 PASS。**UI-13a 在真正权限断言前失败**。
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
---
|
||||
title: "dev rebuild 从临时 worktree 挂载空数据根导致正文投影 409"
|
||||
status: done
|
||||
created: 2026-09-14
|
||||
updated: 2026-09-14
|
||||
severity: critical
|
||||
---
|
||||
|
||||
# dev rebuild 从临时 worktree 挂载空数据根导致正文投影 409
|
||||
|
||||
## 现象
|
||||
|
||||
用户刷新项目 143 后,前端请求:
|
||||
|
||||
```text
|
||||
GET /api/v1/docgov/documents/doc_proj143_intake/content 409
|
||||
DOCUMENT_CONTENT_PROJECTION_MISSING
|
||||
docgov: document content projection missing
|
||||
```
|
||||
|
||||
错误发生在 `projectDocuments.ts` → `controlledDocHydrate.ts` 的受控正文水合链。它不是并发编辑的 `HEAD_CONFLICT`,也不是此前已修过的 canonical hash drift。
|
||||
|
||||
本轮只做只读现场核对与整改设计:没有操作用户会话、没有修改数据库/正文、没有重建共享容器。
|
||||
|
||||
## 结论
|
||||
|
||||
直接根因是 **dev 应用、PI Runner、Cursor Runner 被重建成挂载临时集成 worktree 的空 `data/dev`,而 PostgreSQL 仍沿用原 dev 持久卷**,形成数据库与文件事实源的 split-brain:
|
||||
|
||||
```text
|
||||
PostgreSQL persistent volume
|
||||
document_records.work_dir=/app/data/workspaces/bizdev/intake_1789270446856290128
|
||||
│
|
||||
├─ 主仓 data/dev:output.md 存在,SHA 与 DB/head 一致
|
||||
│
|
||||
└─ 当前容器 /app/data:绑定 /tmp/as-dev-wf409-merge/data/dev,文件不存在
|
||||
```
|
||||
|
||||
`loadControlledDocumentContent` 先取得账本 head,再调用 `InspectProjection`;容器内看不到 `output.md`,因此正确分类为 `MISSING` 并返回 409。前端只是如实暴露后端错误,不是本次根因。
|
||||
|
||||
## 现场证据
|
||||
|
||||
### E1 — 容器挂载源是临时 worktree
|
||||
|
||||
2026-09-14 08:54 UTC 的 `docker inspect shuimu-agent-app-dev`:
|
||||
|
||||
| 项 | 现场值 |
|
||||
|---|---|
|
||||
| Compose working dir | `/tmp/as-dev-wf409-merge` |
|
||||
| Compose config | `/tmp/as-dev-wf409-merge/docker-compose.dev.yml` |
|
||||
| app `/app/data` source | `/tmp/as-dev-wf409-merge/data/dev` |
|
||||
| pi-agent `/app/data/workspaces` source | `/tmp/as-dev-wf409-merge/data/dev/workspaces` |
|
||||
| cursor-agent `/app/data/workspaces` source | `/tmp/as-dev-wf409-merge/data/dev/workspaces` |
|
||||
| app created | `2026-09-14T08:40:44Z` |
|
||||
|
||||
数据库容器的数据仍来自命名卷 `agent-dev-context-pgdata`,不会随 Compose 工作目录切换。由此产生“旧数据库 + 新空文件根”的不一致组合。
|
||||
|
||||
### E2 — 项目 143 数据本身当前完整
|
||||
|
||||
`document_records`:
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| doc_id | `doc_proj143_intake` |
|
||||
| work_dir | `/app/data/workspaces/bizdev/intake_1789270446856290128` |
|
||||
| content_sha256 | `f283ba94c9c037897f021960f51abacee7242c3db8d10f9f2a5e32cde6acf039` |
|
||||
| updated_at | `2026-09-14 05:14:10.302146+00` |
|
||||
|
||||
账本 open version 1 的 head snapshot 302 是人工修订,SHA 同为 `f283...f039`;主仓文件:
|
||||
|
||||
```text
|
||||
/home/weichen/projects/Agent-System/data/dev/workspaces/bizdev/intake_1789270446856290128/output.md
|
||||
size=40075
|
||||
sha256=f283ba94c9c037897f021960f51abacee7242c3db8d10f9f2a5e32cde6acf039
|
||||
```
|
||||
|
||||
同一路径在当前 app 容器内 `stat` 返回 `No such file or directory`。所以无需再次对项目 143 做内容修复;需要恢复正确数据根挂载。
|
||||
|
||||
### E3 — 影响不是单文档
|
||||
|
||||
对 dev 数据库 100 条“非模板且 work_dir 非空”的记录做只读比较:
|
||||
|
||||
| 根目录 | aligned | missing |
|
||||
|---|---:|---:|
|
||||
| 主仓 `/home/weichen/projects/Agent-System/data/dev` | 32 | 68 |
|
||||
| 当前容器挂载 `/tmp/as-dev-wf409-merge/data/dev` | 0 | 100 |
|
||||
|
||||
主仓下的 68 条 missing 包含历史测试/临时路径,不能直接等同于 68 个真实用户缺陷;但当前容器对本次抽样 **100/100 都不可见**,足以确认环境级事故。恢复前任何真实文档读取或 PI 写入都不可信。
|
||||
|
||||
错误根在容器启动后已出现 27 个文件,其中 9 个 CAS blob 的 mtime 为 `08:40:45 UTC`;虽然 08:54 UTC 尚未找到新的 `output.md`,错误根已经不是可直接丢弃的“绝对空目录”,恢复前仍须做完整差异保全。
|
||||
|
||||
只读核对显示 test/main 当前 app 与 PI Runner 仍挂主仓 `data/test`、`data/main`,本轮没有观察到同样的运行事故;但其 Compose 仍使用相对 bind,仍受同一设计缺陷影响。
|
||||
|
||||
### E4 — 健康检查假阳性
|
||||
|
||||
同一时刻 `/health` 与 `/ready` 都返回 200,只检查数据库、schema 和 task store;未验证:
|
||||
|
||||
- 容器绑定的数据根身份;
|
||||
- app 与 runner 是否挂载同一根;
|
||||
- 活跃项目的正文投影是否可达;
|
||||
- 数据库记录与文件根是否属于同一环境实例。
|
||||
|
||||
因此“healthy + schema 33”不能证明文档运行态可用。
|
||||
|
||||
## 根因分析
|
||||
|
||||
### R1 — Compose 相对 bind mount 与调用 worktree 耦合(直接根因)
|
||||
|
||||
`docker-compose.dev.yml` 使用:
|
||||
|
||||
```yaml
|
||||
- ./data/dev:/app/data
|
||||
- ./data/dev/workspaces:/app/data/workspaces
|
||||
```
|
||||
|
||||
Compose 按 project working directory 解析相对路径。`scripts/env-service.sh` 又把 `ROOT_DIR` 定义为脚本所在 worktree 并 `cd` 进去,所以从任何复制/linked worktree 执行 `dev rebuild`,都会把该 worktree 自己的 `data/dev` 当成运行数据根。
|
||||
|
||||
### R2 — 纪律是文档约束,不是可执行门禁
|
||||
|
||||
`scripts/agent-worktree.sh` 只打印“禁止在此目录运行 env-service”,`AGENTS.md` 也规定 worktree 不得操作共享 Docker;但 `env-service.sh` 没有检测 linked worktree、主 worktree、分支、数据根或集成槽位。一次误调用即可静默替换全套容器挂载。
|
||||
|
||||
### R3 — 数据库与文件没有共享存储身份
|
||||
|
||||
数据库使用稳定 named volume;正文使用随调用目录变化的 bind mount。两者没有共同的 environment/storage UUID,也没有启动握手,因此任意一个被指向另一份状态时,进程仍可启动并连接成功。
|
||||
|
||||
### R4 — 账本权威仍被兼容投影阻断
|
||||
|
||||
当前设计声明 ledger head 是权威正文,但 GET 在账本存在时仍要求 `output.md` 投影必须存在且 aligned。于是兼容投影丢失会阻断 UI 读取权威账本。该 fail-closed 对真实 fork 有价值,却把“可安全重建的 missing”与“内容分叉”按同样的可用性后果处理。
|
||||
|
||||
### R5 — 正文更新仍是非原子双写
|
||||
|
||||
人工 PATCH 先提交 PostgreSQL 账本,再单独写 `output.md`;候选 commit/reject 也采用 DB 状态与文件投影分步更新。失败后只依赖同幂等键重试,没有持久 projection job/status 和后台补偿。即使修复本次挂载问题,进程崩溃、权限错误或磁盘故障仍可能再次留下 head 已更新、投影缺失的状态。
|
||||
|
||||
### R6 — 发布验收没有“从不同源码目录 rebuild 后仍接回同一状态”的负例
|
||||
|
||||
既有真实 UI 验收验证过 restart 后恢复,但 restart 不会重新解析 Compose bind mount;本次事故由 rebuild/recreate 触发。现有门禁没有覆盖 linked worktree、临时集成目录或错误数据根的启动拒绝。
|
||||
|
||||
## 为什么会“每次修改后又出现”
|
||||
|
||||
修改本身并不会删除项目 143 正文。本次时间线表明:最新人工修订和主仓 `output.md` 在 05:14 UTC 已一致落盘;08:40 UTC 后续 dev rebuild 把运行容器切到另一份空数据根,刷新才出现 409。
|
||||
|
||||
因此用户感知的“改完再刷新就坏”来自两个事件经常相邻:开发修改 → Agent 在临时 worktree 合并/rebuild → Compose 改绑数据目录。只修某个文档、某个 hydrate effect 或某次 hash 漂移,都无法阻止它复发。
|
||||
|
||||
## 严重度与影响
|
||||
|
||||
`critical`:
|
||||
|
||||
- dev 环境所有受控正文、工作流产物和 runner 工作区均可能不可见或写入错误根;
|
||||
- 错误根上的新输出可能与主仓状态分叉;
|
||||
- health/ready 仍为绿色,集成报告可能产生假 PASS;
|
||||
- test/main 使用同类相对 bind 写法,设计缺陷可横向复制,虽本轮未观察其被错挂载。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- Remediation: [dev 运行数据根隔离与文档投影自愈整改](../remediation/2026-09-14-dev-runtime-data-root-and-projection-remediation.md)
|
||||
- Short-term: [dev runtime data root guard 诊断与设计](../ops/short-term/2026-09-14-dev-runtime-data-root-guard.md)
|
||||
- 前序问题: [项目 143 canonical hash 漂移](./2026-09-14-project143-controlled-content-404.md)
|
||||
|
||||
## 开放问题
|
||||
|
||||
- 恢复前需再次冻结并备份错误根,确认 08:40 UTC 后是否已有新会话、附件、runner 输出或 agent session 写入;08:54 UTC 抽样未发现 `output.md`,不能替代完整差异清单。
|
||||
- test/main 当前挂载源需在实施 Unit A 只读核对;本轮未扩大操作范围。
|
||||
|
||||
## 审查附记(2026-09-14 ~09:23 UTC)
|
||||
|
||||
- 现场复核:`shuimu-agent-app-dev` 仍 created `08:40:44Z`,bind source 仍为 `/tmp/as-dev-wf409-merge/data/dev`;`/health` `/ready` 仍 200,`schema_version=33`。
|
||||
- 主仓 CURRENT 集成槽仍为 `implementer_cursor` / `e2e`。worktree 副本不得写成 idle。
|
||||
- 方案已审查修订:见 [整改方案](../remediation/2026-09-14-dev-runtime-data-root-and-projection-remediation.md)。用户选择事故抢占 + 先改方案再批实施。08:54 的 `f283...f039` 不得再当 Wave 0 硬门槛。
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
title: "临时验证脚本 Path 空字符串拼接导致跨任务取证串味"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
severity: low
|
||||
---
|
||||
|
||||
# 临时验证脚本 Path 空字符串拼接导致跨任务取证串味
|
||||
|
||||
## 现象
|
||||
|
||||
S0.3 真 PI 打样归档时,`rd_design_input_spec-final.md` 一度被写成无关客户的商务对标报告(「掌上无线超声系统 × GE Vscan / Philips Lumify」),而非设计输入规格书终稿。
|
||||
|
||||
## 根因分析
|
||||
|
||||
产品侧小队/工作区创建正常:失败的 `rd_*` 请求因 main-completed 硬 precheck 拒绝,`task_runs.WorkspaceID` 如实为空。
|
||||
|
||||
缺陷在**本地临时取证脚本**(`.doc/test-reports/assets/2026-09-17-rdev-template-depth/run_s0_*.py`)的兜底逻辑:
|
||||
|
||||
1. `ws_id = pi_result.get("workspace_id") or ""` 在响应无该字段时得到空串;
|
||||
2. Python `pathlib`:`Path(bizdev_root) / ""` **坍缩为父目录本身**(无报错);
|
||||
3. 随后 `root.rglob("output.md")` 扫遍共享 `data/dev/workspaces/bizdev/` 全树;
|
||||
4. 「取最长文本」启发式选中历史商务任务终稿并误归档。
|
||||
|
||||
证据:会话内 `task_runs` 失败记录 `WorkspaceID=""`;`Path('/a/b') / '' == Path('/a/b')` 可复现;误归档文件内含 `adhoc_GEVsca_...` 工作区路径。
|
||||
|
||||
## 严重度
|
||||
|
||||
`low` — 仅本地取证脚本;未污染产品库、未改小队/黑板创建逻辑;同轮已用精确工作区路径重归档并随测试报告提交干净终稿。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- 无需产品代码改动。
|
||||
- 经验红线:临时验证脚本禁止「空路径拼接 + 全树 `rglob` + 取最大值」组合;`work_dir`/`WorkspaceID` 为空时必须失败退出,不得扩大搜索范围。
|
||||
|
||||
## 证据
|
||||
|
||||
- 正确终稿:`.doc/test-reports/assets/2026-09-17-rdev-template-depth/rd_design_input_spec-final.md`
|
||||
- 测试报告:`.doc/test-reports/2026-09-17-rdev-template-depth-test-report.md`
|
||||
- 工作区 ID 生成:`internal/squad/workspace.go`(`ws_%s_%d` + UnixNano)
|
||||
|
||||
## 开放问题
|
||||
|
||||
- 无。
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
title: "docgov 变更提案缺少 HTTP 路由"
|
||||
status: resolved
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
severity: medium
|
||||
---
|
||||
|
||||
# docgov 变更提案缺少 HTTP 路由
|
||||
|
||||
## 现象
|
||||
|
||||
引擎侧存在 `docgov.ProposeModification` / `DecideModificationProposal`,但服务端此前仅注册 `POST /api/v1/docgov/proposal/decide`;前端 `App.tsx`「变更方案提议」(`pendingProposal`)为本地模拟。
|
||||
|
||||
## 根因分析
|
||||
|
||||
生命周期三接口与 claim 已注册;变更提案 **propose** 路径从未暴露为 HTTP。
|
||||
|
||||
## 严重度
|
||||
|
||||
`medium` — 不阻塞编制→审核→批准主链;阻塞「认领后小队修改须提案确认」的真实治理。
|
||||
|
||||
## 处置(resolved)
|
||||
|
||||
- 新增 `POST /api/v1/docgov/proposal` → `ProposeModification`
|
||||
- 前端 `proposeModification` / `decideModificationProposal` + App 接线
|
||||
- 单测:`TestServer_DocGovProposeAndDecideHTTP`、`web/src/api/docgov.test.ts`
|
||||
- 任务:`.doc/ops/short-term/2026-09-17-docgov-modification-proposal-http.md`
|
||||
|
||||
## 证据
|
||||
|
||||
- 合入后真实 HTTP 证据见 `.doc/test-reports/assets/2026-09-17-docgov-modification-proposal-http/`
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
title: 文档编制人兼任模式源码核查
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
severity: medium
|
||||
---
|
||||
|
||||
# 文档编制人兼任模式源码核查
|
||||
|
||||
## 结论
|
||||
|
||||
当前 dev 基线 adb48c8 不支持本需求。已有标准三人审批、可选免审批、系统设置白名单可复用,但必须补齐逐文档模式、职责来源和前端多职责。
|
||||
|
||||
## 根因与证据
|
||||
|
||||
1. `internal/projectinstance/duty_mode.go`:partial 拒绝,full 要求三人分离。
|
||||
2. `internal/projectinstance/service.go`:创建者规划权限与激活后冻结已存在。新需求需在这条链上增加总授权,不能只改 UI。
|
||||
3. `internal/docduty/store.go`:HealProjectDocuments 按项目默认职责回填受控文档。`internal/docgov/project_docs.go` 在列表读取时调用;`internal/bizdev/service.go` 在生成后调用。新增逐文档策略必须阻止该链覆盖实例职责。
|
||||
4. `web/src/lib/currentDocRole.ts` 优先返回 author;`docGovActionVisibility.ts` 按单角色显示动作。同人三职会缺审核和批准入口。
|
||||
5. `internal/server/handlers.go` 三个动作端点固定使用相应 action role,并以登录身份调用引擎;`internal/docgov/state_machine.go` 可复用逐步流转。
|
||||
6. `internal/sysadmin/settings.go` 有白名单 bool 设置,但没有本需求 key;存储只保留最后修改人时间,新策略需独立版本与审计。
|
||||
|
||||
以上为静态源码核查,未查询真实用户数据,未执行功能测试,未声称线上已复现或已修复。完整源码映射与实施单元见方案。
|
||||
|
||||
## 关联方案
|
||||
|
||||
[文档编制人兼任审核批准](../remediation/2026-09-17-document-author-only-plan.md)
|
||||
|
||||
## 文档检查
|
||||
|
||||
已检查两级权限、逐文档独立性、full/none 兼容、前后端职责来源、状态与锁、并发授权撤销、成员退出、迁移及回滚。修正一处 docflow 路径为 internal/app/docflow。方案明确区分已知事实与建议口径。
|
||||
|
||||
ce-doc-review 未运行:当前工具目录未提供可调用的 skill invocation 入口;按 ce-plan 的 skill_unreachable 分支记录,不能把本地自检当作独立文档审查通过。
|
||||
|
||||
```yaml
|
||||
fixes_applied: 0
|
||||
proposed_fixes_count: 0
|
||||
decisions_count: 0
|
||||
fyi_count: 0
|
||||
skipped_reason: skill_unreachable
|
||||
skipped_detail: No callable skill invocation interface in this session; local source and consistency checks only.
|
||||
```
|
||||
|
||||
上方计数仅为未运行技能的占位,不代表产品决策已解决。开放问题仍为 R9、R10;用户未答复时保持方案建议,业务实现不得自行视为授权。
|
||||
@@ -1,117 +0,0 @@
|
||||
---
|
||||
title: "首次加载慢:静态资源、字体与初始化请求诊断"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 首次加载性能诊断
|
||||
|
||||
## 结论与适用范围
|
||||
|
||||
当前已复现的主要问题在浏览器加载入口:登录页也下载约 2.82 MB 未压缩 JavaScript;外部 Google Fonts CSS 阻塞页面加载;若用户访问 Vite 3100,首访进一步扩大为 207 个资源请求、12.24 MB。冷缓存与热缓存差异很大,与“尤其第一次慢”一致。
|
||||
|
||||
登录后还有已确认的请求放大和后端重复工作,但没有登录态浏览器瀑布图或 SQL 耗时,不能声称已量化其贡献。用户已确认 3100/8080/8081,系统重启后第一次访问约十数秒;设备、网络与“系统重启”包含宿主机还是仅应用尚未确认;本次未复现用户原始环境的完整等待时间。
|
||||
|
||||
- 主仓读取时 `feature/rdev-core@52f0fbc`;其他 Agent 正在工作,未切换其分支。
|
||||
- 文档独立 worktree 基线为 `dev@d0ef696`。创建前已 fetch;本地 dev 有未推送提交,未 reset/覆盖。
|
||||
- 实测现有 8080/8081/8000 构建入口与 3100 Vite;以资源 hash 为运行产物标识,**没有证据证明容器恰好等于上述源码 commit**。
|
||||
- “首次”定义为新浏览器 context、空 HTTP 缓存;没有重启服务、清空 DB 缓存或重启 Vite,故不是服务/依赖预构建冷启动。
|
||||
- 未登录、没有调用对话/文档写接口;浏览器探针未使用真实用户会话。
|
||||
|
||||
## 实测基线
|
||||
|
||||
工具:隔离 Playwright v1.63.0 Docker 浏览器,host 网络访问既有服务。宿主浏览器缺 libatk,改用本机已有浏览器镜像;未修改应用容器。每个场景一个样本,仅诊断,不是 p95 或交付验收。
|
||||
|
||||
| 场景 | 登录输入框可见 | FCP | 资源数 | transferSize 合计 |
|
||||
|---|---:|---:|---:|---:|
|
||||
| 8080 本机冷缓存 | 662 ms | 664 ms | 4 | 2,857,761 B |
|
||||
| 同 context 再次导航 | 62 ms | 60 ms | 5 | 353 B |
|
||||
| 8080 CDP 10 Mbps / 80 ms 冷缓存 | 2,636 ms | 2,636 ms | 4 | 2,857,761 B |
|
||||
| 同 context 再次导航 | 60 ms | 60 ms | 5 | 353 B |
|
||||
| 8080 CDP 2 Mbps / 80 ms 冷缓存 | 11,776 ms | 11,776 ms | 4 | 2,857,761 B |
|
||||
| 3100 本机冷缓存 | 659 ms | 652 ms | 207 | 12,238,086 B |
|
||||
| 3100 同 context 再次导航 | 162 ms | 160 ms | 208 | 52,253 B |
|
||||
|
||||
transferSize 是浏览器 Resource Timing 可观测资源求和,不含顶层 HTML,不等于全链路抓包流量。输入框可见按导航命令开始至 selector 可见计时,FCP 来自页面 Performance API,两者采样时钟和帧提交不同。CDP 限速为模拟设置,不能代替真实公网 RTT;本机 document TTFB 仍约 1–3 ms。首次/再次均保持已有服务运行,未运行 Vite 冷预构建基准。
|
||||
|
||||
### F1. 入口包过大且未按需加载(高置信)
|
||||
|
||||
- `web/src/main.tsx:2` 静态导入 App;`web/src/App.tsx:98,103,108,145-146` 静态导入导出、系统管理、文件预览等模块;未登录判断直到 `App.tsx:3461`,无法避免入口依赖下载和求值。
|
||||
- `web/src/features/replyExport/download.ts:1` → docx;`web/src/engine/docxRenderer.ts:19-22` → docx、KaTeX、Mermaid;`web/src/engine/xlsxRenderer.ts:1` → XLSX。
|
||||
- `web/src/components/doc/preview/FilePreviewPanel.tsx:19-24` 全部静态导入预览器;DocxViewer、ExcelViewer 各自静态导入重依赖。
|
||||
- 浏览器访问登录页即可观测大 JS。3100 瀑布中含 katex.js 485,944 B、xlsx.js 870,702 B(decodedBodySize)。并非仅仅源码中出现依赖但构建已经排除。
|
||||
- 8080 主 JS `/assets/index-BLnmtk_3.js` = **2,820,055 B**;8081 = 2,805,141 B;8000 = 2,798,137 B。
|
||||
|
||||
因果链:空缓存 → 登录视图与全部工具共入口 → 下载/解析无关依赖 → 网络较慢时登录表单迟迟出现。10 Mbps 下主 JS 下载约 2,373 ms;2 Mbps 首屏约 11.78 秒。没有采集 CPU trace,不能进一步把时间分解成具体库的执行成本。
|
||||
|
||||
### F2. 静态响应无压缩、无明确长缓存策略(高置信)
|
||||
|
||||
- 三个构建入口均携带 `Accept-Encoding: gzip, br` 请求主 JS,响应没有 `Content-Encoding`,`Content-Length` 为原始字节数。
|
||||
- `internal/server/server.go:344-384` 使用 `http.ServeFile`,没有静态压缩协商或显式 Cache-Control。
|
||||
- 同一 8080 JS 离线 gzip 后 **796,146 B**,相对原始包减少约 **71.8%**。这是体积估算,不是已部署优化结果,也不是端到端提速承诺。
|
||||
- 资源有 Last-Modified,没有显式 Cache-Control/ETag。本次再次导航已命中浏览器缓存;**不能写成“完全没有缓存”**。问题是版本化资源缺少可预测的长期缓存契约。
|
||||
|
||||
源站是上述行为,未知用户实际入口是否另有反向代理压缩。优先在真正提供构建资源的层验证和修复。
|
||||
|
||||
### F3. 外部字体 CSS 可放大首次白屏(高置信机制,用户网络贡献待测)
|
||||
|
||||
- `web/index.html:9-15` 的 Google Fonts 是 head 中普通 stylesheet。`display=swap` 控制字体显示,不会让外链 CSS 本身变为非阻塞。
|
||||
- 本机自然请求字体 CSS 耗时 **508 ms**,DOMContentLoaded 609 ms,登录可见 662 ms。
|
||||
- 浏览器拦截并立即失败字体 CSS:登录可见 **210 ms**。Playwright route 会禁用 HTTP cache,因此这个场景不能用于热缓存收益对比,也不能据单样本得出精确净收益。
|
||||
- 控制实验仅让字体 CSS 等待 5 秒再失败,其余请求正常:DOMContentLoaded **5,111 ms**、登录可见 **5,161 ms**。证明该依赖可以把外部等待传到登录首屏,**不表示自然字体请求真的用了 5 秒**。
|
||||
|
||||
### F4. 登录后项目成员扇出并放大会话同步(源码已证实,耗时待测)
|
||||
|
||||
`web/src/App.tsx:524-540` 获取项目后,对每个项目调用成员接口;`:383-387` 每次成员结果用 map 生成新的 projects 数组;`:560-590` 的会话列表 effect 依赖 projects,因此成员返回可重复触发会话列表请求。取消标志仅忽略部分返回,没有 AbortController 终止已发请求。React 批处理可能合并更新,**不能写成固定 N 次会话请求**。
|
||||
|
||||
项目数 N 增大时,初始成员请求为 N,叠加会话重取、setProjects 及本地持久化。`web/src/data/storage.ts:63` JSON.stringify + localStorage.setItem,`App.tsx:343` 随 projects 更新保存。持久化是否成为长任务还须 profile,不能预设为主要根因。
|
||||
|
||||
### F5. 认证有重复查询和同 session 写放大(源码已证实,耗时待测)
|
||||
|
||||
`internal/server/auth_middleware.go:48,62` 已认证并保存 principal;`internal/server/auth_handlers.go:126-139` 的 me 再认证。每次经 `internal/auth/service.go:197-203`、`internal/auth/pg_store.go:335-367` 执行 SELECT session、SELECT status、UPDATE session、GetUserByID。正常 PG me 路径共 8 次认证 DB 操作,加一次权限查询。
|
||||
|
||||
其他鉴权请求也无条件 UPDATE 同一 auth_sessions 行;首屏并发可能放大行锁/连接等待。未采集 pg_stat_activity/锁等待或接口 p95,锁竞争是待验证风险。
|
||||
|
||||
### F6. 文档列表的隐含写修复与轮询叠加(源码已证实,耗时待测)
|
||||
|
||||
`internal/docgov/project_docs.go:59-74` 列表先调用 `HealProjectDocuments`;`internal/docduty/store.go:173-205` 开事务并取得项目 advisory lock(`internal/docduty/revoke.go:111-126`),重复读取创建者/成员,扫描文档,按需逐条 UPDATE,commit 后才正式 SELECT。
|
||||
|
||||
前端 `App.tsx:1507-1545` 每 5 秒为租约同步调用这个完整列表。请求时长超过间隔时可能重叠;相同项目多个标签放大成本。**不能直接删除 heal**:须先补齐创建/成员变更/转交/撤销写路径与历史数据修复闭环。本轮没有用该 GET 做只读探针。
|
||||
|
||||
### F7. 会话列表先聚合消息再分页(源码已证实,耗时待测)
|
||||
|
||||
`internal/ctxmgr/chat_history.go:110-125` 候选会话 JOIN 消息、COUNT、GROUP BY/ORDER BY 后 LIMIT,另取最新消息内容。仅返回少量会话不代表少量消息扫描。`internal/projectworkflow/store.go:171-240` 项目列表也无分页。
|
||||
|
||||
已有 `chat_messages(session_id, created_at)` 索引(`deploy/postgres/goose/00001_baseline.sql:119`);不笼统认定缺索引。先 EXPLAIN/数据量和可见性分析,再决定先分页后统计、索引或摘要。
|
||||
|
||||
### F8. 重启场景补查(用户补充后)
|
||||
|
||||
用户明确 3100、8080、8081 在系统重启后首次进入约十数秒。三种冷态须分开:浏览器 HTTP 缓存、Vite 转换/依赖缓存、Go/DB/代理启动就绪。重启若不改变构建 hash,并不会自动清掉浏览器持久 HTTP 缓存;不能直接用新 context 测量解释全部重启现象。
|
||||
|
||||
现存容器启动记录:dev StartedAt `2026-09-17T07:00:38.127811581Z`,打印“监听地址”于 `07:00:38.293728694Z`(约 **166 ms**);test StartedAt `06:20:05.243037366Z`,打印监听于 `06:20:05.384607542Z`(约 **142 ms**)。这是已有 DB 就绪条件下的一次启动、且日志先于真正 ListenAndServe,**不是 host reboot→ready 时间**;但未支持“Go 每次初始化必然十几秒”。
|
||||
|
||||
`cmd/server/main.go:41-50` 的初始化在监听前,`internal/bizdev/service.go:69-114` 包括 DB Ping/迁移/成员补齐/seed;DB连接段 timeout 5 秒,后续 seed 使用 Background,缺少分阶段耗时。`internal/app/app.go:355` 的 Runtime.Start 幂等,入口重复调用不会重复启动 worker,不能据此误判双倍启动。
|
||||
|
||||
Compose app healthcheck 每 10 秒、start_period 20 秒;start_period 是失败宽限窗口,**不代表强制等待20秒**。若代理/运维脚本等健康状态才放流,则探测周期可能影响可见就绪,需要对齐宿主启动、DB healthy、app listen、ready、首次请求时间。3100 的无缓存 Vite 预构建/按请求转换为独立候选,8080/8081 构建产物不存在 Vite 首次编译。
|
||||
|
||||
隔离 Vite 在 3199 使用独立空 cacheDir,同源码、未重启宿主/DB:监听准备 43 ms,首访登录可见 **1,580 ms**、207 资源/14,445,631 B,再次 171 ms。服务先启动、浏览器随后连接,部分预构建可能已在导航前完成;该值不是“启动到首屏”总时间。支持开发冷态有额外成本,但本机未复现自然网络十数秒;不得仅靠 warmup 宣称已解决 8080/8081。证据见 `../test-reports/assets/2026-09-17-initial-load-performance/vite-cold.json`。
|
||||
|
||||
本轮不重启正在使用的共享服务;U1/U7 纳入计划中的隔离重启矩阵和阶段计时。没有把服务冷启动排除在用户需求之外。
|
||||
|
||||
## 已排除与未证明
|
||||
|
||||
- 本机静态 HTML TTFB 约 1–3 ms;这组未登录测试并非后端生成首页耗时数秒。
|
||||
- 没有请求产品 PI Runner,因此本次首屏慢不能归因于大模型冷启动。
|
||||
- 服务监听前迁移/种子初始化(`cmd/server/main.go:41-50,84-85`;`internal/bizdev/service.go:69-114`)只解释重启就绪,不等于每个新浏览器首访。
|
||||
- 没有用户重启时的 FRP/公网瀑布、登录后基线、慢 CPU profile、数据库 EXPLAIN;不对这些项宣称已复现。
|
||||
- 基线现有测试以功能为主;本轮未发现首屏资源预算/冷缓存性能门禁。未运行业务测试,因为没有业务代码变更。
|
||||
|
||||
## 关联整改与证据
|
||||
|
||||
- [改进方案](../remediation/2026-09-17-initial-load-performance-plan.md)
|
||||
- [诊断测量报告](../test-reports/2026-09-17-initial-load-performance-baseline.md)
|
||||
- [完整浏览器数据](../test-reports/assets/2026-09-17-initial-load-performance/browser.json)
|
||||
- [受控实验](../test-reports/assets/2026-09-17-initial-load-performance/controlled.json)
|
||||
- [静态响应摘要](../test-reports/assets/2026-09-17-initial-load-performance/assets.json)
|
||||
@@ -1,180 +0,0 @@
|
||||
---
|
||||
title: "系统全面体检:任务收口、缺陷与未启用功能审计"
|
||||
status: done
|
||||
created: 2026-09-17
|
||||
updated: 2026-09-17
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 系统全面体检(2026-09-17)
|
||||
|
||||
> 范围:① 规划未实现 / 需变更 / 实施中任务;② 现存与潜在 bug;③ 已实现但未启用或未测试的功能。
|
||||
> 方法:文档 SSOT 盘点(CURRENT / FEATURE-MATRIX / gap-matrix / short-term / long-term / backlog / ADR / handoff)+ Go 全量 vet/build/test + 前端 test/build + 特性开关与环境配置交叉核对。只读审计,未实施任何修改。
|
||||
> 基线验证:`go vet ./...` 与 `go build ./...` 全绿;`go test -short -count=1 ./...` 62 包全 ok;`web` npm test(380+32)与 build 通过。
|
||||
|
||||
---
|
||||
|
||||
## 一、任务状态盘点
|
||||
|
||||
### 1.1 实施中(in_progress)
|
||||
|
||||
| # | 任务 | 位置 | 剩余工作 |
|
||||
|---|------|------|----------|
|
||||
| T1 | partial/deferred 全量收口总控 | `.doc/ops/short-term/2026-09-16-partial-deferred-completion.md`(owner Cline) | W5(SWBOOT-10 真实现 + 真实 PI + UI 二次验收)、W6(FAV shadow→live 放量)、W7(D7 按 ADR 整改,待合规签字)、逐行升 done |
|
||||
| T2 | Control Center 个人中控台 | 2026-09-19 已移出本仓库 | 进度管理改由独立项目承担;本仓库不再保留该模块 |
|
||||
| T3 | 纯软件项目自举 W5b | `.doc/ops/long-term/2026-09-14-software-project-bootstrap-implementation.md` | SWBOOT-10 受控执行器(真 patch/merge)未启动,需独立安全评审,当前 fail-closed stub |
|
||||
|
||||
### 1.2 已规划未开始
|
||||
|
||||
| # | 任务 | 位置 |
|
||||
|---|------|------|
|
||||
| T4 | 首次加载性能 U1/U3–U7 | `.doc/remediation/2026-09-17-initial-load-performance-plan.md`(仅 U2 done:主 JS 传输 2.82 MB→~624 KB) |
|
||||
| T5 | 选择性模块解耦 M4–M6 | `.doc/ops/long-term/2026-09-14-selective-module-decoupling.md`(planned,owner=TBD) |
|
||||
| T6 | 产品 backlog:B5 报价复核、A5/A6 小队降级与 trace、A7 中文注释迁移、D5 KB 按环境隔离评估 | `.doc/backlog/chat-agent-p6-backlog.md`(均无任务文件) |
|
||||
| T7 | `TestReconcile_LegacyRepair_PG` 工程测试债 | gap-matrix DOC-CONTENT-CANONICAL-HASH-DRIFT 行(需隔离 PG,本机无) |
|
||||
| T8 | IAM 收尾开放项:410 退役产品拍板、R13 全量清单勾选 | handoff `2026-09-16-phase3-leftover-closeout.md` |
|
||||
|
||||
### 1.3 部分完成(partial,剩余关闭条件)
|
||||
|
||||
| 行 | 剩余关闭条件 |
|
||||
|----|--------------|
|
||||
| 纯软件项目自举 | SWBOOT-10 非 stub(W5b)+ 真实 PI 全链路 + UI 二次验收 |
|
||||
| FAV | W6 shadow 已合;live 未放量(staging→artifact→publication 各 ≥7 天观察窗) |
|
||||
| Control Center | 2026-09-19 已移出本仓库,不再作为本仓库关闭条件 |
|
||||
| 首次加载性能 | U1/U3–U7 |
|
||||
| 文档可靠性试点 | M1 结论「停止扩面」;M2(U5–U12)明确禁止开工,真实 PI/浏览器验收未勾 |
|
||||
|
||||
### 1.4 deferred 待决策
|
||||
|
||||
- **D7 对话数据治理**:ADR `2026-09-17-d7-chat-data-retention.md` 仍 `pending-compliance-signoff`;W7 盘点未发现违规;签字前禁止物理删除。
|
||||
- **`SEMANTIC_SUMMARY_REPLACE`**:决策默认不启用;启用须另开授权 + fail-closed 灰度。
|
||||
- **`MULTI_INTENT_PLAN_TIER` 升 confirm**:W4 证据闭环,升级需独立授权;永不默认 full。
|
||||
|
||||
### 1.5 文档漂移 / 矛盾(文档债)
|
||||
|
||||
| # | 漂移 | 涉及文件 |
|
||||
|---|------|----------|
|
||||
| D-1 | PU8 四份契约文件仍 `status: in_progress`,但 U9–U12 已升 done、报告已归档 | `.doc/ops/long-term/2026-09-16-pu8-u9/u10/u11/u12-*.md` |
|
||||
| D-2 | ADR modular-monolith-decoupling 仍「提议,等待用户确认」,但 Phase 1/2 已落地并被当作已确认结论引用 | `.doc/adr/2026-09-14-modular-monolith-decoupling.md` |
|
||||
| D-3 | audit/INDEX.md 与 remediation/INDEX.md 末行称首次加载性能「方案未实施」,与 U2 已验收矛盾 | 两个 INDEX.md(**本审计已顺手修正为准确表述**) |
|
||||
| D-4 | handoff `2026-09-15-conversation-intent-dual-tab.md` 的「未完成」已被后续 PASS 覆盖但未回标 | 该 handoff |
|
||||
| D-5 | backlog D3/D7 条目与 W2 done、W7/ADR 草案并存,backlog 未同步 | `.doc/backlog/chat-agent-p6-backlog.md` |
|
||||
| D-6 | PROJECT.md §9「剩余 blocker」表述与 gap-matrix「门禁已签、production_ready=yes」口径冲突 | `PROJECT.md` |
|
||||
|
||||
---
|
||||
|
||||
## 二、Bug 清单
|
||||
|
||||
### 2.1 确认 bug(有明确证据)
|
||||
|
||||
**后端**
|
||||
|
||||
| ID | 描述 | 证据 | 严重度 |
|
||||
|----|------|------|--------|
|
||||
| B-1 | **SSE 聊天流被全局 WriteTimeout=120s 强杀**:`server.go:350` 的 WriteTimeout 是绝对期限;`handleChatStream`(`sse.go:129`)从不调用 `extendSSEWriteDeadline`、无心跳,该机制只接到了 run-events 订阅端点。任何 >120s 的聊天回合(长 PI 推演常见)必断流 | `internal/server/server.go:350`、`internal/server/sse.go:46-64,129` | high |
|
||||
| B-2 | **`POST /tasks/run/stream` 同样无 deadline 延长/心跳**,且断线后无法续订:`sse.go:390` 写死 `Subscribe(created.RunID, 0)`,不接受 `after_seq` | `internal/server/sse.go:305-424,390` | high |
|
||||
| B-3 | `handleRunTaskStream` **静默吞 JSON 解析错误**:`_ = json.NewDecoder(r.Body).Decode(&req)`,畸形 body 以空请求走默认 `TaskKey="intake"`,可能误启动 intake 任务 | `internal/server/sse.go:315,362-364` | medium |
|
||||
| B-4 | `handleRunTaskStream` **Flush 200 SSE 头之后才做会失败的操作**(CreateAndStart/Subscribe),失败时往 SSE 流里写 JSON 错误体;同文件 chat 路径明确「授权必须在 Flush 前」,task 路径未对齐 | `internal/server/sse.go:355-360,383-393` | medium |
|
||||
|
||||
**前端**
|
||||
|
||||
| ID | 描述 | 证据 | 严重度 |
|
||||
|----|------|------|--------|
|
||||
| B-5 | **会话窗口缓存 key 不一致**:读/初次写带 `userId` 前缀,但 `loadOlder`/`loadFullDay`/`jumpToDate`/`loadDayForAnchor`/`appendLiveMessage` 等 7 处后续写入不带前缀 → 刷新/切会话恢复到旧窗口;且 LRU 驱逐只用无前缀 key,带前缀缓存永不驱逐,localStorage 只增不减 | `web/src/hooks/useChatWindow.ts:84,100,136,235,271,315,365,416,439,471`、`web/src/data/storage.ts:164-176` | high |
|
||||
| B-6 | **mount 时 IndexedDB 恢复用陈旧快照整体覆盖 deliverables**:捕获 mount 闭包、非函数式 set,resolve 前新增的 deliverable 被静默丢弃(旁边已有 `deliverablesRef` 未用) | `web/src/App.tsx:326-336` | medium |
|
||||
| B-7 | `useTaskRunStream` 返回**伪 ref**(每渲染新建对象、快照值非 live),且全仓库无消费方——误导性 API | `web/src/hooks/useTaskRunStream.ts:96` | low |
|
||||
|
||||
### 2.2 高风险隐患
|
||||
|
||||
| ID | 描述 | 证据 |
|
||||
|----|------|------|
|
||||
| R-1 | **聊天会话无归属校验**:`getOrCreateSession` 仅凭客户端传入 `session_id` 返回既有内存会话,随后直接覆盖 `sess.UserID`;非项目会话(ProjectID==0)无任何授权关卡,内存 Messages/Facts 可进入他人 Prompt 与 SSE。缓解:session ID 为纳秒时间戳不易猜 | `internal/server/server.go:394-415`、`handlers.go:181`、`sse.go:187`、`stage_access_helpers.go:251-253` |
|
||||
| R-2 | **18 个非测试文件 `rows.Next()` 循环后未查 `rows.Err()`**,中途断连静默截断结果集(ctxmgr 历史/窗口/搜索、docgov engine、freedoc、storage/cas、`cmd/document-content-reconcile` 漏检会让 reconcile 漏报文档) | 如 `internal/ctxmgr/chat_history.go`、`internal/docgov/engine.go`、`cmd/document-content-reconcile/main.go:82` |
|
||||
| R-3 | 事件 dispatcher `Handlers` map **写持锁、读不持锁**(当前仅启动期注册则良性,动态注册即 race) | `internal/events/worker.go:87,154,234` |
|
||||
| R-4 | `memTurns` 全局幂等表只增不删且跨实例共享,长期运行内存缓增、测试间可能串扰 | `internal/ctxmgr/chat_turns.go:169` |
|
||||
| R-5 | `internal/docrevision/pg_store.go:68-208` 十余处 `_ = json.Unmarshal(...)`,账本 JSONB 损坏时静默零值化 | 同左 |
|
||||
| R-6 | 后台 ticker goroutine 无关停通道(通知提醒、vault Drain 错误被丢弃、bizdev 心跳用 `context.Background()`),`Shutdown` 未覆盖 | `notification_reminder_loop.go:15`、`vault.go:63`、`bizdev/service.go:682` |
|
||||
| R-7 | SSE 重连对 401/404 无 fail-fast:任何错误一律退避重连 40 次(~3 分钟)期间 UI 一直 thinking;`streamChat` 对畸形 data 帧直接抛错中断整条流 | `web/src/api/taskRuns.ts:108-140`、`api/chatStream.ts:122` |
|
||||
| R-8 | 组件卸载/登出不 abort 任务流,在途 SSE 继续写 localStorage | `web/src/App.tsx:595,2804` |
|
||||
|
||||
### 2.3 环境 / 配置缺陷
|
||||
|
||||
| ID | 描述 | 证据 | 严重度 |
|
||||
|----|------|------|--------|
|
||||
| E-1 | **main 环境 app `ENV=prod` 与 events `ENV=main` 不一致**:事件信封以 `Environment="prod"` 写入,而 `event_consumer_modes` 只种子 dev/test/main 三行 → app 侧 `WriterLive("prod")` 恒 false(in-process 直连不退出),events worker 按 'main' 判定 → **main 存在双写或 durable 管道空转风险**(取决于 main 行 mode)。dev/test 两服务 ENV 一致,无此问题 | `docker-compose.main.yml:90,160`、`internal/app/docflow/commands.go:276`、`goose/00040:55-59`、`internal/events/dispatcher.go:308-313` | **critical(main 专属)** |
|
||||
| E-2 | **main schema 落后两版(47 vs dev 49)**:00048 给 projects 加 13 列,当前 HEAD 代码直接 SELECT/INSERT 这些列;00049 建 system_settings。若把 dev HEAD 镜像升 main 而不先跑迁移,项目工作流查询/系统设置 API 直接 SQL 报错。**main 晋升顺序必须 events(跑迁移)先于 app** | `goose/00048`、`goose/00049`、`internal/projectworkflow/store.go:76,113` | high(晋升窗口) |
|
||||
| E-3 | `MULTI_INTENT_PLAN_TIER` 未在任何 compose environment 声明(configs/.env 设了也传不进容器);test/main 连 U9–U12 flag 都未声明 → 容器内锁死 legacy,授权升级时需先改 compose | `docker-compose.*.yml` | medium |
|
||||
| E-4 | `CURSOR_RUNNER_URL` 三环境 compose 都注入但代码零读取;cursor-agent 容器是 alpine 占位,cursor-cli 后端容器部署不可达 | `docker-compose.*.yml` | low |
|
||||
| E-5 | `ENABLE_DEV_IMPORT` 不在任何 compose/.env.example;且判断把 `cfg.Env==""` 也算 dev——配置缺失时导入门禁自动放开 | `internal/server/chat_window_api.go:171` | medium |
|
||||
| E-6 | `SEED_DEMO_USERS` 仅 test compose 显式 false;dev 依赖默认播种(demo 密码 123456),main 靠代码 `Env!="dev/test"` 兜底,主 compose 未显式关闭 | `docker-compose.test.yml:91`、`internal/auth/bootstrap.go:67-116` | low |
|
||||
| E-7 | `INTENT_V2_DECISION_TIER` 非法值回退 `query`(激进),与 `MULTI_INTENT_PLAN_TIER` 回退 `legacy`(保守)策略不一致 | `internal/intent/flags.go:47-64` | low |
|
||||
| E-8 | `publisher_gate_test.go:16` 读 `FAV_PUBLISHER_ENABLE`(少 D),与正式变量名不符,该测试门永远走默认分支 | `internal/artifactvault/publisher_gate_test.go:16` | low |
|
||||
| E-9 | main compose 的 system-db initdb 只挂 00001_baseline.sql,与 dev/test 不一致;新建卷时初始脚本漂移(依赖 events 启动迁移补齐) | `docker-compose.main.yml:23` | low |
|
||||
|
||||
---
|
||||
|
||||
## 三、已实现但未启用 / 未测试的功能
|
||||
|
||||
### 3.1 特性开关封存(实现完整,全环境 off)
|
||||
|
||||
| 功能 | 实现位置 | 状态与门禁 |
|
||||
|------|----------|-----------|
|
||||
| FAV 事件订阅者 | `internal/app/fav/subscriber.go` | 三重硬门禁:cmd/events 刻意不注册、registry fail-closed、SetMode 拒绝非 off;仅 ObserveShadow 可达 |
|
||||
| FAV 发布器 | `internal/server/vault.go:18-67` | `FAV_PUBLISHER_ENABLED=false` 三环境显式;且 VAULT_* 三变量 compose 全未声明,容器内即使开 flag 也会静默 return(E-类:实际不可误开,属设计内封存) |
|
||||
| FAV 降级读 | `internal/docquery/service.go:70` | `FAV_DEGRADED_READ=false` 红线保持 |
|
||||
| 多意图 PlanTier shadow/auto_read/confirm | `internal/app/intentflow/turn.go` | 容器内锁死 legacy(见 E-3) |
|
||||
| U9–U12 扩面 | `intentflow/expansion.go`、`mux.go` | 全 false;dev compose 已声明可调,test/main 未声明 |
|
||||
| 意图 V2 shadow/decision | `internal/intent/shadow_v2.go`、`v2_decision.go` | 三环境显式 false |
|
||||
| 语义摘要 shadow | `internal/ctxmgr/semantic_summary.go:216` | 默认 off,且仅 AGENT_BACKEND=pi-agent 时挂载 |
|
||||
| PI change-report 叙事 | `internal/docrevision/narrative.go:68` | 默认 off,仅确定性 fallback(不得冒充完整 PI) |
|
||||
| artifact-vault CLI | `cmd/artifact-vault/main.go` | 未部署 stub |
|
||||
| eventmode cutover CLI | `cmd/eventmode/main.go` | 硬门禁仅 dev 可用(`internal/events/cutover.go:13`) |
|
||||
|
||||
### 3.2 死代码 / 机制先行无消费方
|
||||
|
||||
| # | 项 | 位置 |
|
||||
|---|----|------|
|
||||
| X-1 | `SEMANTIC_FALLBACK_ENABLED` 死 flag:无任何业务消费方,仅 sysadmin 展示;三环境 compose 都在设一个没用的变量 | `internal/intent/flags.go:43`、`internal/app/app.go:285` |
|
||||
| X-2 | `SEMANTIC_SUMMARY_REPLACE` 读取后 `_=` 显式丢弃,刻意永久未接线 | `internal/ctxmgr/semantic_summary.go:257` |
|
||||
| X-3 | goose 00048 三张新表 `project_source_bindings`/`repo_path_allowlist`/`project_type_workflows` 无代码消费方(swboot 目录硬编码内存版,RepoAllowlist 为 stub) | `internal/swboot/catalog.go:92,118`、`repo_allowlist.go` |
|
||||
| X-4 | `system_settings` 白名单 6 键全部无业务消费方——可写不生效,纯机制先行 | `internal/sysadmin/settings.go:57-66` |
|
||||
| X-5 | 前端死组件:`DocumentNotificationList.tsx`(含已读回写,功能完整无挂载点)、`WorkflowPrerequisiteBanner.tsx`、`user/SettingsModal.tsx`(已被 UserSettingsModal 取代);死 API:`api/projectWorkflow.ts:71 activateWorkflow`;`data/storage.ts:141 saveMessages` deprecated no-op | web/src 各文件 |
|
||||
| X-6 | `useTaskRunStream` 伪 ref(同 B-7) | — |
|
||||
|
||||
### 3.3 测试盲区
|
||||
|
||||
| # | 盲区 | 说明 |
|
||||
|---|------|------|
|
||||
| S-1 | `TestReconcile_LegacyRepair_PG` 从未执行 | 要求隔离 PG 且硬拒绝 5433/5434/5435;canonical-hash 修复链路零自动化验证(gap-matrix 已记测试债) |
|
||||
| S-2 | 两个「永久跳过」 | `taskstream_test.go:189`(功能已删,测试成死代码应删除);`plan_owner_test.go:125`(重定向跳过) |
|
||||
| S-3 | 无测试的 cmd 入口 | `cmd/server`、`cmd/events`、`cmd/artifact-vault`、`cmd/dataset`、`cmd/eventmode`、`cmd/recategorize`、`cmd/document-revision-backfill`(仅 bizdev-cli、document-content-reconcile 有);`internal/observability`、`internal/workflow` 无测试文件 |
|
||||
| S-4 | **E2E 默认全不跑**:web/e2e 9 个 spec 全部被环境门禁(`RUN_UI_ACCEPTANCE=1`/`DOCREV_E2E_BASE_URL`/`INTENT_DUAL_TAB=1`),默认 `playwright test` 实跑 0 用例;`test:ui-acceptance` script 只覆盖 1 个 spec,其余 8 个无 script 入口 | web/e2e/、web/package.json:11 |
|
||||
| S-5 | 409 信封处理只覆盖部分消费方:projectMembers、freeformDoc、createTaskRun、chatSessions upsert 等 409 只能裸报错(与 FEATURE-MATRIX hardening backlog 一致) | `web/src/api/projectMembers.ts`、`freeformDoc.ts:177`、`taskRuns.ts`、`chatSessions.ts` |
|
||||
| S-6 | 前端 bundle 大 chunk 未分割(mermaid/katex/xlsx/docx 各成 >500 kB chunk,已有 precompress 缓解) | vite build 警告 |
|
||||
|
||||
---
|
||||
|
||||
## 四、结论与优先级
|
||||
|
||||
**总体判断**:发布门禁与 FEATURE-MATRIX 的 `done/partial/deferred` 口径与代码实况基本一致,未发现「stub 冒充验收」类违规;质量门禁(vet/test/build)全绿。主要风险集中在三处:
|
||||
|
||||
1. **E-1(main ENV 不一致 → 双写/空转)是唯一 critical 级发现**,且只在 main 环境存在, dev/test 的「healthy」不能证明 main 事件链路正确。
|
||||
2. **SSE 120s 断流(B-1/B-2)直接影响长任务可用性**,是用户可感知的现存 bug。
|
||||
3. **封存面(FAV/多意图 tier/U9–U12/语义摘要/PI 叙事)实现完整但容器内不可调或硬门禁封存**,红线达标,但授权放量时会发现 compose 层缺失(E-3)与若干死接线(X-1/X-2)。
|
||||
|
||||
详细整改顺序见 [remediation 方案](../remediation/2026-09-17-system-health-remediation-plan.md)。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- Remediation: [2026-09-17-system-health-remediation-plan.md](../remediation/2026-09-17-system-health-remediation-plan.md)
|
||||
|
||||
## 证据
|
||||
|
||||
- `go vet ./...` / `go build ./...` / `go test -short -count=1 ./...`(62 包 ok)/ `cd web && npm test && npm run build`:2026-09-17 全绿。
|
||||
- 文中所有 `文件:行号` 引用均为 2026-09-17 dev 分支工作区实测。
|
||||
|
||||
## 开放问题
|
||||
|
||||
- E-1 的修复取向(app 改 `ENV=main` vs 事件信封/consumer mode 键改用部署名)需架构决策。
|
||||
- D7 合规签字、`MULTI_INTENT_PLAN_TIER` 升 confirm、FAV live 放量均需用户显式授权,不在本整改自动范围内。
|
||||
- configs/.env.dev/.env.test/.env.main 实际文件未读取(含密钥);若偏离 example 模板,E-3/E-4/E-6 结论需复核。
|
||||
@@ -1,130 +0,0 @@
|
||||
---
|
||||
title: "系统深度体检审计(2026-09-19,dev@e8ed33b)"
|
||||
status: done
|
||||
created: 2026-09-19
|
||||
updated: 2026-09-19
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 系统深度体检审计(2026-09-19)
|
||||
|
||||
> 只读审计,未修改业务代码。分支 `docs/system-deep-audit-2026-09-19`,基点 dev@e8ed33b。
|
||||
> 方法:go vet / go test -short 静态基线 + 五路并行深潜(后端 server/chat、docgov/events/工作流/迁移、前端 web、配置 flag/死代码、安全鉴权)。
|
||||
|
||||
## 一、总体结论
|
||||
|
||||
- **静态基线健康**:`go vet ./...` 零告警;`go test -short ./...` 55 包全 PASS;全仓 TODO/FIXME 仅 2 处非实质。
|
||||
- **四条已声明红线全部核实一致**:`MULTI_INTENT_PLAN_TIER=legacy`、`SEMANTIC_SUMMARY_REPLACE` 未接线、`FAV_DEGRADED_READ=false`、SWBOOT-10 fail-closed stub——代码与三环境 compose 均对齐,无漂移。
|
||||
- **IAM 主链路复核成立**:路由统一挂鉴权中间件、SQL 全参数化、token 哈希存储、错误出参有内部信息过滤。但存在 dev/test 兜底与端点级鉴权缺口(见 S1/S2)。
|
||||
- **本次新发现**:2 项 critical(后端数据竞态 + docgov 吞错)、10 项 high、若干 medium/low。其中 3 项被两路独立审查交叉命中(见 ★ 标记),可信度最高。
|
||||
- FEATURE-MATRIX 已声明的 partial/deferred(rdev、SWBOOT、FAV、D7、首载性能)不在本次重复申报范围;本次发现均为**新增**缺口。
|
||||
|
||||
## 二、Critical(发布前必须评估)
|
||||
|
||||
### C1 ★ docgov 持久化全链路 fire-and-forget 吞错;fencing token 未读回
|
||||
`internal/docgov/lease.go:460-467, 485-490`;`internal/docgov/engine.go:318, 392, 405, 470, 477, 650, 743, 750, 1081-1134`
|
||||
|
||||
租约获取/续约/回收、正文哈希、认领状态、提案决定及**全部审计日志**均为 `_, _ = e.pool.Exec(...)` 静默吞错:
|
||||
- 审计 INSERT 失败 → 合规事件永久丢失,无重试无告警;
|
||||
- 租约 UPDATE 失败 → 内存与 DB 分叉,重启后可并行编辑同一文档;
|
||||
- `lease.go:485` 用 `context.Background()` 脱离请求生命周期;
|
||||
- `loadDocumentFromDBLocked` 的 SELECT 列表**不含 `lease_fencing_token` 列**(00034 迁移已建列)→ 进程重启后 fencing 语义完全失效(合法持锁者被误判 stale,或 stale 写者被放行——两个方向都有缺口)。
|
||||
|
||||
**建议**:持久化失败必须返回 error 或 slog.Error+指标;审计写入失败进重试队列;lease SELECT 补 fencing 列;persistLeaseLocked 失败回滚内存状态。
|
||||
|
||||
### C2 ★ Session 全字段数据竞态 + 跨项目污染
|
||||
`internal/chat/session.go:275-277`;`internal/server/server.go:432-435`;`internal/server/handlers.go:196-198`
|
||||
|
||||
- `Messages`/`UserCtx`/`LastAccessedAt` 的读写锁粒度碎片化:SSE 路径持 `execMu`,而 `hydrateVisibleHistory`、`handleGetProject`、`cleanStaleSessionsLocked`、`server.go:435` 均不持锁。并发 SSE+REST 同会话时 `go test -race` 可复现 data race。
|
||||
- `handleChat` 无锁写 `sess.ProjectID = req.ProjectID`,同一 sessionID 被不同项目请求交错时跨项目串扰。
|
||||
|
||||
**建议**:Session 加 `sync.RWMutex` 统一保护;ProjectID 改为请求级参数不写回共享 sess。
|
||||
|
||||
### C3 SSE WriteTimeout=120s 硬杀长任务 + 心跳 goroutine 生命周期不一致
|
||||
`internal/server/server.go:352-355`;`internal/server/sse.go:252-271`
|
||||
|
||||
全局 `WriteTimeout: 120s`;SSE 靠 45s 续期+15s 心跳兜底,心跳被中间代理吞掉时长 LLM 回合(dialogueTimeout=3min)被强杀。非流式 `handleRunTask` 同步执行数十分钟任务,120s 必然截断响应(业务已执行、客户端收不到结果 → 幂等重试造成重复执行观感)。心跳 goroutine 模式与 `handleTaskRunEvents`(主循环 select,无此问题)不一致。
|
||||
|
||||
**建议**:长任务端点异步化(提交+轮询/SSE);心跳并入主 select 或 WaitGroup 收敛。
|
||||
|
||||
### C4 工作流计划保存跨语句竞态 + completed_by 错填
|
||||
`internal/projectinstance/service.go:185-190`;`internal/projectinstance/stage_store.go:132-138`
|
||||
|
||||
- `SaveWorkflowPlan`:upsert 与 bump revision 两条独立事务,并发下同版本号先互相覆盖 plan 再一方 bump 失败 → **版本号与 plan 内容错位落库**。`Activate` 的 token 前置校验与激活事务间存在 TOCTOU。
|
||||
- `completed_by = (SELECT activated_by ...)`:最终阶段完成的归属人被错填为激活人,审计归属错误。
|
||||
|
||||
**建议**:upsert+bump 同事务 + `FOR UPDATE` 锁 project 行;completed_by 显式传当前操作者。
|
||||
|
||||
## 三、High(建议进入 short-term 整改)
|
||||
|
||||
| # | 发现 | 位置 | 要点 |
|
||||
|---|------|------|------|
|
||||
| H1 ★ | dev/test 未认证静默兜底为 user id=1 | `internal/server/auth_middleware.go:48-51` | `Env=dev|test` + `AllowInMemory` + 无 ContextDB 时,无 token 请求静默识别为 id=1(管理员)。main 已被 `validateProductionSecrets` 兜住。建议:兜底路径加审计日志+启动告警;中期删除 legacy 兜底 |
|
||||
| H2 ★ | docgov 批注/审计端点无资源级鉴权且信任请求体身份 | `internal/server/handlers.go:858-940, 534-552` | 任意登录用户读任意文档批注/审计;`AddComment` 直接用 `req.UserID/UserName/UserRole` 可伪造他人身份;`Claim` 角色由客户端自选。两路审查交叉命中。建议:actor 一律取 principal;读类端点加项目成员校验 |
|
||||
| H3 ★ | 会话查询类端点水平越权 | `chat_turn_api.go:12-45`;`handlers.go:947-981, 429-451` | `handleGetChatTurn`/`handleListChatSessions`/`handleGetUserContext` 的 session_id/user_id 来自 query 不校验归属;userID<=0 时默认 1(种子 admin)。建议:改用 principal 或比对不一致 403 |
|
||||
| H4 | 登录/注册无速率限制 | `server.go:295-296` | 全仓无限流;bcrypt 高成本反而便于 CPU 耗尽 DoS。建议:IP+用户名滑动窗口限流 |
|
||||
| H5 | SSE 任务流缺幂等前置检查 | `internal/server/sse.go:398-424` | REST 路径有 `FindByIdempotencyKey`,SSE 路径没有;EventSource 断线重连产生重复任务执行 |
|
||||
| H6 | 事件 dispatcher stale-fencing 无限重放 | `internal/events/worker.go:206-275` | ErrStaleFencing 直接 cancel+return 不计 Failed;handler 半成功被回滚后事件无限重放,永不可达 dead,无告警 |
|
||||
| H7 | 迁移 00001–00009 缺 down;00012 seed 迁移破坏性 DELETE | `deploy/postgres/goose/` | 前 9 个迁移无 down;00012 无条件 DELETE 30 个 session 的真实消息再插种子;多个迁移事务内 CREATE INDEX(非 CONCURRENTLY)大表会锁表 |
|
||||
| H8 | compose 弱口令兜底 + main 注册默认开放 | `docker-compose.{dev,test}.yml:17,86,101`;`main.yml:101` | dev/test 的 DB/ADMIN 口令有弱默认值;main 已用 `:?required` 强制但 `AUTH_REGISTRATION_ENABLED` 默认 true。建议 test 对齐 main 必填,main 注册默认 false |
|
||||
| H9 | 前端 KaTeX 占位符 XSS | `web/src/engine/renderMarkdown.ts:44-64, 106-108` | 数学公式 catch 分支把未转义原文放入占位符数组,还原发生在 escapeHtml 之后 → XSS。建议:catch 分支 escapeHtml(math) + 占位符随机化 |
|
||||
| H10 | `context.Background()` 脱离请求生命周期 | `internal/chat/session.go:131-134`;`server.go:423,458,566` | LLM 摘要/DB 调用用 Background,客户端断开无法取消,慢库时 handler 挂死。建议:透传请求 ctx + WithTimeout |
|
||||
|
||||
## 四、Medium(选录,详见各专项)
|
||||
|
||||
| # | 发现 | 位置 |
|
||||
|---|------|------|
|
||||
| M1 | 全局缺安全响应头(CSP/nosniff/X-Frame-Options/Referrer-Policy) | `internal/server/server.go:624-636` |
|
||||
| M2 | 租约 TTL 无上限(可锁文档 1000 天)+ AcquireLease 无编辑权校验 | `handlers.go:1196-1203`;`docgov/lease.go:62-70` |
|
||||
| M3 | coordinator 关键词命中强制改写意图 + 模板硬编码"张工您好" | `internal/coordinator/engine.go:409-416, 485` |
|
||||
| M4 | `fmt.Sscanf` 解析 `u_sess_xxx` 必然失败 → UserID=0 审计落空 | `coordinator/engine.go:930-934, 1067-1071` |
|
||||
| M5 | `Runtime.Start` 被 main 与 Server.Start 双重调用且错误被吞 | `server.go:343-345`;`cmd/server/main.go:47` |
|
||||
| M6 | sessions map 无硬上限,惰性清理可被随机 session_id 放大 | `server.go:451-453` |
|
||||
| M7 | 修订三阶段写(账本→DocGov→freeform)无事务,靠客户端重试补偿 | `document_revision_handlers.go:274-318` |
|
||||
| M8 | 测试 flag 名笔误 `FAV_PUBLISHER_ENABLE`(少 D)门闩失效 | `internal/artifactvault/publisher_gate_test.go:16` |
|
||||
| M9 | dev compose 声明永不消费的 `SEMANTIC_SUMMARY_REPLACE`(诱导性配置);dev 与 test/main 默认模型不一致(M2.7-highspeed vs M3) | `docker-compose.dev.yml:119,44` |
|
||||
| M10 | OpsCutover 硬编码 `"dev"`,test/main 无合规 cutover 路径 | `internal/events/cutover.go:12-19` |
|
||||
| M11 | 前端乐观已读无失败回滚;MessageStream prevMsgCount 跨会话不重置;SSE 无 online 感知重连 | `web/src/hooks/useUnreadMarks.ts:176-233`;`MessageStream.tsx:148-154` |
|
||||
| M12 | ExcelViewer 无行数上限内存爆炸;React 19 下 30+ 处裸 setTimeout 无清理 | `ExcelViewer.tsx:42-55` |
|
||||
| M13 | `deploy/postgres/migrations/` 疑似死目录(14 个旧 SQL 无引用,与 goose 重复) | `deploy/postgres/migrations/` |
|
||||
| M14 | `Orchestrator.ResolveDocTask` 静默返回 0 值三权掩盖数据不一致 | `internal/workflow/runtime/orchestrator.go:69-83` |
|
||||
| M15 | PG 事件投递允许乱序而 MemoryBus 有 gap 语义——测试替身与生产行为分叉 | `internal/events/dispatcher.go:56-63` vs `bus.go:99-103` |
|
||||
|
||||
## 五、Low(选录)
|
||||
|
||||
- `handleHealth` 每请求同步两次 DB 往返无缓存无超时(`handlers.go:97-110`)
|
||||
- `writeStoredEvents` json.Marshal 错误被吞(`task_run_handlers.go:437`)
|
||||
- `ReplayPlan.Digest()` 不含 DryRun 字段(纵深防御,`internal/events/replay.go:24-38`)
|
||||
- 前端 localStorage 缓存无版本字段;`lucide-react@^1.16.0` 版本异常需确认来源;App.tsx 4600 行/30 个 useEffect 巨石组件
|
||||
- `handleRunTaskStream` 死参数 `includeDetails/requestID`(`sse.go:417-418`)
|
||||
|
||||
## 六、复核确认无问题的面(证据性记录)
|
||||
|
||||
- SQL 注入:全部 pgx 参数化;仅 4 处 fmt.Sprintf 涉 SQL 均为常量
|
||||
- CORS:白名单制、无 `*`+凭证;SSE 鉴权失败返回 JSON 而非污染流
|
||||
- 日志:密码 bcrypt、token SHA-256 摘要存储;`httpx.LooksInternal` 过滤内部错误串
|
||||
- os/exec:bridge 路径来自服务端配置,用户输入只进 stdin payload;无 text/template 引用
|
||||
- 事件系统:claim 幂等(SKIP LOCKED + fencing 复合判断)、ack+inbox+checkpoint 单事务、envelope 完整性校验、replay 审批人≠操作人——设计正确
|
||||
- 前端:Mermaid strict 模式、链接 noopener、ErrorBoundary 覆盖根组件、EventSource 卸载清理正确
|
||||
|
||||
## 七、优先级建议
|
||||
|
||||
1. **进 main 前必须处理**:C1–C4、H1–H5、H8、H9(H8 的 main 注册默认开放一项)
|
||||
2. **short-term 整改批**:H6、H7、H10、M1、M2、M8(一行修复恢复门闩)
|
||||
3. **backlog**:其余 medium/low
|
||||
|
||||
## 关联整改
|
||||
|
||||
- Remediation: 待立项(建议按第七节优先级拆 short-term 任务)
|
||||
|
||||
## 证据
|
||||
|
||||
- `go vet ./...` 零输出;`go test -short ./...` 55 包 ok(2026-09-19,dev@e8ed33b)
|
||||
- 五路只读深潜:后端 server/chat、docgov/events/工作流/迁移、前端 web、配置/flag/死代码、安全鉴权
|
||||
- 任务条目:[ops/short-term/2026-09-19-system-deep-audit.md](../ops/short-term/2026-09-19-system-deep-audit.md)
|
||||
|
||||
## 开放问题
|
||||
|
||||
- dev 与 test/main 默认模型不一致(M2.7-highspeed vs M3)是否刻意?未见 `.doc/ops` 对齐记录
|
||||
- `deploy/postgres/migrations/` 是否还有外部工具依赖?无则建议归档
|
||||
- H1 legacy 兜底是否有仍在使用的内部工具依赖?删除前需盘点
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: "系统权限设置与项目协作多项缺陷排查"
|
||||
status: done
|
||||
created: 2026-09-20
|
||||
updated: 2026-09-20
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 系统权限设置与项目协作多项缺陷排查
|
||||
|
||||
## 现象
|
||||
|
||||
用户报告:成员管理勾选无效、系统设置「允许编制人兼任审核批准」400、PDF 预览被拦截、任务 runs 403 刷屏、发起编制被标 NETWORK_ERROR、注册/建号 rollback、改密后刷新再强制改密、退出重登出现同名重复项目、无项目仍可对话、右侧工具栏默认展开且不记忆。
|
||||
|
||||
## 根因分析
|
||||
|
||||
| # | 根因 | 关键路径 |
|
||||
|---|------|----------|
|
||||
| 1 | CSP 缺 `frame-src`,blob iframe fallback 到 `default-src 'self'` | `internal/server/cors.go` |
|
||||
| 2 | PdfViewer 同源 iframe 直连,触发 `X-Frame-Options: DENY` 原生拦截页 | `web/src/components/doc/preview/renderers/PdfViewer.tsx` |
|
||||
| 3 | 前端未传 `expected_revision`(该 key 后端强制 CAS) | `web/src/api/systemAdmin.ts` / SettingsSection |
|
||||
| 4 | `ProjectSettingsApiError` 字段名与消费方 `httpStatus`/`errorCode` 不一致 | `web/src/api/projectSettingsError.ts` |
|
||||
| 5 | task-run view 仅放行创建者/owner;前端 403 无停止轮询 | `task_run_auth.go` / `App.tsx` |
|
||||
| 6 | `CanManageProjectMembers` 未读细粒度权限位 | `internal/authz/service.go` |
|
||||
| 7 | memStore `ListProjectsForUser` 忽略成员表 | `internal/projectworkflow/store.go` |
|
||||
| 8 | `user_role_bindings` 插入吞错 → commit rollback;handler 一律 400 | `internal/auth/pg_store.go` |
|
||||
| 9 | 嵌套 `user.mustChangePassword` OR 合并复活 + fetchMe 未回写 session | `authUserMap.ts` / WorkbenchView / useAuthenticatedWorkspaceSync |
|
||||
| 10 | `projects.name` 无唯一约束 + Create 无幂等键;logout 不清 projects 缓存 | `service.go` / migration 00056 / App logout |
|
||||
| 11 | `Project()<=0` 时跳过项目访问校验 | `handlers.go` / `sse.go` / `stage_access_helpers.go` |
|
||||
| 12 | `rightCollapsed` 默认 false 且无持久化 | `AppShell.tsx` / `storage.ts` |
|
||||
|
||||
## 严重度
|
||||
|
||||
`high`
|
||||
|
||||
## 关联整改
|
||||
|
||||
- Short-term: `.doc/ops/short-term/2026-09-20-bug-hunt-permissions-uploads.md`
|
||||
- 分支: `fix/bug-hunt-2026-09-20-permissions-and-uploads`
|
||||
|
||||
## 证据
|
||||
|
||||
- 产品决策:新增 `project:manage_members`;无项目禁止对话并置灰发送按钮;同创建人内项目名唯一 + `client_key` 幂等。
|
||||
- 迁移:`00055_...project-manage-members-permission.sql`、`00056_...project-create-idempotency.sql`
|
||||
|
||||
## 开放问题
|
||||
|
||||
- 无(本批范围内)
|
||||
@@ -1,142 +0,0 @@
|
||||
---
|
||||
title: "模块耦合现状审计(规范与分批整改基线)"
|
||||
status: done
|
||||
created: 2026-09-20
|
||||
updated: 2026-09-20
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 模块耦合现状审计(规范与分批整改基线)
|
||||
|
||||
## 现象
|
||||
|
||||
系统已经是模块化单体,不是未治理的大泥球:`module-boundaries.yaml` + `internal/archtest` 已把 import 与事件登记清到零违规(`baseline_counts.import=0`、`event=0`,二者在 `block_kinds`),可靠事件由独立 `cmd/events` worker 经 PostgreSQL lease 消费。
|
||||
|
||||
故障仍会跨模块扩散的原因不在“缺总线”,而在四类残留:
|
||||
|
||||
1. HTTP 适配层直接持有领域具体类型,而不是只调用用例端口。
|
||||
2. `chat`、`app` 子包与 `coordinator` 用子包拆分避开了 Go 编译环,逻辑上仍互相依赖。
|
||||
3. `docgov` 的状态、角色和错误被多个模块当成本模块词汇使用。
|
||||
4. 带到期日的 SQL/路径例外仍允许非属主写入或拼接工作区路径。
|
||||
|
||||
本审计只记录证据与分级,不改代码。整改批次见 [分批计划](../remediation/2026-09-20-module-decoupling-batch-plan.md)。
|
||||
|
||||
## 根因分析
|
||||
|
||||
### 已有隔离基线(不要推倒)
|
||||
|
||||
| 机制 | 位置 | 现状 |
|
||||
|------|------|------|
|
||||
| 模块化单体 ADR | [2026-09-14-modular-monolith-decoupling](../adr/2026-09-14-modular-monolith-decoupling.md) | 不拆微服务;窄端口 + 组合根 + 领域事件 |
|
||||
| 静态边界 | [module-boundaries.yaml](../system-design/module-boundaries.yaml) | import allowlist、表唯一写者、路径属主、事件生产者/消费者 |
|
||||
| 架构门禁 | `internal/archtest`、`scripts/arch-check.sh --mode block` | import/event 零容忍 |
|
||||
| 进程内端口 | `internal/app/*flow`(例:`internal/app/chatflow/ports.go`) | 消费者拥有窄接口;组合根注入实现 |
|
||||
| 跨进程事件 | `internal/events` + `cmd/events` | PG outbox/inbox;dev `:8088` / test `:8089` / main `:8090` |
|
||||
| 事件契约 | `internal/events/registry.go` `StaticContracts()` | 11 个事件名、schema version、payload 字段 allowlist;与 YAML parity |
|
||||
|
||||
`StaticContracts` 现有事件:`document.agent_candidate_ready`、`document.agent_version_committed`、`document.downstream_impact_detected`、`document.change_report_degraded`、`document.approved`、`taskrun.completed`、`taskrun.cancelled`、`fav.artifact_staged`(`Enabled: false`)、`intent.plan.awaiting_input`、`intent.plan.step_changed`、`intent.plan.completed`。
|
||||
|
||||
### 热点 1(P1):`server` 上帝适配层
|
||||
|
||||
`internal/server/server.go` 的 `Server`(约 40–80 行)同时持有 `*bizdev.Service`、`*coordinator.CoordinatorEngine`、`*docgov.GovernanceEngine`、`*docrevision.Service`、`*taskrun.Manager`、`*projectinstance.Service`、`*pgxpool.Pool` 等具体类型。同结构体里只有少数字段是端口(`chatflow.ChatLog`、`chatflow.ContextAssembler`、`intentflow.Service`、`intent.Recognizer`)。
|
||||
|
||||
生产 import 覆盖约 30 个内部包(`server.go` 11–34 行)。handler 直接解释领域错误,例如 `internal/server/handlers.go` 对 `docgov.ErrDocumentBusy` 的分支(426、449 行)以及 `docgov.RoleAuthor`(702、1291 行)。
|
||||
|
||||
后果:领域包改一个错误或角色常量,HTTP 层必须跟着改;`pool` 还让适配层有机会绕过表属主写 SQL。
|
||||
|
||||
### 热点 2(P2):`chat` ↔ `app` ↔ `coordinator` 逻辑环
|
||||
|
||||
编译环被子包拆开了,依赖方向没有:
|
||||
|
||||
- `internal/chat/session.go` 11–13 行 import `app/chatflow`、`app/intentflow`、`coordinator`。
|
||||
- `internal/chat/action_executor.go` 10–14 行 import `app/intentflow`、`app/stageflow`、`coordinator`、`docgov`、`taskrun`,并持有具体引擎指针。
|
||||
- `internal/app/chatflow/ports.go` 又 import `coordinator`、`ctxmgr`、`projectinstance`(`AssembleRequest` 直接嵌 `coordinator.UserInfo`)。
|
||||
|
||||
`chat` 既是领域会话,又反向依赖用例包。用例一变,会话执行器就会编译失败,问题不会停在单一模块。
|
||||
|
||||
### 热点 3(P3):`docgov` 词汇泄漏
|
||||
|
||||
生产代码(不含本包测试)直接使用 `docgov` 状态/角色/错误的位置包括:
|
||||
|
||||
- `internal/coordinator/engine.go`:`ErrDocumentBusy`(955)、`StateDrafting`(1596、1598)。
|
||||
- `internal/bizdev/service.go`:`ErrDocumentLocked` / `ErrDocumentBusy`(718)。
|
||||
- `internal/server/handlers.go`、`document_revision_handlers.go`、`auth_helpers.go`:`RoleAuthor`、`ErrDocumentBusy`。
|
||||
- `internal/chat/action_executor.go`:动作名字符串 `"docgov.review_approve"`(58、150 行),以及 `docgov.StateDrafting`(90)。
|
||||
|
||||
这些不是稳定共享词汇(`internal/contracts/vocabulary` 尚未承接它们),而是领域实现类型被当公共 API。
|
||||
|
||||
### 热点 4(P3):工作流定义与实例网
|
||||
|
||||
- `internal/workflowdef/catalog.go` import `projectworkflow`。
|
||||
- `internal/workflowdef/validator_v2.go` import `workflow`。
|
||||
- `internal/projectinstance` 生产文件(`store.go`、`service.go`、`gate.go`、`types.go` 等)import `workflowdef`。
|
||||
- `internal/workflow/runtime/orchestrator.go` import `projectinstance`。
|
||||
|
||||
定义、目录、实例和运行时互相看得见对方的包。改一份工作流校验会同时碰到定义包和实例包。
|
||||
|
||||
### 热点 5(P4):巨型文件
|
||||
|
||||
非测试生产文件行数(2026-09-20 `wc -l` 口径,探索盘点):
|
||||
|
||||
| 行数 | 文件 |
|
||||
|------|------|
|
||||
| 1844 | `internal/coordinator/engine.go` |
|
||||
| 1590 | `internal/bizdev/service.go` |
|
||||
| 1395 | `internal/server/handlers.go` |
|
||||
| 1291 | `internal/projectinstance/store.go` |
|
||||
| 1245 | `internal/intent/recognizer.go` |
|
||||
| 1235 | `internal/projectworkflow/store.go` |
|
||||
| 1207 | `internal/docgov/engine.go` |
|
||||
| 1172 | `internal/docrevision/service.go` |
|
||||
| 1151 | `internal/squad/workspace.go` |
|
||||
| 1028 | `internal/freedoc/service.go` |
|
||||
|
||||
单文件过大本身不是耦合,但它把多个用例绑在同一变更面上,评审和回滚半径变大。拆分应跟在解环之后,避免边搬边改依赖。
|
||||
|
||||
### 热点 6(P4):前端 API 层无统一客户端
|
||||
|
||||
`web/src/api/` 约 37 个文件按域各写 `fetch()`,`API_BASE` 与鉴权头分散。错误信封、重试和 401 处理无法在一处收口,后端错误契约一变就会在多个 api 文件重复漏改。这是适配层问题,不是把前端改成 RPC。
|
||||
|
||||
### 热点 7(P2,有到期日):边界例外未清零
|
||||
|
||||
[module-boundaries.yaml](../system-design/module-boundaries.yaml) `exceptions` 共 21 条,`baseline_counts` 为 sql_write 5、path 16。
|
||||
|
||||
| 种类 | 条数 | 里程碑 | 到期 | 风险 |
|
||||
|------|------|--------|------|------|
|
||||
| `sql_write` | 4 | U3 | 2026-09-28 | **8 天后到期**。`docduty`、`docrevision` 仍写 `document_records` / `freeform_documents` |
|
||||
| `sql_write` | 1 | U8 | 2026-10-26 | `projectinstance` 终止流程直接取消 `task_runs` |
|
||||
| `path` | **3** | U4 | 2026-09-28 | **同样到期**。`docrevision/projection.go` + server `document_revision_access.go` / `document_revision_handlers.go` 仍点名 `output.md`(对账前文档少记 handlers 一条) |
|
||||
| `path` | **13** | U5 | 2026-10-12 | `agent`、`bizdev`、`coordinator`、`docgov`、`storage` 仍拼接工作区路径或把 `data/dev` 写进提示 |
|
||||
|
||||
到期后若门禁把这些 kind 升为 block 而代码未迁走,构建会失败;若继续延期而不迁,非属主写入会继续让文档/任务故障跨包扩散。本轮不改 YAML,清零归整改批次 G。
|
||||
|
||||
## 严重度
|
||||
|
||||
整体 `high`:不会单独打穿已签发布门禁(`production_ready` 不因本审计回退),但 P1/P2 使“问题停在单一模块”尚未成立。
|
||||
|
||||
| 级别 | 热点 | 扩散方式 |
|
||||
|------|------|----------|
|
||||
| P1 | server 具体类型装配 | 领域改动直接编译失败到 HTTP |
|
||||
| P2 | chat/app/coordinator 逻辑环 | 会话、意图用例、协调引擎必须同改 |
|
||||
| P2 | 2026-09-28 到期的 sql_write/path 例外 | 非属主写表或读工作区文件 |
|
||||
| P3 | docgov 词汇泄漏 | 状态机常量变成跨包协议 |
|
||||
| P3 | workflow 定义/实例网 | 校验与运行时同改 |
|
||||
| P4 | 巨型文件、前端 fetch 分散 | 变更面大,不立刻产生跨表写入 |
|
||||
|
||||
## 关联整改
|
||||
|
||||
- Remediation: [2026-09-20-module-decoupling-batch-plan.md](../remediation/2026-09-20-module-decoupling-batch-plan.md)
|
||||
- 开发规范: [2026-09-20-module-development-standards.md](../system-design/2026-09-20-module-development-standards.md)
|
||||
- 上位约束(不重复制定): [架构](../system-design/2026-09-14-module-decoupling-architecture.md)、[Phase 2](../remediation/2026-09-15-module-decoupling-ipc-phase2-remediation-plan.md)、[影响面守则 §2](../remediation/2026-09-16-partial-deferred-completion-plan.md)
|
||||
|
||||
## 证据
|
||||
|
||||
- 结构体与 import:`internal/server/server.go`、`internal/chat/session.go`、`internal/chat/action_executor.go`、`internal/app/chatflow/ports.go`。
|
||||
- 事件契约:`internal/events/registry.go` `StaticContracts`。
|
||||
- 例外账本:`module-boundaries.yaml` `exceptions` 与 `baseline_counts`(import 0 / sql_write 5 / path 16 / event 0)。
|
||||
- 盘点方式:2026-09-20 只读检索生产 import 与 `docgov` 符号引用;行数来自当时文件长度,后续拆分后以 `wc -l` 重测为准。
|
||||
|
||||
## 开放问题
|
||||
|
||||
- U3/U4 例外在 2026-09-28 到期后,是先延长豁免并写原因,还是立刻占用 `docgov` mutex 做批次 G 的第一刀。本审计不代决,批次 G 开工前必须二选一,禁止静默改到期日。
|
||||
- `internal/contracts/vocabulary` 在架构文档中已定义,代码侧尚未作为 docgov 状态/角色的唯一出口。批次 C 再决定是新建该包还是把稳定枚举留在消费者端口。
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
title: "2026-09-20 系统全量体检审计"
|
||||
status: done
|
||||
created: 2026-09-20
|
||||
updated: 2026-09-20
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 2026-09-20 系统全量体检审计
|
||||
|
||||
## 现象
|
||||
|
||||
在 `production_ready=yes`、dev/test/main 健康、近期 triage 已合入的前提下,对全系统做只读深度体检,发现若干**未写入 gap-matrix 的 critical/high**,以及一批 medium/low 加固项。
|
||||
|
||||
方法:四路并行深潜(后端 Go、安全鉴权、前端 web、基础设施)+ 本机实证(goose 版本表、容器 health、口令登录、代码交叉复核)。
|
||||
|
||||
## 根因分析(P0 / critical,均已实证)
|
||||
|
||||
| ID | 发现 | 位置 | 证据 |
|
||||
|----|------|------|------|
|
||||
| P0-MIG | 迁移序号空洞 00054;`chat_summaries` 建表与 summarizer 写失败修复滞留未合入分支 | `feature/capability-enablement-impact-plan@848a0457`;dev 代码仍读写不存在表 | `goose_db_version` 53→55→57 跳号;`to_regclass('chat_summaries')` 空;`summarizer.go:119` `_ = err` |
|
||||
| P0-IDOR-PREF | 偏好写入信任请求体 `user_id`,无归属校验 | `internal/server/handlers.go:508-537` | 无 `requireAuthenticatedUser` 比对 |
|
||||
| P0-IDOR-SESS | `handleGetProject` 以 `callerUserID=0` 调会话,归属校验被跳过 | `server.go:458-463`;`handlers.go` / `project_handlers.go` | `if callerUserID > 0` 守卫 |
|
||||
| P0-IDOR-RECAT | 重分类无会话归属;空 `session_id` 触及全库消息 | `chat_recategorize_api.go`;`ctxmgr/recategorize.go` | `WHERE ($1 = '' OR session_id = $1)` |
|
||||
| P0-PANIC | taskrun 订阅发送在锁外,Unsubscribe `close` 后向 closed channel 发送 panic | `taskrun/manager.go:481-497` vs `:590` | select default 不挡 closed;全仓非测试 `recover()`=0 |
|
||||
| P0-RACE | 同步 `POST /chat` 不取 `execMu`,与 SSE 并发 data race | `handlers.go:240` vs `sse.go:341` | 09-19 C2 残留半修 |
|
||||
| P0-CRED-BACKUP | 三环境 DB 口令硬编码进仓库;生产口令与脚本一致可登录 | `scripts/backup-system-db.sh:43-56` | 实测 `prod_highly_secure_db_pass` 可连 main |
|
||||
| P0-CRED-PUSH | push 脚本把 token 拼进 URL,`ps` 可见 | `scripts/git-push-dev.sh:23` | `https://oauth2:${TOKEN}@...` |
|
||||
| P0-XSS | 块编辑器 math 错误分支未转义 | `BlockEditorModal.tsx:206`;`MathBlockView.tsx:20` | catch 裸拼 + `dangerouslySetInnerHTML` |
|
||||
|
||||
### 环境与分支脱节(本轮不做晋升,记 backlog)
|
||||
|
||||
| ID | 发现 | 证据 |
|
||||
|----|------|------|
|
||||
| ENV-MAIN-DRIFT | main 分支 goose 最高 00025,main 库 schema 52;灾备从分支重建不可复现 | `git ls-tree main`;`goose_db_version` MAX=52 |
|
||||
| ENV-TEST-DRIFT | test 分支最高 00056,test 库已 57 | 实测 |
|
||||
| DOC-SCHEMA | CURRENT 写 dev schema 56,实测 57 | health JSON |
|
||||
| GOOSE-DUP56 | dev 库 version_id=56 记账两行(id 57/58,间隔 2ms) | SQL 取证 |
|
||||
|
||||
## 严重度
|
||||
|
||||
- **critical / P0**:上表 P0-*(本轮整改)
|
||||
- **high / medium / low**:见下方「非 P0 清单」与 [long-term](../ops/long-term/2026-09-19-audit-remainder.md) 2026-09-20 增补区
|
||||
|
||||
## 关联整改
|
||||
|
||||
- Remediation: [../remediation/2026-09-20-p0-remediation-plan.md](../remediation/2026-09-20-p0-remediation-plan.md)
|
||||
- Short-term: [../ops/short-term/2026-09-20-p0-hotfixes.md](../ops/short-term/2026-09-20-p0-hotfixes.md)
|
||||
|
||||
## 证据
|
||||
|
||||
- `go vet ./...` 零告警(2026-09-20)
|
||||
- `go test -short ./...`:仅 `TestPiAgentDockerBuildContext_RunnerModulesPresent` 因外网镜像源 EOF 失败,属测试卫生
|
||||
- 三环境 health:dev/test schema **57**,main **52**;events `:8088`/`:8089`/`:8090` ok
|
||||
- 四路深潜交叉:IDOR×3、XSS、凭证、迁移空洞均被 ≥2 条路径或本机取证命中
|
||||
|
||||
## 非 P0 清单(摘要,详 long-term)
|
||||
|
||||
**后端**:XFF 限流可绕过;events `cancelFns` 只增不减;docrevision/docgov 全局锁内 DB I/O;Shutdown 5s vs 长任务;`idemLocks` 无界;SSE query 传消息;C1 缓存不失效;chat 落库非原子等。
|
||||
|
||||
**前端**:`useChatWindow` 切会话竞态;PLAN_CONFIRM 无 try/catch;turn Map 只增不减;重置密码死功能;ErrorBoundary 仅顶层;SSE `\r\n`;token localStorage + 无全局 401 登出等。
|
||||
|
||||
**基础设施**:容器 root、无资源限制;健康检查路径不一致;main events 挂 shared-net;init 三套;Dockerfile Go 1.23 基镜像;backup 无定时;main 分支对齐晋升专项。
|
||||
|
||||
## 开放问题
|
||||
|
||||
- capability 分支合入后 00054 重编号为 00058 是否与其他未合并旁支再撞号?(当前仅该分支占用 54)
|
||||
- main 分支对齐晋升时 00057 会对存量项目做不可逆改名——晋升前需预演清单
|
||||
@@ -1,234 +0,0 @@
|
||||
---
|
||||
title: "Agent 工作规范增删改审查"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
owner: Codex
|
||||
reviewed_dev_sha: a241e838150f218f3a09d3523f93291b847d45fd
|
||||
implementation_status: not_started
|
||||
---
|
||||
|
||||
# Agent 工作规范增删改审查
|
||||
|
||||
## 结论
|
||||
|
||||
现有方向合理:任务 worktree、主目录保护、串行集成、真实证据和安全清理应继续保留。当前最值得做的是**消除冲突、减少重复维护、让关键门禁可执行**,不是继续扩充一份越来越长的 AGENTS。
|
||||
|
||||
本轮建议集中为 10 组增删改与 2 项安全补充观察。它们不都是缺陷:下文区分已验证问题、流程简化建议与已有方案的实施事项。只形成审查结果,没有修改生效规则、脚本、锁、运行环境或业务代码。
|
||||
|
||||
已确定的用户选择不重新讨论:全部新增写入走 `.worktrees`;锁先交付统一入口与提交门禁防误改,OS 权限隔离后续实施;本轮是规范审查,不是实施授权。
|
||||
|
||||
## 1. 审查范围与现场
|
||||
|
||||
冻结基线为本地 `dev@a241e838`,审查在 `.worktrees/agent-policy-review` 进行。覆盖 AGENTS、PROJECT、worktree 工作规范、Cursor 四条规则、任务/收口/handoff 模板、Herdr roster,并检查相关脚本与测试入口。
|
||||
|
||||
主目录采样为干净 dev;未 fetch 或推送。本轮新分支只写审查记录和自己的 CURRENT 快照,不修改被审查规范。
|
||||
|
||||
实际测量:
|
||||
|
||||
- 基线 CURRENT 并行认领共有 **161 条**:158 条 done、2 条 in_progress、1 条 cancelled。新增本轮认领后为 162 条;不把本轮新增记录算成基线问题。
|
||||
- 基础启动链六份文件合计 **71,205 字符**,这是文件字符数,不是模型 token 数或耗时指标。
|
||||
- CURRENT 焦点有 5 项,而 AGENTS 要求 1–3 项;其中长期红线混在当前焦点中。
|
||||
- 之前的规范收口 `d5302a76` 与 `.locks` 方案 `5987bdcd` 均不是本轮基线 dev 的祖先,不能把它们当作所有 Agent 已能读取的生效规则。
|
||||
- 本轮没有运行 Go、前端、数据库或产品 PI 测试;命令问题来自源码筛选条件核查,不宣称本轮复现了产品运行故障。
|
||||
|
||||
## 2. 优先级总表
|
||||
|
||||
“先修”是工程流程优先级,不改变产品 FEATURE-MATRIX 或 production_ready。
|
||||
|
||||
| ID | 类别 | 建议动作 | 优先级 | 直接收益 |
|
||||
|---|---|---|---|---|
|
||||
| R01 | 已验证冲突 | 修改测试范围与验收模型规则 | 先修 | 消除纯文档也被要求真实 PI 的矛盾 |
|
||||
| R02 | 已验证命令问题 | 修改真实 PI 示例为准确、可核验的入口 | 先修 | 避免漏测而误以为完成全链路 |
|
||||
| R03 | 流程简化建议 | 新增任务分级,允许一个主文档承载小任务 | 第二批 | 少建重复记录,减少共享文件写入 |
|
||||
| R04 | 已验证膨胀/不一致 | 精简 CURRENT 和启动读取范围 | 第二批 | 活跃冲突更易发现,降低每轮上下文成本 |
|
||||
| R05 | 已验证状态矛盾 | 修改会话结束与任务完成定义 | 先修 | 防止为了结束会话把未完成任务写成 done |
|
||||
| R06 | 已验证过强要求 | 删除固定五层提交顺序,保留逻辑原子性 | 第二批 | 代码与测试一起可验证、可回退 |
|
||||
| R07 | 已验证引用问题 + 结构调整 | 确立规范唯一来源与生效版本 | 先修 | 避免客户端副本、草案和历史记录互相覆盖 |
|
||||
| R08 | 规范增强建议 | 新增任务授权记录与例外处理边界 | 第二批 | 授权内持续执行,超范围才停下确认 |
|
||||
| R09 | 已知方案实施事项 | 优先落实最小工具门禁 | 与先修并行规划 | 把已知运维误操作挡在执行前 |
|
||||
| R10 | 收口流程增强 | 明确清理执行者、保留原因和复查触发 | 第二批 | 已完成 worktree 不再长期无主积累 |
|
||||
|
||||
## 3. 具体增删改
|
||||
|
||||
### R01 修改:测试要求必须按变更范围生效
|
||||
|
||||
**依据**:`AGENTS.md:118`、`PROJECT.md:118` 明确纯工程规范/文档不调用产品 PI;`.cursor/rules/test-reports-standard.mdc:49,61` 仍要求报告包含全量 Go 回归,并在报告生成前做真实 PI 全链路。后者是 alwaysApply。旧收口分支虽包含相关澄清,但尚未进入本轮基线 dev。
|
||||
|
||||
**后果**:Agent 依据不同入口可能运行无关长测试、误动共享服务,或把必要测试当作可选。冲突本身应先消除,不能依靠“Agent 应该理解”。
|
||||
|
||||
**建议修改**:测试范围统一在一处定义,PROJECT 和客户端规则引用它:
|
||||
|
||||
| 变更 | 必要验证 |
|
||||
|---|---|
|
||||
| 纯规范/普通文档 | 差异、链接、状态与指令一致性 |
|
||||
| 治理脚本 | 沙盒临时仓库中的真实分支、锁、退出与拒绝路径;不以 shell 语法检查替代行为验证 |
|
||||
| Go/接口 | 对应单测、项目 Go/架构门禁,受影响 PG/鉴权负例 |
|
||||
| 前端 | 对应测试和构建;受影响交互用真实浏览器 |
|
||||
| 迁移/运行配置 | 独立环境升级、兼容性、回退/前滚条件及就绪验证 |
|
||||
| 产品 Agent/工作流 | 受影响真实产品 PI 链路;不得以 stub/SKIP 替代 |
|
||||
|
||||
固定七段报告模板改为“完整报告模板”,小型文档/脚本验证可用精简报告或任务内验证节;必须保留实际命令、结果、提交与适用范围。不要删除真实性要求,也不允许把未运行记作 PASS。
|
||||
|
||||
模型要求按目标环境的已批准配置核验并记录实际值。`PROJECT.md:118` 的固定 M2.7-highspeed 不能不分环境套用:当前 dev Compose 默认 M2.7-highspeed,而 test/main Compose 默认 M3。这里是配置源码差异,未检查运行中的秘密配置;建议保留环境策略,禁止为“满足文档”自行切换模型。
|
||||
|
||||
### R02 修改:真实 PI 命令要准确选择测试并证明没有跳过
|
||||
|
||||
**依据**:`PROJECT.md:91–92` 使用 `RUN_PI_E2E=1 ... go test ./... -run 'PI'`。测试名 `TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E`(`internal/server/piagent_e2e_test.go:66`)及 `TestWorkflowGovernance_PiAgent_PG_*`(同模块的 `workflow_governance_piagent_pg_test.go:264,278,293`)不匹配大小写敏感的 `PI`。
|
||||
|
||||
**后果**:命令执行范围与“全链路”的名称不一致;配置缺失还可能让数据库用例跳过。退出码 0 不能单独证明验收完成。
|
||||
|
||||
**建议修改**:优先引用已有 `scripts/run-nightly-real-pi.sh` 作为明确基线入口,写清独立 TEST_DATABASE_URL、Runner 认证、KB/运行环境要求。该脚本当前仅选 U8 和 FullNoneMixedChain 两类测试,**不能把它表述为覆盖全部工作流**;任务按变更范围追加精确测试名与浏览器验收。增加 expected-tests 与实际执行/SKIP 对照,保存最终提交、配置与证据。
|
||||
|
||||
不得在文档中填写真实凭证,也不运行测试来试探生产数据。
|
||||
|
||||
### R03 新增:任务分级;删除小任务必须重复建多份记录的要求
|
||||
|
||||
**依据**:`AGENTS.md:12,37,41–44` 要求任何任务落盘、任务文、研究/审计产物、验收及交接;没有最小产物集或合并记录的规则。
|
||||
|
||||
**建议**:保留“需要审计的工作必须有持久证据”,明确三档:
|
||||
|
||||
- **信息答复**:解释已有结果、查询简单状态,且不产生新决策、持久成果、仓库写入或运行副作用,可直接答复;不为一次答复单独开 worktree。若要写入任何成果,仍进入任务 worktree。
|
||||
- **单一小任务/有价值的只读审查**:一个任务文或专用 audit/research 主文档可同时承载范围、结论、验证、状态和交接;不强制再复制同一内容到另外三份文档。
|
||||
- **跨模块、多阶段、数据/部署任务**:完整 task、必要 plan、验证报告、handoff;仅在信息确实独立时拆文件,互相链接而不复制全文。
|
||||
|
||||
本次这样的实质规范审查仍须落盘,不能以“只读”免除证据。将相关追问、修正与收口归入原 task_id;只读子审查使用父任务的范围和记录,不为每个 reviewer 再开业务任务链。无关新增任务才从 dev 建新分支。
|
||||
|
||||
这项改变需要审核采纳;本轮仍遵守现有落盘规则,没有提前使用豁免。
|
||||
|
||||
### R04 修改:CURRENT 只承载活跃协调,历史留索引
|
||||
|
||||
**依据**:CURRENT 161 条认领中 158 条已完成;`AGENTS.md:132` 要求 1–3 焦点,当前正文有 5 项。
|
||||
|
||||
**建议删除/迁移**:从 CURRENT 活跃表移出已完成/取消且没有后续阻塞的行,历史 owner、branch、worktree、证据在归档任务/历史索引保留。将长期红线独立为受控约束区或链接;它不是每天反复排序的焦点。
|
||||
|
||||
**建议保留**:正在进行、阻塞、等待集成及仍需清理的事项。cleanup_pending 是清理/操作阶段,不新增为 task.status 的第六种状态;一行可写任务 done、cleanup pending,并给 owner、原因和下次检查条件。
|
||||
|
||||
**启动读取修改**:每会话先读短核心规则、项目入口、活跃状态摘要;编码前按范围补读相关模块标准、相关 FEATURE-MATRIX 行、任务/方案及操作规程。发布才读完整发布门禁。不要通过摘要跳过硬红线,也不要要求每次解释一个已知结果都重读全部历史。
|
||||
|
||||
模块开发任务应有明确条件指针指向已有 `.doc/system-design/2026-09-20-module-development-standards.md`,复用现有接口/事件/表写者规则,不新造一套编码规范。
|
||||
|
||||
### R05 修改:会话结束、任务完成、合入与清理分别判定
|
||||
|
||||
**依据**:收口模板第 3 行适用于“任务完成或切换 Agent”,第 22 行却无条件要求 `status=done`;AGENTS 同时允许 blocked/cancelled。任务模板已有 deployment/cleanup 字段,但缺少明确的结果判定与集成/同步状态。
|
||||
|
||||
**建议替换收口条件**:
|
||||
|
||||
> 会话结束不等于任务完成。根据实际情况保留 in_progress、blocked、cancelled 或 done;只有任务范围内的验收条件满足才能 done。换 Agent 必须记录剩余工作及接管条件。只有终态任务才归档;不得为了归档改成 done。
|
||||
|
||||
为任务记录补充按需字段:`review_state`、`integration_state`、`deployment`、`cleanup`、`remote_sync`。例如“方案研究 done、review pending、未合入、deployment not_required”是合法状态;“代码已合入、部署 failed”不能报交付完成。字段由工具生成优先,避免人工重复维护多张表。
|
||||
|
||||
研究/审查的验收是有据可审的产物,不要求把未获实施授权的方案部署到 dev。实现任务的 done 则按其获授权交付范围判定。收口报告始终区分本地提交、dev 合入、实际运行版本和远端状态。
|
||||
|
||||
### R06 删除:固定按数据库、服务、API、测试、文档分层提交的硬性顺序
|
||||
|
||||
**依据**:`.cursor/rules/git-workflow-and-environments.mdc:33–38` 规定“一个任务必须”按五类依次提交;AGENTS 的原子提交目标是一个逻辑变更一批。
|
||||
|
||||
**后果**:小修复也被机械拆分,代码与对应测试分离;一些提交无法独立构建/验证,回退时还可能留下半套契约。
|
||||
|
||||
**建议替换**:
|
||||
|
||||
> 每个提交围绕一个可解释、可验证、可回退的逻辑变更;实现与其回归测试可同批。迁移、兼容阶段、配置或文档只有在独立审查/回退有价值时拆分,不要求每项任务凑齐固定提交层次。
|
||||
|
||||
保留 Conventional Commits、明确文件范围、渐进式交付和独立 worktree;不以“原子”为名把无关改动揉成一批。
|
||||
|
||||
### R07 修改:规范来源、生效状态与客户端薄入口
|
||||
|
||||
**已验证的小错误**:`.cursor/rules/git-secrets-autonomy.mdc:2,8` 把 Secrets 指向 AGENTS §8,实际在 §9。AGENTS 开头称可整文件复制到任意项目,但正文包含本仓库日期路径、脚本和 Herdr 约定;应改为“可复用基线,项目路径/流程需调整”。
|
||||
|
||||
**建议新增规范生命周期**:每项规则记录 proposed/approved/active/deprecated 的规则状态、适用范围、生效提交与 owner;工具能力另记 manual/enforced。这里是规则生命周期,不复用任务 status。
|
||||
|
||||
外层系统约束和当前用户授权仍有效;项目内部规则冲突时有明确处理:AGENTS 保存通用硬边界,PROJECT 定义其授权范围内的项目细则,专门 runbook 负责操作流程;客户端入口只引用同一来源,不复制一套近似规则。草案、旧审计和历史报告属于证据,不能自行覆盖生效规则;较新的日期不等于已生效。
|
||||
|
||||
此前收口和锁方案未进入当前 dev,说明“已经写好/提交”与“已被所有新任务读取”必须分开。旧任务启动时记录 policy revision,集成前重读当前 dev 的相关生效规则;期间发生变化时做差异检查,不默默套旧规则,也不突然按未来未实施机制阻塞旧任务。
|
||||
|
||||
删除 PROJECT 中重复的“当前已无 blocker”等长期硬编码断言,改为引用有日期/制品身份的权威门禁结果。模型、schema、角色可用性等动态值记录在环境/执行收据中;不要在多个入口重复写一份可能过期的“当前值”。
|
||||
|
||||
### R08 新增:任务授权记录与例外边界
|
||||
|
||||
这是一项规范增强建议,不是声称现有 Agent 已越权。现有手册限制自动审批扩权、push 和破坏性操作,但任务模板只有范围/非目标,没有统一记录“这次到底获准做到哪一步”。
|
||||
|
||||
建议任务创建时记录:任务类型(研究/实现/运维)、用户目标、允许写路径、可执行环境、交付终点及明确禁止项。已授权范围内自主持续执行,不在每个 Git/测试步骤重复确认;分析和方案请求默认不包含业务实施。
|
||||
|
||||
只有扩大业务范围、增加外部写入、操作未授权环境或破坏性恢复等才重新确认。push 仍遵守明确授权规则;凭证存在不代表允许推送。合理默认写进任务模板,不用每次都问用户一张权限问卷。
|
||||
|
||||
紧急/迁移例外需记录 owner、原因、范围、期限/退出条件和恢复动作;例外仅覆盖明确条款。`AGENTS.md:29` 的紧急热修免启动阅读不能被解释为允许主目录直接开发、删库或取消验收。
|
||||
|
||||
### R09 落实:先做最小执行门禁,不再只增加禁止句
|
||||
|
||||
这是上一治理/锁方案已承认的工程任务,不作为“新发现的缺失要求”重复计数。
|
||||
|
||||
**已有证据**:AGENTS 已禁用旧 helper 的 create/remove;源码仍包含省略 dev 起点和强制删除。env-service 的根目录来自脚本所在树,缺少执行目录/锁守卫。CURRENT 第 11 行及关联 MinerU 报告已记录一次 worktree rebuild 引起数据挂载漂移,说明风险并非仅理论;本轮未重演该事故。
|
||||
|
||||
**建议实施顺序**:
|
||||
|
||||
1. 修 worktree create/remove 的明确基线、主仓定位和安全删除。
|
||||
2. 给共享服务写操作加主目录/dev/操作身份/持锁前置检查,明确 status 等只读入口;构建必须校验真实源码与申报 SHA。
|
||||
3. 为 CURRENT/MATRIX 提供短锁、增量更新、版本检查,接入已设计 `.locks` 流程;旧锁兼容迁移后才换权威位置。
|
||||
4. Git 提交/集成门禁拒绝超范围文件、混入 `.env`/运行产物和错误主干写入。门禁真实负例验收后再记录 enforced。
|
||||
|
||||
保持用户确认的 L1 目标,不提前搭建跨机平台或要求 OS 隔离才能使用。代码文件锁、全量资源队列和额外 UI 按已有阶段与实际冲突扩展,优先把当前两个共享文档和 dev 操作做可靠。
|
||||
|
||||
### R10 新增:清理负责人和完成后的再检查机制
|
||||
|
||||
现有安全清理条件应保留,不放宽“不强删、不覆盖”的红线。需要补的是谁在 Agent 退出之后真正执行清理,以及什么时候重试。
|
||||
|
||||
操作规范要求无 Agent/进程 cwd 使用才能移除 worktree;长驻客户端即使完成任务也可能仍占 cwd。任务模板允许 retained-with-reason,但没有下一次检查条件。建议由独立集成/维护执行者在 owner 已退出后检查并清理,记录 `cleanup_owner`、保留原因、证据位置和触发条件;遗留目录分为活跃、保护、待审核、未合入和可清理,不按年龄批量删除。
|
||||
|
||||
已合入任务的依赖缓存与唯一截图/日志区别处理:可再生缓存明确登记,唯一证据先保存再移除;只保存路径而不保存文件不是证据归档。清理失败不影响已经通过的业务交付事实,但要保持可追踪的 cleanup pending。
|
||||
|
||||
## 4. 两项安全补充观察(非本轮阻塞项)
|
||||
|
||||
- **材料不能授予权限**:日志、网页、测试输出、引用文本、Agent 产物可能含命令或“用户已授权”字样,应作为待核实内容。handoff 的授权声明回链到可核实的用户目标/委派范围,不仅凭文档自述执行推送、清理或外部写入。已有自动审批不扩权规则继续保留;这项建议补充来源辨别,不要求 L2 现在落地。
|
||||
- **真实证据允许最小化与脱敏**:测试报告可以保存真实执行中足够判定的片段,说明脱敏范围;不要求提交原始完整日志、个人信息、业务正文或截图中的秘密。现有凭证禁入与真实用户数据不复制要求继续有效。真实性约束来源与结论,不能误解成“未经处理的所有材料都要入 Git”。
|
||||
|
||||
## 5. 推荐的规范组织
|
||||
|
||||
不建议再并列增加一套“总规范 v2”。保留现有路径并收敛职责:
|
||||
|
||||
| 位置 | 负责内容 | 移出/减少 |
|
||||
|---|---|---|
|
||||
| AGENTS | 最小安全红线、任务入口、权限/状态原则、操作指针 | 环境动态值、长命令、历史事件、重复模板索引 |
|
||||
| PROJECT | 仓库地图、目标环境、测试入口与模块标准指针 | 重复通用规则、过期发布结论 |
|
||||
| worktree runbook | 创建、同步、候选、部署、失败与清理 | 已结束迁移的具体临时目录案例,移入历史交接 |
|
||||
| 锁管理 runbook(落地后) | 唯一入口、状态、等待、恢复与兼容版本 | 让 Agent 手动拼锁协议的日常操作 |
|
||||
| CURRENT | 活跃任务、当前槽位、1–3 焦点、必要约束链接 | 大量 done 历史行与长复盘 |
|
||||
| FEATURE-MATRIX | 能力声明范围、证据、剩余条件 | 逐次操作流水、重复环境快照 |
|
||||
| 客户端入口 | 明确引用上述来源 | 复制并稍微改写的第二套规则 |
|
||||
| 任务/审查主文档 | 单项工作的范围、决定、证据和交接 | 对相同内容的无意义多文件复制 |
|
||||
|
||||
## 6. 改动顺序与验收
|
||||
|
||||
**第一批:消除矛盾。** R01、R02、R05、R07 的明确错误先修。检查从所有客户端入口读取后,纯文档、业务修复、暂停交接、取消任务、真实 PI 验收五种场景都得到一致决策。
|
||||
|
||||
**第二批:减少流程负担。** 采纳 R03/R04/R06/R08/R10 后更新模板与薄入口;历史只迁移、不删除。验证信息问答不触发无意义写入,实质审计有唯一主产物,代码与测试能形成完整逻辑提交,未完成任务不会被强制 done。
|
||||
|
||||
**第三批:工具实现。** R09 与既有 `.locks` 分阶段方案合并为一个实施队列,不重复造项目。用两个并行任务、锁冲突、旧版本共享文档、错误工作区部署、异常退出和清理拒绝的真实证据验收。当前 user-approved 的 L1 防误改边界不变。
|
||||
|
||||
规范检查可以自动化为轻量 `doctor/lint`:本地链接、必需字段/状态、过期 waiver、活跃认领冲突、测试入口存在、脚本能力版本与规范声明对齐。没有明确规则契约的模糊 prose lint 不作硬失败,也不为文案偏好构造复杂测试。
|
||||
|
||||
## 7. 审查覆盖与可信度
|
||||
|
||||
使用 ce-doc-review 非交互只读流程,审查依据为上述实际文件及脚本,而非仅凭历史记忆。
|
||||
|
||||
| 审查视角 | 结果 | 本报告处理 |
|
||||
|---|---|---|
|
||||
| 一致性(独立上下文) | 3 项 | 复用声明/引用合入 R07,焦点上限合入 R04 |
|
||||
| 可执行性(独立上下文) | 1 项 | PI 测试筛选问题合入 R02,主审已核对源码 |
|
||||
| 范围/减负(独立上下文) | 3 项 | 合入 R03/R04;保留实质审计必须落盘,收窄纯只读豁免 |
|
||||
| 安全(独立上下文) | 2 项观察,置信锚 50 | 仅列为 §4 补充观察,不当作已证实漏洞 |
|
||||
| 反例审查(独立上下文) | 0 项新增缺陷 | 候选 SHA、失败恢复、累计部署差异等已有引用约束,未重复提出 |
|
||||
| 主审当前源核查 | 测试范围冲突、状态模板、提交顺序、动态配置与工具事实 | 补充 R01/R05/R06 等;明确区分改进建议与已知实施项 |
|
||||
|
||||
外部第三方 CLI 跨模型复核未执行:本轮未获得向其他外部服务发送仓库文档的显式授权;未以此阻塞会话内独立视角审查。未更改技能或项目配置来伪造关闭该步骤。
|
||||
|
||||
未采纳的建议形态:不把纯只读豁免扩大到有持久价值的审计;不把 cleanup_pending 塞进既有任务 status;不要求当前实现 OS 级权限隔离;不因为当前 helper 明确标为未修复,就重复说规范已承诺了不存在的能力。
|
||||
|
||||
**已应用规范修正:0。** 上述均是待审核建议。本轮只写审查产物与任务记录,未升级 FEATURE-MATRIX、未改 production_ready、未运行产品测试、未合入 dev 或 push。
|
||||
|
||||
## 8. 相关资料
|
||||
|
||||
- [当前工作手册](../../AGENTS.md)
|
||||
- [项目入口](../../PROJECT.md)
|
||||
- [已采纳工作方式](../ops/2026-09-21-agent-worktree-workflow.md)
|
||||
- [既有治理方案](../remediation/2026-09-21-agent-workflow-governance-plan.md)
|
||||
- `.locks` 补充方案:目前在 `feature/agent-lock-coordination-plan@5987bdcd` 的 `.doc/remediation/2026-09-21-agent-lock-coordination-plan.md`,不在本轮 dev 基线;后续合入时再建立普通相对链接。
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
title: "文档存储 CoW(写时复制)现状审计"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
severity: low
|
||||
---
|
||||
|
||||
# 文档存储 CoW(写时复制)现状审计
|
||||
|
||||
## 背景
|
||||
|
||||
用户诉求:上传文档要「几个人传同一份只存一份」,涉及可编辑文档时「考虑 CoW,写入时复制」。本审计确认系统当前的去重与写时复制实现状态,并明确本次收口补齐了什么。
|
||||
|
||||
## 现状分析
|
||||
|
||||
系统存在两套内容存储,均已采用内容寻址(Content-Addressed Storage, CAS),天然满足去重与 CoW 语义:
|
||||
|
||||
### 1. 二进制资产:`internal/storage/cas.go`
|
||||
|
||||
- 物理对象表 `storage_blobs` 以 `sha256` 为主键,`ref_count` 记录引用数。
|
||||
- 上传命中相同 sha 时([cas.go](../../internal/storage/cas.go) `storeFileDB`)**不写第二份物理文件**,仅 `ref_count + 1`,并新建一条 `file_references` 逻辑引用。→ 满足「多人传同一文档只存一份」。
|
||||
- 文件路径 `blobs/<xx>/<yy>/<sha>.bin` 由内容 hash 唯一决定;`StoreFile` 对已存在 blob **只读不覆写**(命中去重分支直接返回)。内容变化 → hash 变化 → 新路径新文件。→ 即 CoW:修改等价于写入新对象,旧对象不被就地改写。
|
||||
|
||||
### 2. 可编辑文档正文:`internal/docrevision/pg_store.go`
|
||||
|
||||
- `document_content_blobs` 以 `content_sha256` 为键,`ensureBlobTX` 使用 `INSERT ... ON CONFLICT DO NOTHING`([pg_store.go:309](../../internal/docrevision/pg_store.go))。
|
||||
- 每次编辑保存生成新 `document_snapshots`,指向新的 `content_sha256`;未变化的正文块复用同一 blob 行。→ 编辑保存不会复制未改动内容,写入时才产生新 blob。→ 满足「可编辑文档 CoW」。
|
||||
|
||||
## 结论
|
||||
|
||||
- **去重**:物理层早已实现(sha256 + ref_count);本次补齐的是**逻辑提示**——把 `FileReference.IsDeduplicated` 透出到上传/列表 API 的 `deduplicated` 字段,并在前端附件卡片与文档预览面板展示「重复·已复用」,让"只存一份"对用户可见。跨项目/同项目的逻辑引用记录保留(权限与审计需要),不做合并(已与用户确认方案:物理一份 + 提示)。
|
||||
- **CoW**:语义已是事实实现,但**缺防回归守卫**。本次新增 `TestCAS_ImmutabilityCoWContract`([cas_test.go](../../internal/storage/cas_test.go))固化契约:① 相同内容重复写入 → 物理 blob 数不变、字节不变;② 内容变化写入 → 新 blob、旧 blob 不被覆写、历史引用仍读原始字节。未来任何"就地改写 blob"的实现都会在测试期失败。
|
||||
|
||||
## 严重度
|
||||
|
||||
`low` —— 现状正确,本次为可见性增强 + 契约固化,无缺陷修复。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- 任务:[2026-09-21-upload-parse-ux-dedup.md](../ops/short-term/2026-09-21-upload-parse-ux-dedup.md)
|
||||
- 验收报告:[2026-09-21-upload-parse-ux-dedup-test-report.md](../test-reports/2026-09-21-upload-parse-ux-dedup-test-report.md)
|
||||
|
||||
## 开放问题
|
||||
|
||||
- `storage_blobs.ref_count` 目前只增不减;引用删除(若未来支持资产删除)需配套 decrement 与 blob 物理回收,属后续独立任务,不在本次范围。
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
title: "pi-native 对比未过 P95 门槛"
|
||||
status: planned
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
severity: medium
|
||||
---
|
||||
|
||||
# pi-native 对比未过 P95 门槛
|
||||
|
||||
## 现象
|
||||
|
||||
真实 MiniMax-M2.7-highspeed 双后端对比中,`pi-native` 六例全部写出目标文件,容器 `pi-agent` 只有两例文档任务成功。按成功样本计算的 P95 仍是 `pi-native` 16.616s、容器 6.926s,比值为 2.40,超过 1.3 倍替换门槛。因此 dev 默认后端保持 `pi-agent`。
|
||||
|
||||
## 根因分析
|
||||
|
||||
- 时延样本只统计成功且无 P0 的用例。容器 `reasoning` 画像使用 `--no-tools`,不会把助手正文落成目标文件,四例返回 `MISSING_TARGET`,不进入 P95。容器 P95 只由两例较快的文档任务构成。
|
||||
- `pi-native` 的 P95 落在 `doc-outline`(16.616s)。同一提示在容器上是 6.926s。文档任务本身慢于 1.3 倍,不是分位数算法造成的。
|
||||
- 第一轮对比把分位索引截断成 0,两例成功时取了更快的那例,已作废。本结论使用 nearest-rank(`ceil`)后的第二轮日志。
|
||||
|
||||
## 严重度
|
||||
|
||||
`medium`。运行时可以继续在分支上迭代,当前默认链路未切换,容器后端仍可回退。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- 任务:`.doc/ops/short-term/2026-09-21-go-agentx-runtime.md`
|
||||
- 报告:`.doc/test-reports/2026-09-21-go-agentx-runtime-test-report.md`
|
||||
- 后续:缩短 `pi-native` 文档轮次时延,或把门槛改成按同一成功用例配对比较后重新实测。未重新通过前不改 `AGENT_BACKEND`。
|
||||
|
||||
## 证据
|
||||
|
||||
- `.doc/test-reports/assets/go-agentx-runtime/ab-live.txt`
|
||||
- `.doc/test-reports/assets/go-agentx-runtime/ab-live-round1.txt`(作废的截断分位)
|
||||
|
||||
## 开放问题
|
||||
|
||||
- 容器结果不回传 token,本轮容器用量为 0,无法比较 token。
|
||||
- `reasoning` 画像的成功定义是否应要求容器也把正文写入目标文件。当前判定仍按两边各自的 `Result.Success` 与目标文件是否出现。
|
||||
@@ -1,156 +0,0 @@
|
||||
---
|
||||
title: "当前系统模块解耦现状审查"
|
||||
type: docs
|
||||
date: 2026-09-22
|
||||
source_sha: d034aa00e5785f51234b484f9dca6bf4fb037660
|
||||
task_id: modular-contract-standard-2026-09-22
|
||||
---
|
||||
|
||||
# 当前系统模块解耦现状审查
|
||||
|
||||
## 结论与范围
|
||||
|
||||
当前系统属于**已有实质模块化基础,但契约一致性、数据所有权与运行隔离尚未闭合的模块化单体**。不是只有文件夹拆分:已有应用用例、共享事务、PostgreSQL outbox/delivery/inbox、独立 events 进程、PI Runner HTTP typed-result 边界。
|
||||
|
||||
下一步收益最大的工作是统一业务入口、修正事件顺序契约、补运行时校验和资源预算。把现有相互依赖的实现全部包装为 HTTP 服务,会保留语义耦合并引入跨进程失败窗口。
|
||||
|
||||
本报告针对固定源码 SHA,只读检查 Go/React、架构配置、迁移和部署定义。**未检查当前实际镜像/进程/数据库积压,未运行 Go/PG/PI/浏览器或故障注入测试。** 下文“实现存在”是源码证据;“可能造成”是风险推导;不宣称现网事故已复现,也不改变 FEATURE-MATRIX 或发布门禁。
|
||||
|
||||
关联:[通用规范](../system-design/2026-09-22-generic-module-contract-standard.md)、[采用规划](../remediation/2026-09-22-modular-platform-adoption-plan.md)、[任务与验证](../ops/short-term/2026-09-22-modular-contract-standard.md)。
|
||||
|
||||
## 分维度判断
|
||||
|
||||
| 维度 | 已有基础 | 当前局限 | 判断 |
|
||||
|---|---|---|---|
|
||||
| 模块职责 | domain/app/server 分层,组合根 | server 认识大量实现,跨包类型泄漏 | 部分解耦 |
|
||||
| 业务入口 | docflow/stageflow/chatflow 用例 | 对话和 HTTP 同一动作存在旁路 | 需优先收敛 |
|
||||
| 数据边界 | 表 owner 清单与 UoW | 5 项 SQL 写例外、16 项路径例外 | 明确但未闭合 |
|
||||
| 事件通信 | 可靠 PG 投递与独立进程 | 顺序规则与 ADR 冲突,校验不完整 | 机制具备,语义有缺口 |
|
||||
| 并发与幂等 | claim、lease、token、DB 收据 | 慢消费者共享循环,同 ID 异载荷不校验 | 部分保证 |
|
||||
| 跨进程边界 | Web/server、PI Runner、events | 业务模块大多仍共享 server 进程/资源 | 不能宣称全模块故障隔离 |
|
||||
| 前端功能 | API/hooks 拆分 | 根状态和 setter 跨功能共享 | 文件组织优于状态边界 |
|
||||
| 工程约束 | arch-check 与契约 registry | 静态覆盖有限,不证明运行隔离 | 有工具,须明确盲区 |
|
||||
|
||||
不提供无权重依据的“解耦百分比”。以下发现按对数据与行为的实际影响排序,而非按文件大小排序。
|
||||
|
||||
---
|
||||
|
||||
## A1. 事件领取规则与已接受的顺序契约相冲突
|
||||
|
||||
**高优先级源码问题。** ADR 规定允许首个高领域版本 bootstrap,禁止把 MemoryBus 的连续版本等待搬到 PG dispatcher:`.doc/adr/2026-09-15-event-consumer-checkpoint.md:12-23`。
|
||||
|
||||
当前 `internal/events/dispatcher.go:39-46,75-84` 采用 `version <= checkpoint + 1`;无 checkpoint 时只接纳版本 0/1。生产者 `internal/app/docflow/commands.go:182-185` 使用 document record ID,`:211-214` 使用 candidate ID,`:162-165` 使用文档账本版本。这些不是从 1 开始连续的事件序号。
|
||||
|
||||
因此在“无 checkpoint、第一条版本为 42”这一明确条件下,该事件按 SQL 不能被领取。是否已有这种实际积压未查数据库,不能报成现网观测。
|
||||
|
||||
现有 `internal/events/pg_test.go:18-28` 固化同样 gap 规则;`dispatcher_pg_test.go:105-109` 使用 v1/v2,不能覆盖稀疏首事件。
|
||||
|
||||
**建议验收**:真实 PG 下测试首次 v42、v42→v47、部分事件订阅、毒消息隔离;按既有 ADR 恢复 bootstrap,或经明确新 ADR 引入独立事件序列及迁移。通用规范对应 MCS-15。
|
||||
|
||||
## A2. 同一批准动作存在 HTTP 与对话入口分叉
|
||||
|
||||
**高优先级待验证风险。** HTTP `internal/server/handlers.go:793-808` 调用 `docflow.Commands.Approve`,后者在 `internal/app/docflow/commands.go:173-188` 执行 UoW 与 EventApproved。
|
||||
|
||||
对话 `internal/chat/action_executor.go:68-76` 直接调用 GovernanceEngine.ApproverApprove;`internal/app/app.go:294-307` 已不再注册旧通知/批准 hook,`internal/docgov/engine.go:957-960` 的直接路径仅尝试旧 hook。
|
||||
|
||||
源码证明入口路径不同,存在绕过 durable workflow_advance/notify 的风险;本次未执行真实对话批准,不能把完整用户后果记为已复现。
|
||||
|
||||
**建议验收**:同一授权场景分别从 HTTP、对话、后台任务触发,比较授权拒绝、状态提交、事件、工作流推进与通知,所有入口汇入同一用例。通用规范对应 MCS-04。
|
||||
|
||||
## A3. 契约登记尚未成为完整运行时校验
|
||||
|
||||
`internal/events/registry.go:28-52` 登记 producer、consumer、schema、PayloadFields;`:75-91` 主要检查启用与消费者。
|
||||
|
||||
`internal/events/envelope.go:65-85` 检查基础字段、schema、digest/scope,但不按事件逐项校验 producer allowlist、JSON 必填/类型/额外字段。`internal/events/pg.go:32-47` 依赖此验证。`inventory.go:29-63` 也未完成 payload 结构检查。
|
||||
|
||||
实际 `internal/app/docflow/commands.go:279` 的 Producer 为 `docflow`,registry 示例为 `app/docflow`(`registry.go:42-46`),当前路径不会因此拒绝。消费 hydration `dispatcher.go:204-224` 与 handler 调用 `worker.go:252` 也不能证明所有入口统一重新校验。
|
||||
|
||||
**建议验收**:未知事件/schema、伪造 producer、缺必填、异类型、超大 payload、digest/tenant/environment 不符均有发布和消费负例。通用规范对应 MCS-08/09/18/21。
|
||||
|
||||
## A4. 消费者逻辑独立,但资源执行仍串行共享
|
||||
|
||||
`internal/events/worker.go:99-113` 逐一 RunOnce 各消费者;`:137-147` 一批先 claim 再逐个 handle。心跳直到该条 handle 才启动(`:208-234`)。
|
||||
|
||||
慢消费者会延迟同 worker 的其他消费者;预取队尾还可能在开始处理前耗掉 lease。增加副本能缓解吞吐,不证明消费者有独立预算和公平性。当前可隔离永久错误,不等于慢任务也隔离。
|
||||
|
||||
**建议验收**:阻塞一个消费者、保持另一个持续输入,后者满足自己的延迟预算;批量排队超过租期时不允许并发重复副作用。先按空闲槽 claim,并配置每消费者超时、并发、池配额;高风险任务再进程隔离。对应 MCS-14/17。
|
||||
|
||||
## A5. 去重与健康检查不能被扩大解释
|
||||
|
||||
`internal/events/pg.go:43` 对相同 event_id 使用 DO NOTHING,未比较已有 payload digest。因此“重复 ID 被忽略”并不保证“同键异载荷会冲突”。
|
||||
|
||||
`cmd/events/main.go:91-115` 的 health、ready、live 分别关注进程、DB/schema/注册条件、调度心跳;`worker.go:109-112` 在处理前 Touch 且忽略 RunOnce 返回错误。Compose healthcheck 使用 /health(`docker-compose.dev.yml:170-175`)。
|
||||
|
||||
**建议验收**:同 ID 同内容返回既有结果、不同内容冲突;依赖持续失败时最老消息年龄和分消费者失败数告警,不能依靠健康探针证明业务前进。对应 MCS-13/19/20。
|
||||
|
||||
---
|
||||
|
||||
## B1. 组合根、契约类型与实现仍相互渗透
|
||||
|
||||
优点:`internal/app/app.go:96` 集中装配,`internal/server/server.go:87` 接收 runtime。限制:`server.go:40-84` 持有领域具体服务、pool、上下文等,`:123-132` 还回填 Runtime 并初始化执行器。HTTP 适配器获得整个 Runtime,难以维持最小依赖。
|
||||
|
||||
`internal/app/stageflow/usecase.go:10-37` 是窄端口且未配置时 fail closed,但 `types.go:3-15` alias 到 bizdev 模型。`internal/app/chatflow/ports.go:75-106` 返回 ctxmgr/coordinator/projectinstance 具体类型。接口改变了调用位置,仍未彻底隐藏内部模型。
|
||||
|
||||
本次 server 生产 SQL 搜索未发现真实业务 SQL,**不能把持有 pool 等同于已经直接越权写表**。改造重点是缩小可用能力与未来变更影响,不虚构违规。
|
||||
|
||||
## B2. 单写者有登记,仍有明确例外
|
||||
|
||||
`.doc/system-design/module-boundaries.yaml:276-374` 登记表 owner,`:471-511` 登记 5 项 SQL 例外。
|
||||
|
||||
源码确认:`internal/docrevision/pg_store.go:456-477` 更新 freeform_documents/document_records;`internal/docduty/store.go:144`、`revoke.go:154` 修改 document_records;`internal/projectinstance/store.go:920` 更新 task_runs。
|
||||
|
||||
建议通过 owner repository/用例端口逐项归还写权,保留必需事务边界。不得为了删除一个 import,把同一 SQL 移到万能公共 repository。
|
||||
|
||||
## B3. 共享事务值得保留,不能随意替换为网络调用
|
||||
|
||||
`internal/app/docflow/commands.go:88-112` 使用 UoW 与 owner GetForUpdate;`internal/docrevision/pg_store.go:482-491` 加入同一事务;`internal/app/uow/pg_uow.go:52-80,95-124` 提供有界事务重试、锁等待和提交。
|
||||
|
||||
`internal/app/app.go:269-275` 接入 events.PGSink,`internal/events/pg.go:17-58` 拒绝无 UoW 发布并同事务创建 envelope/delivery。这是实质强一致性能力。若以后拆进程,必须重新定义跨域中间态、补偿和对账,不能用分布式锁替代事务。
|
||||
|
||||
## B4. 文件与前端状态也构成模块间隐式协议
|
||||
|
||||
文件证据:`internal/coordinator/context.go:456-459` 读取 output.md;`engine.go:691-701,895,1051` 读写/拼接共享产物路径;`internal/docgov/lease.go:415-416` 写 projection 文件。文件 owner、不可变引用、版本与发布原子性应与数据库同样治理。
|
||||
|
||||
前端证据:`web/src/App.tsx:130-170,1163-1204,1367-1406` 将消息、交付物、缓存及 setter 传给多个功能 hooks;`useSendMessage.ts:85-121` 可修改多个域状态。建议 owner 管理状态、对外命令/查询/事件;浏览器内无需强制 HTTP。
|
||||
|
||||
`web/src/api/authHeaders.ts:27-44` 已有认证辅助,但 chatStream、taskRuns、docgov 等仍各自 fetch。统一 client 应处理通用超时、错误、取消与身份,功能 DTO 继续分域。
|
||||
|
||||
## B5. 静态架构检查有价值,但证明范围有限
|
||||
|
||||
`internal/archtest/scan.go:38-70` 默认只扫 internal 生产 Go;`:169-205` 检查 import allowlist 和登记表的 SQL 字符串。它不涵盖前端、默认 cmd 范围、动态 SQL 完整语义、实际权限、兼容性和资源隔离。
|
||||
|
||||
`scan.go:18,392-410` 的事件匹配范围主要为 document.* / intent.plan.* 和特定调用模式,不能根据 YAML 中存在 taskrun/fav 就假定每条协议都被检查。
|
||||
|
||||
`module-boundaries.yaml:182-225` 仍允许 server 依赖大量领域;`:641-651` 登记 sql_write=5、path=16 基线。**这是读取到的配置,不是本次 arch-check 执行结果。**
|
||||
|
||||
---
|
||||
|
||||
## 可保留的隔离与演进能力
|
||||
|
||||
- 独立 worker:`cmd/events/main.go:68-89,127-130` 注册 notify/advance/projection,FAV 明确不注册;Compose 已有 events 服务。历史“没有独立 worker”的判断已过时。
|
||||
- 领取与确认:`dispatcher.go:49-97,163-200,227-259` 有原子 claim、owner/token、attempt、inbox/checkpoint;旧 ClaimIDs 已禁用。
|
||||
- DB 效果原子性:`worker.go:247-275` 的 handler、fenced ack、commit 同事务;仅适用于参与同一 DB 事务的效果,不能扩展为任意外部 IO。
|
||||
- 消费者实现:`internal/app/docproject/consumer.go:73-94` 使用事件回执与 no-replace;`docadvance/consumer.go:80-104` 使用同事务推进与通知。
|
||||
- 冻结执行输入:`internal/workflow/runtime/orchestrator.go:27-41,69-85` 从冻结实例取职责,缺失时拒绝,可泛化为任务绑定配置/契约版本。
|
||||
- PI Runner:`internal/agent/piagent.go:145-194` 有 HTTP/Bearer、超时、run_id、typed result 和大小限制;`remote_result.go:63-79` 对存在但非法 typed 字段 fail closed。
|
||||
|
||||
## 测试证据边界
|
||||
|
||||
以下是已有测试定义,不是本次 PASS:
|
||||
|
||||
| 路径 | 已有测试意图 | 本次状态 |
|
||||
|---|---|---|
|
||||
| internal/app/docflow/same_tx_pg_test.go | 状态与 outbox 同事务回滚 | 未运行 |
|
||||
| internal/events/dispatcher_pg_test.go | 多 worker、off/shadow、ack、隔离 | 未运行 |
|
||||
| internal/app/docnotify/e1a_pg_test.go | 通知权限、shadow/live、回滚 | 未运行 |
|
||||
| internal/app/docadvance/e1b_pg_test.go | 工作流事件消费 | 未运行 |
|
||||
| internal/app/docproject/e1c_pg_test.go | 投影与 no-replace | 未运行 |
|
||||
| internal/agent/piagent_typed_e2e_test.go | 条件启用的真实 PI | 未运行 |
|
||||
|
||||
PG 测试在 short 或缺少独立 DSN 时可跳过;PI 测试有显式开启条件。建议新增 A1–A5 的针对性场景,再做受影响用户入口验收。未经授权,本次不启动这些实现或共享环境测试。
|
||||
|
||||
## 与原方案的关系
|
||||
|
||||
继续引用 2026-09-20 A–G 分批整改作为现有依赖收敛清单,不能据此宣称原批次已经完成。A1–A5 是本次新增或细化的源码证据,实施时应并入同一治理链,避免开第二套互相冲突的解耦项目。
|
||||
|
||||
原规范保留模块化单体,本次通用规范允许按条件选择进程/服务隔离。两者分别用于“当前项目生效规则”和“未来项目待采纳标准”,没有自动覆盖关系。
|
||||
@@ -1,27 +0,0 @@
|
||||
# 历史问题补录:可选职责与正文哈希
|
||||
|
||||
补录日期:2026-09-23;owner:Codex;登记任务:[issue-learning-2026-09-23](../ops/short-term/2026-09-23-issue-learning.md)。这是两个问题的登记主记录,原审计、修复任务及验收报告继续作为事实证据;没有重新运行产品测试或读取业务数据。`evidence_basis=historical`,当前运行状态未复测,源码复核基线为 `2fdb6e548e3784771f27e6a9e79b9c364f76c566`。
|
||||
|
||||
## nullable-duty
|
||||
|
||||
- issue_id:`ISSUE-20260923-nullable-duty`;issue_state:`resolved`;severity:high;recurrence_count:0(指登记后重开次数,非历史发生总数)。
|
||||
- 发现/修复日期:2026-09-17;原处理 owner:Cursor;补录 owner:Codex;原任务:`fix/docgov-optional-duty-null-fk`。
|
||||
- 现象与已证实根因:[原审计](2026-09-17-docgov-optional-duty-null-fk.md)。可选 reviewer 缺席合法返回 0,但创建路径直接写入可空 FK;heal 路径已有空值映射,创建路径漏改。底层 FK 又被错误分型掩盖。
|
||||
- 同类范围:可选职责的创建/heal 写入边界。历史报告验证 reviewer/approver 为 NULL;不能由此推断所有 FK、全职责模式和全部授权边界均已验证。
|
||||
- 修复思路:保留可选职责语义,在 SQL 边界将缺席值映射 NULL,并改善错误分型;通过强制配置 reviewer 绕过错误会改变业务契约。未发现其他尝试的实测记录,不虚构失败实验。
|
||||
- 修复经过/提交:[原任务](../archive/ops/2026-09-17-docgov-optional-duty-null-fk.md),历史合并 `e488d10`;本次只核对原文记录,不把短 SHA 当当前制品身份。
|
||||
- 验证与关闭范围:[原报告](../test-reports/2026-09-17-docgov-optional-duty-null-fk-test-report.md) 记录单测、PG 集成、真实任务 API 启动与 DB NULL;证明账本创建通过,不证明真实 UI 或 PI 全流程完成。历史 deployment=passed(dev,来源为原报告),当前运行未复测。
|
||||
- 本次复核:当前源码 `internal/docgov/engine.go` 创建路径仍调用 `nullIfZero`;这是源码检查,未重跑 PG。
|
||||
- 经验:[LESSON-20260923-nullable-duty](../ops/lessons/2026-09-23-nullable-duty.md)。后续触发:职责模型或任一持久化入口变化时复核,异常复发重开。独立的 flushSync 警告不在本条关闭范围。
|
||||
|
||||
## content-hash
|
||||
|
||||
- issue_id:`ISSUE-20260923-content-hash`;issue_state:`resolved`;severity:critical;recurrence_count:0(登记后)。
|
||||
- 发现/修复日期:2026-09-14;原处理:Cursor 修复、Antigravity UI 验收;补录 owner:Codex。
|
||||
- 现象与因果链:[原审计](2026-09-14-project143-controlled-content-404.md)。文件存在却被报 404;规范化去掉有硬换行语义的双空格,bootstrap 只改账本哈希未同步文件;并发 hydration 与无效轮询更新放大故障。
|
||||
- 同类范围:旧文档 bootstrap、规范化、账本/文件投影、错误映射与刷新竞态。历史扫描范围见原审计,不扩大为所有数据无问题。
|
||||
- 修复思路/选择:[整改方案](../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md)。保持文本语义、原子投影和结构化错误;历史原文件与旧 head 先保全再显式 migration_repair。静默覆盖原文件会丢失语义,不能用于“对齐哈希”。这不是本轮数据操作授权。
|
||||
- 修复经过:[原审计关闭结果](2026-09-14-project143-controlled-content-404.md#关闭结果) 与 [最终报告](../test-reports/2026-09-14-controlled-content-ui-acceptance.md);后续水合/缓存修复合入 `d0e8f60`、`36e4bc3`。报告保留早期失败及无效运行,只有 clean-run3 / full-chain-final 属最终有效证据。
|
||||
- 验证与关闭范围:原报告记录旧项目真实页面、全链路主阶段和重启恢复 PASS;历史 deployment=passed(dev)。不据此宣告当前 production_ready 或当前制品无回归。
|
||||
- 本次复核:`internal/docrevision/canonicalize.go` 已委托 doccontent;`canonicalize_golden_test.go` 包含硬换行和封装一致性测试。本次未执行这些测试。
|
||||
- 经验:[LESSON-20260923-content-hash](../ops/lessons/2026-09-23-content-hash.md)。后续触发:canonicalizer、bootstrap、投影或水合修改时复核;复发追加时间线并重开。
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
issue_id: ISSUE-20260923-matrix-status-regression
|
||||
issue_state: resolved
|
||||
severity: high
|
||||
owner: Cursor
|
||||
task_ids: [module-batches-ag-status-fix-2026-09-23]
|
||||
created: 2026-09-23
|
||||
occurred_at: 2026-09-23
|
||||
updated: 2026-09-23
|
||||
recurrence_count: 0
|
||||
evidence_basis: current
|
||||
lesson_ids: [LESSON-20260923-matrix-status-cas]
|
||||
---
|
||||
|
||||
# FEATURE-MATRIX 状态字段被合并冲突回退
|
||||
|
||||
按 [闭环规范](../ops/2026-09-23-issue-learning-workflow.md) 维护。关联任务:[module-batches-ag-status-fix](../ops/short-term/2026-09-23-module-batches-ag-status-fix.md)。
|
||||
|
||||
## 事实与证据
|
||||
|
||||
- **预期**:`module-batches-ag` 在 A–G 合入且 arch-check 全 0 后保持 `done`(提交 `77bdbdbc` 已写入)。
|
||||
- **实际**:本地 `dev` tip 上该行状态为 `planned`,剩余工作栏仍写「关闭本伞行」与 A–G 已合入事实矛盾;用户观感为「多次要求实现但未实现」。
|
||||
- **触发**:含 FEATURE-MATRIX 的 closeout / sync 合并冲突手解,取了无 `record_id` 或旧侧行内容。
|
||||
- **影响**:后续会话按 `planned` 错误前提规划,可能重复实施或延误收口;不构成发布 blocker(发布关系仍为 `non_blocker`)。
|
||||
- **环境**:本机 `dev` @ `18b9556f`(任务基线);修复提交见本任务 feature 分支。
|
||||
- **复现(修复前)**:`git show 77bdbdbc:.doc/status/FEATURE-MATRIX.md` 该行 status=`done`;修复前 tip 同行为 `planned`。
|
||||
|
||||
## 根因与同类范围
|
||||
|
||||
- **已证实**:共享文档在 `docs apply` 行级 CAS / `record_id` 稳定键启用前窗口内,merge 冲突对手解无机器核验状态字段;手解取旧侧覆盖 `done`。
|
||||
- **已排除**:A–G 代码未合入(合入 merge commits 与 arch-check PASS 否定)。
|
||||
- **共用机制**:CURRENT / FEATURE-MATRIX 等协调 SSOT;任何绕过 `docs apply` 的整表手改或冲突取旧侧。
|
||||
- **同类入口**:其他矩阵行、CURRENT 认领行在无 CAS 收据时同样脆弱;本轮只修 `module-batches-ag`,不扩大扫全表 unless 另授权。
|
||||
|
||||
## 修复思路与过程
|
||||
|
||||
| 日期 | 假设 / 尝试 / 动作 | 实际结果与证据 | 决策 / 下一步 / owner |
|
||||
|---|---|---|---|
|
||||
| 2026-09-23 | 只读考古 git + arch-check | A–G 已落地;状态回退成立 | 按计划修正登记,不重做代码 / Cursor |
|
||||
| 2026-09-23 | docs apply 行级 CAS 恢复 `done` + 登记 lesson | MATRIX 行 status=`done`;header 同步;arch-check PASS | resolved;合入 local_dev / Cursor |
|
||||
|
||||
方案:恢复矩阵事实状态;登记问题与经验;强制后续矩阵变更走 `docs apply`;合入含 MATRIX 的合并后机器核对目标 `record_id` 状态列。
|
||||
|
||||
## 验收与关闭
|
||||
|
||||
- 原例:PASS — MATRIX `module-batches-ag` status=`done`(docs apply 收据 + commit `b9d09c97`)。
|
||||
- 同类:本任务不批量改其他行;风险已记入 lesson。
|
||||
- 正常:PASS — `docs apply` 无拒绝;`./scripts/arch-check.sh --mode block` PASS(worktree tip)。
|
||||
- deployment:`not_required`(纯文档)。
|
||||
- resolved:2026-09-23;范围=状态登记与台账,不含 Server 镜像字段增量。
|
||||
|
||||
## 经验与复发
|
||||
|
||||
- lesson:[LESSON-20260923-matrix-status-cas](../ops/lessons/2026-09-23-matrix-status-cas.md)
|
||||
- 防护:能力完成升 `done` 已有 `docs:approve` + evidence `cat-file` 门禁;复发时重开本 issue 并检查是否绕过 apply。
|
||||
@@ -1,297 +0,0 @@
|
||||
---
|
||||
title: "系统整改与重构方案 — 前两阶段及取消状态契约审核检查清单"
|
||||
status: done
|
||||
created: 2026-09-23
|
||||
updated: 2026-09-23
|
||||
severity: high
|
||||
task_id: modular-refactor-review-2026-09-23
|
||||
---
|
||||
|
||||
# 系统整改与重构方案 — 前两阶段及取消状态契约审核检查清单
|
||||
|
||||
## 1. 目的与范围
|
||||
|
||||
本清单供**产物机器**上的方案执行者,对照自查《系统整改与重构方案》中**阶段 1、阶段 2、取消状态契约**是否可审、可测、可回退。
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 目标方案(产物机器,本机不可见) | `.doc/remediation/2026-09-22-agent-system-modular-refactor-plan.md` |
|
||||
| 目标 worktree(产物机器) | `.worktrees/modular-contract-standard-2026-09-22` |
|
||||
| 本机清单基线 | local `dev@8f0e31e53a5f8d0dd25a908ba6d127a5bb6768a4` |
|
||||
| 本轮授权 | **仅编制清单并合入本机 dev**;不实施业务代码;不审核方案正文(本机无正文);不 push |
|
||||
| 自查结果枚举 | `符合` / `偏差` / `阻断` |
|
||||
|
||||
**非目标**:阶段 3–6 全量逐条(除非阶段 1/2 或取消契约依赖它们);业务实施;改 YAML 例外;FAV live / `production_ready` / test·main 晋升。
|
||||
|
||||
## 2. 「22 条规范」映射回填(本机未定位权威编号表)
|
||||
|
||||
本机可见权威材料中**没有**名为「22 条规范」的独立编号清单。邻近可对账来源:
|
||||
|
||||
| 候选来源 | 本机状态 | 与「22」的距离 |
|
||||
|---|---|---|
|
||||
| [模块开发规范](../system-design/2026-09-20-module-development-standards.md) §2–§4(端口规则表、事件契约、故障隔离红线 1–7、checklist) | active | 条目合计接近但**未编号为 1–22** |
|
||||
| [耦合审计](./2026-09-20-module-coupling-audit.md) + [A–G 分批计划](../remediation/2026-09-20-module-decoupling-batch-plan.md) | A–G 能力行已 `done` | 21 条 YAML `exceptions` + 边界规则,**非**「22 条规范」正文 |
|
||||
| 产物机器新方案(2026-09-22) | 本机不可见 | **应以方案正文为准** |
|
||||
|
||||
产物机器回填表(填完后本清单才可宣称「22 条已闭环对账」):
|
||||
|
||||
| 规范编号 | 方案章节/工作包 ID | 本机对账锚点(规范/A–G/代码路径) | 阶段归属 | 自查 |
|
||||
|---|---|---|---|---|
|
||||
| N01 | _待填_ | _待填_ | 1 / 2 / cancel / 其他 | |
|
||||
| N02 | _待填_ | _待填_ | | |
|
||||
| … | | | | |
|
||||
| N22 | _待填_ | _待填_ | | |
|
||||
|
||||
若方案「22 条」≠ 上表候选来源,在回填表首行注明**权威出处路径 + SHA**,禁止用 A–G `done` 冒充新方案已验收。
|
||||
|
||||
## 3. 判定规则
|
||||
|
||||
| 判定 | 条件 |
|
||||
|---|---|
|
||||
| 符合 | 方案条目写明代码位置、依赖、责任范围、测试场景、回退条件;与本机锚点无冲突;测试可复现 |
|
||||
| 偏差 | 可合入意图成立,但路径过时、依赖遗漏、测试偏弱或回退含糊;实施前须修订方案 |
|
||||
| 阻断 | 与生效规范/[验证契约](../ops/2026-09-21-validation-contract.md)/表写者/事件至少一次语义冲突;或回退会丢数据/假 PASS |
|
||||
|
||||
每条核对项须留下:方案段落锚点、对照 SHA、结论、证据路径(可为本机相对路径或产物机器截图哈希)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 阶段 1 — 契约、模块职责、验证基线
|
||||
|
||||
### R1.1 三种通信契约完整且无第四种
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 模块开发规范 §2.1–§2.3;ADR 模块化单体 |
|
||||
| 应核对代码/文档 | `internal/app/*/ports.go`;`internal/events/registry.go` `StaticContracts()`;`internal/server` wire DTO;方案工作包是否禁止 gRPC/全局 bus/跨包未导出 helper |
|
||||
| 依赖与责任 | 消费者定义端口;组合根(`internal/app`、`cmd/*`)注入;server 不持领域 SQL |
|
||||
| 测试场景 | 新增端口无 JSON/`pgx`/物理路径;事件改动跑 registry↔YAML parity;HTTP 错误信封 `code/message/request_id` |
|
||||
| 回退核对 | 契约变更可单批 revert;不留下「半套第四种通信」 |
|
||||
| 自查 | |
|
||||
|
||||
### R1.2 表唯一写者与解包事务名单
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 规范 §4 红线 1–2;`module-boundaries.yaml` `table_owners` |
|
||||
| 应核对代码 | YAML `table_owners` / `tx_unpackers`;工作包是否把跨表原子性放在用例 UnitOfWork,而非各模块自开事务 |
|
||||
| 依赖与责任 | 非属主不得 `INSERT/UPDATE/DELETE`;server/chat 不得解包 `pgx.Tx`(除非已登记例外且有到期日) |
|
||||
| 测试场景 | `./scripts/arch-check.sh --mode block`;针对新增写路径的属主负例 |
|
||||
| 回退核对 | 回退代码与恢复/删除 exception **成对**,避免门禁与代码错位 |
|
||||
| 自查 | |
|
||||
|
||||
### R1.3 事件信封与至少一次投递 + 幂等
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 规范 §2.2、§3.2 |
|
||||
| 应核对代码 | `internal/events/registry.go`;`ClaimLeases` / outbox 同 UoW;消费者 inbox/`source_event_id`(例:`internal/notification/service.go` `EmitVisible*`) |
|
||||
| 依赖与责任 | 生产路径为 PG outbox + `cmd/events`;`MemoryBus` 仅特征测试 |
|
||||
| 测试场景 | 重复投递仅一个可见副作用;缺 `environment`/`project_id` fail closed;永久失败进 dead/quarantine 不堵其他订阅者 |
|
||||
| 回退核对 | 不回退到 SELECT-only claim(`ClaimIDs` 已禁用) |
|
||||
| 自查 | |
|
||||
|
||||
### R1.4 模块职责与 A–G 残留边界
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | [A–G 分批计划](../remediation/2026-09-20-module-decoupling-batch-plan.md);FEATURE-MATRIX「模块解耦批次 A–G」=`done` |
|
||||
| 应核对 | 新方案 17 工作包是否**重复**已合入的 A–G,或明确「在 A–G 之上增量」;互斥 mutex 是否与已关闭批次冲突 |
|
||||
| 依赖与责任 | 新工作包不得把 FAV live / RPC / `production_ready` 回退写进完成定义 |
|
||||
| 测试场景 | 声明的依赖边在合入后可用 `go list` / arch-check 证明消失或未回潮 |
|
||||
| 回退核对 | 单工作包 revert;不整支回滚无关批次 |
|
||||
| 自查 | |
|
||||
|
||||
### R1.5 验证基线与门禁衔接
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | [验证契约](../ops/2026-09-21-validation-contract.md);规范 §7 |
|
||||
| 应核对 | 方案阶段 1「验证基线」是否映射到:`arch-check --mode block`、`go vet ./...`、`go test -short ./...`;前端相关则 `npm test` / `npm run build`;纯文档不要求 PI |
|
||||
| 依赖与责任 | stub/SKIP 不得作交付 PASS;共享环境测试须持锁 |
|
||||
| 测试场景 | 方案每个工作包的「测试场景」列能落到精确包路径或 `-run` 名 |
|
||||
| 回退核对 | 失败时保留候选证据,不伪造 PASS |
|
||||
| 自查 | |
|
||||
|
||||
### R1.6 稳定词汇与跨包错误
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 规范 §3.3;批次 C |
|
||||
| 应核对 | `internal/contracts/vocabulary`;方案是否禁止新增 `docgov.State*` / `Role*` / `Err*` 跨包引用 |
|
||||
| 依赖与责任 | 带哈希/路径的函数留在属主模块(如 `doccontent`) |
|
||||
| 测试场景 | 热点引用改为端口或词汇后,原状态机测试仍绿;HTTP code 不变 |
|
||||
| 回退核对 | 单批 revert |
|
||||
| 自查 | |
|
||||
|
||||
---
|
||||
|
||||
## 5. 阶段 2 — 通知事务、事件领取、授权、业务入口一致性
|
||||
|
||||
### R2.1 通知与领域提交同事务
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 规范 §2.2「副作用与 receipt 能进同一数据库事务的必须同事务」;§4 红线 4(持锁不做外部 IO) |
|
||||
| 应核对代码 | `internal/notification/service.go` / `document_events.go`(`EmitVisible*` 要求 caller fenced tx);`internal/app/docadvance/consumer.go`;dispatcher `handle` 在 lease tx 内调用 handler |
|
||||
| 依赖与责任 | notify 消费者不在持锁路径调 LLM/HTTP/SSE;可见通知以 `source_event_id` / dedupe 幂等 |
|
||||
| 测试场景 | 提交失败无可见通知;重复 `source_event_id` 成功且不双写;`HashVisibleNotifications` 类对账 |
|
||||
| 回退核对 | 回退后不得留下「已提交领域、无通知」或相反的半状态;优先前滚修复 |
|
||||
| 自查 | |
|
||||
|
||||
### R2.2 事件领取:lease、续租、抢占
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 规范 §2.2;Phase 2 事件计划(投递/lease 语义) |
|
||||
| 应核对代码 | `internal/events/dispatcher.go` `ClaimLeases` / `HeartbeatLease`;`internal/events/worker.go`;`cmd/events` |
|
||||
| 依赖与责任 | 生产禁止 `ClaimIDs`;quarantine/expire 不可被再次 claim;多 worker 互斥由 `FOR UPDATE SKIP LOCKED` 语义保证 |
|
||||
| 测试场景 | `dispatcher_pg_test`:双 worker 仅一人领到;quarantine 不可领;续租失败不再处理 |
|
||||
| 回退核对 | 不恢复已禁用的 SELECT-only claim;lease 时长变更有观察窗 |
|
||||
| 自查 | |
|
||||
|
||||
### R2.3 授权检查收敛点
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 规范 §2.1「Principal 只来自已认证会话」;§2.3 授权拒绝不泄露存在性;多意图设计「卡片/SSE 不能替代授权」 |
|
||||
| 应核对代码 | `internal/authz`;`internal/server/*_handlers.go`(task/intent/freeform 等)在 Flush/副作用前鉴权;`events.AuthorizePrincipal` 于消费者路径 |
|
||||
| 依赖与责任 | 请求体不得覆盖 UserID/ProjectID;消费者授权失败 → quarantine,非无限重试 |
|
||||
| 测试场景 | 跨用户 IDOR 负例 403;SSE 鉴权在 Flush 前(对照 gap `AUTH-TASK-SSE`);重复提交不绕过 |
|
||||
| 回退核对 | 回退不得重新打开已关闭 IDOR;测试与代码同批 |
|
||||
| 自查 | |
|
||||
|
||||
### R2.4 业务入口一致性(HTTP / 对话 / SSE / 事件投影)
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 规范 §2.3;多意图权威性排序:认证主体与资源 → 授权/不变量 → PG → 卡片投影 → SSE |
|
||||
| 应核对代码 | 同一命令是否只经一个用例入口;chat action 与 REST 是否共用端口;投影/SSE 是否只读权威状态 |
|
||||
| 依赖与责任 | GET 不修投影(红线 6);修复为独立命令并写审计 |
|
||||
| 测试场景 | 双入口同输入同权威结果;刷新后以 GET 覆盖本地缓存;投影丢失仍能经 active discovery 找回 |
|
||||
| 回退核对 | 入口合并失败时可切回旧入口且状态不分裂 |
|
||||
| 自查 | |
|
||||
|
||||
### R2.5 与阶段 1 基线的衔接(方案自述三处衔接问题)
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 用户汇报:审阅发现的三处衔接问题已修正 |
|
||||
| 应核对 | 方案正文是否显式列出三处问题的**原描述、修正段落、回归检查**;是否仍依赖未合入的阶段 3+ 契约 |
|
||||
| 依赖与责任 | 修正不得静默改验证契约或放宽 arch-check |
|
||||
| 测试场景 | 针对三处各有一条可执行核对(文档锚点或测试名) |
|
||||
| 回退核对 | 修正可独立 revert 而不拆阶段 1 |
|
||||
| 自查 | |
|
||||
|
||||
---
|
||||
|
||||
## 6. 取消状态契约 — Runner 取消、未知结果、SSE 恢复
|
||||
|
||||
> 用户建议优先审核。本机可见实现重心:`internal/taskrun`(`Cancel`/`StatusCancelled`/`taskrun.cancelled` 事件)、`internal/server/task_run_handlers.go`(Cancel + SSE `after_seq`)、`internal/agent/piagent.go`、多意图计划中的 cancel 转移。
|
||||
|
||||
### R3.1 取消状态机覆盖全转移
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 方案「取消状态契约」;多意图步骤状态含 `cancelled`;`taskrun.cancelled` 事件登记 |
|
||||
| 应核对 | 状态集合是否覆盖:`cancel_requested` →(执行中)→ `cancelled` / `unknown`(或方案等价命名);禁止从终态回退到 running |
|
||||
| 代码锚点 | `internal/taskrun/finalize.go`(`Commands.Cancel`、`StatusCancelled`、事件名);`manager.go` `Cancel`;意图计划状态机(若工作包触及) |
|
||||
| 依赖与责任 | 取消与 finalize 竞态仅一个终态(见 `TestPG_FinalizeCancelRaceOneTerminal` / `TestCommands_CancelWinsOverFinalizeMemory`) |
|
||||
| 测试场景 | 用户取消、租约过期视同取消、Runner 已结束后的迟到取消、双端并发 cancel/finalize |
|
||||
| 回退核对 | 回退不得出现双终态或「已取消仍计费/仍写产物」 |
|
||||
| 自查 | |
|
||||
|
||||
### R3.2 未知结果:幂等重试与人工裁定
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 操作规范/AGENTS:Docker/网络超时先区分未知与未执行;管理器不自动撤销外部副作用 |
|
||||
| 应核对 | 方案是否定义 `unknown`(或等价)的进入条件、可见对外语义、幂等重试键、人工裁定 API/运维入口、超时升级 |
|
||||
| 代码锚点 | taskrun 结果应用路径;PI Runner 客户端(`internal/agent/piagent.go`);方案工作包列出的裁定命令 |
|
||||
| 依赖与责任 | 未知不得冒充 `succeeded`/`cancelled`;重试必须带 fencing/idempotency,避免双执行 |
|
||||
| 测试场景 | Runner 超时无响应 → unknown;重试仅一次可见副作用;裁定后 SSE/GET 一致 |
|
||||
| 回退核对 | 清除 unknown 标记不得删除审计;禁止自动 Down/删库「恢复」 |
|
||||
| 自查 | |
|
||||
|
||||
### R3.3 执行租约、fencing 与取消的交互
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 多意图设计:短 lease + owner + lease_until + fencing;续租失败不再领步骤 |
|
||||
| 应核对 | 取消是否使 lease 立即失效;旧 fencing token 的迟到心跳/完成是否被拒绝 |
|
||||
| 代码锚点 | `internal/taskrun` store/lease;workspace lease 相关迁移与调用 |
|
||||
| 依赖与责任 | 持 lock 期间取消不调用外部 IO;取消收据与 outbox 同事务(若发 `taskrun.cancelled`) |
|
||||
| 测试场景 | 取消后旧 worker 心跳失败;fencing 错则拒绝 finalize |
|
||||
| 回退核对 | 放宽 fencing 视为阻断,不得以「兼容」绕过 |
|
||||
| 自查 | |
|
||||
|
||||
### R3.4 SSE 恢复后与权威状态一致
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 系统健康整改 Wave0(`after_seq`、心跳、Flush 前鉴权);多意图「SSE 允许重复/乱序/丢失,缺口 GET 对账」 |
|
||||
| 应核对代码 | `internal/server/task_run_handlers.go`(`after_seq`、`extendSSEWriteDeadline`、Cancel handler);`web/src/api/taskStream.ts`;聊天 SSE 同等语义 |
|
||||
| 依赖与责任 | SSE 非权威;取消/unknown 以 PG/GET 为准覆盖本地 |
|
||||
| 测试场景 | 断线重连不重复创建运行;取消过程中重连看到终态;WriteTimeout 后同 turn 不误 409(对照 `DOCREV-SSE-IDEM-BUSY` 经验) |
|
||||
| 回退核对 | 去掉 `after_seq` 视为回归阻断 |
|
||||
| 自查 | |
|
||||
|
||||
### R3.5 Runner 取消传播
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| 规范来源 | 方案阶段 2/3 交界:Runner 取消与未知结果 |
|
||||
| 应核对 | HTTP/对话取消 → taskrun → PI Runner 取消信号是否端到端定义;Runner 已完成后的取消应答 |
|
||||
| 代码锚点 | `Manager.Cancel`;server cancel 路由;PI 客户端 cancel |
|
||||
| 依赖与责任 | 取消失败进入 unknown 而非假 cancelled(若方案如此定义则测试锁定) |
|
||||
| 测试场景 | Runner 可取消;Runner 无响应 → unknown;已终态 cancel 幂等成功 |
|
||||
| 回退核对 | 回退保留「至少不双执行」不变量 |
|
||||
| 自查 | |
|
||||
|
||||
---
|
||||
|
||||
## 7. 工作包级抽查模板(阶段 1/2 + 取消相关包)
|
||||
|
||||
对方案中每个相关工作包复制下表(ID 以方案为准):
|
||||
|
||||
| 工作包 ID | 阶段 | 规范 Nxx | 代码位置(方案 vs 本机) | 依赖 | 责任范围 | 测试场景可执行? | 回退可操作? | 判定 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| WP-? | 1 | | | | | 是/否 | 是/否 | |
|
||||
| WP-? | 2 | | | | | | | |
|
||||
| WP-? | cancel | | | | | | | |
|
||||
|
||||
**阻断级缺省**(出现任一条则该包不得开工实施):
|
||||
|
||||
1. 无精确文件/包路径,或路径在本机 `dev@8f0e31e5` 已改名且方案未更新。
|
||||
2. 测试场景只有「手动看看」或依赖 stub 作交付。
|
||||
3. 回退是「再想想」或要求硬重置/删库。
|
||||
4. 扩大写路径/mutex 未在任务登记中重新认领。
|
||||
5. 将卡片/SSE/前端缓存当作授权或权威状态。
|
||||
|
||||
## 8. 产物机器回填指引
|
||||
|
||||
1. 在产物机器打开方案 + 本清单(本清单合入本机 `dev` 后,经授权 `push` 或手动同步到产物机器)。
|
||||
2. 先填 §2 的 N01–N22 映射;未填完不得宣称阶段 1 审核通过。
|
||||
3. 按 §4–§6 逐条标 `符合`/`偏差`/`阻断`,证据写入方案附录或 `.doc/test-reports/`(普通文档级即可)。
|
||||
4. 若有 `阻断`:只改方案文档,**不**开工对应业务代码;修正后更新方案 `updated` 与衔接说明。
|
||||
5. 全部阶段 1/2 + 取消契约无 `阻断` 且偏差有修订计划后,在产物机器 CURRENT 登记「方案审核通过、待实施授权」——实施须**另开**任务与授权,不由本清单授权。
|
||||
6. 本清单单列任务 `modular-refactor-review-2026-09-23`;方案合入/实施不得冒用本 task_id 扩权。
|
||||
|
||||
## 9. 本机环境与证据边界
|
||||
|
||||
| 项 | 记录 |
|
||||
|---|---|
|
||||
| 本机 | macOS Darwin;仓库 `/private/tmp/Agent-System` |
|
||||
| 方案正文 | **不可见**(另一主机 `/home/weichen/projects/...`;origin/frp-mix 无对应分支) |
|
||||
| agentctl | 本机已可用 `with` / `docs apply` / `validate` / `integrate`(进程层);创建本任务时已 `task register` |
|
||||
| 清单性质 | 审核**方法**与核对项,不是对方案正文的已审结论 |
|
||||
|
||||
## 10. 相关链接
|
||||
|
||||
- 任务记录:[../ops/short-term/2026-09-23-modular-refactor-review.md](../ops/short-term/2026-09-23-modular-refactor-review.md)
|
||||
- 模块开发规范:[../system-design/2026-09-20-module-development-standards.md](../system-design/2026-09-20-module-development-standards.md)
|
||||
- A–G 分批:[../remediation/2026-09-20-module-decoupling-batch-plan.md](../remediation/2026-09-20-module-decoupling-batch-plan.md)
|
||||
- 耦合审计:[./2026-09-20-module-coupling-audit.md](./2026-09-20-module-coupling-audit.md)
|
||||
- 验证契约:[../ops/2026-09-21-validation-contract.md](../ops/2026-09-21-validation-contract.md)
|
||||
- gap-matrix:[../remediation/gap-matrix.md](../remediation/gap-matrix.md)
|
||||
- 操作规范:[../ops/2026-09-21-agent-worktree-workflow.md](../ops/2026-09-21-agent-worktree-workflow.md)
|
||||
@@ -1,67 +0,0 @@
|
||||
# 管理员重置密码 / 登录凭据缺陷 — 问题主记录
|
||||
|
||||
更新:2026-09-24。任务:`admin-password-reset-2026-09-24`。
|
||||
|
||||
## ISSUE-20260924-admin-reset-dead
|
||||
|
||||
### 问题
|
||||
|
||||
管理台「重置密码」按钮调用 `authClient.adminResetPassword`,客户端硬 `throw`,后端无 `reset-password` 路由;UI 仍硬编码 `ResetPass123` 暗示成功。验收脚本曾重置 `chenwei` 哈希且不披露口令后,管理员无法通过 UI 恢复访问。
|
||||
|
||||
### 根因
|
||||
|
||||
T20-F4 已设计未实施(选项 B 卡产品)。`password_changed_at` 停在 2026-09-20 证明重置从未入库。
|
||||
|
||||
### 修复
|
||||
|
||||
`POST /api/v1/admin/users/{id}/reset-password`:服务端随机临时口令、`must_change_password=true`、撤销会话、审计表 `user_password_reset_audits`(goose 00067);前端接线并去掉硬编码。
|
||||
|
||||
### 状态
|
||||
|
||||
resolved(本任务合入后)。
|
||||
|
||||
---
|
||||
|
||||
## ISSUE-20260924-login-error-envelope
|
||||
|
||||
### 问题
|
||||
|
||||
登录失败响应 `code=AUTHZ` / `message=无权访问`,前端再把整段 JSON 原文塞进 `Error.message`,用户误判为权限问题。
|
||||
|
||||
### 根因
|
||||
|
||||
`httpx.CodeFromStatus(401)=AUTHZ` + `SafeMessage`;`auth.ts` login 未用信封解析、未优先 `error` 领域字段。
|
||||
|
||||
### 修复
|
||||
|
||||
`authErrorMessage` 优先取信封 `error`;不改全局 AUTHZ 映射(事件复用与安全取舍另立专项)。
|
||||
|
||||
### 状态
|
||||
|
||||
resolved。
|
||||
|
||||
---
|
||||
|
||||
## ISSUE-20260924-zombie-credentials
|
||||
|
||||
### 问题
|
||||
|
||||
`CreateUser` 在 `PasswordHash==""` 时静默跳过 `user_credentials` 插入;`LEFT JOIN` + `COALESCE` 使登录哈希为空串,任意密码均失败且报错与真凭据错误相同。
|
||||
|
||||
### 盘点(只读,2026-09-24)
|
||||
|
||||
| 环境 | total | missing_cred | empty_username |
|
||||
|---|---|---|---|
|
||||
| dev | 416 | 263 | 255 |
|
||||
| test | 9 | 0 | 0 |
|
||||
| main | 4 | 3 | 0 |
|
||||
|
||||
main 三行为 goose 00011 seed(`seed-admin` 等),非业务用户。本任务**不清理**存量;仅 fail-closed 防新增。
|
||||
|
||||
### 修复
|
||||
|
||||
PgStore/MemoryStore `CreateUser` 拒绝空哈希;`Login` 对空哈希记 `slog.Warn(user_id)` 仍统一 401。
|
||||
|
||||
### 状态
|
||||
|
||||
resolved(机制);存量清理 = open / 另授权。
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
issue_id: ISSUE-20260924-cursor-hook-event-contract
|
||||
issue_state: open
|
||||
severity: medium
|
||||
owner: Cursor
|
||||
task_ids: [cursor-governance-hooks-2026-09-24]
|
||||
created: 2026-09-24
|
||||
occurred_at: 2026-09-24
|
||||
updated: 2026-09-24
|
||||
recurrence_count: 0
|
||||
evidence_basis: current
|
||||
lesson_ids: [LESSON-20260924-cursor-hook-advisory-gates]
|
||||
---
|
||||
|
||||
# Cursor hook 事件字段契约未文档化
|
||||
|
||||
## 事实与证据
|
||||
|
||||
预期:`beforeMCPExecution` / `sessionStart` / `stop` 的 stdin 字段名与 matcher 匹配串在官方文档中明确,便于 failClosed 硬门禁。
|
||||
实际:官方 create-hook skill 仅明确 `beforeShellExecution` 的 `command` 字段;`beforeMCPExecution` 不支持 `updated_input`;`sessionStart` 无文档化返回字段可注入上下文;`MCP: ...` matcher 形式只写给 `preToolUse` 族。实现层字符串探测存在 `mcp_server_name`/`tool_name`/`tool_input`,但非文档契约。
|
||||
|
||||
证据:本任务调研记录;单元测试用多名容错驱动;真实 Cursor IDE 事件采样待 `CURSOR_HOOKS_PROBE=1`。
|
||||
|
||||
## 根因与同类范围
|
||||
|
||||
客户端 hook API 文档滞后于实现。同类:任何依赖未文档化 hook 输入的 failClosed 门禁都有假阴性/假阳性风险。
|
||||
|
||||
## 修复思路与过程
|
||||
|
||||
| 日期 | 动作 | 结果 | 下一步 |
|
||||
|---|---|---|---|
|
||||
| 2026-09-24 | 落地 advisory hooks + 多名容错 + probe 开关;异形 fail-open | 单元回归 PASS | 用户触发真实 MCP/shell 事件采样后收紧 |
|
||||
|
||||
## 验收与关闭
|
||||
|
||||
- 静态/单元:已覆盖(见测试报告)
|
||||
- 实机:打开 `CURSOR_HOOKS_PROBE=1`,触发一次 `pi_subagent_roles` 与一次 shell,归档 `.cursor/hook-probe.jsonl` 片段到测试报告 assets;确认字段名后可将 matcher/`failClosed` 收紧并将本 issue → verifying/resolved
|
||||
|
||||
## 经验与复发
|
||||
|
||||
见 [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md)。
|
||||
|
||||
## 2026-09-24 IDE 采样更新
|
||||
|
||||
- `postToolUse` 审计:`tool_name` / 审计字段为 `MCP:pi_subagent_roles`(带 `MCP:` 前缀)。
|
||||
- 修复:`_lib.normalize_tool_name` 剥前缀;回归 `test_ask_mcp_prefixed_tool_name_bad_sha`。
|
||||
- `pi_subagent_roles` IDE MCP 调用 PASS;`postToolUse` 收据 checklist 已注入。
|
||||
- `beforeMCPExecution` 完整 stdin 仍缺(Cursor 进程未设 `CURSOR_HOOKS_PROBE=1`);issue 保持 verifying。
|
||||
- `agentctl`/`jev` 未出现在 IDE MCP 缓存目录;进程可手动 stdio 启动;与路径修复独立,另记。
|
||||
@@ -1,37 +0,0 @@
|
||||
# ISSUE-20260924-non-author-400-duty
|
||||
|
||||
## 摘要
|
||||
|
||||
非编制项目成员无法上传/总结/对话写草稿;权限错误经 `writeDocGovError` 默认落成 HTTP **400**。
|
||||
|
||||
## 根因
|
||||
|
||||
1. `domainHTTPStatus` 未映射 `ErrOnlyAuthorCanEdit` / `ErrReviewerCannotEdit` / `ErrApproverCannotEdit` → 403。
|
||||
2. `classifyAccess` / `AllowedTaskKeys` / `CanEditDocumentContent` 将 run/edit 绑编制职责(三道门协同过宽)。
|
||||
3. 前端写意图路由偶发把「总结+写动词」送入 task run。
|
||||
|
||||
## 处置(deny_only_submit)
|
||||
|
||||
- run/edit → 项目成员级;submit/review/approve 保留职责门禁。
|
||||
- AuthorID 仍归编制职责人(`docduty.Resolve` 不变)。
|
||||
- 人工编辑传 `ActorIsMember`,不复用 `RoleSystem`。
|
||||
|
||||
## 验证
|
||||
|
||||
见 [测试报告](../test-reports/2026-09-24-non-author-member-access-test-report.md);真实 PI PASS。
|
||||
|
||||
## 状态
|
||||
|
||||
resolved(2026-09-24)
|
||||
|
||||
## 五态收口(2026-09-24)
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| review_state | accepted(真实 PI `TestNonAuthorMember_PiAgent_RunEditSubmitGates` PASS;工程门禁 PASS) |
|
||||
| integration_state | merged_local_dev(`dev@e98e2d71`;feature tip `8b2621a4` 为祖先) |
|
||||
| deployment | not_required(本轮未要求加载 launchd 业务制品) |
|
||||
| cleanup | pending(`.worktrees/non-author-member-access-2026-09-24` 与 integrate 现场待独立维护者复查后清理;禁止 `--force`) |
|
||||
| remote_sync | pushed(`origin/dev` = `e98e2d71`,`./scripts/git-push-dev.sh dev` 已成功) |
|
||||
|
||||
相关 agentctl 任务:`non-author-member-access-2026-09-24`、`non-author-member-access-docs-2026-09-24`、`integrate-non-author-docs-2026-09-24` 均为 `done`。
|
||||
@@ -1,45 +0,0 @@
|
||||
# PI Subagent 执行器初版边界审查
|
||||
|
||||
task_id:subagent-workflow-standard-2026-09-24;issue_id:ISSUE-20260924-pi-executor-boundaries。
|
||||
owner:Cursor(修复)/ Codex(复核);issue_state:resolved;severity:high。
|
||||
本记录针对尚未发布的执行器初版,不表示 dev 或产品 Runner 存在这些实现。
|
||||
|
||||
## 事实与机制
|
||||
|
||||
1. 独立验证发现 PI 内置工具的路径规范化与扩展守卫不一致。安装版本 0.85.1 的 tools/path-utils.js 中 resolveToCwd 使用 stripAtPrefix 并展开 home;初版守卫使用 path.resolve(root,input)。
|
||||
2. 以专门创建的 /tmp/pi-guard-audit-* 临时目录及 outside.txt 假文件测试 @绝对路径,实际结果为 guard_blocked=false、actual_tool_path_escapes=true。没有读取真实密钥或业务文件。
|
||||
3. 同类范围:@ 前缀、~ 前缀、相对父路径、符号链接、Unicode/读取路径规范化;MCP 的同仓/工作区验证和临时文件写入;报告幂等与损坏收据;进程树/输出上限/环境变量隔离。
|
||||
4. 初版静态阅读另发现:跨仓 MCP 可能执行目标仓脚本;输出仅在 communicate 完成后截断;只回收仍存活 leader 的进程组;测试环境黑名单不足;模型报告用关键词推导 PASS。上述需要实现修复和负例,不以本行代替实测。
|
||||
5. 初版测试夹具存在 eager stderr.read(),在 MCP 仍存活时阻塞。host 两次仅终止 /tmp/pi-subagent-test-* 的假 MCP 子进程以释放测试,未终止产品或用户进程。
|
||||
|
||||
## 复现与迭代
|
||||
|
||||
- 初次 RED:19 项,7 failures / 11 errors,主实现未创建;存在性/调用失败为已缺失功能,不当作实现通过。
|
||||
- 初版回归:19 项,4 failures / 7 errors;耗时含夹具死锁处理。后续错误数不作为发布质量结论,待主机完整重跑。
|
||||
- Cursor 首轮 supervisor 已由 host 为明确的修复交接发送 TERM,退出143;源文件保留。没有未知写副作用后盲目重派,第二轮是带具体修复清单的新执行。
|
||||
- 本机 Qwen3.8-Flash、GLM-5.3-Flash 无工具短请求连通通过,实际 provider/model 与配置一致,正常 stop + agent_end/agent_settled。仅连接证据。
|
||||
- GLM-5.3 对初版整包快照的只读审查 300 秒超时,无完整结论;不报审查 PASS。进程由 subprocess 超时处理结束,未授予工具,无仓库写入。
|
||||
|
||||
## 修复与验收要求
|
||||
|
||||
Cursor 修复清单已交接:统一/拒绝路径规范化;MCP 同仓注册验证和无租约写入;有界双向进程通信/整体回收;测试环境白名单;严格请求/配置与冻结 SHA;损坏收据禁止重派;报告完成与审查通过分离;最终事件完整性;禁用 PI 隐式重试;相关真实 Git/进程/MCP 回归。
|
||||
|
||||
关闭条件:静态发现均落实对应修复或有证据排除;原例与同类负例通过;真实 PI 调用经新执行器完成;审查与测试报告保存。修复中,不新增 validated 经验;验证后再总结。
|
||||
|
||||
## 2026-09-24 修复关闭
|
||||
|
||||
issue_state=resolved 仅针对未发布初版的约定缺陷;代码提交 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119,主机完整工程回归 173 项通过,提交后专项 34 项通过;最终 Cursor CLI→MCP→PI 中 ls/read 全通过。实际覆盖、早期失败和独立 GLM 审查边界见[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。
|
||||
新增[经验](../ops/lessons/2026-09-24-pi-tool-boundaries.md)。本文件前面的“修复中/待验证”为初版历史,当前结论以本节为准。dev 集成/客户端 IDE 验收不由本问题关闭状态推导。
|
||||
|
||||
## cursor-cli-mcp-path
|
||||
|
||||
issue_id:ISSUE-20260924-cursor-cli-mcp-path;issue_state:deferred;severity:medium;owner:工程维护;日期:2026-09-24。
|
||||
本机 Cursor CLI 2026.09.18 在项目 MCP args 中未展开 workspaceFolder 变量,原样传给 Node。pi-subagents 新入口已改工作区相对路径并实测通过。
|
||||
同类只读检查:agent mcp list 也显示既有 agentctl / jev Connection failed,它们仍使用相同变量写法;codegraph ready。未进一步修改/验收这两个既有服务,也未断言 IDE 同样失败。官方支持声明与本机观测须分开。
|
||||
此残差不阻塞 PI MCP(其内部直接调用主仓治理 CLI),不构成本轮产品发布结论;后续由工程维护在 Cursor CLI 升级或这两项 MCP 接入验收时检查路径/stdio 协议,形成独立修复与实际客户端证据。仅保留问题,不宣称已修复。
|
||||
|
||||
|
||||
## cursor-cli-mcp-path 续:NDJSON 回包
|
||||
|
||||
2026-09-24 IDE:`pi-subagents`/`codegraph` ready;`agentctl`/`jev` 不在 MCP 缓存。
|
||||
根因补充:后两者 `send()` 使用 `Content-Length` 帧,而可加载的 `pi-subagents` 使用换行分隔 JSON-RPC。已改为 NDJSON 回包并补 `"type":"stdio"`;仍接受 Content-Length 请求。单元:`scripts/tests/test_mcp_ndjson_framing.py`。IDE 重载后需再核 `list-tools`。
|
||||
@@ -1,111 +0,0 @@
|
||||
# Cursor Auto 与 Subagent 工作流研究及文档验证报告
|
||||
|
||||
日期:2026-09-24;owner:Codex;task_id:subagent-workflow-standard-2026-09-24。
|
||||
范围:现行规范、Cursor 项目配置及官方文档;交付[规范草案](../ops/2026-09-24-subagent-workflow-standard.md)。未运行 Cursor 对话/真实 subagent,未修改产品或运行环境。
|
||||
|
||||
## 1. 研究结论
|
||||
|
||||
推荐主 Agent 协调、按需委派、独立审查与验证的流程。用户提出的八步可作为起点,但需在开始明确授权/验收标准,在方案阶段设计测试,在实施中自测,合并后核对实际运行结果,最后归档和清理。
|
||||
|
||||
| 方案 | 收益 | 代价/缺陷 | 结论 |
|
||||
|---|---|---|---|
|
||||
| 单 Agent 顺序完成全部阶段 | 简单、额外上下文成本低 | 实施者自审容易沿用错误假设 | 适合小型文档/研究;代码交付补独立审查 |
|
||||
| 每阶段固定一个 Agent / 固定模型 | 阶段职责直观 | 无效启动和文档重复;固定模型背离 Auto;阶段间易丢授权/版本 | 不采用 |
|
||||
| 主 Agent + 按需 analyst/reviewer/verifier | 保留上下文入口,独立检查,成本可控 | 需可靠派发包、证据接收和异常恢复 | 推荐;实现并行按风险逐步启用 |
|
||||
|
||||
这是本项目基于现状的设计判断,不是 Cursor 平台保证。
|
||||
|
||||
## 2. 官方能力与推论
|
||||
|
||||
查阅日期为 2026-09-24。在线文档会变化,客户端接入必须另验;不采用社区传闻作为技术契约。
|
||||
|
||||
| 来源 | 查证事实 | 对本规范的影响 |
|
||||
|---|---|---|
|
||||
| [Cursor Subagents](https://cursor.com/docs/subagents) | 自定义角色可位于 .cursor/agents;model 默认 inherit;readonly 与后台字段可配置;子上下文需要主 Agent 提供输入;默认共享 checkout | 采用继承策略、显式交接、仓库管理的写隔离;只读报告由主 Agent 保存 |
|
||||
| [Cursor Models & Pricing](https://cursor.com/docs/models-and-pricing) | Auto 是平台模型路由选项,公开文档列有不同优化模式 | 规则不绑定模型、价格或固定路由;按实际 UI/账户能力记录 |
|
||||
| [Cursor Rules](https://cursor.com/docs/rules) | 支持 AGENTS.md 和项目规则 .mdc | 根入口/客户端入口只指向单一规范,避免重复规则漂移 |
|
||||
|
||||
推论与限制:inherit 能表达继承意图,不足以证明实际模型身份或所有 Auto 请求的路由;独立上下文不保证跨模型独立性;只读权限与运行测试的写产物需要区别处理。Auto 可用性、角色加载、权限、真实派发及费用均未在本会话实测,不保证任何套餐或所有版本可用。云执行不在本次授权与建议默认范围内。
|
||||
|
||||
## 3. 当前仓库证据
|
||||
|
||||
检查基线:dev = 5423b261f97f371bdf7fa5066e9305f9eddaef42;本地 origin/dev 跟踪引用比较为 ahead 74 / behind 0。未 fetch,不能据此声明服务器当前引用。
|
||||
|
||||
- AGENTS / PROJECT:已定义授权分级、任务 worktree、独立状态、业务实施和研究边界。
|
||||
- worktree 操作规范:已有 agentctl 租约、候选验证/合入、共享环境持锁、清理负例和收口要求。
|
||||
- 验证契约:依据变更范围取并集,要求真实用户流程与持久证据;文档变更不要求产品回归。
|
||||
- 文档地图/任务模板:已有最小文档原则,可以按阶段留证而不制造九份重复文档。
|
||||
- .cursor/rules:已有 agentctl、文档、Git 和测试入口。rg --files .cursor 未发现项目 .cursor/agents 角色定义;不推断用户全局目录没有角色。
|
||||
- .cursor/hooks.json:存在 beforeShellExecution 的 Git 守卫;未见本流程阶段完整性校验。此处仅配置阅读,没有实际触发 hook。
|
||||
- cursor --version:3.21.16 / 8ae78e8eee1e63479c7e0504b664bc0a80c68000 / x64;agent --version:2026.09.18-9a7762b。CLI 版本不代表 IDE 当前会话配置已验收。
|
||||
- agentctl status:当前配置 policy_revision 为 agent-governance-2026-09-23-fav-constraint-restored;存在其他任务持 env:dev。研究不使用该环境,不改他人任务。
|
||||
|
||||
已读规范修订与工具配置 revision 不同,记录两者分别是什么,不把一个全局字段视作所有 Markdown 修订版本。
|
||||
|
||||
## 4. ISSUE-20260924-cursor-test-rule-drift
|
||||
|
||||
issue_state:open;严重度:medium;owner:Codex(研究);evidence_basis:本次源码/配置阅读;产品影响未复现。
|
||||
预期:客户端测试规则只引用验证契约,由适用范围和批准环境决定套件/Runner。
|
||||
实际:.cursor/rules/test-reports-standard.mdc(alwaysApply=true)仍要求报告附全量 go test -v ./...,固定 MiniMax-M2.7-highspeed,并指向已不存在的 PROJECT §8。与验证契约中的范围选择、实际批准模型、普通小任务记录方式不一致。
|
||||
|
||||
已证实机制:客户端复制完整测试规则形成第二份来源,主规范修订后副本继续陈旧。未证实:实际 Cursor 是否因此执行了错误模型/测试、费用或运行行为是否受影响。
|
||||
为何已有保护不足:静态读取显示没有针对该副本文案与验证契约的一致性证据;本次没有运行 hook/CI,不能断言所有自动防护都缺失。
|
||||
同类检查范围:.cursor/rules 下五个规则文件及 hooks 配置、根 AGENTS/PROJECT、验证契约、规范登记、任务/收口模板。其余四个 mdc 主要转发入口;本次未检查所有其他客户端和全局规则。
|
||||
|
||||
推荐修复:将该 mdc 缩为验证契约与报告路径指针;结构要求归并现有权威文件,避免再复制模型与全量命令。不是改产品 Runner 模型或删除必要验证。
|
||||
验收:规则文本无固定模型/无条件全量测试/失效章节;文档任务、Go 任务、产品 PI 任务分别映射到既有验证矩阵;Cursor 实际读取入口并正确选择验证层级。静态修复与实机行为分别报告。
|
||||
时间线:2026-09-24 发现并登记;本次仅提出修复,未实施,issue 保持 open。无新 validated lesson;未验证修复不包装成经验。
|
||||
|
||||
## 5. 风险和关键设计
|
||||
|
||||
- 阶段和角色不是一对一关系:固定九名 Agent 会增加交接成本;初期三角色足够,主 Agent 可实施。
|
||||
- 只读 reviewer 无法自行写审查文件:主 Agent 转存并保留作者/ID,避免“要求只读同时要求落盘”的矛盾。
|
||||
- verifier 运行构建/测试会写缓存、数据甚至环境:单独授权,持对应租约,不能装作普通只读检查。
|
||||
- 子 Agent 默认共享目录:采用单写者;并行写另建登记 worktree,主会话的自动隔离配置不替代仓库门禁。
|
||||
- 审查和测试必须绑定版本:修复后重审受影响范围;候选变化重验;运行制品与报告提交分开。
|
||||
- 清理在验收后:唯一日志/截图先归档,owner 退出后由维护者复查,不主动删除当前使用的工作区。
|
||||
- 人工确认默认在可审方案形成后;已有端到端授权则沿用。用户未回复偏好,本草案采用该可调整默认,不把沉默当批准。
|
||||
- 模型路由和自动审批不同:Auto 不扩大业务或环境权限,普通 Cursor 不套用 Herdr 固定模型。
|
||||
- 阶段规范为 manual;文档审核通过不等于自动执行系统已实现。
|
||||
|
||||
## 6. 文档验收与未运行项
|
||||
|
||||
本次仅文档研究。静态检查结果在任务“验证与证据”节记录;检查对象为本次全部变更文件内容。
|
||||
情景自审覆盖:研究-only、简单文档、标准功能、修复回环、并行冲突、readonly 转存、子任务未知、候选变化、验收失败、清理拒绝、上下文恢复。该项是文档推演,不能作为运行负例 PASS。
|
||||
|
||||
本次未执行:Cursor Auto 真实派发、Cursor 项目角色配置安装、并行写锁实测、业务测试、产品 PI、浏览器、部署和清理。新规范的 V1–V10 实机清单是后续接入验收项。
|
||||
|
||||
## 7. 文档情景自审记录
|
||||
|
||||
审查者:Codex 主 Agent;独立性:self_review。以下为阅读草案逐项推演,结果仅表示文字路径可执行,不表示已运行客户端。
|
||||
|
||||
| 情景 | 对照位置 | 结论 |
|
||||
|---|---|---|
|
||||
| 只研究方案,未授权实现 | §2、S3 | 可交付研究,其后标不适用;不会顺推业务实现 |
|
||||
| 一处低风险文档修改 | §4、§7 | 主 Agent 自检,一份主文档可承载阶段,无需九个角色 |
|
||||
| 代码已修改但审查未回收 | S5、§5 | 不进入集成;后台结果需接收 |
|
||||
| 修复后旧审查/旧测试仍通过 | S5–S7 | 新版本需适用复核与验证,旧 PASS 不覆盖 |
|
||||
| readonly reviewer 需要报告 | §4、§7 | 子角色回传,主 Agent 在租约内转存 |
|
||||
| 测试生成缓存或写环境 | S6、§8 | verifier 可写但须明确产物范围/环境与租约 |
|
||||
| 两个子任务争用同路径 | §5 | 单写者或独立登记隔离,不能无锁并发 |
|
||||
| 子任务超时且副作用未知 | §6 | 保留 unknown,核对现场后决定恢复 |
|
||||
| 合并前 dev 已变化 | S7 | 重建候选并重新验证 |
|
||||
| 已合入但运行验收失败 | S8、S9 | 不宣布完成、不清理;修复/交接 |
|
||||
| owner 仍在 worktree 或有唯一日志 | S9、§5 | 保留现场,归档后由独立维护者复查 |
|
||||
| 会话中断后恢复 | §6、§7 | 从首个未满足门禁继续,核对未回收子任务 |
|
||||
|
||||
初次静态检查真实输出:`FILES=8 LOCAL_LINKS=84 STAGES=10 ISSUE_IDS=5 / PASS`。
|
||||
命令:`git diff --check`(exit 0);Python 内联检查全部本次 Markdown 变更(含 untracked)的相对链接/锚点、S0–S9、规则状态字段和 issue ID 唯一性(exit 0)。不验证外部网页永久可达或实际 Cursor 行为。
|
||||
只读 `agentctl docs drift`:status=ok、regressions=[];开放能力候选未修改,不等于产品就绪。
|
||||
|
||||
## 8. 后续决策:本机 PI 与可调整模型配置
|
||||
|
||||
用户在同一任务后续对话明确:子智能体采用 gmktec 本机 PI;仅允许 minimax-cn/MiniMax-M3、zai-coding-cn/glm-5.3、zai-coding-cn/glm-5.3-flash、qwen-token-plan-cn/qwen3.8-max、qwen-token-plan-cn/qwen3.8-flash。随后明确代码由 Cursor 实施,并因 M3 的实际使用反馈将其移出默认流程,最后确认该默认安排并要求可调整文档。
|
||||
|
||||
这些用户决策取代本报告前文 r1 中 Cursor 原生 .cursor/agents/inherit 的接入建议;前文保留为研究历史,不再作为当前实现方向。现行模型映射唯一来源为[模型配置](../ops/2026-09-24-subagent-model-config.md),流程草案同步到 r2。没有改变 Herdr 或产品 Runner。
|
||||
|
||||
2026-09-24 再次执行 pi --offline --no-extensions --no-skills --no-prompt-templates --no-themes --no-context-files --no-approve --list-models,exit 0;精确五个 provider/model 均存在。此命令没有模型推理,不证明各角色能力或连接状态。配置字段由主 Agent 人工读取,当前不含执行器/热加载/自动校验实现。
|
||||
|
||||
## 9. 执行器已接入(后续实现)
|
||||
|
||||
用户进一步授权接入自动调用 PI 的执行器。代码提交 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119,真实 Cursor CLI→MCP→PI 和 173 项工程回归通过,详情见[验证报告](../test-reports/2026-09-24-pi-executor-test-report.md)及[运行说明](../ops/2026-09-24-pi-subagent-executor.md)。前文关于未接入/未调用的说明属于当时研究阶段;当前交付范围与未覆盖项以上述新报告为准。完整流程草案审批、dev 集成和远端同步分别记录。
|
||||
@@ -1,208 +0,0 @@
|
||||
---
|
||||
title: "对话办公能力全景盘点"
|
||||
created: 2026-09-25
|
||||
owner: Cursor
|
||||
task_id: dialogue-office-expansion-2026-09-25
|
||||
policy_revision: cursor-governance-2026-09-24-r1 @ 44161d2ad2d7aada3e9ff88127b52148543278e5
|
||||
review_state: pending
|
||||
integration_state: pending
|
||||
deployment: not_required
|
||||
cleanup: pending
|
||||
remote_sync: not_requested
|
||||
status: done
|
||||
confidence: high
|
||||
---
|
||||
|
||||
# 调研:对话办公能力全景盘点
|
||||
|
||||
## 范围与授权
|
||||
|
||||
- **用户目标**:以「对话辅助办公」为初衷,最大限度扩展对话可操作范围;**创建项目、添加成员、设置等治理结构操作保持 UI 专属**。
|
||||
- **本轮交付**:研究报告 + 分期整改计划(文档落盘);P0–P3 **实施另起任务**。
|
||||
- **允许写路径**:`.doc/audit`、`.doc/remediation`。
|
||||
- **基线 SHA**:`44161d2ad2d7aada3e9ff88127b52148543278e5`(建场时 local `dev`)。
|
||||
- **非目标**:不改产品代码、不更新 CURRENT/FEATURE-MATRIX/gap-matrix、不部署。
|
||||
- **整改方案**:[2026-09-25-dialogue-office-expansion-plan.md](../remediation/2026-09-25-dialogue-office-expansion-plan.md)
|
||||
|
||||
## 结论
|
||||
|
||||
1. 注册表共 **32** 个 ActionKey(非早期估计的 34);主链路与 intentflow 计划执行面 **双轨脱节**:计划层 U11/U12 已把部分键 live 化,单意图协调层仍对认领/送审/工作流触发等返回「假成功」话术。
|
||||
2. HTTP **169** 条路由可按对话边界分为:可操作候选 **A=46**、只读查询 **B=66**、UI 专属写/管理台 **C=44**、平台基线 **13**。
|
||||
3. 消除假成功、打通 dry-run、接真实查询源、再扩新写意图,应按 P0→P3 分期;一律复用 doc-review 四道防线(识别分流 → 话语分类 → 角色×状态出卡 → 执行二次鉴权),两步确认 + 服务端权威校验。
|
||||
|
||||
## 证据
|
||||
|
||||
| 项 | 路径/命令 | 结果 |
|
||||
|----|-----------|------|
|
||||
| ActionKey SSOT | `internal/intent/registry.go` `registerBuiltinActions` L145–187 | **32** 键 |
|
||||
| 主链 docgov | `internal/coordinator/engine_docgov.go` | claim/submit 假成功;approve/reject 有 PendingAction |
|
||||
| 主链 workflow | `internal/coordinator/engine_workflow.go` | switch 确认闭环断裂;trigger 引导 UI |
|
||||
| intentflow dry-run | `internal/app/intentflow/expansion.go` L195–216 | docgov 5 dry-run + run-control 2 dry-run |
|
||||
| HTTP 路由 | `rg 'mux\.HandleFunc\("' internal/server/server.go internal/server/document_revision_handlers.go` | **169** |
|
||||
| 样板 | doc-review-lifecycle `09fe9723`;`card_policy.go` / `recognizer_matchers_docgov.go` / `action_executor.go` | 四道防线可复用 |
|
||||
|
||||
## 1. 意图执行矩阵(32 ActionKey)
|
||||
|
||||
**执行类别说明**
|
||||
|
||||
| 类别 | 含义 |
|
||||
|------|------|
|
||||
| `real-exec` | 协调层或 PendingAction 已调用领域服务真写 |
|
||||
| `pending-action` / `confirm-card+pending` | 出确认卡或挂起期望,确认后 `action_executor` 真写 |
|
||||
| `query-direct` | 只读查询,直接回复(可能含硬编码兜底) |
|
||||
| `prose-only` | 仅自然语言,无业务副作用(或明确拒绝) |
|
||||
| `假成功` | StatusAccepted/成功话术,但未调用权威写服务 |
|
||||
| `dry-run` | intentflow Owner 返回 `validated_only` receipt,无副作用 |
|
||||
|
||||
| ActionKey | 中文 | 主链类别 | 计划链(intentflow) | 主处理 | 后端 owner |
|
||||
|-----------|------|----------|----------------------|--------|------------|
|
||||
| `project.advisory` | 进展/风险查询 | query-direct | QueryOwner | `engine_query.go:handleQueryProgress` | 协调层/LLM |
|
||||
| `project.fact.supplement` | 补充项目事实 | real-exec | Mutate(flag 下 dry→live) | `engine_stage.go:handleSupplementInfo` | ctxmgr / MutateOwner |
|
||||
| `project.stage.advance` | 推进阶段 | real-exec / 无 runner 时 prose 模拟 | — | `engine_stage.go:handleAdvanceStage` | stageflow |
|
||||
| `task.run` | 触发生成任务 | real-exec | TaskRunAdapter | `engine_task.go:handleTriggerTask` | stageflow / taskrun |
|
||||
| `task.run.adhoc` | 特设任务 | real-exec | — | `engine_task.go:handleTriggerAdhocTask` | 同上 |
|
||||
| `conversation.chat` | 闲聊 | prose-only | — | `engine_consult.go:handleCasualChat` | dialogue LLM |
|
||||
| `conversation.decline` | 暂缓建议 | prose-only | — | `engine_stage.go:handleDeclineExpectation` | 上下文 |
|
||||
| `document.claim` | 认领文档 | **假成功** | live(U11) | `engine_docgov.go:250–277` | 主链仅改 Claimed 列表;计划→docgov |
|
||||
| `document.review.submit` | 提交审核 | **假成功** | live(U11) | `engine_docgov.go:280–295` | 主链纯文案;计划→`SubmitForReview` |
|
||||
| `document.review.approve` | 审核通过 | pending-action | **dry-run** | `engine_docgov.go:handleDocGovApprove` | `docgov.ReviewApprove` |
|
||||
| `document.review.reject` | 审核驳回 | confirm-card+pending | **dry-run** | `engine_docgov.go:handleDocGovReject` | `docgov.ReviewReject` |
|
||||
| `document.final.approve` | 终审批准 | confirm-card+pending | **dry-run** | 同上 Approve 分支 | `docgov.ApproverApprove` |
|
||||
| `document.final.reject` | 终审驳回 | confirm-card+pending | **dry-run** | 同 reject | 同上 |
|
||||
| `document.proposal.decide` | 提案裁决 | confirm 分支真挂起 / **默认分支假成功** | **dry-run** | `engine_docgov.go:298+` | confirm_*→PendingAction |
|
||||
| `regulation.query` | 法规查询 | query-direct | QueryOwner | `engine_query.go:handleQueryRegulations` | kb.Client + 模板兜底 |
|
||||
| `case.query` | 相似案例 | query-direct | QueryOwner | `engine_query.go:handleQuerySimilarCases` | SearchSimilarCases + **硬编码案例** |
|
||||
| `permission.query` | 权责查询 | query-direct | — | `engine_query.go:handleQueryUserRights` | UserDocs 上下文 |
|
||||
| `document.reject_reason.query` | 驳回原因 | query-direct | — | `engine_query.go:handleQueryRejectReason` | 黑板 + default 文案 |
|
||||
| `card.confirm` | 确认挂起期望 | confirm 元动作 | — | expectation 映射 | 路由至目标 intent |
|
||||
| `project.stage.execute` | 阶段执行确认 | 注册有、switch **无独立 case** | — | 实际走 advance | 同 advance |
|
||||
| `security.forbidden` | 安全禁止 | prose-only | RejectPlan | `engine_consult.go` | — |
|
||||
| `workflow.switch` | 切换激活工作流 | **假成功(确认后无执行)** | **dry-run** | `engine_workflow.go:12–59` | **边界上属结构治理 → 宜诚实拒绝/引导 UI** |
|
||||
| `workflow.run` | 运行工作流 | **假成功(引导 UI)** | live(U12) | `engine_workflow.go:62–90` | 计划→`CreateWorkflowRun` |
|
||||
| `workflow.status.query` | 工作流状态 | query-direct | — | `engine_workflow.go:93` | UserProjectContext |
|
||||
| `document.status.query` | 文档状态 | query-direct(常空模板) | — | `engine_workflow.go:117` | 模板/document_summary |
|
||||
| `conversation.help` | 能力帮助 | query-direct | — | `engine_workflow.go:139` | AvailableActions |
|
||||
| `conversation.unsupported` | 不支持 | prose-only | — | `engine_workflow.go:159` | — |
|
||||
| `run.status.query` | 运行状态 | query-direct | — | `engine_run.go:handleRunStatusQuery` | WorkDir |
|
||||
| `run.resume` | 续跑 | confirm-card+pending | live(U12) | `engine_run.go:handleRunResume` | taskrun |
|
||||
| `run.restart` | 重启 | confirm-card+pending | **dry-run** | `engine_run.go:handleRunRestart` | taskrun.restart |
|
||||
| `project.impact.analyze` | 影响分析 | query-direct | — | `impact_actions.go` | ImpactActions |
|
||||
| `project.doc.revise_propose` | 修订提案 | confirm-card+pending | — | `impact_actions.go` | ProposeRevision |
|
||||
|
||||
### 1.1 假成功清单(主链路优先)
|
||||
|
||||
| # | Legacy / Key | 文件:行号 | 当前行为 | P0 建议 |
|
||||
|---|--------------|-----------|----------|---------|
|
||||
| 1 | `DOCGOV_CLAIM` / `document.claim` | `engine_docgov.go:250–277` | 仅 append `UserDocs.Claimed`,回复「已成功认领」,不调 docgov | 真执行 `RecordDocumentViewed`/claim API + 确认(若需) |
|
||||
| 2 | `DOCGOV_SUBMIT_REVIEW` / `document.review.submit` | `engine_docgov.go:280–295` | 纯成功文案,无状态变更 | 真执行 `Gov.SubmitForReview` + 角色门禁 |
|
||||
| 3 | `DOCGOV_PROPOSAL_DECIDE` 默认分支 | `engine_docgov.go:383–397` | 非 confirm_* 时按 proposal_action 返回采纳/拒绝文案,不写文档 | 默认分支诚实澄清或走确认卡;禁止假成功 |
|
||||
| 4 | `SWITCH_WORKFLOW` / `workflow.switch` | `engine_workflow.go:12–59` | 设 NextExpectation 要求确认,**确认后无写路径** | **诚实拒绝**:属 UI 专属(`PUT …/active-workflow`);或确认后明确「请在设置面板操作」 |
|
||||
| 5 | `TRIGGER_WORKFLOW` / `workflow.run` | `engine_workflow.go:62–90` | 「请在面板确认」话术,不创建 run | 确认卡 + `CreateWorkflowRun`(对齐 U12) |
|
||||
|
||||
附带(非计划 P0 五处,但同类):无 runner 时 `ADVANCE_STAGE`/`TRIGGER_TASK` 模拟成功;`VIEW_DOC` lifecycle 空模板。
|
||||
|
||||
### 1.2 intentflow 仍 dry-run 的键
|
||||
|
||||
**DocGov**(`docGovActionKeys` 7 − `DocGovLiveActionKeys` 2 = **5**):
|
||||
|
||||
- `document.review.approve`
|
||||
- `document.review.reject`
|
||||
- `document.final.approve`
|
||||
- `document.final.reject`
|
||||
- `document.proposal.decide`
|
||||
|
||||
**Run-control**(4 − live `workflow.run`/`run.resume` = **2**):
|
||||
|
||||
- `workflow.switch`(计划层 dry-run;产品边界建议永久不 live 写,改为拒绝)
|
||||
- `run.restart`
|
||||
|
||||
见 `internal/app/intentflow/expansion.go` L195–216;dry-run 行为 `DryRunAdapter.Execute` → `validated_only`。
|
||||
|
||||
## 2. HTTP 169 路由 × 对话边界
|
||||
|
||||
**统计口径**:`internal/server/server.go` `Routes()` + `document_revision_handlers.go` `registerDocumentRevisionRoutes()` 中 `mux.HandleFunc("METHOD path")` = **169**。不含中间件 OPTIONS、SPA 静态子路径。
|
||||
|
||||
| 类别 | 计数 | 含义 |
|
||||
|------|-----:|------|
|
||||
| **A 对话可操作候选** | 46 | 读写副作用;对话须两步确认后经服务层落库 |
|
||||
| **B 只读查询候选** | 66 | GET + preview POST |
|
||||
| **C UI 专属** | 44 | 治理结构写 + admin 全域(含管理台只读) |
|
||||
| 平台基线 | 13 | health/ready、认证、SPA、`/me` 自服务 |
|
||||
| **合计** | **169** | |
|
||||
|
||||
### 2.1 A — 对话可操作候选(46)
|
||||
|
||||
| 模块 | n | 代表路径 | 对话意图现状 |
|
||||
|------|--:|----------|--------------|
|
||||
| docgov | 11 | `POST …/docgov/{claim,submit-review,review-decision,approver-decision,proposal,proposal/decide,comments,content,lease/*}` | 批准/驳回已打通;claim/submit 主链假成功;comments 等偏 UI |
|
||||
| docrevision | 2 | `PATCH …/documents/{id}/content` · `POST …/agent-candidates/{id}/decision` | 正文 PATCH 仅 HTTP;候选决策可对话扩展 |
|
||||
| trace | 6 | `POST …/trace/{index,analyze}` · `…/edges/{id}/decision` · `…/reopen` · `…/recheck/…/clear` | 影响分析意图有;**边裁决/重开仅 HTTP** |
|
||||
| 补充批次 | 1 | `POST …/supplement-impacts/{batch_id}/decision` | 补充意图有;批次确认可对话化 |
|
||||
| 工作流运行(非结构) | 2 | `POST …/workflows/{key}/run` · `…/stages/{stage}/advance` | run 主链假成功;advance 有意图 |
|
||||
| 任务执行 | 6 | `POST …/tasks/{run,run/stream,runs}` · `…/{cancel,resume}` | 触发/续跑已打通 |
|
||||
| 对话写 | 8 | `POST …/chat*` | 会话基础设施 |
|
||||
| 意图计划 | 1 | `POST …/intent-plans/{id}/decisions` | intentflow + HTTP 双通道 |
|
||||
| 自由文档 | 6 | `POST/PUT/DELETE …/freeform-documents*` | **仅 HTTP** → P3 候选 |
|
||||
| 资产 | 2 | `POST …/assets` · `…/reparse` | **仅 HTTP** → P3 |
|
||||
| 通知 | 1 | `PATCH …/notifications/{id}` | **仅 HTTP** → P3 |
|
||||
| 用户偏好 | 1 | `PUT …/context/user/preference` | 低优先级 |
|
||||
|
||||
### 2.2 B — 只读查询候选(66)
|
||||
|
||||
项目/工作流/成员/设置 **GET**、termination/activation **preview**、chat 历史检索、docgov audit/comments GET、修订 ledger GET、资产 raw、通知列表、context/cases 等。
|
||||
|
||||
对话已覆盖:进展、文档/工作流/运行态、驳回原因、法规/案例/权限(案例与进展有硬编码兜底)。
|
||||
仍偏 HTTP:职责现状、修订版本/diff、trace 图、终止预览、成员列表只读(允许对话只读引导,禁止代写)。
|
||||
|
||||
### 2.3 C — UI 专属红线(44,对话永久禁写)
|
||||
|
||||
| 模块 | 写操作(禁入) |
|
||||
|------|----------------|
|
||||
| 项目/成员 | `POST /projects` · `POST|PUT|DELETE …/members` |
|
||||
| 职责 | `PATCH …/doc-tasks/{taskKey}/duties` |
|
||||
| 工作流结构/生命周期 | `PUT …/workflow-plan` · `PUT …/active-workflow` · `POST …/workflow-instances/activate` · `POST …/terminate` |
|
||||
| Admin | 角色/用户/密码/工作流定义 publish·retire/模板/config/system settings/maintenance/workspaces cleanup |
|
||||
|
||||
对话侧应对命中措辞走 `security.forbidden` / `conversation.unsupported`,**仅允许只读查询与引导**(如读职责现状、`termination-preview`)。
|
||||
|
||||
> **澄清**:`workflow.switch`(改 active-workflow)落入 C;`workflow.run`(创建运行实例)落入 A。P0 对前者诚实拒绝,对后者真执行。
|
||||
|
||||
## 3. 查询硬编码兜底
|
||||
|
||||
| 场景 | 位置 | 问题 |
|
||||
|------|------|------|
|
||||
| 相似案例 | `engine_query.go:420–426` | 无数据时硬编码 PRJ-2025-008 / PRJ-2024-019 |
|
||||
| 驳回原因 | `engine_query.go:260–276` + `card_policy.go:defaultRejectReasonText` | 黑板/事件捞取失败则默认文案 |
|
||||
| 法规 | `engine_query.go:382–388` | KB 空则 GB/YY 模板 |
|
||||
| 进展简报 | `engine_query.go:83–164` | 默认项目名与长硬编码段落 |
|
||||
| 文档状态 | `engine_workflow.go:126–129` | lifecycle 空 → 引导面板 |
|
||||
|
||||
## 4. 复用样板:doc-review 四道防线
|
||||
|
||||
参考合入/分支证据:`feature/doc-review-lifecycle-2026-09-25` @ `09fe9723`(批注/重开/积压/送审真执行)。
|
||||
|
||||
| 防线 | 符号 | 要点 |
|
||||
|------|------|------|
|
||||
| ① 识别分流 | `recognizer_matchers_docgov.go:matchDocGovAction` | 查询语气不误路由写动作 |
|
||||
| ② 话语分类 | `card_policy.go:ClassifyRejectUtterance`(Web 对称) | QUERY / EXECUTE / OTHER |
|
||||
| ③ 角色×状态出卡 | `ResolveRejectCard` / `buildRejectConfirmCard` | 无权限不出危险按钮 |
|
||||
| ④ 执行二次鉴权 | `handleDocGovReject/Approve` + `chat/action_executor.go` | 确认后调 `GovernanceEngine` |
|
||||
|
||||
后续写意图扩展必须复制该模式,禁止「话术成功、服务未写」。
|
||||
|
||||
## 5. 开放问题
|
||||
|
||||
- `project.stage.execute` 注册未接线:是否删除或显式映射到 advance(实施期决定)。
|
||||
- 自由文档/通知/资产对话化的产品优先级与确认文案(P3 开工前再确认)。
|
||||
- `workflow.switch` 是否保留意图仅作「引导 UI」还是识别层直接 `unsupported`(推荐后者,减少假确认)。
|
||||
|
||||
## 建议动作
|
||||
|
||||
见整改计划 P0–P3;本调研 **status=done** 仅表示盘点可审,**不代表问题已修复**。
|
||||
|
||||
## 状态与交接
|
||||
|
||||
- 产物:本文 + [整改计划](../remediation/2026-09-25-dialogue-office-expansion-plan.md)
|
||||
- 实施:另起 `feature/dialogue-office-p0-…` 等任务;每期独立验证与验收
|
||||
- CURRENT / MATRIX / gap-matrix:本轮不动
|
||||
- catalog:`feature=dialogue-office`,scope `.doc/audit`+`.doc/remediation`;与 `docgov` feature claim 硬冲突,故未占用 `docgov` 键
|
||||
@@ -1,267 +0,0 @@
|
||||
---
|
||||
title: "系统全面 Code Review(local_dev tip)"
|
||||
status: done
|
||||
created: 2026-09-26
|
||||
owner: Cursor
|
||||
task_id: "system-code-review-2026-09-26"
|
||||
policy_revision: "agent-governance-2026-09-21-r1 + cursor-governance-2026-09-24-r1 @ f4c1b73f28580ad3df6db4f9ec0a80057006e516"
|
||||
review_state: accepted
|
||||
integration_state: integrated
|
||||
deployment: not_required
|
||||
cleanup: done
|
||||
remote_sync: not_requested
|
||||
updated: 2026-09-26
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 系统全面 Code Review(local_dev tip)
|
||||
|
||||
## 范围与授权
|
||||
|
||||
- **用户目标**:对系统做一次全面 code review,并按规范形成报告;**不允许实施修复**,只形成报告。
|
||||
- **被审对象**:本地 `dev` tip `f4c1b73f28580ad3df6db4f9ec0a80057006e516`(merge: swboot-closeout-2026-09-26-r3);运行态参考 no-docker local_dev(`bin/agent-server`,schema 75),本报告以代码与门禁证据为主。
|
||||
- **允许写路径**:`.doc/`(本审计主文档、INDEX、short-term 任务记录)。
|
||||
- **交付终点**:可审审计报告 + 索引挂接;不改业务代码、不改 gap-matrix / FEATURE-MATRIX 状态值、不部署。
|
||||
- **非目标**:逐文件全量行审、依赖 CVE 扫描、前端 XSS 系统化、动态渗透、实施整改。
|
||||
- **方法**:并行四轴审查(架构边界 / 安全 / 可维护性 / 关键执行路径)+ 本机 `./scripts/arch-check.sh --mode block`、规模盘点与关键片段复核。
|
||||
|
||||
## 问题登记与经验检索
|
||||
|
||||
- **issue_id**:本轮不新建 ISSUES 行;发现项以本报告 FIND-* 编号跟踪。若后续授权修复,再按 [闭环规范](../ops/2026-09-23-issue-learning-workflow.md) 升 issue。
|
||||
- **检索词**:`IDOR`、`GetUserContext`、`session_id`、`validated_only`、`fencing`、`arch-check`、`table_owners`、`ALLOW_IN_MEMORY`、`sh -c`、`swboot`。
|
||||
- **命中**:历史审计见 [INDEX](./INDEX.md)(模块耦合 2026-09-20、对话办公盘点 2026-09-25、gap-matrix);经验库无与本轮 FIND-SEC-01 完全同题的已关闭 lesson。**采纳检查**:对照模块开发规范 §2/§4、authz fail-closed 惯例、intentflow 注释契约。
|
||||
|
||||
## 总判(Verdict)
|
||||
|
||||
`arch-check --mode block` **PASS**,且多项生产门禁(任务路径 stub 拒绝、FAV outbox consumer 多层禁用、docgov 角色不信任 body)仍然有效。但系统存在三类结构性风险:
|
||||
|
||||
1. **安全旁路**:会话上下文 IDOR(已证实);Authorizer 无池 fail-open;swboot `sh -c` + 前缀白名单。
|
||||
2. **门禁空心化**:未登记表的 SQL 写被 arch-check **静默跳过**;server 仍持 `Runtime.Pool` 并直查/直写。
|
||||
3. **多入口编排**:docgov / 多意图 / flag 面平行三套,关闭开关时存在静默降级。
|
||||
|
||||
本轮 **不改变** gap-matrix 的 `production_ready` 叙事;下列 critical/high 建议作为独立 remediation 候选,待授权后再立项。
|
||||
|
||||
## 现象
|
||||
|
||||
只读审查与门禁核验,无用户报障个案。审查期望:合入 swboot / dialogue-ctx / jevdecide / semantic-replace 后的 tip 在模块边界、鉴权与关键执行路径上仍满足生效规范。实际:门禁绿,但多处规范语义与实现分叉(见 Findings)。
|
||||
|
||||
## Findings(按严重度)
|
||||
|
||||
置信度说明:`verified` = 父会话已打开源码复核;`agent` = 子代理报告、抽样一致;`inferred` = 机制推断未跑动态用例。
|
||||
|
||||
### Critical
|
||||
|
||||
#### FIND-SEC-01 — 会话消息 IDOR(`session_id` 无归属校验)
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 授权 / IDOR |
|
||||
| 位置 | `internal/server/handlers_context.go:17-50`;`internal/ctxmgr/manager.go:377-385` |
|
||||
| 证据 | `handleGetUserContext` 仅校验 `user_id` 为本用户/管理员;`GetUserContext` 对 `chat_messages` 使用 `WHERE session_id = $1` **无 owner 条件**。对照 `chatflow` 读路径会校验会话归属。 |
|
||||
| 影响 | 已登录用户若获知他人 `session_id`,可读取对方最近聊天正文。 |
|
||||
| 置信度 | verified · high |
|
||||
| 修复方向(不实施) | 复用 chatflow 会话授权;或按 `session.owner_id`/`user_id` 过滤后再返回。 |
|
||||
|
||||
#### FIND-ARCH-01 — arch-check 对未登记表静默跳过(表唯一写者门禁盲区)
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 门禁 / 模块边界 |
|
||||
| 位置 | `internal/archtest/scan.go:198-205`;`module-boundaries.yaml` `table_owners`(约 59 表) |
|
||||
| 证据 | `if !tracked { continue }`;本机 tip:`swboot_controlled_executions` / `projects` / `project_source_bindings` / `outbox_events` **UNTRACKED**;`arch-check --mode block` 仍 PASS。 |
|
||||
| 影响 | 新表(含 swboot)可任意包写入而不触发 block;「表唯一写者」对未入库表无强制力。 |
|
||||
| 置信度 | verified · high |
|
||||
| 修复方向 | 未登记表的生产写应变 fail-closed,或强制登记。 |
|
||||
|
||||
#### FIND-ARCH-02 — server 持 Pool 直装 swboot 并 SQL 旁路
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 组合根越界 |
|
||||
| 位置 | `internal/server/swboot_handlers.go`(NewPGRepoAllowlist / ControlledPatchExecutor / 直查 bindings & executions) |
|
||||
| 证据 | 与模块规范 §2.1「server 只拿用例或端口」冲突;`app.Build` 已另有 allowlist 装配。 |
|
||||
| 影响 | HTTP 层成为第二组合根;边界回归。 |
|
||||
| 置信度 | agent · high(与规范条文一致) |
|
||||
| 修复方向 | 收成 app 用例端口;禁止 handler 使用 `rt.Pool`。 |
|
||||
|
||||
### High
|
||||
|
||||
#### FIND-SEC-02 — Authorizer 无池时成员判定 fail-open
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 鉴权 fail-open |
|
||||
| 位置 | `internal/authz/authorizer.go:112-114`、`205-207` |
|
||||
| 证据 | `!a.enabled()`(pool==nil)时 `IsProjectMember`/`IsProjectOwner` 对 `userID>0` 返回 true;组合根始终 `NewAuthorizer(pool)`,nil pool 时 `authorizer()!=nil`,绕过「nil → failClosed」分支。 |
|
||||
| 影响 | AllowInMemory / 无库误配时,任意登录用户可访任意 `project_id`。生产有 `ALLOW_IN_MEMORY` 门禁则触发面缩小,**机制本身仍 fail-open**。 |
|
||||
| 置信度 | verified · high |
|
||||
|
||||
#### FIND-SEC-03 — swboot 受控执行:`sh -c` + basename 前缀白名单
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 命令注入面 / 边界语义 |
|
||||
| 位置 | `internal/swboot/executor.go`(`sh -c`、前缀匹配);`ApproveMerge` 恒拒 |
|
||||
| 证据 | 允许判定为字段首段 basename 前缀;命令经 shell 执行。执行器自身不做 merge/push,但若 admin allowlist 含 `git`/`bash` 等,客户端可间接 push/merge/deploy。 |
|
||||
| 影响 | 在 creator + 宽松 allowlist 前提下,隔离 worktree 内可越出「测试命令」意图。 |
|
||||
| 置信度 | agent · high |
|
||||
| 说明 | 与 MATRIX「永不 merge/push/deploy」在「执行器 API」语义下仍成立;真正边界在 **admin 命令白名单粒度**。 |
|
||||
|
||||
#### FIND-FLOW-01 — intentflow `validated_only`/`proposed` 可经 confirm 进入 dispatch
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 执行模式门禁 |
|
||||
| 位置 | `internal/app/intentflow/plans.go:365-376`;`intent_plan_handlers.go:86-88`;`ExecuteClaimed` 不读 `ExecutionMode` |
|
||||
| 证据 | `DecisionConfirm` **允许** `PlanProposed`;确认后 HTTP 调用 `DispatchEligible`;`AllowedModes` 策略字段几乎未被执行路径使用。 |
|
||||
| 影响 | shadow「安全」依赖「无人 Confirm」,而非执行器硬拒绝;U10/U11 live 已接线时可升级为真实写。 |
|
||||
| 置信度 | verified · high(静态);未做动态 confirm 用例 |
|
||||
|
||||
#### FIND-QUAL-01 — docgov / 多意图多入口并行(职责扩散)
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 可维护性 / 双写路径 |
|
||||
| 位置 | chat `docgov.*` PendingAction;`app/docgov_owner.go` `document.*`;`server/handlers_docgov.go`;intent vs intentflow 双套 flags |
|
||||
| 证据 | 同一 `GovernanceEngine` 三入口;`intent.FeatureFlags` 与 `intentflow.FeatureFlags` 并存;Coordinator ~40 intent case + intentflow OwnerMux 平行。 |
|
||||
| 影响 | 鉴权/确认/审计易漂移;回归矩阵笛卡尔积;开关关闭时 Mux→Query 静默降级(FIND-FLOW-02)。 |
|
||||
| 置信度 | agent · high |
|
||||
|
||||
#### FIND-ARCH-03 — bizdev / Runtime / 万能 Engine 门面残留
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 架构债 |
|
||||
| 位置 | `internal/bizdev/service.go`;`internal/app/app.go` Runtime;`docgov`/`coordinator` Engine |
|
||||
| 证据 | bizdev 自开池并装配多引擎;Runtime 暴露 Pool+数十服务;Engine 方法面极大。arch-check allowlist 放行上帝包,PASS ≠ 模块化健康。 |
|
||||
| 影响 | 新功能默认堆 handler/Runtime;与解耦批次目标持续摩擦。 |
|
||||
| 置信度 | agent · high |
|
||||
|
||||
### Medium
|
||||
|
||||
| ID | 摘要 | 关键位置 | 置信度 |
|
||||
|---|---|---|---|
|
||||
| FIND-SEC-04 | 授权拒绝 404/403 区分,泄露资源存在性 | `task_run_auth.go`、`auth_helpers.go` | agent |
|
||||
| FIND-SEC-05 | Chat SSE:阶段拒绝在 Flush 之后;`user_role` 可写入会话上下文 | `sse.go` | agent |
|
||||
| FIND-SEC-06 | 对话 `agent.NewBackend` 对未知名默认 stub;生产密钥校验不禁 stub | `agent/backend.go`、`config.go` | agent |
|
||||
| FIND-SEC-07 | 未认证 `/api/v1/vault/status` 暴露 FAV 开关 | `auth_middleware.go`、`vault.go` | agent |
|
||||
| FIND-SEC-08 | 会话 token 存 `localStorage`(XSS 放大) | `web/src/api/auth.ts` | agent |
|
||||
| FIND-DOC-01 | docgov 省略 fencing token 仍可写;heartbeat persist / squad reclaim fail-open | `docgov/lease.go` | agent |
|
||||
| FIND-DOC-02 | `CommitAgentVersion` 与 edit lease 解耦竞态面 | `docrevision/service_agent.go` | agent |
|
||||
| FIND-FLOW-02 | `OwnerMux` 在 U10/U11/U12 关闭时静默降级到 Query | `intentflow/mux.go` | agent |
|
||||
| FIND-ARCH-04 | notification handler 端口失败后回落 Pool SQL | `notification_handlers.go` | agent |
|
||||
| FIND-ARCH-05 | 提案批准后 handler 裸 goroutine 副作用 | `handlers_docgov.go` | agent |
|
||||
| FIND-ARCH-06 | 错误信封拼接 `err.Error()` | 多 handler | agent |
|
||||
| FIND-QUAL-02 | 全局 flag/metrics 损害并行测试隔离 | `intent/flags.go`、`intentflow/*` | agent |
|
||||
| FIND-QUAL-03 | 巨石文件逼近/超过规范阈值(见规模盘点) | squad/taskrun/server/web | verified |
|
||||
|
||||
### Low / 契约说明
|
||||
|
||||
| ID | 摘要 |
|
||||
|---|---|
|
||||
| FIND-JEV-01 | jevdecide assist 失败为 **fail-open 回规则**(不编造);若产品要求「jev 挂则拒答」则不满足——属契约澄清,非实现疏忽。 |
|
||||
| FIND-DOC-03 | summarizer 注释仍写「REPLACE 不接线」,与已合入 `applySemanticReplace` 矛盾。 |
|
||||
| FIND-EVT-01 | 事件 payload 密钥过滤面窄于 taskrun `StripSecrets`(子串级)。 |
|
||||
|
||||
## 同类问题与影响范围
|
||||
|
||||
| 关联场景 | 共用机制 | 检查与证据 | 判定 |
|
||||
|---|---|---|---|
|
||||
| chatflow 读会话 | 会话 owner 校验 | chatlog Adapter authorize | 主路径健全;**旁路** `GetUserContext` 缺校验 |
|
||||
| 任务 SSE 鉴权 | Flush 前 RequireProjectAccess | gap-matrix AUTH-TASK-SSE PASS | 项目门健全;阶段拒绝在流后属中危差异 |
|
||||
| FAV outbox | Enabled:false + Register/Claim 硬拒 | registry/dispatcher/eventsconsumer | **未见旁路打开** |
|
||||
| swboot ApproveMerge | 恒拒 | repo_allowlist | 自身 API 健全;命令白名单是真边界 |
|
||||
| 生产 ALLOW_IN_MEMORY | validateProductionSecrets | config.go | 非空 Env 的 prod 有防护;空 Env+内存组合仍危险 |
|
||||
|
||||
**未覆盖(明确边界)**:govulncheck/npm audit;MinerU/Embedding SSRF 动态验证;FAV degraded 跨项目读 E2E;Markdown XSS 系统化;全量 `BeginTx` 持锁外呼追踪。
|
||||
|
||||
## 方案与验收(仅建议,本轮不实施)
|
||||
|
||||
### 建议优先级
|
||||
|
||||
1. **P0**:FIND-SEC-01(IDOR)— 补会话归属;加回归(他用户 session_id → 403/空)。
|
||||
2. **P0**:FIND-ARCH-01 — arch-check 未登记表 fail-closed;补登记 swboot/projects 等属主。
|
||||
3. **P1**:FIND-SEC-02 — Authorizer `!enabled()` 改 fail-closed 或与 `failClosedAuthz` 对齐。
|
||||
4. **P1**:FIND-SEC-03 / FIND-FLOW-01 — argv 化命令 + 收紧白名单;Confirm 拒绝 `validated_only`/`proposed` 或执行器硬读 mode。
|
||||
5. **P2**:收敛 docgov/多意图单一写路径与单一 flag 面;收回 server Pool。
|
||||
|
||||
### 验收提示(未来修复任务)
|
||||
|
||||
按 [验证契约](../ops/2026-09-21-validation-contract.md)「问题修复的回归范围」:原例 + 同类旁路 + 正常授权路径;工程侧补 `archtest` 用例证明未登记表 block。
|
||||
|
||||
## 严重度
|
||||
|
||||
报告整体:`high`(存在已证实 IDOR + 门禁盲区;未做动态利用)。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- 既有: [模块解耦分批](../remediation/2026-09-20-module-decoupling-batch-plan.md)、[对话办公扩展](../remediation/2026-09-25-dialogue-office-expansion-plan.md)、[gap-matrix](../remediation/gap-matrix.md)
|
||||
- **本轮未新建 remediation 文件**(用户禁止实施;方案仅建议)。授权后建议拆:`remediation/2026-09-26-system-code-review-followups.md`。
|
||||
|
||||
## 证据
|
||||
|
||||
### 门禁与规模(本机)
|
||||
|
||||
```text
|
||||
被审 SHA: f4c1b73f28580ad3df6db4f9ec0a80057006e516
|
||||
arch-check --mode block → production gate passed
|
||||
tracked table_owners ≈ 59;swboot_controlled_executions/projects/project_source_bindings/outbox_events = UNTRACKED
|
||||
|
||||
Go 生产文件 LOC 前列(非测试):
|
||||
cmd/bizdev-cli/main.go 1017
|
||||
internal/squad/workflow.go 963
|
||||
internal/server/task_run_handlers.go 858
|
||||
internal/taskrun/manager.go 813
|
||||
…
|
||||
|
||||
Web:
|
||||
web/src/App.tsx 1748
|
||||
web/src/engine/docxRenderer.ts 1263
|
||||
…
|
||||
```
|
||||
|
||||
### 子代理
|
||||
|
||||
| 轴 | 类型 | 用途 |
|
||||
|---|---|---|
|
||||
| 架构边界 | architecture-critic | 模块规范对抗审 |
|
||||
| 安全 | security-auditor | OWASP 向只读审(无 PoC) |
|
||||
| 可维护性 | thermo-nuclear-code-quality-review | 上帝对象/双路径/开关丛林 |
|
||||
| 关键路径 | code-explorer | intentflow/docgov/swboot/FAV/jev |
|
||||
|
||||
### 运行态(旁证,非本报告验收对象)
|
||||
|
||||
此前会话:no-docker `bin/agent-server` `vcs.revision` = tip;`/api/v1/health`+`/ready` ok,schema 75。
|
||||
|
||||
## 开放问题
|
||||
|
||||
1. FIND-FLOW-01:产品是否故意允许对 shadow `proposed` 计划一键 Confirm 升 live?若否,属缺陷;若是,应改文档/MATRIX 与执行器注释。
|
||||
2. FIND-JEV-01:assist「失败 fail-closed」的产品定义是否等于「回退规则」?
|
||||
3. 是否授权将 FIND-SEC-01/ARCH-01 升 ISSUES 并开 remediation?
|
||||
|
||||
## 修复经过与经验
|
||||
|
||||
- **本轮未实施任何代码修复**(用户硬约束)。
|
||||
- 不新增 lesson:发现尚未经验证修复闭环。
|
||||
- 复发提醒:旁路 HTTP(绕过 chatflow/Owner)是鉴权回归的高发点。
|
||||
|
||||
## 状态与交接
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| 任务状态 | `done`(研究产物可审) |
|
||||
| review_state | pending(待人工审阅报告) |
|
||||
| integration_state | pending(报告合入 local_dev 另走 integrate) |
|
||||
| deployment | not_required |
|
||||
| cleanup | pending |
|
||||
| remote_sync | not_requested |
|
||||
| 剩余工作 | 授权后开 P0 修复任务;本 worktree 合入/清理由独立维护者执行 |
|
||||
| 禁止续作 | 在本任务下直接改业务代码冒充「顺便修」 |
|
||||
|
||||
## Positive observations
|
||||
|
||||
1. `arch-check` 对**已登记** import/sql/path/event 仍 enforced。
|
||||
2. FAV outbox consumer `Enabled:false` 多层硬拒,未见旁路打开。
|
||||
3. 任务 SSE 项目鉴权在 Flush 前;docgov 角色取 principal 不信任 body。
|
||||
4. 语义摘要 shadow:lease 提交后再 Summarize,符合持锁不做外部 IO。
|
||||
5. swboot/jevdecide 领域包 import allowlist 自身较窄;污染主要在接线层。
|
||||
@@ -1,344 +0,0 @@
|
||||
---
|
||||
title: "多仓库架构研究证据与审查记录"
|
||||
date: 2026-09-28
|
||||
task_id: multi-repo-design-2026-09-28
|
||||
evidence_basis: current_source_and_readonly_api
|
||||
---
|
||||
|
||||
# 多仓库调研证据
|
||||
|
||||
范围:[待审方案](../remediation/2026-09-28-multi-repo-architecture-plan.md)。
|
||||
记录只读 API 和源码事实,不包含业务正文、凭证值、认证头、原始数据库或敏感截图。
|
||||
未对远端执行 POST/PATCH/DELETE,也未 push、部署或创建远端仓库。
|
||||
|
||||
## Git and Gitea
|
||||
|
||||
本地研究基线:dev@a3db288a7aa055ff5884e3aa4d91511959cff721,开始时主目录干净。
|
||||
任务 worktree:.worktrees/multi-repo-design-2026-09-28,分支 feature/multi-repo-design-2026-09-28。
|
||||
`git rev-list --left-right --count fabd85a65e15f3417431ba6f004a8bcdf9cb83cb...a3db288a7aa055ff5884e3aa4d91511959cff721` 返回 `0 306`。
|
||||
因此领先 306 不是仅依据缓存 origin/dev;远端实时 API 的 SHA 与缓存一致,且祖先关系已核对。
|
||||
本轮未 fetch 修改 remote-tracking ref,未同步远端。
|
||||
|
||||
Gitea GET /api/v1/version 返回 1.27.3。
|
||||
GET /api/v1/user/repos 分页(本次一页已取完六仓),仅保留所需元数据:
|
||||
|
||||
| 仓库 | private | empty | default_branch | description | 结论 |
|
||||
|---|---|---|---|---|---|
|
||||
| weichen/Agent-System | false | false | dev | 空 | 保留主仓 |
|
||||
| weichen/Agent-System-Squad | false | true | main | 空 | 名称可复用,尚无组件内容 |
|
||||
| weichen/Agent-System-Development-Documents | false | true | main | 空 | 可复用,导入内容须分类 |
|
||||
| weichen/Development-Guidelines | false | true | main | 空 | 可复用 |
|
||||
| weichen/Agent-System-Releases | false | true | main | 空 | 只适合公开发布目标 |
|
||||
| weichen/Development-Manager | false | false | dev | 空 | 已有治理工具,不应重建覆盖 |
|
||||
|
||||
仓库 has_actions=true 只证明设置开启,不证明 runner/CI/权限可用。
|
||||
所有六仓当前读取身份有 admin/push/pull 权限;此事实不扩大本轮授权。
|
||||
|
||||
Agent-System 实时分支摘要:
|
||||
- dev: fabd85a65e15f3417431ba6f004a8bcdf9cb83cb
|
||||
- test: 0e4b111dff3726f5379e8168e3d00a244e111747
|
||||
- main: 210fe4a7bb2fd56c34a215c53e07617cccf81e49
|
||||
- 三分支 protected=false,GET branch_protections 返回 []。
|
||||
|
||||
Development-Manager 的 branch_protections 同样返回 []。
|
||||
两仓 GET releases?limit=3 返回 [];只说明本次未列出发布记录,不把 Git tags 当 Releases。
|
||||
两仓 repository-level GET actions/runners 返回 runners=[];没有检查实例级/组织级 runner,不推断整个实例无 runner。
|
||||
四个 empty 仓的 branches 返回 null,与 empty 状态一起解释为没有可列出的分支,不虚构 main 已有提交。
|
||||
|
||||
读取本机 /swagger.v1.json:
|
||||
MergePullRequestOption 的 do enum 包含 merge/rebase/rebase-merge/squash/fast-forward-only/manually-merged;
|
||||
包含 head_commit_id、merge_commit_id、force_merge。
|
||||
BranchProtection 包含 required_approvals、dismiss_stale_approvals、block_on_outdated_branch、status_check_contexts、push/merge allowlist 等。
|
||||
这是字段证据,未验证运行语义;方案 U1/U2 要做授权演练。
|
||||
|
||||
## Existing Development Manager
|
||||
|
||||
远端 README/PROJECT/MIGRATION 当前可读。
|
||||
MIGRATION 记录:2026-09-24T15:39Z,从 Agent-System dev@edbe59247872ef5861bafd30068955e22288c6ff 复制式拆出;新初始历史,未携带 .locks。
|
||||
PROJECT 将其定位为治理工具权威演进仓,阶段 A 通过 projects 聚合本机各项目 .locks,阶段 B 中央 API 尚预留。
|
||||
这是仓库文档的当前声明,不等于运行态部署证明。
|
||||
|
||||
本机 Development-Manager 目录存在,dev@8867e38ceb7cc71fa65d1a0f80178faff53fcb4c,工作树干净,缓存 origin/dev 无领先/落后提示。
|
||||
本次未单独核对其远端 dev SHA,因此不声称实时完全同步。
|
||||
本机 Development-Guidelines 目录不存在;历史记忆中的同名旧工作区不作为当前事实。
|
||||
|
||||
## Squad Boundary Evidence
|
||||
|
||||
| 路径 | 当前机制 | 设计影响 |
|
||||
|---|---|---|
|
||||
| internal/squad/service.go:113 | Service 引用主仓 config.Config | 注入 Options,不反向依赖主仓 |
|
||||
| internal/bizdev/service.go:195 | 直接 squad.NewService(cfg) | 装配与适配保留产品应用 |
|
||||
| internal/squad/workflow.go:547 | agent.Request、重试/失败分类与物化 | 执行端口、失败语义、重试归属要显式 |
|
||||
| internal/squad/service.go:256 | 直接主仓 stream 事件 | Squad 事件由应用映射至 SSE/持久状态 |
|
||||
| internal/squad/workspace_adapter.go:6 | 返回主仓 WorkspaceRef | 适配留应用侧 |
|
||||
| internal/squad/service.go:524 | templates/xlsx/cdo_quote.xlsx | 运行包资产不能仅包含 Markdown |
|
||||
| internal/bizdev/service_task_finalize.go:68 | 质量失败短路 | 不可将执行完成等同正式提交 |
|
||||
| internal/bizdev/service_task_finalize.go:35 | 编制人提交身份与 OnBehalfOf 分离 | 不改变产品授权 |
|
||||
| .doc/system-design/module-boundaries.yaml:283 | 七包依赖 allowlist | 先解耦,再独立 Go 模块 |
|
||||
|
||||
rg 穷举正式 Go import 显示 Squad 直接使用方涉及 29 文件/9 目录,包括 bizdev/chat/coordinator/server/intent/materialindex/projectcontext 与 CLI/script。
|
||||
主模块 `go.mod` 为 `module chat-agent-system`,Go 版本声明 1.27.1;本轮不推断目标机器工具链已安装。
|
||||
独立模块继续 import 主仓 internal 包不可行。
|
||||
现行模块开发标准明确模块化单体;仓库独立不自动授权增加 RPC/微服务。
|
||||
|
||||
## Tooling and Documentation Evidence
|
||||
|
||||
| 路径 | 观察 | 必须适配 |
|
||||
|---|---|---|
|
||||
| scripts/agentctl.py:598–610 | Git common-dir 需等于 main/.git | 标准 submodule 的 .git 文件布局当前不支持 |
|
||||
| scripts/agent_worktree.py:95–102 | 要求主工作区 .git 为目录 | 不能仅改 agentctl 一个入口 |
|
||||
| scripts/agentctl.py:642–669 | 直接 sqlite3.connect 至本地主仓 .locks/state.sqlite | 多 clone 不是共享协调域 |
|
||||
| scripts/agentctl.py:2861 | 本地 manager.lock 与队列循环 | 本地 daemon 不等于跨机服务 |
|
||||
| scripts/agentctl.py:1599–1625 | 按父仓 staged 文件识别共享文档并查收据 | .doc gitlink 不能替代内容级检查 |
|
||||
| scripts/agentctl.py:1287 / 1333 / 2245 | git show / cat-file 读取 HEAD/dev 中的文档与证据 | 跨仓 repo+SHA+path 引用 |
|
||||
| internal/archtest/boundaries.go:107 | 机器模块契约位于 .doc | 留在代码仓,不作为普通文档搬离 |
|
||||
| scripts/candidate-images-build.sh:60 | 仅 git archive 主仓提交 | 子模块源码固定递归导出 |
|
||||
| scripts/pi_subagents.py、agentctl_w4.py、.cursor | 多处固定 .doc 位置 | 客户端入口、报告及治理一起迁移 |
|
||||
|
||||
主目录 agentctl status 本轮返回 status=ok、protocol version=1;
|
||||
实际 policy revision 为 agent-governance-2026-09-23-fav-constraint-restored。
|
||||
CURRENT 顶部历史摘要仍有 2026-09-23 信息,活跃任务表更晚;方案未用其历史环境状态代替 Git/API 现状。
|
||||
|
||||
## Build and Runtime Assets
|
||||
|
||||
- scripts/build-single-binary.sh 构建 Web,然后 CGO_ENABLED=0 构建 cmd/server,写入版本 ldflags;不是全平台发布流程。
|
||||
- web/embed.go 的 go:embed all:dist 可将前端纳入二进制。
|
||||
- templates/embed.go 仅嵌入 docs/*.md;internal/template/loader.go 读取 configs/agents 指令和 configs/shared/writing.md。
|
||||
- deploy/app/Dockerfile 仍显式复制 web/dist、迁移、templates、configs,构建 server/events。
|
||||
- internal/localpg/localpg.go 查找本机 pg_ctl;数据库不是被 Go 服务自带。
|
||||
- deploy/pi-agent/Dockerfile 使用 Node 22 与单独 PI 包,固定 CLI 0.85.1;Runner 是额外执行依赖。
|
||||
- .github/workflows/ci.yml 有 Go/PG/Web 验证;nightly-real-pi.yml 有 Gitea 专用 runner/上传兼容说明。
|
||||
- 主仓 tree 跟踪 docgov.test、notification.test、projectinstance.test、storage.test;制品仓应避免继续提交二进制正文,历史不自动重写。
|
||||
- 未编译新平台、未启动服务、未读模型密钥、未读取 IDE 中业务 output.md。
|
||||
|
||||
## Lessons Reused
|
||||
|
||||
检索 .doc/audit/ISSUES.md 与 .doc/ops/lessons/INDEX.md,核对当前源码后采纳:
|
||||
- LESSON-20260923-matrix-status-cas:文档状态与 CAS 收据不能因拆仓失效。
|
||||
- LESSON-20260924-cursor-hook-advisory-gates:客户端提示与硬门禁分层,不称 UI/本地 hook 足以保护远端。
|
||||
- LESSON-20260926-failclosed-bypass-contract:缺失组件/收据/权限失败关闭,禁止 gitlink 绕过。
|
||||
- LESSON-20260927-server-facts-and-iso-db-recipe:未来验证使用明确隔离 DB,不回退至真实 dev。
|
||||
- 当前 Squad step-empty-output、squad-commit-authority、quality-heading 相关台账按原状态保留;本轮不修复、不关闭。
|
||||
|
||||
这次没有实施与运行验证,不新增 validated 经验;多仓适配风险在本研究记录和计划出口追踪,进入实施后按对应失败事实建问题/回归记录。
|
||||
未修改共享 ISSUES/CURRENT/MATRIX,避免把待审架构建议写成现行缺陷修复/生效规范。
|
||||
|
||||
## Review Record
|
||||
|
||||
ce-plan 研究后,由 ce-doc-review 的一致性、可执行性、安全、范围、产品价值、反向挑战视角复核。
|
||||
本地审查的四项实际修订:
|
||||
1. 五分钟上游通知明确为后续自动化目标,首期检查点不伪称实现该 SLA。
|
||||
2. U1 只验基线/平台可行性,完整候选队列/回写恢复在 U2 实现后验收,消除前置依赖循环。
|
||||
3. 内部完整源码包与公开源码包分开;公开包采用允许清单,排除私有开发资料,并加入负例。
|
||||
4. U6a 提前从当前固定单仓基线交付私有包试点,U6b 在拆仓后复验同一构建合同。
|
||||
|
||||
补充跨模型检查曾通过 ce-doc-review 的 claude CLI 路线请求 claude-opus-5/high,对 security/product/adversarial/whole-doc 发起只读复核。四个任务在本地审查完成后仍未返回结果,主代理主动终止附加检查;runner 记录 timeout(reaped on request before completion),result 读取均返回 3、没有审查产物。未验证实际服务模型,未将其计为独立复核或 PASS。此限制不改变本地六视角的事实与修订记录。
|
||||
|
||||
本地审查汇总:coherence 1、feasibility 1、security 1、product 1 项已修订;scope/adversarial 没有追加有效问题。未对复用同一子代理上下文的后续角色作独立性加权。
|
||||
用户要求完整待审方案,允许对本轮草稿调整完善,四项修改均保持 Product Contract 与用户已确认边界;不存在需要以草稿修订为由提前实施的动作。
|
||||
|
||||
最终文档检查:三份 Markdown 的 frontmatter、代码围栏、相对链接、R1–R10/U1–U6/V1–V12 覆盖与 whitespace 检查通过;git diff --check 通过。实施测试均未运行。
|
||||
只读收口:agentctl cleanup report exit=0,19 worktrees,ready=0、blocked=19;没有删除。agentctl docs drift exit=0,30 records、regressions=0、open_capabilities=3;没有改 MATRIX。
|
||||
CodeGraph 在开始与收口运行 sync -q 成功;其近似索引仅辅助定位,依赖完整性以 rg 核对。
|
||||
这些是文档审查修订,不是系统已支持的能力。
|
||||
|
||||
## External References
|
||||
|
||||
- [Git submodule](https://git-scm.com/docs/git-submodule):固定提交、相对 URL 解析。
|
||||
- [Go 模块布局](https://go.dev/doc/modules/layout):internal 可见性与公开包。
|
||||
- [Go cgo](https://go.dev/cmd/cgo/):交叉编译与 C 工具链边界。
|
||||
- [Gitea Actions FAQ](https://docs.gitea.com/usage/actions/faq/):PR head 与合并候选区别。
|
||||
- [Gitea Actions token](https://docs.gitea.com/usage/actions/token-permissions/):fork 和跨仓权限。
|
||||
- [Gitea 保护分支](https://docs.gitea.com/usage/access-control/protected-branches/):审批与状态检查配置。
|
||||
- [Gitea 仓库权限](https://docs.gitea.com/1.22/usage/permissions/):私有仓访问语义;最终以实例 ACL 实测为准。
|
||||
|
||||
## Revision 2: Web and Agent-Native
|
||||
|
||||
授权来源:用户在原方案审阅中追加前端拆仓和 pi-native/agent-native 共享执行基础设计;沿用 task_id,不启动实施。
|
||||
本轮源码基线仍为 a3db288a7aa055ff5884e3aa4d91511959cff721,文档上一提交为 de90d0cd70e5cfadbd680e8caf8bdf18724e44a8。
|
||||
旧机器登记已 done,agentctl 不提供 reopen;新增同 worktree 的执行登记 multi-repo-design-2026-09-28-r2,逻辑任务和三个允许写路径不变。
|
||||
|
||||
### Confirmed Wiring
|
||||
|
||||
| 证据位置 | 确认的事实 |
|
||||
|---|---|
|
||||
| internal/agent/backend.go:38–60 | 公共 Backend/Execute,工厂支持 pi-agent/pi-native;native 包裹 PI fallback;未知名默认 Stub |
|
||||
| internal/app/app.go:132–133 | 通过同一工厂创建助手 dialogueBackend 并注入 coordinator |
|
||||
| internal/coordinator/dialogue_llm.go:126 | 助手调用 Execute,交付 reply.md;当前非直接返回文本接口 |
|
||||
| internal/squad/service.go:261、402 | Squad 任务/工作流也调用同一后端工厂 |
|
||||
| internal/config/config.go:109 | 源码默认 AGENT_BACKEND 为 pi-agent;不证明运行配置 |
|
||||
| internal/app/app.go:162–186 | 语义摘要、文档变更叙事、U9 segment 仍有 pi-agent 名称条件 |
|
||||
| internal/agent/pinative.go:17–28、96 | PiNativeBackend 是产品配置/工作区与 agentx.Run 的适配层 |
|
||||
| internal/agentx/loop.go | 具备原生 loop、tool 调度、stream、usage、turn cap;不是完整产品持久任务控制面 |
|
||||
| internal/agentx/llm/client.go:14 | 当前是兼容 Chat Completions 的 client,不能推断全供应商适配 |
|
||||
| internal/agentx/session/jsonl.go | 本地 JSONL transcript 与对象 mutex;不是跨进程执行租约 |
|
||||
| internal/agent/fallback.go:21–41 | native 不成功且 context 未取消时尝试 PI;Name 仍可为 pi-native,仅日志记录实际回退 |
|
||||
| internal/taskrun/backend.go | 另有后端名称 allowlist 和生产 stub 限制,改名需全入口一致 |
|
||||
| web/package.json / vite.config.ts | 独立 npm 构建、测试与 Vite API proxy,可作为独立源码仓 |
|
||||
| web/embed.go:14 | 当前 Go embed 与前端目录共置,不能直接整体搬走而不处理 Go import |
|
||||
| internal/server/static_assets.go:16、20–36、resolveDistDir | 导入主模块 web;磁盘资源优先,多个相对路径可能遮蔽内嵌 UI |
|
||||
| web/src/api/* / admin/console | 手写 API 客户端、auth header/cookie、后端信息展示需要契约与兼容检查 |
|
||||
|
||||
CodeGraph sync 成功并 explore PiNativeBackend;rg 再确认助手/Squad 工厂调用和 agentx import 依赖。
|
||||
未读取业务 output.md、workspace.json、模型密钥或运行实例环境;没有调用真实模型或产品 Agent。
|
||||
所以结论是“源码支持双方选择 native、具备公共接口”,不是“当前两条线上路径已运行 native”或“native 全能力已验收”。
|
||||
|
||||
### Revision Decisions
|
||||
|
||||
1. 新增 Agent-System-Web 与 Agent-Native 仓库建议;Core 不再承载前端源码和通用 Agent 内核。
|
||||
2. Agent-Native 包含 contract/runtime/adapters/conformance;公共 contract 不反向依赖 Core/Squad,Core 注入后端,Squad 只使用契约。
|
||||
3. 模型适配、完整 Agent 适配、工具适配分开;保留未来吸收先进实现的空间,不承诺任意 SDK/CLI 即插即用。
|
||||
4. pi-native 旧名、AGENTX 配置与 .agentx 数据路径提供兼容;默认后端不随拆仓切换。
|
||||
5. 区分 native 自身成功与 PI fallback 成功;未知副作用不自动跨后端重放。
|
||||
6. Web 构建产物在隔离构建上下文物化到 Core embed 目录,仍可发布一个包含 UI 的服务二进制;不提交 dist 或软链接越界。
|
||||
7. 增加 U7/U8、R11–R13、V13–V16,同步更新仓库地图、拓扑、Core/Squad 依赖、发布组合和描述;没有只追加一个与旧建议矛盾的附录。
|
||||
|
||||
### Revision Verification
|
||||
|
||||
本轮针对新增边界做源码/官方资料核对与作者一致性复核,不复用第一轮六视角结果作为修订 2 的新增审查证据;未发起额外外部模型复核。
|
||||
复核修正:U7a 先形成可独立获取的最小 contract 模块,U4 消费它,U7b 再迁 native/PI 实现,避免 Squad 和完整 Native 提取相互等待。
|
||||
Go embed 的包/模块边界据[官方文档](https://pkg.go.dev/embed)确认;Vite 独立构建/后端集成据[官方指南](https://vite.dev/guide/backend-integration)核对;工具与完整 Agent 的区别参考[MCP 架构](https://modelcontextprotocol.io/docs/learn/architecture)。
|
||||
仅实施计划中定义真实 native/PI、浏览器与平台验收,本轮未运行,不能标 PASS。
|
||||
|
||||
## Revision 3: Ubuntu-only and PI Core Parity
|
||||
|
||||
用户确认近期不需要 Ubuntu ARM/Apple Silicon;异步澄清确认目标为“对齐核心能力并逐步替代”,不是仅兼容接口或完整上游复刻。仍未授权实施。
|
||||
本机 uname -m=x86_64,os-release=Ubuntu 26.04.1 LTS;当前支持目标改为 linux/amd64,无需本期交叉编译。
|
||||
只读核对 deploy/pi-agent/Dockerfile 固定包0.85.1;npm 该版本元数据 gitHead=d981de1229ef899957bbe968bc8dcda02a21f477,repository=earendil-works/pi,license=MIT。通过内存读取发布tarball检查README/compaction/rpc/extensions文档,无安装/执行包代码;未验证运行容器版本。
|
||||
项目 pi-args 默认 --mode rpc --no-session,workspace 为受限工具且加载扩展;Runner提供 /v1/run 与 /v1/search,typed-result-v1 与 Tavily 属于实际依赖范围。
|
||||
agentx 已有 loop/tools/session/stream/steering/follow-up;没有因此推断完整 PI compaction/扩展/会话兼容。
|
||||
现有 abtest/Suite 只有6例;Judge比较成功率/P0/P95≤1.3倍;live测试直接 NewPiNativeBackend 禁止隐性fallback,RUN_AGENTX_AB=1 才运行。本轮未运行它,不把既有测试代码当通过证据。
|
||||
新增独立 U9 能力盘点→补齐→对比→渐进启用→替代收口;移除本期双平台要求、macOS签名阻断与ARM构建要求;更新描述与验收。
|
||||
来源:https://registry.npmjs.org/@earendil-works%2fpi-coding-agent/0.85.1 与固定提交的上游 README/docs;上游main仅用于导航,能力基线以固定版本为准。
|
||||
|
||||
## Revision 4: Governance Review
|
||||
|
||||
用户要求根据多仓/Ubuntu/Agent-Native方案复审锁、agentctl及规范,可在方案中删减不必要/频繁出问题的机制并补齐缺项。
|
||||
授权仍为研究和待审文档,不执行规范切换,不改变现行工具/配置/数据库/远端设置。
|
||||
|
||||
### Confirmed Issues and Evidence
|
||||
|
||||
ISSUE-20260928-governance-lock-domain,issue_state=investigating,owner=Codex(方案),影响为独立工作区无关写入被全仓恢复状态阻塞。
|
||||
已证实机制:scripts/agentctl.py:532–557 的 path 资源和 overlaps 没有工作区标识;path:. 覆盖所有相对路径。
|
||||
scripts/agentctl_console.py:186 为 integrate_prepare 获取 path:. + git:index + git:dev;:211–220 对合并失败尝试abort后仍标 recovery_required。
|
||||
scripts/agentctl.py:982–998 的持锁比较继续纳入 recovery_required,因此一个候选冲突/失败可能长期挡住不同worktree。
|
||||
本会话 r2 提交与 r3 文档写入实际均被同一 operation 拒绝;它不是仅根据代码猜测的风险。
|
||||
没有调查那个集成任务具体合并失败的底层原因,不能声称已经定位其全部根因。
|
||||
|
||||
问题类别还包括过度恢复升级:execute 在带 env/git:dev 的命令非零退出时统一需要恢复(agentctl.py:1145–1146);应按实际副作用证据区分,不能因此把真正未知结果直接释放。
|
||||
physical_names 将 git:dev 与 env:dev 绑定同一 dev-integration.lock;固定制品部署后可分离代码引用与运行环境锁。
|
||||
|
||||
另有 task 生命周期不一致:规范允许 blocked并要求原task_id续办,task close 只支持done/cancelled,register拒绝非active的同ID。
|
||||
本会话曾尝试blocked而被CLI明确拒绝;新增-r2/-r3只是受限工具下的执行登记,逻辑研究任务一直保持原ID。
|
||||
建议新工具原ID可reopen/update-state,执行尝试另有attempt_id,旧运行副作用日志保留。
|
||||
|
||||
治理快照(本轮只读SQLite URI mode=ro):completed=1455、failed=208、recovered=167、busy=21、recovery_required=1。
|
||||
其中recovered为command=144、integrate_prepare=22、integrate=1;这不是错误率、误报率或性能基准,不把正常恢复也算缺陷。
|
||||
阻塞operation为 integrate-nightly-advance-2026-09-28-r2-prepare-838577a7,resources含git:dev/path:./该候选tree,exit_code=1。
|
||||
稍后复核该记录已为recovered,本代理没有调用recover、删锁或修改管理数据库状态来解除它;正常agentctl with随后返回成功。
|
||||
Development-Manager中的对应overlaps/Lease/prepare与task close逻辑仍同类,不能靠只把工具搬仓根治。
|
||||
|
||||
### Decisions and Replacements
|
||||
|
||||
方案KTD6改用Gitea原生PR合并/保护/CI,取消默认自建签名收据网关、机器人直推与manually-merged回写。
|
||||
仍显式验证base/head/候选tree/组件manifest,合入后的真实SHA绑定制品和部署;不能将PR head测试当合并候选通过。
|
||||
方案KTD13给出retain/replace/remove矩阵、局部资源身份、known-failure/unknown分类、任务续办、清理和规范层级。
|
||||
U2负责替代治理与切换,补V19–V23负例;不是另外堆一套大型协调服务。
|
||||
工作区的源码副本不互锁;同实际目录和共享环境保留适用保护;产品数据库事务/文档职责/运行租约不在工程锁裁剪范围。
|
||||
|
||||
暂不修改共享ISSUES/lessons索引:本次用户明确仅允许三个待审文档,本节保存问题主记录候选,实施/正式文档集成时由相应owner补索引。
|
||||
没有修复和回归运行,不把上述问题标resolved或经验标validated;既有coordination-authority问题继续按原状态追踪。
|
||||
|
||||
### Authority and Exception Record
|
||||
|
||||
曾因正常入口仍被全仓恢复锁阻塞,请求只针对这三份文档的临时租约豁免。
|
||||
用户批准:owner=Codex,原因=待审文档落盘被无关恢复操作阻塞,覆盖=本任务三文档的agentctl with前置,禁止=解锁/改工具或现行规范/提交/推送;有效期=保存完成即结束;恢复动作=保留可审diff,恢复正常租约流程。
|
||||
实际结果:原阻塞先恢复,r3与r4方案主体通过agentctl with保存;随后新操作integrate-nightly-advance-automation-2026-09-28-r7-prepare-dca474ad再次进入recovery_required,正常入口拒绝最后的文档写入。
|
||||
本轮最后保存使用用户已批准的豁免,仅对原三文档直接写入;没有调用recover、删除锁、修改hook/agentctl/现行规范或提交/推送。完成保存和校验即终止豁免,后续回归正常租约流程。
|
||||
用户确认的“仅三份待审文档、不提交或推送”作为本次交付限制保留。
|
||||
|
||||
修订3的Ubuntu单平台和U9原生核心替代已经本轮正常落盘;修订2工作区改动一并保留,没有丢弃或覆盖其他任务文件。
|
||||
本次审查是源码/运行元数据/官方Gitea资料的定向核对与作者一致性检查,未声称重复进行了首轮六视角或外部模型审查。
|
||||
|
||||
最终校验:3份文档、6个相对链接、15项要求、9个实施单元、23项验收场景,结构/ID/链接/旧方案残留检查通过;git diff --check exit=0。收口盘点cleanup total=18/blocked=18/ready=0,未清理;docs drift regressions=0/open_capabilities=3。没有实施、编译或真实运行验收。本轮使用的一次性三文档豁免至此结束,不提交/不推送。
|
||||
|
||||
## Revision 5: Proportionate Everyday Rules
|
||||
|
||||
用户追加“很多规范过严,按最新方案适当完善”;本轮仍仅修订原方案、证据与任务,不批准或启用新规范。
|
||||
读当前AGENTS、PROJECT、验证契约、经验闭环、收口模板及KTD13;核实已有纯文档免全量测试/按机制选场景/矩阵按声明更新等合理条款,未把它们误报为全都缺失。
|
||||
|
||||
问题是执行尺度和入口一致性:Go/接口验证矩阵列全包vet/short,而报告章节又说明不无条件全量;需明确本地迭代/组件CI/组合发布三个检查阶段。
|
||||
启动阅读、每次收口盘点、任务与多表状态、逐修复lesson要求,对小改动容易叠加成本;应区分硬边界、默认做法和工具建议。
|
||||
本会话没有测试耗时/误报率统计,不虚构量化收益;提出的改进以规则文本和已出现流程阻塞为依据。
|
||||
保留真实权限、持久性、运行制品、敏感数据和已确认外部副作用边界。
|
||||
|
||||
新增KTD14及验证分层/证据复用/规则强度说明,扩展U2的规范模板同步和日常演练,新增R16/V24/V25。
|
||||
不新增implementation unit或独立报告,避免为了精简流程再扩大产物层级。
|
||||
本轮仅修订三文档,使用新的r5执行登记承载同一个逻辑task_id;上一轮一次性豁免已结束,本轮不自动沿用。
|
||||
|
||||
修订5验证:三文档结构、6个相对链接、R1–R16/U1–U9/V1–V25唯一性与待审状态检查通过,git diff --check通过。只读cleanup为18项blocked、0项ready,docs drift无回退;未清理工作区。正常agentctl with写入,无需也未沿用上轮临时豁免;未提交、推送、修改生效规范或执行产品测试。
|
||||
|
||||
## Revision 6: Remove Coding Workflow Dependence
|
||||
|
||||
用户明确反馈Agent主要精力被agentctl任务领取、提交、合并消耗。本轮收敛KTD13/14的职责,新增KTD15:普通编码流程零agentctl依赖,任务/PR单一状态来源;治理恢复归维护者,发布部署独立。
|
||||
这不是已经测得时间占比;依据为用户观察与本会话两次跨工作区锁阻塞、登记续办及blocked CLI不匹配的实际记录。
|
||||
修改U2优先顺序,先完成本地减负与Gitea交接,再做多仓适配;不把新的task/reopen/claim平台作为减负前提。新增V26端到端日常流程验收。
|
||||
本轮仅修订原三份待审文档,不启用新规则,不提交/推送;现行登记仍按当前工具执行,逻辑task_id未变。
|
||||
|
||||
## Revision 7: Single Executable, Instance Configuration and Native Infrastructure
|
||||
|
||||
用户连续补充:同一套单文件应用供测试/生产等多个实例,通过启动配置隔离;希望.env、CLI、系统设置后读覆盖;进一步评估KB/DB/文档库用launcher、daemon、应用内启动或原生程序。
|
||||
本轮作为原任务续办,只完善原三文档;此前中断段只读检查已完成,没有启动或变更产品服务。
|
||||
|
||||
### Baseline and Current Source Checks
|
||||
|
||||
原研究worktree仍HEAD=de90d0cd(业务源码基线a3db288a);主目录本轮已为test@fd177f8dd5c7e5714476b59efc1b9a2ae27bdb22,dev=b9339cd27206f519f423eaa6a1601d3a67dfac01。
|
||||
没有切换/重置主目录或重新合并业务源码。
|
||||
对a3db288a..dev的config/localpg/sysadmin settings/db migrate/main/app/templates/web embed/build-single-binary以及kb/storage/workspace/docrevision相关路径做diff --stat,无差异输出;本节结论同时适用于本轮核对的这些dev路径,不能推及未查模块或运行环境。
|
||||
没有读取.env真实值、用户output.md、workspace.json、运行数据库数据或修改系统设置。
|
||||
|
||||
### Source Findings
|
||||
|
||||
| 来源 | 已确认事实与影响 |
|
||||
|---|---|
|
||||
| cmd/server/main.go:22–40、config/config.go:103、159–174 | 默认→env文件→进程env,CLI只覆盖env/port/host/backend;默认.env路径与Load空字符串的overlay路径不同 |
|
||||
| config/config.go:99、localpg/localpg.go:36/48/74 | 存在dev默认路径与部分直接os.Getenv读取;尚非统一最终配置快照 |
|
||||
| sysadmin/settings.go:78/229/275 | 独立DB→进程env→默认解析,不直接消费已合并CLI/.env的cfg;不能说所有系统设置已整体覆盖启动配置 |
|
||||
| sysadmin/service.go:NewService、settings/store | 系统设置来自所选业务PG,key无实例命名空间;用它配置自身连接会循环 |
|
||||
| sysadmin/apply.go、settings.go:199、app/app.go | 部分键推送PI /admin/reload;保存、热更新和真正启动消费并不等价 |
|
||||
| db/migrate.go:RunMigrations/ResolveMigrationsDir | 当前Goose从磁盘SQL目录读取;现有二进制尚未内嵌全部迁移 |
|
||||
| web/embed.go、templates/embed.go、template/loader.go、squad/service.go | Web与部分Markdown已内嵌,agent指令和xlsx等仍依赖磁盘路径 |
|
||||
| localpg/localpg.go:100/123/271/287 | 查找已安装PG→可initdb建cluster→createdb建应用库→启用vector;不是安装数据库,也不创建独立KB语料库 |
|
||||
| localpg/localpg.go:187/261/307、cmd/server/main.go | 当前按端口就绪判断、已有角色bootstrap、started标记与defer清理不足以证明所有权/崩溃恢复;os.Exit可绕过defer |
|
||||
| kb/client.go:75/94、kb/store.go、kb/embed.go | KB是应用内检索代码直连PG;embedding/reranker为外部HTTP能力;连通不等于语料与索引已准备 |
|
||||
| storage/cas.go:42、workspace/capability.go、docrevision/pg_store.go | 文档库由PG账本/内容与持久文件组成,非独立文档daemon |
|
||||
| app/app.go:224、workspace/lease.go | 进程内workspace租约不足以宣称多副本共享同一数据根已安全;独立实例与HA副本分开 |
|
||||
| cmd/server/main.go:71、cmd/events/main.go | server已有可选内置events consumer,单文件模式可收敛到同一程序角色,不必分发第二个应用程序 |
|
||||
|
||||
两项后续调查候选:配置解析双路径/生效声明不一致、managed-local PG所有权与失败回收不足。
|
||||
本轮没有运行复现或修复,不登记为resolved,不改共享ISSUES索引;U10中给出针对性正负例。
|
||||
既有data-dir-doubled、PI runner DATA_DIR覆盖、隔离DB经验直接用于路径归一化与禁止隐式dev回退的验收设计。
|
||||
|
||||
### Decisions
|
||||
|
||||
1. 单版本单个Ubuntu amd64应用文件内置Web/SQL/prompts/xlsx等资产,同文件可启动多个独立实例;配置/数据/日志不打进程序。
|
||||
2. 不新增应用launcher/KB/文档daemon;同一二进制提供serve/init/migrate/config检查,系统服务管理应用和原生PG。
|
||||
3. 产品部署设置放独立实例配置根的instance-settings文件,作为普通部署参数的最终层;产品业务策略仍在所选DB,key各有唯一owner。
|
||||
4. bootstrap identity/config_root/settings读取模式不自覆盖;DB/KB/目录等可经UI配置,但须重启/迁移后确认applied,不能在进行中任务里换一半。
|
||||
5. 默认existing;显式创建逻辑库与安装PG/建立cluster/迁移schema/导入KB区分;managed-local仅可选自有cluster。
|
||||
6. 配置身份、DB角色、可写目录、cookie/密钥、Runner上下文和文件/数据库备份同时隔离;一套二进制不构成隔离证明。
|
||||
7. U10为应用部署新工作,U6a要先满足其最小单文件/外部PG出口;不把该需求隐藏在U9的PI能力替代里。
|
||||
|
||||
复核由独立只读子审查覆盖配置链、存储/进程依赖与设计一致性,补齐saved/applied、最终配置冲突检查和外部进程停止权。
|
||||
本轮没有额外外部模型审查、编译、initdb、建库、启动/停止daemon、服务配置写入或业务数据迁移。
|
||||
|
||||
### Primary References
|
||||
|
||||
- [PostgreSQL initdb](https://www.postgresql.org/docs/current/app-initdb.html):cluster初始化与原生进程身份。
|
||||
- [CREATE DATABASE](https://www.postgresql.org/docs/current/sql-createdatabase.html):逻辑数据库创建。
|
||||
- [PostgreSQL启动与系统服务](https://www.postgresql.org/docs/current/server-start.html):原生postgres/pg_ctl和系统服务职责。
|
||||
- [pg_ctl](https://www.postgresql.org/docs/current/app-pg-ctl.html):原生管理边界。
|
||||
- [pgvector项目](https://github.com/pgvector/pgvector):PG内扩展而非单独daemon。
|
||||
systemd官方man页面本次抓取403,未将该失败当作成功资料;系统服务建议参考PostgreSQL官方启动文档。
|
||||
|
||||
修订7验证:3文档结构、6个相对链接、R1–R19/U1–U10/V1–V34唯一性与待审标记检查通过,git diff --check通过;只读cleanup为20项blocked/0项ready,docs drift无回退,未清理。源码/配置/生命周期定向复核完成;未编译、建库、运行实例或部署。文档通过正常agentctl with保存,本次未使用临时豁免,仍不提交/不推送。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user