design(v2): 增加概率雷达与组件依据追溯并验证沙盘联动

This commit is contained in:
2026-09-29 01:10:01 +08:00
parent 1351dd0633
commit 47ec30a562
11 changed files with 177 additions and 61 deletions
+8
View File
@@ -29,3 +29,11 @@
“为什么是这个判断”打开依据抽屉:数据卡(现金流/回款/设备权属)、Skill(回款交叉核验/权属一致性)、历史经验(H-018适用与例外)、规则(尚无已确认硬性阻断,仍有两项缺证)。卡片编号/版本为演示元信息,不声称已执行。明确这些解释展示未来可追溯结构,不构成42%的计算来源;42%来自原型情景表,非模型计算、非历史统计。
沙盘中“当前基线42%”固定;“所选情景”大数字、对照横条、差值立即随复选框change更新,不需要点击运行才看到数字。初始未勾选42%、0个百分点。勾选“银行流水核验支持回款解释”→58%、+16个百分点;仅“权属材料核验一致”→51%、+9个百分点;同时→64%、+22个百分点。取消选项恢复对应值,全部取消42%;采用预设组合表而非简单加法,合并结果不相加。全部数值同样有紧邻演示标识。
每次变化同步展示所选假设、变化原因、仍缺资料(勾选一项剩1项,两项剩0项仅为模拟),并注明真实核验未完成、仍需人工复核。补件也可能发现新风险,真实概率未必上升。返回真实预审仍42%,模型本地/关闭切换不得人为调节概率;Jev未配置仍禁用。保留依据按钮,文案为“查看概率与判断依据”,打开追溯抽屉,不能阻止即时反馈。原型数字用独立demoProbability字段/情景表,真实probability仍为空。
## 本轮新增:概率解释驾驶舱(取代简单数字区)
用户要求更直观、更有科技感的雷达图,并明确依托miniOpenClaw、Skills、Tools、Rules。设计方向保持深绿导航+浅色评审区;主卡片可用局部深绿科技面板,细网格、同心刻度、青绿描边和克制动效,不改变整站色彩。当前无真实数据,不能发明权重、真实审批算法或SHAP贡献。
主卡左侧为大号概率环42%及“演示值”,右侧六轴SVG雷达。六轴是证据核验阶段,不是风险分数:回款核验、财务勾稽、权属核验、交易要素、经验适配、规则覆盖。刻度0未提供、1仅有说明、2资料待核、3交叉核验、4人工复核(人工设定,序数刻度,不可求平均);初始[1,2,1,2,2,1]。缺证是未知,不是低信用评分。图例固定“证据阶段≠审批概率,雷达面积不换算为42%”。可点击维度,旁边等价六维按钮列表也可键盘选择。
首页雷达始终显示当前基线。沙盘另放雷达叠图,灰色虚线基线保持原状,绿色实线假设情景:流水勾选只让回款轴从1变3,权属勾选只让权属轴从1变3;其余维度不动;取消还原。两维的3都标“假设完成核验”,不写已执行。概率环/数值沿用42/58/51/64组合演示表,+0/+16/+9/+22百分点。无需额外运行按钮。
点击轴或维度按钮展示可读的依据链抽屉:数据卡ID和版本→Skill方法ID/版本→允许的只读Tools→示例核查输出/缺证→规则状态→历史经验适用/例外。所有ID/内容为虚构示例;Tools名称是受控只读能力示例,不能显示真实运行成功时间/耗时或调用日志。可使用read_project_snapshot、read_document、read_checks、read_method、read_experiences;它们的含义是读取冻结上下文、材料、核验结果、方法和经验,不声称这些读取工具本身完成财务计算或权属认证。财务计算等新工具属于规划,不能伪造已实现。Skill组织方法和允许工具,Rules负责硬约束/缺证状态,不能被平均分抵消;Jev/local只做专项判断。miniOpenClaw编排这些组件、冻结运行版本并留下轨迹,不能绕过白名单。图形要让这些关系自然可读,不只放一堆技术标签。
“42%如何得到”单独按钮/抽屉:本次真实可复核过程是未选假设→命中DEMO-TABLE-v1的00条目→人工演示42%,不是雷达求和/平均/真实模型预测。沙盘按钮必须显示当前选择命中的00/10/01/11条目和对应42/58/51/64,不能永远显示基线。可用四行小表高亮当前条目,明确没有真实模型版本/历史样本/校准结果。下方展示未来生产链路(清楚标规划):数据卡事实→Skills调用授权Tools→Rules及有效性检查→受控概率估计与历史校准→主审解释与人工审批。未校准真实probability为空,不给假数字。若关键规则待核实,不能说规则通过;确认阻断时标阻断,不仅压低数字。
保留当前全部交互和原有ID,包括baseline-probability、btn-show-basis、basis-dialog、tab-*、panel-*、assume-bank/title、sim-prob-val/delta/bar、sim-explanation/remaining、run-simulation、evidence-dialog、checklist-dialog、validation-dialog、mobile-menu等。原有依据入口继续可用。新增ID建议:radar-baseline、radar-scenario、dimension-dialog、dimension-title、dimension-trace、probability-method-dialog、method-row-00/10/01/11、method-result、btn-probability-method、btn-scenario-method;维度按钮data-dimension属性0至5,data-context=baseline或scenario。实现JS点击/键盘、Escape和焦点返回。1440/1024/390可读无横向溢出,SVG用viewBox,图表有等价列表,支持prefers-reduced-motion。不上传内部源码或真实客户数据。
+4 -4
View File
@@ -11,17 +11,17 @@
".superdesign/concept-design-system.md"
],
"fingerprints": {
".superdesign/concept-design-system.md": "77ba2052e2c41f7f716069d6cbfc34314fbe23cbc7ffc17675b40d45613bc2e7"
".superdesign/concept-design-system.md": "9176ea5b98021b9081c207c13d769d153632c8c8b08bc6941cb491de03976bd2"
},
"components": [],
"drafts": {
"7484f5c4-0415-4a87-a772-c42339680737": {
"title": "兴邦金租智审工作台 - 演示概率沙盘",
"visualDirection": "深色导航+浅色工作区;深绿金融评审风格",
"currentVersion": 4
"visualDirection": "深色导航+浅色工作区;概率环、六维证据雷达与受控追溯",
"currentVersion": 6
}
},
"updatedAt": "2026-09-28T16:36:04.318766+00:00"
"updatedAt": "2026-09-28T17:08:39.717041+00:00"
}
}
}
+2
View File
@@ -74,3 +74,5 @@ UI 门禁尚未通过:路由位置、统一 token 实现、i18n 文件、视
无 Jev Key 时 Jev 配置不进入可选列表;本地可用则可选择本地。没有可用配置时仅保留关闭并说明未配置。业务请求只传 judgment_profile_id,不传 URL 或 Key;后端重新校验,失败按 E-13 显示。提交中禁改本次选择,运行结束或排队后修改选择均需发起新运行。
结果展示本次实际提供方、未完成题目和拒答/unknown;关闭显示“专项核查已关闭”。失效/超时不把选中项悄悄变为另一个模型,不展示占位高分。对应 AC-17/18/19/20/21;页面路由及真实交互待 UI 阶段实施。
概率可视化增量:主结果使用概率环、六轴证据核验阶段雷达和维度追溯;具体阶段含义、假设联动、miniOpenClaw/Skills/Tools/Rules职责及P-14–17验收见[概率设计第6节](13-probability-prototype.md#6-概率环证据雷达与解释链2026-09-29增量)。演示数值不能转换为真实信用评分或概率贡献。
+13
View File
@@ -80,3 +80,16 @@
本次按原型交互轻量路径记录,沿用AC-08/11/12/21和P-01–13,补充设计与测试;没有越过业务实现门禁。交付为原型及文档备份,没有修改现有src/backend业务代码、没有合并main、没有发布镜像。真实概率仍待审批事件定义、历史数据验证与校准。
远程备份状态(2026-09-29):已配置origin在SSH握手阶段关闭连接,重试与只读诊断均复现。本次增量先保存本地提交,Gitea远端SHA未核验,不能标记本次已远程备份。此前已核验的备份不受本地提交影响。日志在test-evidence/20260929-probability-prototype/gitea-connection.log。
## 2026-09-29 六维雷达与解释链增量
同一Superdesign草稿现为版本6。新增首页概率环、六维证据阶段雷达、可点击维度与等价按钮、数据卡→Skill→授权只读Tools→Rules→经验的具体追溯。新增概率出处抽屉:区分当前人工DEMO-TABLE-v1与未来真实估计/校准链路。沙盘只改变所选回款/权属轴,基线虚线保持不变;出处抽屉同步高亮所选00/10/01/11与42/58/51/64结果。
- [雷达首页](prototypes/prescreen-radar-overview.png) / [沙盘叠图](prototypes/prescreen-radar-simulation.png);旧截图保留。
- 新增P-14–17详见[概率设计第6节](13-probability-prototype.md),沿用BR-09/12/13与AC-08/11/12/13/21。
- 新增[雷达测试](prototypes/check-radar.cjs)由[原型回归入口](prototypes/check-probability.cjs)调用。本地与线上各163项断言通过:六维键盘/图轴点击、来源映射、四种情景、未选轴不变、主结果隔离、响应式与既有交互。
- 项目统一验证9项通过:test-evidence/20260929-010559-1351dd0/REPORT.md。执行期间仅补充手机SVG字号与测试,未改变业务源码;最终原型在local-final和remote-final重跑全部相关浏览器断言。完整日志、计划、图片与最终摘要位于test-evidence/20260929-radar-prototype/。
- 生成稿曾遗漏首页雷达/维度动作,并将维度误换为信用属性;已按确定规格补齐。手机图内文字缩放过小,放大后重新验证。测试与截图不等于独立视觉审核或真实模型准确性验收。
- 第6版云端回读与本地HTML仅换行风格不同。现有业务src/backend及部署未改;不越过业务实现门禁。
Gitea连接仍在SSH握手阶段被远端关闭,本次先保存本地提交,远程备份未完成。设计服务上的原型已更新;这与Gitea源码备份是不同边界。
+21
View File
@@ -48,3 +48,24 @@ miniOpenClaw承载受控编排与运行追溯;数据卡、Skills和经验资
## 5. 原型验收映射
延续 [原型验收](12-prototype.md) 的编号,新增 P-08–13;保留原有P-01–07。验证所有四种组合、取消、立即更新、百分点、依据、基线隔离、提供方切换无伪造加分及演示标识。结果与截图存入 test-evidence/20260929-probability-prototype/,不与真实概率模型的验证混称。
## 6. 概率环、证据雷达与解释链(2026-09-29增量)
用户要求更有科技感的展示并看懂概率出处。采用概率环+六轴证据雷达+维度追溯抽屉+概率出处抽屉,在同一原型内替换简单概率展示。属于原型交互轻量路径,复用BR-09/12/13及AC-08/11/12/13/21;不变更生产概率契约、不把草案门禁当已通过。
六轴依次为回款核验、财务勾稽、权属核验、交易要素、经验适配、规则覆盖。刻度为演示的证据阶段:0未提供、1仅有说明、2资料待核、3交叉核验、4人工复核。它们是序数阶段,不是信用分或可平均的百分比;不能根据面积推出概率。生产应由版本化核验规则定义各阶段,不能让大模型随意赋分。
原型基线为[1,2,1,2,2,1]。沙盘流水假设只将回款从1改为3,权属假设只将权属从1改为3,其他轴不变;3在此意味着“假设核验成立”,未执行真实核验。基线轮廓用虚线、情景轮廓用实线,并有文字列表,颜色不是唯一载体。
维度详情包含data_card_id/version、skill_id/version、allowed_tools、示例输入/输出/缺证、rule_id/version/status和经验适用/例外。已核对现有backend/services/assistant_model.py的受控只读能力:read_project_snapshot、read_document、read_checks、read_method、read_experiences,并按skill.allowed_tools过滤。图中仅借用这些能力名称说明职责;读取核验记录不能被描述成该Tool亲自完成核验,原型不伪造成功日志。miniOpenClaw负责编排、冻结版本与轨迹;Skills组织方法及工具范围;Rules约束主审和模型;Jev/local为可选专项判断。
概率出处抽屉分为两层:当前原型展示DEMO-TABLE-v1、选择键00/10/01/11、高亮行和42/58/51/64结果(人工表,无模型和校准);未来规划展示受控事实与核验结果→特征构建→概率估计/历史校准→有效性与硬规则检查→主审解释及人工审批。待核实不等于通过,硬阻断不允许被高分抵消;真实模式缺少校准依然为null。不得画假权重、假特征贡献或用雷达面积装饰成计算依据。
表面状态:基线固定、所选情景即时更新;依据弹层打开/关闭、当前维度选择、来源表当前行均为本地状态。所有用户均为演示评审员,没有真实权限操作;无加载/接口错误态,因为没有网络业务请求,生产异常继续沿用E-06/07/15。按钮支持键盘与焦点返回、图表有等价文本、响应式不裁切、遵守reduced-motion。
| ID | Given / When / Then | 关联 |
|---|---|---|
| P-14 | Given 基线,When 查看雷达,Then 六维阶段和文本一致、清楚说明不计算概率 | AC-08/12 |
| P-15 | Given 任一维度,When 点击或键盘激活,Then 展示该维度卡片/Skill/只读Tools/Rules与经验边界 | AC-08/21 |
| P-16 | Given 基线或选中情景,When 查看概率出处,Then 显示对应演示表行与结果,规划链路明确未接入 | AC-12 |
| P-17 | Given 勾选/取消/关闭专项模型,When 雷达更新,Then 只更新相关情景轴,基线及原意见不变 | AC-11/13/21 |
+4
View File
@@ -63,3 +63,7 @@ needs-design-decision:完整状态色、间距尺度、响应断点、组件
## 2026-09-28 原型方向补充
用户已选“深色导航+浅色工作区”。Superdesign 原型采用深绿导航、浅灰工作背景和白色证据面板,通过关系图与克制动效体现科技感。具体候选颜色、间距及交互在 .superdesign/concept-design-system.md;记录与验收见 [交互原型](12-prototype.md)。这些为原型设计决策,尚未写入生产CSS,以上已观察值的事实状态不变。
## 2026-09-29 概率解释可视化
沿用原型色板,概率环强调结果、六轴雷达强调证据阶段;局部科技面板使用现有深绿/青绿语义色,不引入营销插画。图表须附刻度定义、虚实线图例与等价可交互文字列表。只使用短时状态过渡,prefers-reduced-motion时关闭;无持续扫光或闪烁。维度选择进入依据抽屉,原型概率来源进入人工情景表。图形不能暗示权重、面积或资料完整度与真实审批概率等价。详见[概率设计](13-probability-prototype.md)。
+2 -1
View File
@@ -3,7 +3,7 @@
const {chromium}=require('playwright');
const fs=require('fs'),path=require('path'),{pathToFileURL}=require('url');
(async()=>{
const dir=path.resolve(process.env.EVIDENCE_DIR||'test-evidence/20260929-probability-prototype/local');fs.mkdirSync(dir,{recursive:true});
const dir=path.resolve(process.env.EVIDENCE_DIR||'test-evidence/20260929-radar-prototype/local');fs.mkdirSync(dir,{recursive:true});
const browser=await chromium.launch({headless:true,...(process.env.CHROMIUM_PATH?{executablePath:process.env.CHROMIUM_PATH}:{})});
const page=await browser.newPage({viewport:{width:1440,height:1000}});const errors=[],checks=[];page.on('pageerror',e=>errors.push(e.message));
const check=(name,value)=>{checks.push({name,passed:!!value});if(!value)throw Error(name)};
@@ -14,6 +14,7 @@ const fs=require('fs'),path=require('path'),{pathToFileURL}=require('url');
check('P08 baseline 42%',await page.locator('#baseline-probability').innerText()==='42%');
check('P08 explicit demo label',await page.getByText('审批通过概率 · 演示值',{exact:true}).isVisible());
check('P08 uncalibrated explanation',await page.getByText('人工设定,仅演示交互;未经历史数据校准。',{exact:false}).isVisible());
await require('./check-radar.cjs')({page,check,shot});
const baseline=await page.locator('#real-recommendation').innerText();await shot('01-overview');
await page.locator('#btn-show-basis').click();check('P11 basis opens',await page.locator('#basis-dialog').isVisible());
const basis=await page.locator('#basis-dialog').innerText();
+40
View File
@@ -0,0 +1,40 @@
// Shared radar assertions for the standalone prototype test runner.
module.exports = async function verifyRadar({page,check,shot}) {
const dimensions=['回款核验','财务勾稽','权属核验','交易要素','经验适配','规则覆盖'];
await page.locator('#tab-overview').click();
check('P14 baseline radar visible',await page.locator('#radar-baseline').isVisible());
const points=await page.locator('#radar-baseline polygon[data-series="baseline"]').getAttribute('points');
check('P14 six vertices',points.trim().split(/\s+/).length===6);
for(let i=0;i<6;i++){
const button=page.locator(`button[data-dimension="${i}"][data-context="baseline"]`).first();
await button.focus();await page.keyboard.press('Enter');
check(`P15 dimension ${i} title`,(await page.locator('#dimension-title').innerText()).includes(dimensions[i]));
const trace=await page.locator('#dimension-trace').innerText();
for(const term of ['数据卡','Skill','Tools','Rules','read_'])check(`P15 ${i} trace ${term}`,trace.includes(term));
check(`P15 ${i} simulated trace`,trace.includes('演示'));
await page.keyboard.press('Escape');check(`P15 ${i} focus return`,await button.evaluate(e=>e===document.activeElement));
}
await page.locator('#radar-baseline [data-dimension="2"]').click();check('P15 radar axis clickable',(await page.locator('#dimension-title').innerText()).includes('权属核验'));await page.keyboard.press('Escape');
await page.locator('#btn-probability-method').click();
check('P16 baseline lookup', (await page.locator('#method-result').innerText()).includes('42%'));
check('P16 demo table version',(await page.locator('#probability-method-dialog').innerText()).includes('DEMO-TABLE-v1'));
await shot('radar-method-baseline');await page.keyboard.press('Escape');
await page.locator('#tab-simulation').click();
const scenarioBase=await page.locator('#radar-scenario polygon[data-series="baseline"]').getAttribute('points');
const basePoints=scenarioBase.trim().split(/\s+/);
for(const [bank,title,key,value] of [[false,false,'00',42],[true,false,'10',58],[true,true,'11',64],[false,true,'01',51],[false,false,'00',42]]){
await page.locator('#assume-bank').setChecked(bank);await page.locator('#assume-title').setChecked(title);
const selected=(await page.locator('#radar-scenario polygon[data-series="scenario"]').getAttribute('points')).trim().split(/\s+/);
check(`P17 unchanged baseline ${key}`,await page.locator('#radar-scenario polygon[data-series="baseline"]').getAttribute('points')===scenarioBase);
check(`P17 independent baseline ${key}`,await page.locator('#radar-baseline polygon[data-series="baseline"]').getAttribute('points')===points);
check(`P17 cash axis ${key}`,bank?selected[0]!==basePoints[0]:selected[0]===basePoints[0]);
check(`P17 title axis ${key}`,title?selected[2]!==basePoints[2]:selected[2]===basePoints[2]);
check(`P17 other axes ${key}`,[1,3,4,5].every(i=>selected[i]===basePoints[i]));
await page.locator('#btn-scenario-method').click();check(`P16 scenario result ${key}`,(await page.locator('#method-result').innerText()).includes(value+'%'));
check(`P16 selected row ${key}`,await page.locator('#method-row-'+key).getAttribute('aria-selected')==='true');await page.keyboard.press('Escape');
}
await page.locator('#assume-bank').check();await page.locator('#assume-title').check();
await page.locator('button[data-dimension="0"][data-context="scenario"]').first().click();check('P15 scenario labeled assumption',(await page.locator('#dimension-trace').innerText()).includes('假设'));await shot('radar-dimension-scenario');await page.keyboard.press('Escape');
await page.locator('#radar-scenario').scrollIntoViewIfNeeded();await shot('radar-scenario-overlay');
await page.locator('#tab-overview').click();await page.locator('[data-sd-id="8"]').evaluate(e=>e.scrollTop=0);await shot('radar-overview');
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

+83 -56
View File
@@ -55,7 +55,20 @@
@media(max-width:768px){.mobile-menu{display:flex;font-size:22px;min-width:44px;height:44px;align-items:center;justify-content:center}#prototype-navigation{display:none!important;position:fixed;top:68px;bottom:0;left:0;z-index:30;min-height:0!important;box-shadow:0 16px 48px rgba(16,43,39,.16)}#prototype-navigation.mobile-open{display:flex!important}body [data-sd-id="8"]{padding:20px}body [data-sd-id="3"]{padding:8px 12px}body [data-sd-id="12"]{font-size:24px}body [data-sd-id="19"]{padding:20px}body [data-sd-id="82"]{display:flex}body [data-sd-id="46"]{display:grid;grid-template-columns:1fr 1fr}body [data-sd-id="53"]{gap:12px}body [data-sd-id="60"]{max-width:none;text-align:center}body [data-sd-id="44"]{display:none}.condition-grid{grid-template-columns:1fr}body [data-sd-id="37"]{gap:24px}body [data-sd-id="26"]{gap:32px}body [data-sd-id="14"]{font-size:14px}.proto-panel{padding:20px}}
body [data-sd-id="60"]{min-width:112px;max-width:none;white-space:nowrap;text-align:center}input[type=radio]{accent-color:#17634C}#prototype-navigation>a.is-active{background:transparent}
#probability-hero{flex-wrap:wrap}#probability-hero>div{flex-wrap:wrap;gap:12px}#probability-hero>div>span:last-child{white-space:nowrap}#sim-prob-delta{white-space:nowrap}#basis-dialog>div{padding:0;height:auto!important}body [data-sd-id="9"]{flex-shrink:0}
#probability-hero{flex-wrap:wrap}#probability-hero>div{flex-wrap:wrap;gap:12px}#probability-hero>div>span:last-child{white-space:nowrap}#sim-prob-delta{white-space:nowrap}#basis-dialog>div{padding:0;height:auto!important}body [data-sd-id="9"]{flex-shrink:0}
.radar-polygon { transition: all 300ms ease; }
.radar-polygon-sandbox { fill: rgba(23,99,76,0.15); stroke: #17634C; stroke-width: 2; }
.radar-polygon-baseline { fill: transparent; stroke: #DCE4DF; stroke-width: 1; stroke-dasharray: 4; }
.radar-axis { stroke: #DCE4DF; stroke-width: 1; }
.radar-tick { stroke: #B1C6BE; stroke-width: 1; }
.radar-label { font-size: 11px; fill: #52675C; cursor: pointer; }
.radar-label:hover { fill: #17634C; font-weight: bold; }
body #probability-hero{display:block;width:100%;background:#102B27;color:#F3F7F5;border:1px solid #244D41;border-radius:12px;padding:20px;background-image:linear-gradient(#B1C6BE08 1px,transparent 1px),linear-gradient(90deg,#B1C6BE08 1px,transparent 1px);background-size:24px 24px}
.cockpit-heading{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;font-size:12px;letter-spacing:1px;color:#B1C6BE}.cockpit-badge{border:1px solid #52675C;border-radius:20px;padding:3px 10px}.cockpit-grid{display:grid;grid-template-columns:minmax(190px,.8fr) minmax(260px,1.2fr);gap:16px;align-items:center}.probability-center{text-align:center}.probability-ring{position:relative;width:200px;height:200px;margin:0 auto}.probability-ring svg{width:100%;height:100%}.ring-ticks{fill:none;stroke:#52675C;stroke-width:2;stroke-dasharray:1 7}.ring-track{fill:none;stroke:#244D41;stroke-width:8}.ring-value{fill:none;stroke:#B1C6BE;stroke-width:8;stroke-linecap:round;transform:rotate(-90deg);transform-origin:100px 100px}.ring-copy{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:8px}.ring-copy strong{font-size:46px;line-height:1;font-weight:600;letter-spacing:-2px}.ring-copy span{font-size:12px;color:#B1C6BE}.cockpit-button{border:1px solid #B1C6BE;border-radius:8px;padding:10px 16px;font-size:14px;color:#F3F7F5;min-height:44px}.cockpit-button:hover{background:#244D41}.cockpit-muted{font-size:12px;color:#B1C6BE;margin-top:12px}.radar-caption{font-size:15px;font-weight:600;display:flex;justify-content:space-between;gap:12px}.radar-caption small{font-size:12px;color:#B1C6BE}.radar-chart svg{width:100%;height:auto;max-height:275px;overflow:visible;display:block}.radar-chart .grid-line{fill:none;stroke:currentColor;opacity:.25;stroke-width:1}.radar-chart .stage-label{font-size:10px;fill:currentColor;opacity:.75}.radar-chart .dimension-label{font-size:12px;fill:currentColor;cursor:pointer}.radar-chart .dimension-label:hover{text-decoration:underline}.radar-chart [data-series=baseline]{fill:#B1C6BE22;stroke:#B1C6BE;stroke-width:2}.dimension-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}.dimension-list button{font-size:12px;text-align:left;padding:8px;border:1px solid #52675C;border-radius:6px;min-height:44px}.dimension-list b{font-weight:500;display:block}.dimension-list span{font-size:11px;color:#B1C6BE}.dimension-list button:hover{background:#244D41}.cockpit-foot{font-size:12px;line-height:1.8;color:#F3F7F5;border-top:1px solid #52675C;padding-top:12px;margin-top:16px}.cockpit-foot span{color:#B1C6BE}.trace-strip{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;font-size:12px;color:#52675C}.trace-strip .text-action{font-size:12px;min-height:36px}.scenario-radar-card{min-width:0;flex:1;background:#F8FAF9;border:1px solid #DCE4DF;border-radius:12px;padding:20px;color:#52675C}.scenario-probabilities{display:flex;justify-content:space-between;gap:16px}.scenario-probabilities>div:last-child{text-align:right}.scenario-probabilities small{display:block;font-size:12px}.scenario-probabilities strong{display:block;font-size:30px;color:#17634C}.scenario-probabilities #sim-prob-delta{font-size:12px;color:#17634C;display:block;white-space:nowrap}.scenario-meter{height:5px;background:#DCE4DF;border-radius:4px;margin:12px 0;overflow:hidden}.scenario-meter>div{height:100%;background:#17634C;transition:width 180ms}.radar-legend{display:flex;justify-content:center;gap:16px;font-size:12px}.scenario-radar-card [data-series=baseline]{fill:none;stroke:#64766C;stroke-dasharray:5 4}.scenario-radar-card [data-series=scenario]{fill:#17634C22;stroke:#17634C;stroke-width:2}.scenario-radar-card .dimension-list{grid-template-columns:repeat(2,minmax(0,1fr))}.scenario-radar-card .dimension-list button{border-color:#DCE4DF}.scenario-radar-card .dimension-list span{color:#52675C}.scenario-radar-card .dimension-list button:hover{background:#EAF3EC}.proto-panel .radar-help{font-size:12px;line-height:1.65;margin:12px 0;color:#64766C}.method-table{width:100%;font-size:14px;border-collapse:collapse}.method-table caption{font-size:12px;color:#64766C;text-align:left;margin-bottom:12px}.method-table th,.method-table td{padding:12px 8px;border-bottom:1px solid #DCE4DF;text-align:left}.method-table [aria-selected=true]{background:#EAF3EC;color:#17634C;font-weight:600;outline:1px solid #17634C}.method-subheading{font-size:17px;font-weight:600;margin:24px 0 12px}.trace-chain{list-style:none;padding:0;margin:0}.trace-chain li{border-left:2px solid #B1C6BE;padding:0 0 16px 16px;margin-left:5px}.trace-chain li b{font-size:14px}.trace-chain li p{font-size:14px;overflow-wrap:anywhere}.trace-chip{font-size:12px;color:#52675C;background:#F8FAF9;padding:8px;border:1px solid #DCE4DF;border-radius:6px;overflow-wrap:anywhere}.cockpit-grid *:focus-visible{outline-color:#B1C6BE}body [role=tab][data-tab][aria-selected=false]{border-color:transparent!important}
@media(max-width:1250px) and (min-width:1101px){.cockpit-grid{grid-template-columns:1fr}.probability-ring{width:170px;height:170px}}
@media(max-width:768px){body #probability-hero{padding:16px}.cockpit-grid{grid-template-columns:1fr}.radar-chart svg{max-height:none}.probability-ring{width:180px;height:180px}.cockpit-heading{font-size:11px}.dimension-list{grid-template-columns:repeat(2,minmax(0,1fr))}.scenario-radar-card{padding:12px}.radar-caption{margin-top:16px}.trace-strip{line-height:1.8}}
@media(max-width:768px){.radar-chart .dimension-label{font-size:16px}.radar-chart .stage-label{font-size:14px}}
</style>
</head>
<body>
@@ -102,20 +115,15 @@
<section class="bg-card rounded-panel p-32 shadow-card border border-border flex flex-col gap-24" data-sd-id="19">
<div class="flex justify-between items-start" data-sd-id="20">
<div class="flex flex-col gap-8 w-full max-w-3xl" data-sd-id="21">
<!-- Added Probability Hero Area -->
<div class="flex items-center gap-16 mb-4" id="probability-hero">
<div class="flex items-baseline gap-6">
<span class="text-[36px] font-bold text-primary leading-none tracking-tight" id="baseline-probability">42<span class="text-[20px]">%</span></span>
<span class="text-[12px] text-primary bg-normal-bg px-10 py-4 rounded-full border border-normal-text/20 font-medium">审批通过概率 · 演示值</span>
</div>
<button class="text-[14px] text-primary hover:text-primary-hover font-medium flex items-center gap-4 px-12 py-6 rounded-button hover:bg-normal-bg transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary" id="btn-show-basis">
<iconify-icon icon="lucide:help-circle"></iconify-icon> 查看判断依据
</button>
</div>
<div class="probability-cockpit" id="probability-hero">
<div class="cockpit-heading"><span>DECISION INTELLIGENCE / 预审透视</span><span class="cockpit-badge">DEMO · 人工演示</span></div>
<div class="cockpit-grid"><div class="probability-center"><div class="probability-ring"><svg aria-hidden="true" viewbox="0 0 200 200"><circle class="ring-ticks" cx="100" cy="100" r="87"></circle><circle class="ring-track" cx="100" cy="100" r="73"></circle><circle class="ring-value" cx="100" cy="100" pathlength="100" r="73" stroke-dasharray="42 100"></circle></svg><div class="ring-copy"><strong id="baseline-probability">42%</strong><span>审批通过概率 · 演示值</span></div></div><button class="cockpit-button" id="btn-probability-method">42% 如何得到 <span aria-hidden="true">↗</span></button><p class="cockpit-muted">依据可追溯 · 正式审批由人工决定</p></div>
<div class="radar-main"><div class="radar-caption">六维证据雷达 <small>基线 / 阶段 0—4</small></div><div class="radar-chart"><svg aria-label="六维证据核验阶段,详细内容见下方维度按钮" id="radar-baseline" role="group" viewbox="-180 -140 360 280"></svg></div><div class="dimension-list" data-dimension-list="baseline"></div></div></div>
<div class="cockpit-foot">证据阶段 ≠ 审批概率 · 雷达面积不换算为 42%<br/><span>0 未提供 · 1 仅有说明 · 2 资料待核 · 3 交叉核验 · 4 人工复核</span></div>
</div><div class="trace-strip"><span><b>miniOpenClaw</b> 受控编排</span><span>数据卡 → Skills → Tools → Rules → 主审</span><button class="text-action" id="btn-show-basis">查看判断依据 ↗</button></div>
<div class="text-[12px] text-warning-text bg-warning-bg px-12 py-8 rounded-button border border-warning-text/20 inline-flex w-fit items-center gap-6 mb-8">
<iconify-icon class="text-[14px]" icon="lucide:info"></iconify-icon> 人工设定,仅演示交互;未经历史数据校准。目标定义:以本次材料版本提交后的首次审批通过。
</div>
<!-- End Probability Hero Area -->
<h2 class="text-[24px] font-bold text-ink-main mt-4" data-sd-id="22" id="real-recommendation">主审意见:补充材料后再判断</h2>
<p class="text-[16px] text-ink-sub max-w-2xl leading-relaxed" data-sd-id="23">
经营现金流与回款说明存在待核实差异,建议先补齐两项关键证据,再推进评审。
@@ -238,51 +246,19 @@
<div class="condition-grid"><div><strong>适用条件</strong><p>客户结构稳定,回款与应收记录可逐笔匹配。</p></div><div><strong>例外边界</strong><p>收入集中、关联回款未穿透或材料真实性未核实。</p></div></div>
<div class="notice">条件相似不等于结论相同。当前项目仍缺银行流水与权属核验。</div>
</section>
<!-- Updated Simulation Tab -->
<section aria-labelledby="tab-simulation" class="proto-panel" hidden="" id="panel-simulation" role="tabpanel">
<div class="section-eyebrow">SCENARIO / 条件推演</div>
<div class="section-eyebrow">SCENARIO / 证据成熟度推演</div>
<h2>补齐证据之后,审批概率如何变化?</h2>
<div class="notice">模拟结果,不改变真实项目。以下仅假设证据真实且完成核验;补件也可能发现新风险,真实概率未必上升,仍需人工复核。</div>
<div class="notice">模拟结果,不改变真实项目。仅假设证据真实且核验支持解释;补件也可能发现新风险,实际概率未必上升。</div>
<div class="flex flex-col lg:flex-row gap-24 mt-24 mb-24">
<div class="flex-1 flex flex-col gap-12">
<p class="muted mb-8">选择准备补充的材料,观察演示概率变化:</p>
<label class="scenario-choice"><input id="assume-bank" type="checkbox"/> <span><strong>补充近六个月银行流水</strong><small>假设逐笔匹配后支持账期变化解释</small></span></label>
<label class="scenario-choice"><input id="assume-title" type="checkbox"/> <span><strong>补充设备权属证明</strong><small>假设合同、发票与设备清单一致且经核验</small></span></label>
<p class="muted mb-8">选择假设补充核验的材料,观察证据六边形扩张与概率变化:</p>
<label class="scenario-choice"><input id="assume-bank" type="checkbox"/> <span><strong>假设银行流水逐笔匹配</strong><small>假设核验支持账期变化解释;只改变回款核验维度</small></span></label>
<label class="scenario-choice"><input id="assume-title" type="checkbox"/> <span><strong>假设设备权属证明一致</strong><small>假设合同、发票与设备清单核验一致;只改变权属维度</small></span></label>
</div>
<div aria-live="polite" class="flex-1 bg-panel border border-border rounded-panel p-24 flex flex-col justify-center">
<div class="flex justify-between items-end mb-16">
<div>
<div class="text-[12px] text-ink-mute mb-8">当前基线 (演示值)</div>
<div class="text-[24px] font-bold text-ink-main leading-none">42%</div>
<div class="scenario-radar-card"><div aria-live="polite" class="scenario-probabilities"><div><small>当前基线 · 演示值</small><strong>42%</strong></div><div><small>所选情景 · 演示值</small><strong id="sim-prob-val">42%</strong><span id="sim-prob-delta">+0 百分点</span></div></div><div class="scenario-meter"><div id="sim-prob-bar" style="width:42%"></div></div><div class="radar-legend"><span>┄┄ 基线</span><span>━━ 所选假设</span></div><div class="radar-chart"><svg aria-label="六维证据核验阶段,详细内容见下方维度按钮" id="radar-scenario" role="group" viewbox="-180 -140 360 280"></svg></div><div class="dimension-list" data-dimension-list="scenario"></div><p class="radar-help">证据阶段 ≠ 审批概率;0 未提供 · 1 仅有说明 · 2 资料待核 · 3 交叉核验 · 4 人工复核</p><p class="radar-help">人工设定,仅演示交互;未经历史数据校准</p><button class="text-action" id="btn-scenario-method">所选情景概率如何得到 ↗</button></div>
</div>
<div class="text-right">
<div class="text-[12px] text-ink-mute mb-8">所选情景 (演示值)</div>
<div class="flex items-baseline gap-8 justify-end">
<span class="text-[36px] font-bold text-primary leading-none tracking-tight" id="sim-prob-val">42%</span>
<span class="text-[14px] font-bold text-normal-text bg-normal-bg px-8 py-2 rounded-full opacity-0 transition-opacity duration-200" id="sim-prob-delta">+0 百分点</span>
</div>
</div>
</div>
<div class="flex flex-col gap-12">
<div class="flex items-center gap-12">
<span class="text-[12px] text-ink-mute w-[32px] shrink-0 text-right">基线</span>
<div class="flex-1 h-[8px] bg-border rounded-full overflow-hidden">
<div class="h-full bg-ink-mute rounded-full" style="width: 42%;"></div>
</div>
</div>
<div class="flex items-center gap-12">
<span class="text-[12px] text-ink-mute w-[32px] shrink-0 text-right">模拟</span>
<div class="flex-1 h-[8px] bg-border rounded-full overflow-hidden">
<div class="h-full bg-primary rounded-full transition-all duration-200 ease-out" id="sim-prob-bar" style="width: 42%;"></div>
</div>
</div>
</div>
<div class="text-[12px] text-warning-text mt-16 flex items-center justify-center gap-4">
<iconify-icon icon="lucide:info"></iconify-icon> 人工设定,仅演示交互;未经历史数据校准
</div>
</div>
</div>
<button class="primary-button" id="run-simulation">查看概率与判断依据</button>
<button class="primary-button" id="run-simulation">查看模拟判断依据</button>
<p aria-live="polite" class="muted mt-12" id="simulation-feedback">概率、原因与待核实事项随勾选即时更新。</p>
<div aria-live="polite" class="condition-grid mt-16" id="simulation-comparison">
<div><small>真实预审 · 保持不变</small><h3>2 项待核实</h3><p>补充材料后再判断</p></div>
@@ -353,7 +329,6 @@
<section aria-labelledby="evidence-source-tab" id="evidence-source" role="tabpanel"><p class="muted" id="source-location">回款说明.pdf · 第3页 · 虚构演示</p><blockquote id="source-quote">主要客户账期延长,预计下一季度集中回款。</blockquote><div class="notice" id="source-gap">尚未提供对应银行流水,不能仅凭解释确认回款。</div><p class="muted">来源可定位不代表材料真实性已经核验。</p></section>
<section aria-labelledby="evidence-basis-tab" hidden="" id="evidence-basis" role="tabpanel"><h3>从解释到判断,仍缺一环</h3><p id="basis-copy">现有说明提出了账期变化的解释,但需要银行流水与应收账龄交叉核验。专项判断不能替代主审综合意见。</p><h3>建议下一步</h3><p id="basis-next">补充近六个月银行流水,逐笔匹配主要客户回款。</p></section>
</dialog>
<!-- NEW: Basis Drawer -->
<dialog aria-labelledby="basis-title" class="evidence-dialog" id="basis-dialog">
<header class="dialog-header">
<div>
@@ -363,7 +338,7 @@
<button aria-label="关闭依据抽屉" class="close-button" data-close="basis-dialog">×</button>
</header>
<div class="p-24 overflow-y-auto" style="height:calc(100vh - 90px)">
<div class="notice mb-24">当前基线 42% 来自人工设定的原型情景表,非模型计算、非历史统计。以下展示未来的追溯结构,不构成数字的计算来源。</div><div class="notice" id="demo-probability-source">演示情景表:无假设 42%;流水核验支持解释 58%;权属核验一致 51%;两者同时成立 64%。组合结果单独设定,不能把增幅简单相加。</div>
<div class="notice mb-24">当前基线 42% 来自人工设定的原型情景表,非模型计算、非历史统计。以下展示未来的追溯结构,不构成数字的计算来源。</div>
<div class="flex flex-col gap-24">
<div>
<h3 class="text-[16px] font-bold text-ink-main mb-12 flex items-center gap-8"><iconify-icon icon="lucide:database"></iconify-icon> 1. 状态与数据卡</h3>
@@ -376,7 +351,7 @@
<h3 class="text-[16px] font-bold text-ink-main mb-12 flex items-center gap-8"><iconify-icon icon="lucide:cpu"></iconify-icon> 2. 技能与规则 (Skill Trace)</h3>
<ul class="checklist">
<li><strong>回款交叉核验</strong> <span class="text-ink-mute text-[12px]">SKILL-04 · v1.0(演示)</span><p>状态:待核实。缺少对应时间段银行流水,不能判定核验通过或不通过。</p></li>
<li><strong>权属一致性比对</strong> <span class="text-ink-mute text-[12px]">SKILL-09 · v1.0(演示)</span><p>发现发票与清单异常。</p></li>
<li><strong>权属一致性比 timelines</strong> <span class="text-ink-mute text-[12px]">SKILL-09 · v1.0(演示)</span><p>发现发票与清单异常。</p></li>
</ul>
</div>
<div>
@@ -394,8 +369,27 @@
</div>
</div>
</dialog>
<dialog aria-labelledby="checklist-title" class="center-dialog" id="checklist-dialog"><header class="dialog-header"><div><div class="section-eyebrow">NEXT ACTION / 演示清单</div><h2 id="checklist-title">项目补件清单</h2></div><button aria-label="关闭补件清单" class="close-button" data-close="checklist-dialog">×</button></header><ol class="checklist"><li><strong>近六个月银行流水与应收账龄</strong><p>标注主要客户逐笔回款,说明与合同账期的对应关系。</p></li><li><strong>设备权属材料</strong><p>提供采购合同、发票和设备清单,并解释品名差异。</p></li></ol><div class="notice">DEMO-026 · 虚构演示,未发送至任何业务系统。</div><button class="primary-button" id="copy-checklist">复制清单</button><p aria-live="polite" id="copy-status"></p></dialog>
<dialog aria-labelledby="validation-title" class="center-dialog" id="validation-dialog"><header class="dialog-header"><div><div class="section-eyebrow">VALIDATION / 验证计划</div><h2 id="validation-title">待开展脱敏盲测</h2></div><button aria-label="关闭验证计划" class="close-button" data-close="validation-dialog">×</button></header><p>先冻结样本和预测,再揭示专家参考意见。当前没有真实验证结果。</p><ol class="checklist"><li>基础预审:不使用历史经验</li><li>经验增强:主审结合已审核经验</li><li>专项增强:分别验证本地模型与 Jev(可选)</li></ol><div class="notice">关注重大问题漏检、无依据结论、有效补件与耗时。阈值在试点前约定。</div></dialog>
<dialog aria-labelledby="dimension-title" class="evidence-dialog" id="dimension-dialog"><header class="dialog-header"><div><div class="section-eyebrow">TRACE / miniOpenClaw</div><h2 id="dimension-title"></h2></div><button aria-label="关闭维度依据" class="close-button" data-close="dimension-dialog">×</button></header><div id="dimension-trace"></div></dialog><dialog aria-labelledby="method-title" class="center-dialog" id="probability-method-dialog"><header class="dialog-header"><div><div class="section-eyebrow">PROBABILITY / 结果出处</div><h2 id="method-title">这次概率如何得到</h2></div><button aria-label="关闭概率出处" class="close-button" data-close="probability-method-dialog">×</button></header><div aria-live="polite" class="notice" id="method-result"></div><p>当前依据:人工情景表 <strong>DEMO-TABLE-v1</strong>。没有模型计算、真实样本统计或校准结果;六维雷达不能求和、平均或按面积换算成概率。</p><table class="method-table"><caption>选择键:流水假设 / 权属假设;数字为人工演示值</caption><thead><tr><th>键</th><th>假设组合</th><th>演示输出</th></tr></thead><tbody><tr id="method-row-00"><td>00</td><td>两项均未选择</td><td>42%</td></tr><tr id="method-row-10"><td>10</td><td>流水核验支持解释</td><td>58%</td></tr><tr id="method-row-01"><td>01</td><td>权属核验一致</td><td>51%</td></tr><tr id="method-row-11"><td>11</td><td>两项假设均成立</td><td>64%</td></tr></tbody></table><h3 class="method-subheading">真实版如何计算 · 后续规划</h3><ol class="trace-chain"><li><b>01 数据卡 → Skills / 授权 Tools</b><p>读取冻结事实与核验记录,保留来源和方法版本。</p></li><li><b>02 特征构建 → 概率估计 → 历史校准</b><p>在明确审批口径、样本范围和制度版本后训练与验证。模型、样本、校准:当前均未接入。</p></li><li><b>03 Rules / 有效性检查 → 主审解释</b><p>缺证标待核实;硬性阻断不能被高概率抵消。未校准的真实概率保持空值。</p></li><li><b>04 miniOpenClaw 保留轨迹 → 人工审批</b><p>主审解释综合结论;Jev/local只承担可选专项判断,不能用其置信度替代审批概率。</p></li></ol></dialog>
<dialog aria-labelledby="checklist-title" class="center-dialog" id="checklist-dialog">
<header class="dialog-header"><div><div class="section-eyebrow">NEXT ACTION / 演示清单</div><h2 id="checklist-title">项目补件清单</h2></div><button aria-label="关闭补件清单" class="close-button" data-close="checklist-dialog">×</button></header>
<ol class="checklist">
<li><strong>近六个月银行流水与应收账龄</strong><p>标注主要客户逐笔回款,说明与合同账期的对应关系。</p></li>
<li><strong>设备权属材料</strong><p>提供采购合同、发票和设备清单,并解释品名差异。</p></li>
</ol>
<div class="notice">DEMO-026 · 虚构演示,未发送至任何业务系统。</div>
<button class="primary-button" id="copy-checklist">复制清单</button>
<p aria-live="polite" id="copy-status"></p>
</dialog>
<dialog aria-labelledby="validation-title" class="center-dialog" id="validation-dialog">
<header class="dialog-header"><div><div class="section-eyebrow">VALIDATION / 验证计划</div><h2 id="validation-title">待开展脱敏盲测</h2></div><button aria-label="关闭验证计划" class="close-button" data-close="validation-dialog">×</button></header>
<p>先冻结样本和预测,再揭示专家参考意见。当前没有真实验证结果。</p>
<ol class="checklist">
<li>基础预审:不使用历史经验</li>
<li>经验增强:主审结合已审核经验</li>
<li>专项增强:分别验证本地模型与 Jev(可选)</li>
</ol>
<div class="notice">关注重大问题漏检、无依据结论、有效补件与耗时。阈值在试点前约定。</div>
</dialog>
<script>
(()=>{
const $=s=>document.querySelector(s),all=s=>[...document.querySelectorAll(s)],sd=n=>$('[data-sd-id="'+n+'"]');
@@ -416,6 +410,38 @@
all('input[name=model]').forEach(r=>r.onchange=()=>{const off=r.value==='off';$('#model-status').textContent=off?'专项核查已关闭。主审仍可基于证据与经验给出有限意见。':'本地开源模型(演示)。无真实模型请求;主审负责综合预审意见。';sd(56).textContent=off?'未执行':'不足';sd(55).textContent=off?'专项核查':'专项支持'});
const dimensionNames=['回款核验','财务勾稽','权属核验','交易要素','经验适配','规则覆盖'];
const baseStages=[1,2,1,2,2,1],stageNames=['未提供','仅有说明','资料待核','交叉核验','人工复核'];
const dimensionTraces=[
{card:'DC-CASH v1.2',skill:'SKILL-04 v1.0 · 回款交叉核验',tools:'read_project_snapshot / read_document / read_method / read_checks',input:'回款说明.pdf第3页与应收明细;近六个月银行流水缺失。',output:'账期变化仍只有说明,无法逐笔比对。',rule:'RULE-CASH v1.0 · 待核实,不能把解释当成已收回资金。',experience:'H-018:客户结构稳定且能逐笔匹配时参考;关联回款未穿透时不适用。'},
{card:'DC-FIN v1.0',skill:'SKILL-FIN v1.0 · 财务口径核对',tools:'read_project_snapshot / read_document / read_method / read_checks',input:'演示报表与财务说明;原始凭证和口径待复核。',output:'仅说明资料待核,未完成收入、利润、现金流勾稽。',rule:'RULE-FIN v1.0 · 期间和口径未确认时不得直接比较或加分。',experience:'经验只在期间、口径、行业适用条件一致时参考,不能套用阈值。'},
{card:'DC-TITLE v1.0',skill:'SKILL-09 v1.0 · 权属一致性',tools:'read_project_snapshot / read_document / read_method / read_checks',input:'设备清单与发票品名差异;采购合同附件待补。',output:'只有差异说明,真实权属尚待核验。',rule:'RULE-01 v1.0 · 待核实,尚未确认阻断不代表红线核查通过。',experience:'参考核验步骤而非套用审批结论;权属链不完整时不适用通过意见。'},
{card:'DC-DEAL v1.0',skill:'SKILL-DEAL v1.0 · 交易要素核对',tools:'read_project_snapshot / read_method / read_checks',input:'演示融资3,000万元、36个月、设备直租。',output:'要素已列示,未核对合同条件和租金安排。',rule:'RULE-DEAL v1.0 · 条款和还款安排待复核,列示不等于有效。',experience:'交易类型与期限匹配只是筛选条件,不是审批依据。'},
{card:'DC-EXP v1.0',skill:'SKILL-EXP v1.0 · 经验适用性核查',tools:'read_project_snapshot / read_method / read_experiences',input:'虚构经验H-018及适用条件与例外。',output:'已展示候选经验;当前缺少逐笔匹配证据,不能直接套用。',rule:'RULE-EXP v1.0 · 真实经验须审核、发布并冻结版本;本条仅演示。',experience:'客户结构稳定、逐笔回款匹配;收入集中或关联回款未穿透属于例外。'},
{card:'DC-RULE v1.0',skill:'SKILL-RULE v1.0 · 规则结果汇总',tools:'read_project_snapshot / read_method / read_checks',input:'演示规则清单与缺证状态,真实制度尚未接入。',output:'仍有待核实规则,未形成规则全部通过的判断。',rule:'RULE-GATE v1.0 · 未知不能当通过;确认硬阻断时独立提示,不能被高分抵消。',experience:'历史案例不能豁免当前有效规则;制度版本变化需重新确认适用。'}
];
function scenarioKey(){return Number($('#assume-bank').checked)+''+Number($('#assume-title').checked)}
function points(stages){return stages.map((v,i)=>{const a=i*Math.PI/3;return ((v/4)*90*Math.sin(a)).toFixed(2)+','+(-(v/4)*90*Math.cos(a)).toFixed(2)}).join(' ')}
function selectedStages(){const v=[...baseStages];if($('#assume-bank').checked)v[0]=3;if($('#assume-title').checked)v[2]=3;return v}
function buildRadar(context){
const svg=$('#radar-'+(context==='baseline'?'baseline':'scenario'));
let html='';
for(let n=1;n<=4;n++)html+='<polygon class="grid-line" points="'+points(Array(6).fill(n))+'"/><text class="stage-label" x="5" y="'+(-n*22.5+3)+'">'+n+'</text>';
const labelPositions=[[0,-111,'middle'],[96,-49,'start'],[96,58,'start'],[0,117,'middle'],[-96,58,'end'],[-96,-49,'end']];
dimensionNames.forEach((name,i)=>{const a=i*Math.PI/3;html+='<line class="grid-line" x1="0" y1="0" x2="'+90*Math.sin(a)+'" y2="'+(-90*Math.cos(a))+'"/>'});
html+='<polygon data-series="baseline" points="'+points(baseStages)+'"/>';
if(context==='scenario')html+='<polygon data-series="scenario" points="'+points(baseStages)+'"/>';
dimensionNames.forEach((name,i)=>{const [x,y,anchor]=labelPositions[i];html+='<text class="dimension-label" data-dimension="'+i+'" data-context="'+context+'" role="button" tabindex="0" aria-label="查看'+name+'依据" x="'+x+'" y="'+y+'" text-anchor="'+anchor+'">'+name+'</text>'});
svg.innerHTML=html;
$('[data-dimension-list="'+context+'"]').innerHTML=dimensionNames.map((name,i)=>'<button data-dimension="'+i+'" data-context="'+context+'"><b>'+name+'</b><span data-stage-label="'+i+'">'+baseStages[i]+' · '+stageNames[baseStages[i]]+'</span></button>').join('');
}
function updateRadar(){const stages=selectedStages();$('#radar-scenario [data-series="scenario"]').setAttribute('points',points(stages));all('[data-dimension-list="scenario"] [data-stage-label]').forEach(el=>{const i=Number(el.dataset.stageLabel),v=stages[i];el.textContent=v+' · '+(v!==baseStages[i]?'假设已核验':stageNames[v]);});}
function openDimension(i,context){const d=dimensionTraces[i],assumed=context==='scenario'&&selectedStages()[i]!==baseStages[i];$('#dimension-title').textContent=dimensionNames[i]+' · '+(context==='scenario'?'情景依据':'当前依据');$('#dimension-trace').innerHTML='<div class="notice">虚构演示链,未执行真实工具调用。'+(assumed?'本情景假设该维度交叉核验成立;原项目仍待核实。':'当前材料仍须核验,不能仅凭阶段推出概率。')+'</div><div class="trace-chip">miniOpenClaw · 受控编排示意 / 组件版本为示例</div><ol class="trace-chain"><li><b>01 数据卡 · '+d.card+'</b><p>'+d.input+'</p></li><li><b>02 Skill · '+d.skill+'</b><p>组织专业方法;只使用授权的数据域与工具。</p></li><li><b>03 Tools · 允许的只读能力</b><p>'+d.tools+'</p><p>读取上下文、方法或核验记录,不代表读取工具已完成业务认证。</p></li><li><b>04 核查输出 · '+(assumed?'假设状态':'当前示例')+'</b><p>'+(assumed?'假设补充材料真实,交叉核验支持解释;实际调用尚未发生。':d.output)+'</p></li><li><b>05 Rules · 不可被模型分数覆盖</b><p>'+d.rule+'</p></li><li><b>06 历史经验 · 适用与例外</b><p>'+d.experience+'</p></li></ol><div class="notice">该链解释专业判断的方法与边界,不是42%的数学计算。Jev/local为可选专项判断;概率服务与校准仍待建设。</div>';showDialog('dimension-dialog');}
function openMethod(context){const key=context==='baseline'?'00':scenarioKey(),value=demoScenarios[key].demoProbability;$('#method-result').textContent=(context==='baseline'?'当前基线':'所选假设情景')+' → 命中 '+key+' 条目 → '+value+'%(人工演示值)';all('[id^="method-row-"]').forEach(row=>row.setAttribute('aria-selected',row.id==='method-row-'+key));showDialog('probability-method-dialog');}
buildRadar('baseline');buildRadar('scenario');
all('[data-dimension][data-context]').forEach(el=>{el.onclick=()=>openDimension(Number(el.dataset.dimension),el.dataset.context);if(el.tagName.toLowerCase()==='text')el.onkeydown=e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();el.onclick()}}});
$('#btn-probability-method').onclick=()=>openMethod('baseline');$('#btn-scenario-method').onclick=()=>openMethod('scenario');
// Artificial prototype lookup only: never writes a production probability.
const demoScenarios = {
'00': {demoProbability:42, remaining:'2 项仍待核实(模拟)', reason:'未选择假设。回款与设备权属证据仍有缺口,保持演示基线。'},
@@ -433,6 +459,7 @@
$('#sim-remaining').textContent=scenario.remaining;
$('#sim-explanation').textContent=scenario.reason;
$('#simulation-comparison').hidden=false;
updateRadar();
}
['assume-bank','assume-title'].forEach(id=>$('#'+id).addEventListener('change',updateSimulation));
$('#run-simulation').onclick=()=>showDialog('basis-dialog');