人手改的那一手真正落得下去;界面不撒谎那几处补齐

手改是**兜 AI 的错**的那一手 —— 这一轮把它从「摆在那儿但落不了地」做成真的:

件上就地改
· 保存**按地址收**,不看当下那张卡:载荷从前借道工单的 `blocks[i]` 取列名,
  于是熔断卡(没有 blocks)在屏上时,人补的那一格一个字都送不出去 ——
  而他要补的恰恰是把这一单卡住的那个必填格。授权面改由活动清单的台账声明把关。
· **能增删行**:错不止「这一格填错了」,还有「这一行不该在」与「漏了一行」。
  删挂记号不当场抹掉(看得见、可后悔),且**删要说出来**(`drops`)——
  「没回传就是删了」会把一次不完整的回传变成一次删表。
· **必填没填按不下提交**:与放行门 L1 同一个数同一套算法;闸上摆出差在哪一行哪一格。
· 只写真改了的那几行 —— 改一格却留「修订 4 行」的痕,那句话是假的。

判据与门
· 裁量判据带谓词时**谓词说了算**:「选填缺口已补齐」基座数得出来,
  人填好的目标价它照样判「客户未提供」的毛病由此消掉。
· 验收卡判据**读时现算** —— 人在成果件上补一格,判据跟着变。
· 放行门认「**办完了没有**」不认「有人写过」:从前写个 `false` 就把门推开,
  于是一单没打标就进了放行门。三个数全由基座现数。
· 拒回把「活没干完」说成「数或行对不上」的毛病:判据点名的表一行都没写时直说那一步没办。
  **指向两扇打不开的门,比不指还糟。**

界面不撒谎
· 日志只有三色:负责人绿 · 智能体蓝 · 系统灰(归侧五种是度量的分法,不是给人看的)。
· 验收收口答两件事:落了什么(按**交付物**点名,一份成果的几张表并成一行)、
  往哪儿去(转出哪一口、带过去哪些字段);一个口都没发就直说到此为止。
· 签完到收尾之间那一段有自己的话「字已签下,正在落地」—— 中间态本来就该说出来,只是要说对。
· 消息不再被内部事件刷屏:只有从通道进来的件才谈得上「无人认领」。
· 建客户公司与联系人**一次确认落两行**;联系人编码自增不问人;卡面摆表的人读名。

A1 三案例端到端全 released:全 A 类直通 12 拍 / 客户点名跳一条 10 拍 / 新客户缺必填 14 拍。
五道门禁全绿(971 passed)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JsTDjoHovERXyy6Wmw1ALp
This commit is contained in:
2026-08-02 13:41:44 +08:00
co-authored by Claude Opus 5
parent 94f1c7a4ef
commit 259192f736
228 changed files with 27850 additions and 2847 deletions
+343 -4
View File
@@ -116,9 +116,9 @@ export declare const listGrantsRoute: {
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"governance">;
function: z.ZodEnum<{
trigger: "trigger";
data: "data";
task: "task";
trigger: "trigger";
system: "system";
tool: "tool";
activity: "activity";
@@ -155,9 +155,9 @@ export declare const setGrantsRoute: {
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"governance">;
function: z.ZodEnum<{
trigger: "trigger";
data: "data";
task: "task";
trigger: "trigger";
system: "system";
tool: "tool";
activity: "activity";
@@ -187,9 +187,9 @@ export declare const setGrantsRoute: {
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"governance">;
function: z.ZodEnum<{
trigger: "trigger";
data: "data";
task: "task";
trigger: "trigger";
system: "system";
tool: "tool";
activity: "activity";
@@ -508,6 +508,7 @@ export declare const govTaskLogRoute: {
id: z.ZodString;
at: z.ZodString;
sideLabel: z.ZodString;
action: z.ZodString;
title: z.ZodString;
}, z.core.$strip>>;
}, z.core.$strip>;
@@ -1835,12 +1836,20 @@ export declare const installActivityRoute: {
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
messageAllowed: z.ZodDefault<z.ZodBoolean>;
messageHint: z.ZodOptional<z.ZodString>;
inboundComm: z.ZodOptional<z.ZodObject<{
channel: z.ZodDefault<z.ZodString>;
partyField: z.ZodString;
subjectField: z.ZodOptional<z.ZodString>;
bodyField: z.ZodOptional<z.ZodString>;
attachmentsField: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>;
}, z.core.$strip>;
output: z.ZodObject<{
mandatory: z.ZodDefault<z.ZodArray<z.ZodObject<{
name: z.ZodString;
payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
description: z.ZodOptional<z.ZodString>;
when: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>>;
selective: z.ZodDefault<z.ZodArray<z.ZodObject<{
group: z.ZodString;
@@ -1848,6 +1857,7 @@ export declare const installActivityRoute: {
name: z.ZodString;
payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
description: z.ZodOptional<z.ZodString>;
when: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>;
}, z.core.$strip>>>;
}, z.core.$strip>;
@@ -1855,6 +1865,9 @@ export declare const installActivityRoute: {
key: z.ZodString;
label: z.ZodString;
schema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
ledger: z.ZodOptional<z.ZodString>;
ledgers: z.ZodOptional<z.ZodArray<z.ZodString>>;
editableAtRelease: z.ZodOptional<z.ZodArray<z.ZodString>>;
}, z.core.$strip>>>;
acceptanceCriteria: z.ZodDefault<z.ZodArray<z.ZodObject<{
key: z.ZodString;
@@ -1869,6 +1882,11 @@ export declare const installActivityRoute: {
predicate: z.ZodOptional<z.ZodString>;
modelRef: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>>;
revisableAtRelease: z.ZodDefault<z.ZodArray<z.ZodObject<{
key: z.ZodString;
label: z.ZodString;
ledger: z.ZodString;
}, z.core.$strip>>>;
prohibitions: z.ZodDefault<z.ZodArray<z.ZodObject<{
key: z.ZodString;
statement: z.ZodString;
@@ -1911,6 +1929,12 @@ export declare const installActivityRoute: {
domain: z.ZodString;
object: z.ZodString;
label: z.ZodOptional<z.ZodString>;
kind: z.ZodDefault<z.ZodEnum<{
record: "record";
master: "master";
derived: "derived";
}>>;
caseKey: z.ZodOptional<z.ZodString>;
fields: z.ZodArray<z.ZodObject<{
name: z.ZodString;
type: z.ZodEnum<{
@@ -1925,6 +1949,10 @@ export declare const installActivityRoute: {
label: z.ZodOptional<z.ZodString>;
primaryKey: z.ZodDefault<z.ZodBoolean>;
masked: z.ZodDefault<z.ZodBoolean>;
required: z.ZodOptional<z.ZodBoolean>;
tally: z.ZodOptional<z.ZodArray<z.ZodString>>;
expect: z.ZodOptional<z.ZodBoolean>;
auto: z.ZodOptional<z.ZodBoolean>;
}, z.core.$strip>>;
}, z.core.$strip>>>;
listeners: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -2001,6 +2029,20 @@ export declare const installActivityRoute: {
}, z.core.$strip>>;
}, z.core.$strip>>;
}, z.core.$strip>;
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
item: z.ZodString;
intent: z.ZodString;
guide: z.ZodString;
writes: z.ZodDefault<z.ZodArray<z.ZodString>>;
reads: z.ZodDefault<z.ZodArray<z.ZodString>>;
view: z.ZodOptional<z.ZodString>;
tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
doneWhen: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>>;
phases: z.ZodOptional<z.ZodArray<z.ZodObject<{
name: z.ZodString;
items: z.ZodArray<z.ZodString>;
}, z.core.$strip>>>;
}, z.core.$strip>;
skills: z.ZodDefault<z.ZodArray<z.ZodObject<{
id: z.core.$ZodBranded<z.ZodString, "SkillId", "out">;
@@ -2139,7 +2181,13 @@ export declare const listActivitiesRoute: {
name: z.ZodString;
type: z.ZodString;
required: z.ZodBoolean;
label: z.ZodOptional<z.ZodString>;
format: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>;
samples: z.ZodDefault<z.ZodArray<z.ZodObject<{
name: z.ZodString;
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
}, z.core.$strip>>>;
outputPorts: z.ZodArray<z.ZodObject<{
name: z.ZodString;
description: z.ZodOptional<z.ZodString>;
@@ -2184,6 +2232,12 @@ export declare const listLedgerObjectsRoute: {
domain: z.ZodString;
object: z.ZodString;
label: z.ZodOptional<z.ZodString>;
kind: z.ZodOptional<z.ZodEnum<{
record: "record";
master: "master";
derived: "derived";
}>>;
caseKey: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>;
}, z.core.$strip>;
};
@@ -2355,6 +2409,30 @@ export declare const testRunRoute: {
}>;
}, z.core.$strip>;
};
/**
* 仿真测试台 · 试跑**一个活动** —— 与试跑流程包并列的第二种试法。
*
* 为什么要单有一条:开发一个活动时,关心的是「这个活动自己跑不跑得动」——
* 案例模型推不推得开、判据取不取得齐、台账写不写得对、验收卡长什么样。
* 走流程包试,前面几个节点的噪音全得先趟一遍,而且每改一次活动就要重跑整条流。
*
* 起出来的是**真任务**(不挂工作流),照旧落到被指派人的工作台、照旧过 Harness 与放行门 ——
* 试跑不等于假跑:假跑试不出任何东西。区别只在它带 `origin='testbed'`,可以连根拔掉。
*/
export declare const testRunActivityRoute: {
readonly method: "POST";
readonly path: "/api/gov/testbed/run-activity";
readonly body: z.ZodObject<{
activityId: z.ZodString;
data: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
message: z.ZodDefault<z.ZodString>;
ownerId: z.ZodDefault<z.ZodString>;
}, z.core.$strip>;
readonly output: z.ZodObject<{
taskId: z.ZodString;
title: z.ZodString;
}, z.core.$strip>;
};
/**
* 停止仿真 —— **把这一单连根拔掉**:工作流、它的活动任务、工单、实例、trace 全部销毁。
* 仿真不是生产:试跑留下的东西不该在库里、在别人工作台上过夜。
@@ -2362,8 +2440,10 @@ export declare const testRunRoute: {
export declare const testStopRoute: {
readonly method: "POST";
readonly path: "/api/gov/testbed/stop";
/** 两种试法各有其拔法:流程包给 workflowId,单活动给 taskId;都不给 = 拔掉所有试跑残留 */
readonly body: z.ZodObject<{
workflowId: z.ZodString;
workflowId: z.ZodDefault<z.ZodString>;
taskId: z.ZodDefault<z.ZodString>;
}, z.core.$strip>;
readonly output: z.ZodObject<{
destroyed: z.ZodBoolean;
@@ -2371,12 +2451,271 @@ export declare const testStopRoute: {
}, z.core.$strip>;
};
/** 当前在跑的仿真(测试台一次只跑一条)—— 刷新页面也认得回来 */
/**
* 当前这一台仪器上的试跑单(测试台一次只跑一条)—— 刷新页面也认得回来。
*
* **返回还在跑的那一单,以及刚跑完的那一单** —— 两者要分得开:
* `live` 为真才锁旋钮(在跑的不许换台);为假表示它已收尾,观测面照旧摆着结果给人看,
* 但可以再起一单了。从前不分,已终结的单照样被当成「在跑」——
* 跑完之后旋钮永久锁住,人只能刷新整页才起得了下一单(实测)。
*/
export declare const testCurrentRoute: {
readonly method: "GET";
readonly path: "/api/gov/testbed/current";
readonly output: z.ZodObject<{
workflowId: z.ZodOptional<z.ZodString>;
subject: z.ZodOptional<z.ZodString>;
taskId: z.ZodOptional<z.ZodString>;
activityId: z.ZodOptional<z.ZodString>;
live: z.ZodDefault<z.ZodBoolean>;
terminal: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
};
/**
* 单活动试跑的**观测面** —— 一屏看穿这一单:
* 轨迹(每一拍干了什么)· 台账草稿(成果落到哪儿了)· 卡(问了谁什么)· 预算读数。
*
* 流程包那侧看的是 trace 树(节点 → 步骤);活动这侧要看的是**活动内部**,
* 拿 trace 树看不出「第三拍为什么被拒」。
*/
export declare const testActivityStateRoute: {
readonly method: "GET";
readonly path: "/api/gov/testbed/activity/:taskId";
readonly params: z.ZodObject<{
taskId: z.ZodString;
}, z.core.$strip>;
readonly output: z.ZodObject<{
taskId: z.ZodString;
activityId: z.ZodString;
title: z.ZodString;
runtime: z.ZodEnum<{
running: "running";
"awaiting-human": "awaiting-human";
"awaiting-event": "awaiting-event";
suspended: "suspended";
"landing-blocked": "landing-blocked";
terminal: "terminal";
}>;
terminal: z.ZodOptional<z.ZodEnum<{
released: "released";
blocked: "blocked";
stalled: "stalled";
exhausted: "exhausted";
terminated: "terminated";
}>>;
reason: z.ZodOptional<z.ZodString>;
used: z.ZodObject<{
steps: z.ZodNumber;
tokens: z.ZodNumber;
humanCalls: z.ZodNumber;
}, z.core.$strip>;
caps: z.ZodObject<{
steps: z.ZodNumber;
tokens: z.ZodNumber;
humanCalls: z.ZodNumber;
}, z.core.$strip>;
trail: z.ZodArray<z.ZodObject<{
at: z.ZodString;
kind: z.ZodString;
title: z.ZodString;
detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
}, z.core.$strip>>;
drafts: z.ZodArray<z.ZodObject<{
address: z.ZodString;
key: z.ZodRecord<z.ZodString, z.ZodUnknown>;
patch: z.ZodRecord<z.ZodString, z.ZodUnknown>;
}, z.core.$strip>>;
cards: z.ZodArray<z.ZodObject<{
id: z.ZodString;
mode: z.ZodEnum<{
execution: "execution";
acceptance: "acceptance";
}>;
title: z.ZodString;
done: z.ZodBoolean;
result: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>;
}, z.core.$strip>;
};
/**
* 上传一个文件 —— 走 base64 而不是 multipart。
*
* 这一层所有路由都由同一套 zod 契约与 typed-fetch 收着,multipart 得在它旁边另开一条
* 不受契约管的路;而这里要传的是 BOM、规格书这类几十 KB 的件,base64 那点膨胀
* 换来「照旧一条契约管到底」是划算的。真大的件不该走界面上传,该走通道。
*/
export declare const uploadFileRoute: {
readonly method: "POST";
readonly path: "/api/gov/upload";
readonly body: z.ZodObject<{
name: z.ZodString;
contentType: z.ZodDefault<z.ZodString>;
dataBase64: z.ZodString;
}, z.core.$strip>;
readonly output: z.ZodObject<{
ref: z.ZodString;
name: z.ZodString;
contentType: z.ZodString;
size: z.ZodNumber;
text: z.ZodOptional<z.ZodString>;
note: z.ZodString;
}, z.core.$strip>;
};
export type UploadedFile = z.infer<typeof uploadFileRoute.output>;
/** 取回原件 —— 存的是真字节,人点得开才算真留住了 */
export declare const downloadFileRoute: {
readonly method: "GET";
readonly path: "/api/gov/upload/:id";
readonly params: z.ZodObject<{
id: z.ZodString;
}, z.core.$strip>;
readonly output: z.ZodObject<{
name: z.ZodString;
contentType: z.ZodString;
dataBase64: z.ZodString;
}, z.core.$strip>;
};
/**
* 一次试跑的存档 —— **销毁那一刻拍的快照**。
*
* 「停止仿真 = 连根拔掉」这条不变(试跑起的是真任务,不该在别人工作台上过夜);
* 拔掉之前把这一单的观测面存下来。开发活动是反复试的活,「上一版跑了几拍、
* 卡在哪一步、台账写成什么样」正是要拿来比对的东西 —— 拔干净等于每改一次
* 就把上一次的账一并烧了。
*/
export declare const testLogRowSchema: z.ZodObject<{
id: z.ZodString;
kind: z.ZodEnum<{
activity: "activity";
package: "package";
}>;
subject: z.ZodString;
target: z.ZodString;
taskId: z.ZodOptional<z.ZodString>;
workflowId: z.ZodOptional<z.ZodString>;
terminal: z.ZodOptional<z.ZodString>;
reason: z.ZodOptional<z.ZodString>;
used: z.ZodObject<{
steps: z.ZodOptional<z.ZodNumber>;
tokens: z.ZodOptional<z.ZodNumber>;
humanCalls: z.ZodOptional<z.ZodNumber>;
}, z.core.$strip>;
caps: z.ZodObject<{
steps: z.ZodOptional<z.ZodNumber>;
tokens: z.ZodOptional<z.ZodNumber>;
humanCalls: z.ZodOptional<z.ZodNumber>;
}, z.core.$strip>;
trailCount: z.ZodNumber;
draftCount: z.ZodNumber;
cardCount: z.ZodNumber;
startedAt: z.ZodOptional<z.ZodString>;
archivedAt: z.ZodString;
}, z.core.$strip>;
export type TestLogRow = z.infer<typeof testLogRowSchema>;
export declare const listTestLogsRoute: {
readonly method: "GET";
readonly path: "/api/gov/testbed/logs";
readonly output: z.ZodObject<{
runs: z.ZodArray<z.ZodObject<{
id: z.ZodString;
kind: z.ZodEnum<{
activity: "activity";
package: "package";
}>;
subject: z.ZodString;
target: z.ZodString;
taskId: z.ZodOptional<z.ZodString>;
workflowId: z.ZodOptional<z.ZodString>;
terminal: z.ZodOptional<z.ZodString>;
reason: z.ZodOptional<z.ZodString>;
used: z.ZodObject<{
steps: z.ZodOptional<z.ZodNumber>;
tokens: z.ZodOptional<z.ZodNumber>;
humanCalls: z.ZodOptional<z.ZodNumber>;
}, z.core.$strip>;
caps: z.ZodObject<{
steps: z.ZodOptional<z.ZodNumber>;
tokens: z.ZodOptional<z.ZodNumber>;
humanCalls: z.ZodOptional<z.ZodNumber>;
}, z.core.$strip>;
trailCount: z.ZodNumber;
draftCount: z.ZodNumber;
cardCount: z.ZodNumber;
startedAt: z.ZodOptional<z.ZodString>;
archivedAt: z.ZodString;
}, z.core.$strip>>;
}, z.core.$strip>;
};
/** 一次试跑的正文 —— 逐拍轨迹 / 台账草稿 / 发过的卡 */
export declare const testLogDetailRoute: {
readonly method: "GET";
readonly path: "/api/gov/testbed/logs/:id";
readonly params: z.ZodObject<{
id: z.ZodString;
}, z.core.$strip>;
readonly output: z.ZodObject<{
id: z.ZodString;
kind: z.ZodEnum<{
activity: "activity";
package: "package";
}>;
subject: z.ZodString;
target: z.ZodString;
taskId: z.ZodOptional<z.ZodString>;
workflowId: z.ZodOptional<z.ZodString>;
terminal: z.ZodOptional<z.ZodString>;
reason: z.ZodOptional<z.ZodString>;
used: z.ZodObject<{
steps: z.ZodOptional<z.ZodNumber>;
tokens: z.ZodOptional<z.ZodNumber>;
humanCalls: z.ZodOptional<z.ZodNumber>;
}, z.core.$strip>;
caps: z.ZodObject<{
steps: z.ZodOptional<z.ZodNumber>;
tokens: z.ZodOptional<z.ZodNumber>;
humanCalls: z.ZodOptional<z.ZodNumber>;
}, z.core.$strip>;
trailCount: z.ZodNumber;
draftCount: z.ZodNumber;
cardCount: z.ZodNumber;
startedAt: z.ZodOptional<z.ZodString>;
archivedAt: z.ZodString;
trail: z.ZodArray<z.ZodObject<{
at: z.ZodString;
kind: z.ZodString;
title: z.ZodString;
detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
}, z.core.$strip>>;
drafts: z.ZodArray<z.ZodObject<{
address: z.ZodString;
key: z.ZodRecord<z.ZodString, z.ZodUnknown>;
patch: z.ZodRecord<z.ZodString, z.ZodUnknown>;
}, z.core.$strip>>;
cards: z.ZodArray<z.ZodObject<{
id: z.ZodString;
mode: z.ZodString;
title: z.ZodString;
done: z.ZodBoolean;
result: z.ZodOptional<z.ZodString>;
}, z.core.$strip>>;
}, z.core.$strip>;
};
/** 删一条 / 清空 —— 日志是给人比对用的,留多久由人说了算 */
export declare const deleteTestLogRoute: {
readonly method: "DELETE";
readonly path: "/api/gov/testbed/logs/:id";
readonly params: z.ZodObject<{
id: z.ZodString;
}, z.core.$strip>;
readonly output: z.ZodObject<{
deleted: z.ZodNumber;
}, z.core.$strip>;
};
export declare const clearTestLogsRoute: {
readonly method: "DELETE";
readonly path: "/api/gov/testbed/logs";
readonly output: z.ZodObject<{
deleted: z.ZodNumber;
}, z.core.$strip>;
};
/** 全链 Trace:一条工作流的 span 树(节点 → 步骤 / 工具 / 模型 / 人卡) */