This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# 事实核对与作者审阅
|
||||
|
||||
日期:2026-09-29。
|
||||
|
||||
- git status/log:基线47ec30a,当前codex/xingbang-v2-docs-20260928;仅原有无关未跟踪文件,无待覆盖业务改动。
|
||||
- 独立v2目录:仓库v2/及F:/mini-OpenClaw-v2均未创建;迁移仍为计划。
|
||||
- backend/services/assistant_model.py:按allowed_tools过滤read_project_snapshot/read_document/read_checks/read_method/read_experiences,反馈只形成experience_proposal。
|
||||
- backend/services/assistant_experiences.py:已有draft、evaluation、published不可变版本;新卡片与闭环仍需复用设计。
|
||||
- scripts/verify.py存在并使用项目venv;本轮纯文档未运行完整业务验证,不挪用旧版测试结果作为v2实现证据。
|
||||
- 原型HTML/脚本本轮不改;六轴及人工情景表是既有演示,动态维度和闭环UI仅候选规格。
|
||||
- Laya官方仓库 https://github.com/NandhaKishorM/laya :已查阅本地服务、上下文限制、模型差异和Honest limits;未安装/实测。Jev官方 https://docs.typesafe.ai/introduction 已查阅,未接API。
|
||||
- Claude官方 https://code.claude.com/docs/en/memory 已核对@AGENTS.md导入。DeepSeek官方Claude Code指南可从官方搜索发现,正文抓取超时;文档只提供入口,不编写配置命令或固定模型名。
|
||||
- Gitea恢复点的旧核验不等于最新文档备份;本轮远程结果单独记录,不改main、不部署。
|
||||
|
||||
作者自查:正确性——区分会议事件与标签映射、当前能力与设计;一致性——修正保留集先划分再提炼、任务AC映射和异步沙盘;数据/权限——版本、来源、出口、无密钥;验证——机械检查与真实业务验收分开。
|
||||
|
||||
残余:API读清单/DDL、具体代码路径、性能、生产角色、中文模型效果和真实概率均有门禁owner。独立业务/技术评审未进行;CLAUDE入口实际加载与成本改善未测试。
|
||||
@@ -0,0 +1,12 @@
|
||||
# 文档验证计划
|
||||
|
||||
日期:2026-09-29;范围:docs/v2 与根 CLAUDE.md,纯文档交接。
|
||||
|
||||
1. 检查本地Markdown链接和锚点、表格结构、编码字符。
|
||||
2. 原BR/E/AC及ADR/URD编号只追加保留;44条BR、26条E、45条AC唯一连续;全部BR/E有GWT覆盖。
|
||||
3. 检查任务编号T00–T13、跨文档AC引用和异常码/用户文案。
|
||||
4. 核对源码事实及外部来源,列明未知/未实施事项。
|
||||
5. 仅允许docs/v2、CLAUDE.md和本证据变化,git diff --check;记录业务源码未变。
|
||||
6. 保存命令、base SHA、最终文档哈希及结果;不运行业务测试/模型/部署,实际交付Git状态另存delivery.json。
|
||||
|
||||
本检查不证明候选架构已通过独立评审,或Claude/DeepSeek实际接入成功。
|
||||
@@ -0,0 +1,9 @@
|
||||
# 文档检查报告
|
||||
|
||||
日期:2026-09-29。状态:PASS
|
||||
|
||||
检查 31 份Markdown、135 个本地链接;44条BR、26条E、45条AC全部唯一连续并有GWT覆盖;跨文档引用、任务T00–T13、锚点、错误码与表格检查。
|
||||
|
||||
命令:`backend/venv/Scripts/python.exe test-evidence/20260929-v2-handoff/check_docs.py`;cwd为仓库根。基线47ec30a,最终文档SHA256见validation.json。
|
||||
|
||||
git diff --check及范围检查结果见validation.json;业务源码/原型未改变。纯文档未执行verify.py或模型/CLI实测。独立业务/技术审阅未完成,不能据此进入未过门禁的实现。
|
||||
@@ -0,0 +1,78 @@
|
||||
from pathlib import Path
|
||||
import json,re,subprocess,hashlib
|
||||
root=Path.cwd(); out=root/'test-evidence/20260929-v2-handoff'
|
||||
def git(*args):
|
||||
return subprocess.check_output(['git',*args],encoding='utf-8')
|
||||
files=[root/'AGENTS.md',root/'CLAUDE.md',*sorted((root/'docs/project-process').rglob('*.md')),*sorted((root/'docs/v2').glob('*.md'))]
|
||||
issues=[]; links=0
|
||||
for p in files:
|
||||
s=p.read_text(encoding='utf-8')
|
||||
if any(ord(c)<32 and c not in '\n\r\t' for c in s): issues.append(f'control character: {p}')
|
||||
for target in re.findall(r'\[[^\]\n]*\]\(([^)]+)\)',s):
|
||||
target=target.strip('<>').split('#')[0]
|
||||
if not target or re.match(r'^[a-zA-Z][a-zA-Z0-9+.-]*:',target): continue
|
||||
links+=1
|
||||
if not (p.parent/target).exists(): issues.append(f'broken link: {p.name}: {target}')
|
||||
for block in re.findall(r'(?:^\|.*(?:\n|$))+',s,re.M):
|
||||
lines=block.splitlines()
|
||||
if len(lines)<2 or not re.match(r'^\|[\s:|\-]+\|$',lines[1]): issues.append(f'table without header: {p.name}: {lines[0][:80]}')
|
||||
s=(root/'docs/v2/01-requirements.md').read_text(encoding='utf-8')
|
||||
old=git('show','47ec30a:docs/v2/01-requirements.md')
|
||||
counts={}
|
||||
for kind,count in [('BR',44),('E',26),('AC',45)]:
|
||||
ids=re.findall(r'^\| ('+kind+r'-\d+) \|',s,re.M)
|
||||
expected=[f'{kind}-{i:02}' for i in range(1,count+1)]
|
||||
if ids!=expected: issues.append(f'{kind} IDs invalid: {ids}')
|
||||
old_ids=set(re.findall(r'^\| ('+kind+r'-\d+) \|',old,re.M))
|
||||
if not old_ids.issubset(ids): issues.append(f'{kind} baseline IDs lost')
|
||||
counts[kind]=len(ids)
|
||||
rows=re.findall(r'^\| AC-\d+ \|.*$',s,re.M)
|
||||
for row in rows:
|
||||
if not all(t in row for t in ['Given','When','Then']): issues.append(f'not GWT: {row}')
|
||||
covered=set(re.findall(r'\b(?:BR|E)-\d+\b','\n'.join(rows)))
|
||||
required=set(re.findall(r'^\| ((?:BR|E)-\d+) \|',s,re.M))
|
||||
if required-covered: issues.append(f'uncovered: {required-covered}')
|
||||
if covered-required: issues.append(f'undefined: {covered-required}')
|
||||
u=(root/'docs/v2/URD.md').read_text(encoding='utf-8')
|
||||
uids=re.findall(r'^\| (AC-U\d+) \|',u,re.M)
|
||||
if len(uids)!=len(set(uids)) or len(uids)!=9: issues.append('URD acceptance IDs')
|
||||
for row in re.findall(r'^\| MOD-.*$',u,re.M):
|
||||
if not set(re.findall(r'AC-U\d+',row)).issubset(uids): issues.append(f'URD missing AC: {row}')
|
||||
changed=git('diff','47ec30a','--name-only').splitlines()
|
||||
if any(not (p.startswith('docs/v2/') or p == 'CLAUDE.md' or p.startswith('test-evidence/20260929-v2-handoff/')) for p in changed): issues.append('change outside documented scope')
|
||||
# Cross-document stable ID references (expanded ranges validated by endpoint IDs).
|
||||
valid={kind:set(re.findall(r'^\| ('+kind+r'-\d+) \|',(root/'docs/v2/01-requirements.md').read_text(encoding='utf-8'),re.M)) for kind in ['BR','E','AC']}
|
||||
for p in (root/'docs/v2').glob('*.md'):
|
||||
for ref in re.findall(r'\b(?:BR|E|AC)-\d+\b',p.read_text(encoding='utf-8')):
|
||||
if ref not in valid[ref.split('-')[0]]: issues.append(f'undefined cross-document ID: {p.name}: {ref}')
|
||||
hand=(root/'docs/v2/15-development-handoff.md').read_text(encoding='utf-8')
|
||||
if re.findall(r'^\| (T\d+) ',hand,re.M) != [f'T{i:02}' for i in range(14)]: issues.append('task queue IDs')
|
||||
for p in (root/'docs/v2').glob('*.md'):
|
||||
# Verify local heading fragments using GitHub-style punctuation removal.
|
||||
for target in re.findall(r'\[[^\]\n]*\]\(([^)]+)\)',p.read_text(encoding='utf-8')):
|
||||
if '#' not in target or re.match(r'^[a-zA-Z][a-zA-Z0-9+.-]*:',target): continue
|
||||
rel,frag=target.split('#',1); dest=p.parent/rel if rel else p
|
||||
if dest.exists() and dest.suffix=='.md':
|
||||
heads=re.findall(r'^#{1,6} (.+)$',dest.read_text(encoding='utf-8'),re.M)
|
||||
slugs={re.sub(r'[^\w\- ]','',h.strip().lower()).replace(' ','-') for h in heads}
|
||||
if frag not in slugs: issues.append(f'broken anchor: {p.name}: {target}')
|
||||
for row in re.findall(r'^\| E-\d+ \|.*$', (root/'docs/v2/01-requirements.md').read_text(encoding='utf-8'),re.M):
|
||||
if not re.search(r'\b[A-Z][A-Z_]+\b',row) or len(row.split('|'))<5: issues.append(f'error binding missing: {row}')
|
||||
if not (root/'CLAUDE.md').read_text(encoding='utf-8').startswith('@AGENTS.md'): issues.append('Claude must import canonical rules')
|
||||
adr=(root/'docs/v2/09-decisions.md').read_text(encoding='utf-8')
|
||||
adr_ids=re.findall(r'^\| (ADR-\d+) \|',adr,re.M)
|
||||
if adr_ids != [f'ADR-{i:02}' for i in range(1,15)]: issues.append('ADR IDs invalid')
|
||||
old_adr=git('show','47ec30a:docs/v2/09-decisions.md')
|
||||
if not set(re.findall(r'^\| (ADR-\d+) \|',old_adr,re.M)).issubset(adr_ids): issues.append('ADR baseline IDs lost')
|
||||
check=subprocess.run(['git','diff','--check'],capture_output=True,text=True)
|
||||
if check.returncode: issues.append(check.stdout+check.stderr)
|
||||
report={'base_revision':'47ec30a562f12864b7485bb7a43b967fa8f5b755','cwd':str(root),'command':'backend/venv/Scripts/python.exe test-evidence/20260929-v2-handoff/check_docs.py','markdown_files':len(files),'local_links':links,'ids':counts,'status':'PASS' if not issues else 'FAIL','issues':issues,'runtime_tests':'Not run: documentation-only change','hashes':{str(p.relative_to(root)).replace('\\','/'):hashlib.sha256(p.read_bytes()).hexdigest() for p in files}}
|
||||
(out/'validation.json').write_text(json.dumps(report,ensure_ascii=False,indent=2),encoding='utf-8')
|
||||
print(json.dumps({k:v for k,v in report.items() if k!='hashes'},ensure_ascii=False,indent=2))
|
||||
summary = '# 文档检查报告\n\n日期:2026-09-29。状态:' + report['status'] + '\n\n'
|
||||
summary += f"检查 {len(files)} 份Markdown、{links} 个本地链接;44条BR、26条E、45条AC全部唯一连续并有GWT覆盖;跨文档引用、任务T00–T13、锚点、错误码与表格检查。\n\n"
|
||||
summary += '命令:`backend/venv/Scripts/python.exe test-evidence/20260929-v2-handoff/check_docs.py`;cwd为仓库根。基线47ec30a,最终文档SHA256见validation.json。\n\n'
|
||||
summary += 'git diff --check及范围检查结果见validation.json;业务源码/原型未改变。纯文档未执行verify.py或模型/CLI实测。独立业务/技术审阅未完成,不能据此进入未过门禁的实现。\n'
|
||||
if issues: summary += '\n问题:\n' + '\n'.join('- '+x for x in issues) + '\n'
|
||||
(out/'REPORT.md').write_text(summary,encoding='utf-8')
|
||||
raise SystemExit(bool(issues))
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"base_revision": "47ec30a562f12864b7485bb7a43b967fa8f5b755",
|
||||
"cwd": "F:\\mini-OpenClaw-local-stable",
|
||||
"command": "backend/venv/Scripts/python.exe test-evidence/20260929-v2-handoff/check_docs.py",
|
||||
"markdown_files": 31,
|
||||
"local_links": 135,
|
||||
"ids": {
|
||||
"BR": 44,
|
||||
"E": 26,
|
||||
"AC": 45
|
||||
},
|
||||
"status": "PASS",
|
||||
"issues": [],
|
||||
"runtime_tests": "Not run: documentation-only change",
|
||||
"hashes": {
|
||||
"AGENTS.md": "51792b63ff8857f3875a03d8242fb5a2e0898f9a28a2684e5fb61e6e2f2c2271",
|
||||
"CLAUDE.md": "592a82b17f292d81ba8783446e316129ad0737cf25256efe6b18af780712d083",
|
||||
"docs/project-process/01-requirement.md": "0a17308dcfa5f1e0fac84507e9aec8bdf7877880f609ceee7352ea41d62ebe41",
|
||||
"docs/project-process/02-architecture.md": "1ed42b1aba3e5916132138550f4f1687c0d21e33c47140a4f12f603ce04a3a83",
|
||||
"docs/project-process/03-detailed-design.md": "2430148d69d96be36d34868a3b936babbf88729a4e5a82d329b4e81939267faa",
|
||||
"docs/project-process/04-ui-spec.md": "c10134f8480613ef3b3089e287f099905e061c15df0016a0e9ea1767464aab6e",
|
||||
"docs/project-process/05-implementation.md": "541df8d50d69771c7ddb0332838c77b231b2a37fc07e9b2586a4fcb264d7ca67",
|
||||
"docs/project-process/06-validation.md": "f41f1a531c8a43a4b0cde0c0d918514d6936fbb7ae066720b278a68ea65145d8",
|
||||
"docs/project-process/07-delivery.md": "1fa36286bb50605a5e59cd3d7fbe2acf32778f4801b1f49c97185cebacd14f55",
|
||||
"docs/project-process/08-learning.md": "d69aac3638523ec8f90ee400a2dd79bb1bb64726de93b3817d771e8b5105f726",
|
||||
"docs/project-process/README.md": "44892f59d5efa77f0ba4070d179bddf500a501902cd17de23c9c75d7290dea33",
|
||||
"docs/project-process/templates/URD-Template.md": "d55ff174bf88aaecbdf0b24a1d3d70ca6b1a609fb01182acf361d348d677b46a",
|
||||
"docs/project-process/XINGBANG-ADAPTATION.md": "f7f88b86dd6bdabe597ee0decac2ef381b8c1dd74bb734c6f64a0d5b89af0f43",
|
||||
"docs/v2/01-requirements.md": "c969a38b2bdf3534f8026a4fb7b9ae9f9435ed7064f5e89d8faf08dbcaa28e15",
|
||||
"docs/v2/02-architecture.md": "147a26c4edd754536a986078de1a4b9b1d24afa10e6b4259105b83e54fde6199",
|
||||
"docs/v2/03-detailed-design.md": "496fc1086449545f7186f7057f85eca045959c2131c55afee7a12e4bbbebeaf1",
|
||||
"docs/v2/04-ui-spec.md": "3a200ea2bf525f1bde9517651154710eb41f84343f56b3cb3813fcc1513ad04a",
|
||||
"docs/v2/05-implementation-plan.md": "4e30b8dd39ddf653620a9af8e6d5596771f50dd4e026a7c351b6d542ee2390d8",
|
||||
"docs/v2/06-validation.md": "82a693276dc1bef5fb9d83e389d743d1942b50914c569268ac376b00048c88fd",
|
||||
"docs/v2/07-deployment-and-gitea.md": "c0e0f3daf46ddc8de1c90cae52abd6481eb784d7bd4031c8340775aa90d0439f",
|
||||
"docs/v2/08-data-pilot-and-demo.md": "ebae5c0a1e6768e145b8740077e479b15bc2da46d290e494baab06117f3c1b7e",
|
||||
"docs/v2/09-decisions.md": "14e67a46d8488f8b7d86cd370531188f1463202806135c3ac195588fdf83492e",
|
||||
"docs/v2/10-delivery-record.md": "f1e2193cf63dd5969b804bb389bb76e65ca670aa72f28c571bd00dfbfd58cf5d",
|
||||
"docs/v2/11-judgment-providers.md": "4366df02f1553da12ef81b75b4538356ff88973c5b66f0b4bcf9674ddd14c7f3",
|
||||
"docs/v2/12-prototype.md": "4b53ab12a472743a4005839813239d0b68d317d8b317c545b10b12a7d7265ca6",
|
||||
"docs/v2/13-probability-prototype.md": "d63115e0764ab5aa43189d9ce285ac8ba3084f0c3574295e60906a2247138b66",
|
||||
"docs/v2/14-experience-loop.md": "c6b95ff1227597e20c8469e33793558cecb5c0a49c126872d98b7fc1d23754de",
|
||||
"docs/v2/15-development-handoff.md": "5bfbbaa529e1c8789e1a3bd3dcd8770a65b60900187556c18c95d1e074541cd2",
|
||||
"docs/v2/DESIGN.md": "3899bd11cf8b78cef44f3b6490b6d8a4b916bbdbeeb62ee1d02d23530497e114",
|
||||
"docs/v2/README.md": "c6272aa02df5c01e6d24801458bc741d62cf9850c15e40c44bbfdc3023e2feeb",
|
||||
"docs/v2/URD.md": "75bf2b68e1302a9bc344ab34cba41c44bccf880ccead38e738622013eeb1bcea"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user