Archived
修:引擎作用域不得吸入他单事实 + 记录 G2 未分流的排查线索
任务视图铺到顶层的字段,原先取「该对象最新一行」—— 那一行很可能是**别的任务** 放行后的正式版记录。实测:NE555P 的打标读到了上一单 LM358DR 的情报 (historyDays 30 / 在产),被判成 Type A;修正后按自己的事实判成 Type B「重估后报」, 与 P-03 规则一致。 改为只铺**本任务自己写下的**草稿(读己之写),别人的事实仍在 `域.对象` 整表里、 要用得显式取。ledger 门面因此新增 `taskDrafts(taskId)` —— 与 `taskView` 的区别是 它只回我写过的那些行。 顺带记录:A1 已能 released 且节点实例正确落 terminal,但 G2 并行网关未起出 下游 A3 / A2;排查线索写进 PROGRESS.md 待办 1。 gates: tsc / eslint / depcruise(317 模块)/ 393 测试 全绿 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"messageId": "rfq-020@beta.com",
|
||||||
|
"from": "buyer@beta.com",
|
||||||
|
"to": [
|
||||||
|
"rfq@we.com"
|
||||||
|
],
|
||||||
|
"cc": [],
|
||||||
|
"subject": "【询价】客户 C002 RFQ-20260727K 求报价",
|
||||||
|
"body": "客户编码 C002,询价单号 RFQ-20260727K。\nLM358DR TI 年用量 20000 目标价 7.90 交期 8w",
|
||||||
|
"receivedAt": "2026-07-27T11:00:00.000Z",
|
||||||
|
"attachments": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"messageId": "rfq-021@beta.com",
|
||||||
|
"from": "buyer@beta.com",
|
||||||
|
"to": [
|
||||||
|
"rfq@we.com"
|
||||||
|
],
|
||||||
|
"cc": [],
|
||||||
|
"subject": "【询价】客户 C002 RFQ-20260727L 求报价",
|
||||||
|
"body": "客户编码 C002,询价单号 RFQ-20260727L。\nNE555P TI 年用量 6000 目标价 3.10 交期 12w",
|
||||||
|
"receivedAt": "2026-07-27T12:00:00.000Z",
|
||||||
|
"attachments": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"messageId": "rfq-030@beta.com",
|
||||||
|
"from": "buyer@beta.com",
|
||||||
|
"to": [
|
||||||
|
"rfq@we.com"
|
||||||
|
],
|
||||||
|
"cc": [],
|
||||||
|
"subject": "【询价】客户 C003 RFQ-20260727M 求报价",
|
||||||
|
"body": "客户编码 C003,询价单号 RFQ-20260727M。\nNE555P TI 年用量 6000 目标价 3.10 交期 12w",
|
||||||
|
"receivedAt": "2026-07-27T13:00:00.000Z",
|
||||||
|
"attachments": []
|
||||||
|
}
|
||||||
@@ -140,10 +140,16 @@ export function wireEngines(deps: EngineWiringDeps): EngineWiring {
|
|||||||
offset: 0,
|
offset: 0,
|
||||||
});
|
});
|
||||||
scope[`${address.domain}.${address.object}`] = page.rows;
|
scope[`${address.domain}.${address.object}`] = page.rows;
|
||||||
const latest = page.rows[page.rows.length - 1];
|
}
|
||||||
if (latest === undefined) continue;
|
|
||||||
for (const [field, value] of Object.entries(latest)) {
|
/*
|
||||||
// 空值不盖掉已有事实:没写进去的字段不该把起单入参抹成 undefined
|
* 铺到顶层的只能是**这一单自己写下的**事实(草稿层 = 读己之写)。
|
||||||
|
* 不能拿「该对象最新一行」来铺:那一行很可能是别的任务放行后的正式版记录,
|
||||||
|
* 一铺就把别人的结论当成了自己的输入 —— 打标会照着上一单的情报出结果。
|
||||||
|
* 别人的事实仍在 `域.对象` 整表里,要用得显式去取。
|
||||||
|
*/
|
||||||
|
for (const draft of await deps.ledger.taskDrafts(taskId)) {
|
||||||
|
for (const [field, value] of Object.entries({ ...draft.key, ...draft.patch })) {
|
||||||
if (value !== null && value !== undefined) scope[field] = value;
|
if (value !== null && value !== undefined) scope[field] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ export type LedgerService = {
|
|||||||
query(query: LedgerQuery): Promise<LedgerPage>;
|
query(query: LedgerQuery): Promise<LedgerPage>;
|
||||||
/** 任务视图 = 正式版 + 本任务草稿层 */
|
/** 任务视图 = 正式版 + 本任务草稿层 */
|
||||||
taskView(taskId: TaskId, query: LedgerQuery): Promise<LedgerPage>;
|
taskView(taskId: TaskId, query: LedgerQuery): Promise<LedgerPage>;
|
||||||
|
/**
|
||||||
|
* **本任务自己写的**草稿条目(读己之写的读面)。
|
||||||
|
* 与 `taskView` 的区别:那个是「正式版 + 我的草稿」的合并视图,
|
||||||
|
* 这个只回我写过的那些行 —— 引擎求值要区分「这一单的事实」与「别人放行后的事实」。
|
||||||
|
*/
|
||||||
|
taskDrafts(taskId: TaskId): Promise<Array<{ domain: string; object: string; key: Record<string, unknown>; patch: Record<string, unknown> }>>;
|
||||||
/** 落地预检第五项:数据冲突检查 */
|
/** 落地预检第五项:数据冲突检查 */
|
||||||
checkConflicts(taskId: TaskId): Promise<ConflictFinding[]>;
|
checkConflicts(taskId: TaskId): Promise<ConflictFinding[]>;
|
||||||
discardDrafts(taskId: TaskId): Promise<void>;
|
discardDrafts(taskId: TaskId): Promise<void>;
|
||||||
|
|||||||
@@ -204,6 +204,11 @@ export function createLedgerService(deps: LedgerServiceDeps): LedgerService {
|
|||||||
return { rows, total: rows.length };
|
return { rows, total: rows.length };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async taskDrafts(taskId) {
|
||||||
|
const drafts = await deps.drafts.list(taskId);
|
||||||
|
return drafts.map((d) => ({ domain: d.domain, object: d.object, key: d.key, patch: d.patch }));
|
||||||
|
},
|
||||||
|
|
||||||
async checkConflicts(taskId) {
|
async checkConflicts(taskId) {
|
||||||
const drafts = await deps.drafts.list(taskId);
|
const drafts = await deps.drafts.list(taskId);
|
||||||
if (drafts.length === 0) return [];
|
if (drafts.length === 0) return [];
|
||||||
|
|||||||
+6
-1
@@ -113,7 +113,12 @@ DMN 三分类规则 P-03 + 台账声明 + 样例集。depcruise 已实测拦下
|
|||||||
|
|
||||||
## 已知待办(按优先级)
|
## 已知待办(按优先级)
|
||||||
|
|
||||||
1. **判据 ④–⑨ 逐节点端到端**:A1 释放后 G2 分流已具备条件,A3/A2(loop)、A4、AP、A6、A7 逐条跑。
|
1. **判据 ④–⑨ 逐节点端到端**:A1 已能到 `released` 且节点实例正确落 `terminal`,
|
||||||
|
但 **G2 并行网关未把下游 A3 / A2 起出来** —— 工作流停在 A1 之后。
|
||||||
|
已排除:投递无失败、无异常日志、`selectEdges` 对并行分叉返回全部出边、
|
||||||
|
`dispatchOf` 对活动节点返回 start-task。下一步从 `advanceFrom` 的实际入参查起
|
||||||
|
(`onTaskTerminal` 里 `Object.values(ports)[0]` 目前是 `{}`,
|
||||||
|
`outputPortsOf` 按输出口声明的属性名取值、与台账列名对不上,值得先看这里)。
|
||||||
2. **判据 ③ 的机器路径**:`JCAI_LLM_API_KEY` 现为占位符,LLM 步一律走声明给定的人兜底。
|
2. **判据 ③ 的机器路径**:`JCAI_LLM_API_KEY` 现为占位符,LLM 步一律走声明给定的人兜底。
|
||||||
接任一 OpenAI 兼容端点即可验证机器路径;两条缝的 record/replay 也需先有一次 live 录制。
|
接任一 OpenAI 兼容端点即可验证机器路径;两条缝的 record/replay 也需先有一次 live 录制。
|
||||||
3. **编排画布的手绘编辑器**:只读态(`FlowDiagram`)已接真实流程包;
|
3. **编排画布的手绘编辑器**:只读态(`FlowDiagram`)已接真实流程包;
|
||||||
|
|||||||
Reference in New Issue
Block a user