/** * 活动包清单六区与资产形状(编码规范 §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; /** 活动类型两维分类之一(治理台活动库):标准活动 = flow,案例活动 = loop */ export const ACTIVITY_TYPE_LABEL: Readonly> = { 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; /* ── ③ 声明 ─────────────────────────────────────────────────────────── */ 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; 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; /* ── ④ 资产初始版 ───────────────────────────────────────────────────── */ /* 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; /** 失败策略:声明给定,不临场(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; const stepBase = { name: z.string().min(1), label: z.string().min(1), /** 入参映射:取自任务数据 / 上步出参 */ input: z.record(z.string(), z.string()).default({}), /** * 出参写入:落任务数据(草稿态)。 * `key` 指明**写哪一行**(主键列 → 作用域路径)—— 台账对象几乎都有主键, * 不声明键就只能写出无主键的行,合并进正式版时必被非空约束挡下。 */ output: z .object({ domain: z.string(), object: z.string(), key: z.record(z.string(), z.string()).default({}), fields: z.record(z.string(), z.string()), }) .optional(), /** 条件跳步:任务数据上的确定性谓词(S-FEEL),零 LLM */ when: z.string().optional(), /** * 这一步呈现哪张视图模版(`assets.viewTemplates` 里的 name)。 * 「flow:按**步序位置**推送声明的模版」(AM 07)——推什么由声明给定,不由临场决定。 */ view: 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; 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; /* 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; 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; 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; export const businessModelSchema = z.discriminatedUnion('paradigm', [loopModelSchema, flowModelSchema]); export type BusinessModel = z.infer; /* 技能(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; 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; /* ── ⑤ 样例集 ───────────────────────────────────────────────────────── */ 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; /* ── 清单六区合体 ───────────────────────────────────────────────────── */ 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; /* ── 安装两审的报告形状(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; 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; export const installVerdictSchema = z.object({ accepted: z.boolean(), staticFindings: z.array(staticAuditFindingSchema), replay: replayAuditReportSchema, }); export type InstallVerdict = z.infer;