M1: 底座 —— @contracts 首版 + event / ledger / org / llm
@contracts 首版(§8.1 九个文件): - id 品牌 ID / terminal 终态五名与归侧四标签 / envelope 信封六字段与四类事件 - card 工单两模式 + 对话卡族(形状对齐 2026-07-26 原型定稿) - contract7 契约七件 / ledger 三级寻址与写三分 / process-package 流程包 DSL 与触发器三类 - manifest 活动包清单六区(含 CMMN·DMN·步序声明的资产形状)/ org / api 路由契约 模块(L1): - event 信封存储、归属解析三级短路、投递五诺、监听注册表、三级消费裁定 - ledger schema 自生长(最大化合并/最宽类型/只增不破坏)、任务视图叠加、写三分、冲突检查 - org 岗位授权(客体三类×动作三种)、停用前置检查、会话、种子播种 - llm 四元绑定、ModelGateway 三模式(live/record/replay)—— 两缝之一 app 装配:Hono 服务 + 鉴权中间件 + 治理台/工作台路由;drizzle 迁移;AES-256-GCM 凭证密封 ADR-007 工具链与门禁 · ADR-008 投递队列 · ADR-009 凭证加密 (ADR 编号自 007 续:编码规范 §14 已用到 006,README 写「从 005 续」是笔误) 门禁五道全绿;96 个测试通过,含对真实 PG 的 ledger 集成测试 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
co-authored by
Claude Opus 5
parent
7cd664af3a
commit
14d4fa046a
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
* 活动包清单六区与资产形状(编码规范 §8.1;语义出处 OS 11.1,AM 11)。
|
||||
*
|
||||
* 清单机器可读,系统**不执行代码即知包为何物** —— 导入登记、安装静态审、编排装配读的都是清单。
|
||||
* 资产与包分离版本化(OS 11.3):包版本管代码 / 契约 / 交互模版 / Harness;
|
||||
* 资产版本管业务模型 / DMN / 技能 —— 包只携初始版,此后由进化管线在系统内产生。
|
||||
*/
|
||||
import { z } from 'zod';
|
||||
import { activityIdSchema, skillIdSchema } from './id.ts';
|
||||
import { jsonSchemaSchema, sevenPartContractSchema } from './contract7.ts';
|
||||
import { listenerSpecSchema } from './envelope.ts';
|
||||
import { objectDeclarationSchema } from './ledger.ts';
|
||||
|
||||
/* ── 范式 ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
/** 范式只存在于**引擎层**;交互层不可区分(编码规范 §9 双层边界) */
|
||||
export const PARADIGMS = ['loop', 'flow'] as const;
|
||||
export const paradigmSchema = z.enum(PARADIGMS);
|
||||
export type Paradigm = z.infer<typeof paradigmSchema>;
|
||||
|
||||
/** 活动类型两维分类之一(治理台活动库):标准活动 = flow,案例活动 = loop */
|
||||
export const ACTIVITY_TYPE_LABEL: Readonly<Record<Paradigm, string>> = {
|
||||
loop: '案例活动',
|
||||
flow: '标准活动',
|
||||
};
|
||||
|
||||
/* ── ① 身份 ─────────────────────────────────────────────────────────── */
|
||||
|
||||
export const manifestIdentitySchema = z.object({
|
||||
activityId: activityIdSchema,
|
||||
name: z.string().min(1),
|
||||
packageVersion: z.string().min(1),
|
||||
/** 业务分类(一级,组织自定)—— 与活动类型两维平级、相互独立 */
|
||||
category: z.string().min(1),
|
||||
paradigm: paradigmSchema,
|
||||
sdkVersion: z.string().min(1),
|
||||
checksum: z.string().min(1),
|
||||
signature: z.string().optional(),
|
||||
});
|
||||
export type ManifestIdentity = z.infer<typeof manifestIdentitySchema>;
|
||||
|
||||
/* ── ③ 声明 ─────────────────────────────────────────────────────────── */
|
||||
|
||||
export const harnessConfigSchema = z.object({
|
||||
/** 记忆窗口:每次 LLM 调用加载多少轮会话历史 —— 活动侧唯一记忆接口(AM 09) */
|
||||
memoryWindow: z.number().int().min(1).max(200).default(20),
|
||||
/** 停滞检测:多久无推进算空转(ISO-8601 duration) */
|
||||
stallAfter: z.string().min(2).default('PT30M'),
|
||||
/** 时限阶梯 */
|
||||
nudge: z.array(z.object({ after: z.string().min(2), action: z.enum(['nudge', 'escalate']) })).default([]),
|
||||
/** 步失败的默认重试(flow 每步可覆盖) */
|
||||
retry: z.object({ times: z.number().int().min(0).max(10).default(2), backoff: z.string().default('PT30S') }).default({
|
||||
times: 2,
|
||||
backoff: 'PT30S',
|
||||
}),
|
||||
});
|
||||
export type HarnessConfig = z.infer<typeof harnessConfigSchema>;
|
||||
|
||||
export const manifestDeclarationsSchema = z.object({
|
||||
/** 模型声明:自定义模型名(逻辑名);安装静态审核对名称已绑定 */
|
||||
models: z.array(z.string().min(1)).default([]),
|
||||
/** 工具声明:调用契约引用 + 版本约束 */
|
||||
tools: z.array(z.object({ name: z.string().min(1), version: z.string().optional() })).default([]),
|
||||
/** 台账与共享域使用声明(域.对象.字段) */
|
||||
ledger: z.array(objectDeclarationSchema).default([]),
|
||||
/** 静态监听声明 —— 时限必配,悬空监听安装时拒绝 */
|
||||
listeners: z.array(listenerSpecSchema).default([]),
|
||||
harness: harnessConfigSchema,
|
||||
});
|
||||
export type ManifestDeclarations = z.infer<typeof manifestDeclarationsSchema>;
|
||||
|
||||
/* ── ④ 资产初始版 ───────────────────────────────────────────────────── */
|
||||
|
||||
/* flow 的业务模型:步序声明(AM 05) */
|
||||
|
||||
export const STEP_KINDS = ['tool', 'llm', 'human', 'pure-tool'] as const;
|
||||
export const stepKindSchema = z.enum(STEP_KINDS);
|
||||
export type StepKind = z.infer<typeof stepKindSchema>;
|
||||
|
||||
/** 失败策略:声明给定,不临场(AM 5.3) */
|
||||
export const stepFailurePolicySchema = z.object({
|
||||
retry: z.object({ times: z.number().int().min(0).max(10), backoff: z.string().min(2) }),
|
||||
/** 重试仍败 —— 转人兜底(改发人类工具卡)或受阻待人 */
|
||||
fallback: z.discriminatedUnion('kind', [
|
||||
z.object({ kind: z.literal('human'), workOrder: z.enum(['execution', 'acceptance']) }),
|
||||
z.object({ kind: z.literal('blocked') }),
|
||||
]),
|
||||
});
|
||||
export type StepFailurePolicy = z.infer<typeof stepFailurePolicySchema>;
|
||||
|
||||
const stepBase = {
|
||||
name: z.string().min(1),
|
||||
label: z.string().min(1),
|
||||
/** 入参映射:取自任务数据 / 上步出参 */
|
||||
input: z.record(z.string(), z.string()).default({}),
|
||||
/** 出参写入:落任务数据(草稿态) */
|
||||
output: z.object({ domain: z.string(), object: z.string(), fields: z.record(z.string(), z.string()) }).optional(),
|
||||
/** 条件跳步:任务数据上的确定性谓词(S-FEEL),零 LLM */
|
||||
when: z.string().optional(),
|
||||
failure: stepFailurePolicySchema,
|
||||
};
|
||||
|
||||
export const flowStepSchema = z.discriminatedUnion('kind', [
|
||||
z.object({ ...stepBase, kind: z.literal('tool'), tool: z.string().min(1) }),
|
||||
z.object({
|
||||
...stepBase,
|
||||
kind: z.literal('llm'),
|
||||
/** 模板与出参 schema 随声明版本冻结;出参必过 schema 校验(AM 12.3) */
|
||||
model: z.string().min(1),
|
||||
template: z.string().min(1),
|
||||
outputSchema: jsonSchemaSchema,
|
||||
}),
|
||||
z.object({
|
||||
...stepBase,
|
||||
kind: z.literal('human'),
|
||||
/** 工单两模式;末步通常是验收工单 */
|
||||
workOrder: z.enum(['execution', 'acceptance']),
|
||||
/** 卡内容 —— 由 card schema 渲染 */
|
||||
card: z.record(z.string(), z.unknown()),
|
||||
/** 异步步的完成条件 = 人事件;时限必配 */
|
||||
deadline: z.string().min(2),
|
||||
}),
|
||||
z.object({ ...stepBase, kind: z.literal('pure-tool'), tool: z.string().min(1) }),
|
||||
]);
|
||||
export type FlowStep = z.infer<typeof flowStepSchema>;
|
||||
|
||||
export const flowModelSchema = z.object({
|
||||
paradigm: z.literal('flow'),
|
||||
steps: z.array(flowStepSchema).min(1),
|
||||
/** 确定的并行组:组内步无依赖、全完成再继续 */
|
||||
parallelGroups: z.array(z.object({ name: z.string(), steps: z.array(z.string()).min(2) })).default([]),
|
||||
});
|
||||
export type FlowModel = z.infer<typeof flowModelSchema>;
|
||||
|
||||
/* loop 的业务模型:CMMN XML + 案例说明书 + DMN(AM 03) */
|
||||
|
||||
export const dmnDecisionTableSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
label: z.string(),
|
||||
hitPolicy: z.enum(['UNIQUE', 'FIRST', 'PRIORITY', 'COLLECT']).default('FIRST'),
|
||||
inputs: z.array(z.object({ name: z.string().min(1), expression: z.string().min(1) })).min(1),
|
||||
outputs: z.array(z.object({ name: z.string().min(1) })).min(1),
|
||||
rules: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string().min(1),
|
||||
/** 单元格谓词:S-FEEL(空串 = 「-」任意匹配) */
|
||||
when: z.array(z.string()),
|
||||
then: z.array(z.unknown()),
|
||||
annotation: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
.min(1),
|
||||
});
|
||||
export type DmnDecisionTable = z.infer<typeof dmnDecisionTableSchema>;
|
||||
|
||||
export const dmnModelSchema = z.object({
|
||||
/** DRD:声明「定什么需要知道什么」—— 决策 → 依赖的决策 / 输入项 */
|
||||
drd: z.array(
|
||||
z.object({
|
||||
decision: z.string().min(1),
|
||||
requires: z.array(z.string()).default([]),
|
||||
inputs: z.array(z.string()).default([]),
|
||||
}),
|
||||
),
|
||||
tables: z.array(dmnDecisionTableSchema),
|
||||
});
|
||||
export type DmnModel = z.infer<typeof dmnModelSchema>;
|
||||
|
||||
export const loopModelSchema = z.object({
|
||||
paradigm: z.literal('loop'),
|
||||
/** 案例模型 · 机器面:CMMN XML,语义引擎以它为运行结构 */
|
||||
cmmnXml: z.string().min(1),
|
||||
/** 案例模型 · 叙事面:说明书,与 XML **同版本发布,不允许分叉**(AM 12.2) */
|
||||
narrative: z.string().min(1),
|
||||
dmn: dmnModelSchema,
|
||||
});
|
||||
export type LoopModel = z.infer<typeof loopModelSchema>;
|
||||
|
||||
export const businessModelSchema = z.discriminatedUnion('paradigm', [loopModelSchema, flowModelSchema]);
|
||||
export type BusinessModel = z.infer<typeof businessModelSchema>;
|
||||
|
||||
/* 技能(AM 08):载方法不载权力 */
|
||||
|
||||
export const skillSchema = z.object({
|
||||
id: skillIdSchema,
|
||||
label: z.string().min(1),
|
||||
/** 何时适用 —— 常驻上下文只有目录,按事加载正文 */
|
||||
applicability: z.string().min(1),
|
||||
/** 怎么判断、怎么编排工具 */
|
||||
method: z.string().min(1),
|
||||
/** 结晶片段脚本:反复出现的确定性子序列;按纯工具规矩注册留痕 */
|
||||
crystallized: z
|
||||
.array(z.object({ tool: z.string().min(1), input: z.record(z.string(), z.string()) }))
|
||||
.default([]),
|
||||
knowledgeRefs: z.array(z.string()).default([]),
|
||||
version: z.string().min(1),
|
||||
});
|
||||
export type Skill = z.infer<typeof skillSchema>;
|
||||
|
||||
export const manifestAssetsSchema = z.object({
|
||||
businessModel: businessModelSchema,
|
||||
skills: z.array(skillSchema).default([]),
|
||||
/** 视图 HTML 模版 —— 模版是内容不是代码,容器净化渲染、无脚本执行权 */
|
||||
viewTemplates: z.array(z.object({ name: z.string().min(1), html: z.string() })).default([]),
|
||||
/** 卡内容 schema */
|
||||
cardSchemas: z.record(z.string(), jsonSchemaSchema).default({}),
|
||||
/** 蒸馏钩子:终态封卷 / 里程碑达成时从任务记忆归纳 */
|
||||
distillHooks: z
|
||||
.array(z.object({ on: z.enum(['terminal', 'milestone']), milestone: z.string().optional(), prompt: z.string() }))
|
||||
.default([]),
|
||||
});
|
||||
export type ManifestAssets = z.infer<typeof manifestAssetsSchema>;
|
||||
|
||||
/* ── ⑤ 样例集 ───────────────────────────────────────────────────────── */
|
||||
|
||||
export const sampleCaseSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
input: z.record(z.string(), z.unknown()),
|
||||
message: z.string().optional(),
|
||||
/** 期望输出口与载荷形状 —— 首装审与回归的依据 */
|
||||
expect: z.object({
|
||||
ports: z.array(z.string()).min(1),
|
||||
payloadShape: jsonSchemaSchema.optional(),
|
||||
}),
|
||||
});
|
||||
export type SampleCase = z.infer<typeof sampleCaseSchema>;
|
||||
|
||||
/* ── 清单六区合体 ───────────────────────────────────────────────────── */
|
||||
|
||||
export const activityManifestSchema = z.object({
|
||||
identity: manifestIdentitySchema,
|
||||
contract: sevenPartContractSchema,
|
||||
declarations: manifestDeclarationsSchema,
|
||||
assets: manifestAssetsSchema,
|
||||
samples: z.array(sampleCaseSchema).min(1),
|
||||
/** ⑥ 代码入口:.JS 产物的入口与校验和 */
|
||||
entry: z.object({ file: z.string().min(1), checksum: z.string().min(1) }),
|
||||
});
|
||||
export type ActivityManifest = z.infer<typeof activityManifestSchema>;
|
||||
|
||||
/* ── 安装两审的报告形状(OS 11.2) ─────────────────────────────────── */
|
||||
|
||||
export const staticAuditFindingSchema = z.object({
|
||||
code: z.enum([
|
||||
'signature-invalid',
|
||||
'sdk-incompatible',
|
||||
'schema-invalid',
|
||||
'tool-contract-missing',
|
||||
'model-name-unbound',
|
||||
'dangling-listener',
|
||||
'template-has-script',
|
||||
'environment-capability',
|
||||
'dynamic-eval',
|
||||
'ledger-type-conflict',
|
||||
'acceptance-level-misreported',
|
||||
]),
|
||||
severity: z.enum(['error', 'warn']),
|
||||
message: z.string(),
|
||||
at: z.string().optional(),
|
||||
});
|
||||
export type StaticAuditFinding = z.infer<typeof staticAuditFindingSchema>;
|
||||
|
||||
export const replayAuditReportSchema = z.object({
|
||||
/** 「旧成不坏」是生效硬门;「旧败能成」为报告参考项,不作门槛 */
|
||||
oldPassStillPass: z.boolean(),
|
||||
checked: z.number().int().min(0),
|
||||
regressions: z.array(z.object({ taskId: z.string(), detail: z.string() })).default([]),
|
||||
newlyBlocked: z.array(z.object({ taskId: z.string(), detail: z.string() })).default([]),
|
||||
/** 首次安装无历史:免回放审,以静态审 + 样例集替代 */
|
||||
skippedNoHistory: z.boolean().default(false),
|
||||
});
|
||||
export type ReplayAuditReport = z.infer<typeof replayAuditReportSchema>;
|
||||
|
||||
export const installVerdictSchema = z.object({
|
||||
accepted: z.boolean(),
|
||||
staticFindings: z.array(staticAuditFindingSchema),
|
||||
replay: replayAuditReportSchema,
|
||||
});
|
||||
export type InstallVerdict = z.infer<typeof installVerdictSchema>;
|
||||
Reference in New Issue
Block a user