Archived
fix(w05): s_bound 哨兵只在真有料号不在库时开门;全包清掉 disable 教学;version 1.0.1
浏览器全流程走查(样例 1「都在库·常路」)熔断,根因两条:①disable 在本引擎里不可达 (Disabled 只能从 Enabled 来,普通计划项一直停在 Available,disable 恒被拒);②s_bound 在每条路上都开(只看 demand_request_rows/sub_eval_pn_check_rows 两个恒真的读数),都在库 时把两个数据工单项照样推进「当下可为」,逼模型去 disable 它们、连拒五拍。 修:s_bound 的 onPart/ifPart 都改盯 sub_eval_pn_check_exists_status_absent > 0 —— 都在库时门不开,两项静静停在 Available、不进「当下可为」、根本用不上 disable;有缺库时 门照常开。S0_bind 的 guide 与其余各处教 disable 的句子全部清掉,改写清楚「都在库你什么 都不用做」,并明写「任何时候都不要对计划项用 disable」。s_p08_created 未动(都在库时 parts_profile_rows 本就是 0,它本来就不开)。 steps.test.ts 补两条回归测试:s_bound 条件文本含 sub_eval_pn_check_exists_status_absent > 0(退回旧写法会红);NARRATIVE 与全部 ASSESSMENT_STEPS[].guide 里不出现「disable + 计划 项 id」这种祈使形(正则只逮教模型真去调用的句子,不误伤「不要用 disable」这类禁止句)。 manifest.ts 的 identity.packageVersion 1.0.0 → 1.0.1(安装恒新增,不升版本改动装不进去); pnpm activities:install 已重装,静态审无提示(零发现,清单行未追加 findings 后缀)。 48/48 测试(steps.test.ts 18 + activity.test.ts 30)与 typecheck 全绿。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FJcX8A6TWp4GRs41TYryEh
This commit is contained in:
@@ -154,14 +154,30 @@ describe('说明书与剧本的骨架', () => {
|
|||||||
expect(s3).toContain('工具调用后同拍其余动作作废');
|
expect(s3).toContain('工具调用后同拍其余动作作废');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('S0 剧本写明库里都有就 disable S0d 两项;S0d_p08_master 剧本写明候选 ≥2 才问、=1 必建、原 PN 硬阻塞', () => {
|
it('S0 剧本写明都在库时数据工单两项本就不会进「当下可为」;S0d_p08_master 剧本写明候选 ≥2 才问、=1 必建、原 PN 硬阻塞', () => {
|
||||||
const s0 = ASSESSMENT_STEPS.find((s) => s.item === 'S0_bind')?.guide ?? '';
|
const s0 = ASSESSMENT_STEPS.find((s) => s.item === 'S0_bind')?.guide ?? '';
|
||||||
expect(s0).toContain('disable S0d_p08_master');
|
expect(s0).toContain('当下可为');
|
||||||
|
expect(s0).toContain('不要对计划项用');
|
||||||
const s0d = ASSESSMENT_STEPS.find((s) => s.item === 'S0d_p08_master')?.guide ?? '';
|
const s0d = ASSESSMENT_STEPS.find((s) => s.item === 'S0d_p08_master')?.guide ?? '';
|
||||||
expect(s0d).toContain('硬阻塞');
|
expect(s0d).toContain('硬阻塞');
|
||||||
expect(s0d).toContain('候选只有 1 颗');
|
expect(s0d).toContain('候选只有 1 颗');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('s_bound 哨兵真的检查了「有料号不在库」这件事(都在库时门不该开;退回旧写法会红)', () => {
|
||||||
|
expect(CMMN_XML).toContain('sub_eval_pn_check_exists_status_absent > 0');
|
||||||
|
const sBoundBlock = /<sentry id="s_bound">[\s\S]*?<\/sentry>/.exec(CMMN_XML)?.[0] ?? '';
|
||||||
|
expect(sBoundBlock).toContain('caseFileItemRef="sub_eval_pn_check_exists_status_absent"');
|
||||||
|
expect(sBoundBlock).toContain('sub_eval_pn_check_exists_status_absent > 0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('说明书与全部剧本里不会教模型对计划项调用 disable(允许出现在「不要 disable」这类禁止句里)', () => {
|
||||||
|
// 只逮「disable + 计划项 id」这种祈使形(教模型真的去调用它);
|
||||||
|
// 「不要…用 `disable`」「Disabled 只能从 Enabled 来」这类禁止句/状态名不含「disable + id」,不会被误伤。
|
||||||
|
const disableCallPattern = /disable\s+(S\d[a-zA-Z_]*|T_release)/;
|
||||||
|
expect(NARRATIVE).not.toMatch(disableCallPattern);
|
||||||
|
for (const step of ASSESSMENT_STEPS) expect(step.guide, step.item).not.toMatch(disableCallPattern);
|
||||||
|
});
|
||||||
|
|
||||||
it('S0d 拆成两项各自绑自己的 view(P-10 那份件不会永远推不出来),两项都没有 doneWhen', () => {
|
it('S0d 拆成两项各自绑自己的 view(P-10 那份件不会永远推不出来),两项都没有 doneWhen', () => {
|
||||||
const p08 = ASSESSMENT_STEPS.find((s) => s.item === 'S0d_p08_master');
|
const p08 = ASSESSMENT_STEPS.find((s) => s.item === 'S0d_p08_master');
|
||||||
const p10 = ASSESSMENT_STEPS.find((s) => s.item === 'S0d_p10_document');
|
const p10 = ASSESSMENT_STEPS.find((s) => s.item === 'S0d_p10_document');
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
* 工作区件,不能共用同一个 view):
|
* 工作区件,不能共用同一个 view):
|
||||||
* 启动期 → S0_bind(AI:铸案号、建 P-01 V1、锁规则版本、逐个 PN 查库、写存在性核对表)
|
* 启动期 → S0_bind(AI:铸案号、建 P-01 V1、锁规则版本、逐个 PN 查库、写存在性核对表)
|
||||||
* 0.5a 等待数据(建主数据)→ S0d_p08_master(人:数据工单 P-08;候选 ≥2 缺库先决策卡;
|
* 0.5a 等待数据(建主数据)→ S0d_p08_master(人:数据工单 P-08;候选 ≥2 缺库先决策卡;
|
||||||
* 库里都有就 disable 这一项)
|
* 都在库时哨兵不开,这一项与下一项都不会进「当下可为」)
|
||||||
* 0.5b 等待数据(建资料)→ S0d_p10_document(人:数据工单 P-10;库里都有就 disable 这一项)
|
* 0.5b 等待数据(建资料)→ S0d_p10_document(人:数据工单 P-10;都在库时同样不会进「当下可为」)
|
||||||
* 1 建立评估上下文 → S1_input_confirm(人:执行工单 01,评估输入清单,件上补缺口)
|
* 1 建立评估上下文 → S1_input_confirm(人:执行工单 01,评估输入清单,件上补缺口)
|
||||||
* 2 读取并标准化 → S2_normalize(AI:P-11 主记录骨架 + 差异明细对照行)
|
* 2 读取并标准化 → S2_normalize(AI:P-11 主记录骨架 + 差异明细对照行)
|
||||||
* 3 逐项差异评估 → S3_assess(AI + 两枚工具:四态 / 风险 / 证据 / 影响 / 推荐等级 / 验证任务)
|
* 3 逐项差异评估 → S3_assess(AI + 两枚工具:四态 / 风险 / 证据 / 影响 / 推荐等级 / 验证任务)
|
||||||
@@ -61,10 +61,10 @@ export const CMMN_XML = `<?xml version="1.0" encoding="UTF-8"?>
|
|||||||
<caseFileItem id="landing_prepared_total" name="拟落账已备好(S5 写完时置一)"/>
|
<caseFileItem id="landing_prepared_total" name="拟落账已备好(S5 写完时置一)"/>
|
||||||
</caseFileModel>
|
</caseFileModel>
|
||||||
<casePlanModel id="plan" name="差异评估" autoComplete="true">
|
<casePlanModel id="plan" name="差异评估" autoComplete="true">
|
||||||
<!-- ① 已绑定:需求主记录与存在性核对都写下了 —— 数据工单那一项的入场前提 -->
|
<!-- ① 已绑定且真有料号不在库:需求主记录与存在性核对都写下了、至少一颗还 absent —— 数据工单那一项的入场前提 -->
|
||||||
<sentry id="s_bound">
|
<sentry id="s_bound">
|
||||||
<onPart id="op_b" caseFileItemRef="sub_eval_pn_check_rows"><standardEvent>update</standardEvent></onPart>
|
<onPart id="op_b" caseFileItemRef="sub_eval_pn_check_exists_status_absent"><standardEvent>update</standardEvent></onPart>
|
||||||
<ifPart id="if_b"><condition>demand_request_rows > 0 and sub_eval_pn_check_rows > 0</condition></ifPart>
|
<ifPart id="if_b"><condition>demand_request_rows > 0 and sub_eval_pn_check_rows > 0 and sub_eval_pn_check_exists_status_absent > 0</condition></ifPart>
|
||||||
</sentry>
|
</sentry>
|
||||||
<!-- ②′ 芯片主数据已建齐 —— 补资料那一步的入场前提(基座现数) -->
|
<!-- ②′ 芯片主数据已建齐 —— 补资料那一步的入场前提(基座现数) -->
|
||||||
<sentry id="s_p08_created">
|
<sentry id="s_p08_created">
|
||||||
@@ -108,13 +108,13 @@ export const CMMN_XML = `<?xml version="1.0" encoding="UTF-8"?>
|
|||||||
<!-- 启动期:铸案号、建需求 V1、锁规则版本、逐个料号查库(能算的不问人) -->
|
<!-- 启动期:铸案号、建需求 V1、锁规则版本、逐个料号查库(能算的不问人) -->
|
||||||
<humanTask id="S0_bind" name="建立评估上下文:绑定四项、新建需求、存在性核对"/>
|
<humanTask id="S0_bind" name="建立评估上下文:绑定四项、新建需求、存在性核对"/>
|
||||||
|
|
||||||
<!-- 0.5a 等待数据(建主数据):P-08 数据工单;触达人,不给 doneWhen;库里都有就 disable -->
|
<!-- 0.5a 等待数据(建主数据):P-08 数据工单;触达人,不给 doneWhen;都在库时 s_bound 不开,不进「当下可为」 -->
|
||||||
<humanTask id="S0d_p08_master" name="数据工单:补建芯片主数据(P-08)">
|
<humanTask id="S0d_p08_master" name="数据工单:补建芯片主数据(P-08)">
|
||||||
<entryCriterion id="ec_s0d8" sentryRef="s_bound"/>
|
<entryCriterion id="ec_s0d8" sentryRef="s_bound"/>
|
||||||
<itemControl><manualActivationRule id="m_s0d8"/></itemControl>
|
<itemControl><manualActivationRule id="m_s0d8"/></itemControl>
|
||||||
</humanTask>
|
</humanTask>
|
||||||
|
|
||||||
<!-- 0.5b 等待数据(建资料):P-10 数据工单;触达人,不给 doneWhen;库里都有就 disable -->
|
<!-- 0.5b 等待数据(建资料):P-10 数据工单;触达人,不给 doneWhen;都在库时 s_p08_created 不开,不进「当下可为」 -->
|
||||||
<humanTask id="S0d_p10_document" name="数据工单:补建原厂技术资料(P-10)">
|
<humanTask id="S0d_p10_document" name="数据工单:补建原厂技术资料(P-10)">
|
||||||
<entryCriterion id="ec_s0d10" sentryRef="s_p08_created"/>
|
<entryCriterion id="ec_s0d10" sentryRef="s_p08_created"/>
|
||||||
<itemControl><manualActivationRule id="m_s0d10"/></itemControl>
|
<itemControl><manualActivationRule id="m_s0d10"/></itemControl>
|
||||||
@@ -181,7 +181,7 @@ export const NARRATIVE = `§0 开案:**判断候选料号在技术上能不能
|
|||||||
**存在性检查与数据工单**:启动时逐个料号在 \`parts.profile\` 里查(原 PN + 每个候选)。查无记录 = 「完全没有」,
|
**存在性检查与数据工单**:启动时逐个料号在 \`parts.profile\` 里查(原 PN + 每个候选)。查无记录 = 「完全没有」,
|
||||||
要人从零建整条主数据 —— 发**数据工单**(一张表一张单:P-08 一张、P-10 一张);PN 在库但个别字段缺 = 「有而不全」,
|
要人从零建整条主数据 —— 发**数据工单**(一张表一张单:P-08 一张、P-10 一张);PN 在库但个别字段缺 = 「有而不全」,
|
||||||
归执行工单 01 补。原 PN 缺 = 硬阻塞必须建;候选缺:候选 ≥2 时先问人放弃还是创建,候选 = 1 时必须建。
|
归执行工单 01 补。原 PN 缺 = 硬阻塞必须建;候选缺:候选 ≥2 时先问人放弃还是创建,候选 = 1 时必须建。
|
||||||
**库里都有就把 S0d_p08_master 与 S0d_p10_document 两项都 disable 掉**(此单不走这条),别发空单。
|
**库里都有的话这两项的入场前提本就不成立**(此单不走这条),不会出现在你的「当下可为」里,别发空单。
|
||||||
|
|
||||||
**六步走**:绑定与存在性核对 → (等待数据)→ 人补评估输入 → 标准化对照表 → 逐项评估 → 人审结论(可循环)→ 拟落账 → 人放行。
|
**六步走**:绑定与存在性核对 → (等待数据)→ 人补评估输入 → 标准化对照表 → 逐项评估 → 人审结论(可循环)→ 拟落账 → 人放行。
|
||||||
|
|
||||||
@@ -298,8 +298,10 @@ current_stage = "assessing"。application_scenario / bom_position **这一步不
|
|||||||
|
|
||||||
【写 \`${D}.verdict\` 一行】eval_ref、request_id、rule_version = "${RULE_VERSION}"、original_internal_pn、candidate_total = 候选数组长度。
|
【写 \`${D}.verdict\` 一行】eval_ref、request_id、rule_version = "${RULE_VERSION}"、original_internal_pn、candidate_total = 候选数组长度。
|
||||||
|
|
||||||
写完引擎自己收这一项。收完先看 \`${D}.pn_check\`:有 absent 的 → 下一项是 S0d_p08_master(数据工单);一个 absent 都没有 →
|
写完这一项就结束。有 absent 的 → 下一项是 S0d_p08_master(数据工单),照常往下办。
|
||||||
**disable S0d_p08_master 与 S0d_p10_document 两项**(reason 写「原 PN 与全部候选都在库,无需建主数据」),然后等 S1 那一项 Enabled。`,
|
**都在库的话你什么都不用做** —— 数据工单那两项的入场前提本就不成立,它们不会出现在你的「当下可为」里,
|
||||||
|
下一拍你会直接看到「评估输入与资料补齐确认」那一步。**任何时候都不要对计划项用 \`disable\`**:
|
||||||
|
本引擎里 \`Disabled\` 只能从 \`Enabled\` 来,而普通计划项一直停在 \`Available\`,disable 一定被拒。`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
item: 'S0d_p08_master',
|
item: 'S0d_p08_master',
|
||||||
@@ -309,7 +311,7 @@ current_stage = "assessing"。application_scenario / bom_position **这一步不
|
|||||||
view: 'p08-master-create',
|
view: 'p08-master-create',
|
||||||
tools: [],
|
tools: [],
|
||||||
/* 触达人,不给 doneWhen;人工激活:发卡就算启动 */
|
/* 触达人,不给 doneWhen;人工激活:发卡就算启动 */
|
||||||
guide: `这一项只在 \`${D}.pn_check\` 里有 absent 行时走;都在库就由 S0_bind 把这一项与下一项 S0d_p10_document 一起 disable 掉。**先分岔,再动作**:
|
guide: `这一项只在 \`${D}.pn_check\` 里有 absent 行时走 —— 都在库时入场前提本就不成立,这一项与下一项 S0d_p10_document 都不会进你的「当下可为」。**先分岔,再动作**:
|
||||||
|
|
||||||
【先看轨迹】这一项里已经发过哪些卡、人答了什么(【当前这一步】下面那行引擎事实说得清楚):
|
【先看轨迹】这一项里已经发过哪些卡、人答了什么(【当前这一步】下面那行引擎事实说得清楚):
|
||||||
· 原 PN absent → **硬阻塞**,不问人,直接进入「建」的名单;
|
· 原 PN absent → **硬阻塞**,不问人,直接进入「建」的名单;
|
||||||
@@ -341,8 +343,8 @@ current_stage = "assessing"。application_scenario / bom_position **这一步不
|
|||||||
view: 'p10-document-create',
|
view: 'p10-document-create',
|
||||||
tools: [],
|
tools: [],
|
||||||
/* 触达人,不给 doneWhen;人工激活:发卡就算启动 */
|
/* 触达人,不给 doneWhen;人工激活:发卡就算启动 */
|
||||||
guide: `这一项只在 \`${D}.pn_check\` 里有 absent 行时走(要走到这一步,S0d_p08_master 必然已经收完);都在库就由 S0_bind 把这一项与
|
guide: `这一项只在 \`${D}.pn_check\` 里有 absent 行时走(要走到这一步,S0d_p08_master 必然已经收完);都在库时入场前提本就不成立,
|
||||||
S0d_p08_master 一起 disable 掉。
|
这一项与 S0d_p08_master 都不会进你的「当下可为」。
|
||||||
|
|
||||||
【发 P-10 数据工单】「建」的名单就是 \`${D}.pn_check\` 里仍是 exists_status = "absent" 的那几行(候选 ≥2 时被放弃的那些,
|
【发 P-10 数据工单】「建」的名单就是 \`${D}.pn_check\` 里仍是 exists_status = "absent" 的那几行(候选 ≥2 时被放弃的那些,
|
||||||
S0d_p08_master 那一步已经把它们改成 "abandoned",不在这份名单里)。同一拍照说明书④发那张 P-10 数据工单(title 里列全料号,只发一次),
|
S0d_p08_master 那一步已经把它们改成 "abandoned",不在这份名单里)。同一拍照说明书④发那张 P-10 数据工单(title 里列全料号,只发一次),
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export const manifest: ActivityManifest = {
|
|||||||
identity: {
|
identity: {
|
||||||
activityId: ACTIVITY_ID,
|
activityId: ACTIVITY_ID,
|
||||||
name: 'ACT-WORK-05 · 差异评估',
|
name: 'ACT-WORK-05 · 差异评估',
|
||||||
packageVersion: '1.0.0',
|
packageVersion: '1.0.1',
|
||||||
category: '需求分析与方案匹配',
|
category: '需求分析与方案匹配',
|
||||||
sdkVersion: '0.1.0-m5',
|
sdkVersion: '0.1.0-m5',
|
||||||
checksum: 'dev-checksum-part-substitution-assessment',
|
checksum: 'dev-checksum-part-substitution-assessment',
|
||||||
|
|||||||
Reference in New Issue
Block a user