/** * Gate Engine Types — 门禁引擎共享类型定义(叶子类型层)。 * * 职责边界: * - 负责:GateDefinition、GateCheck、BlockingDetail、GateResult、CheckResult、EvaluationContext * 等门禁引擎结构化类型,作为执行器和注册表桥接共同依赖的叶子模块。 * - 不负责:门禁评估执行(gate_engine.ts)、执行器注册表(gate_executors.ts)、派生注册表桥接(gate_registry_bridge.ts) * * 被谁调用:gate_engine.ts、gate_executors.ts 与 gate_registry_bridge.ts * 调用谁:shared/types(SystemType)、types/index(TaskContext)、context/config/resolver(ResolvedConfig)、 * verify/audit/probe_rule(ProbeRule)、domain/asset_registry/derived_types(BlockCheckConfig) * * 数据流:类型定义 → 供 gate 引擎与执行器/桥接引用 * 持久化:无持久化(纯类型定义) */ import type { SystemType } from "../shared/types.js"; import type { TaskContext } from "../types/index.js"; import type { ResolvedConfig } from "../context/config/resolver.js"; import type { ProbeRule } from "../verify/audit/probe_rule.js"; import type { BlockCheckConfig } from "../domain/asset_registry/derived_types.js"; /** 门禁 YAML 解析后的结构化定义 */ export interface GateDefinition { /** 所属阶段 */ stage: string; /** 门禁描述 */ description: string; /** 检查项列表 */ checks: GateCheck[]; /** brownfield 项目可继承的父 gate 文件路径 */ inherits?: string; /** 门禁作用域:stage=阶段级;slice=切片级,由完整验证在有部署输入时执行 */ gate_scope?: "stage" | "slice"; /** 源文件路径(用于日志) */ source_file?: string; } /** 单个检查项 */ export interface GateCheck { /** 检查 ID(自动生成如果 YAML 中缺失) */ id: string; /** 检查名称 */ name: string; /** 分类(deployment_check / evidence_check / ...) */ category: string; /** 严重程度 */ severity: "error" | "warning"; /** 检查类型:deterministic = 可代码执行,semantic = AI 语义评估 */ check_type: "deterministic" | "semantic" | ""; /** 代码执行器名称(可选,缺失则 AI-only) */ executor?: string; /** 规则描述 */ rule: string; /** 需要的证据 */ evidence_required: string[]; /** 是否需要产物 */ required_artifact?: string; /** L0/L1 项目探针规则(仅 executor="probe" 的 check 携带,直达强类型,不塞 JSON) */ probe_rule?: ProbeRule; /** 规则文件名(从 rules/ 搜索)。executor 读取该文件解析 pattern 执行检查 */ rule_source?: string; /** 外部命令(仅 executor="external_command" 携带):要执行的命令,如 "npx"/"mvn"/"grep" */ command?: string; /** 外部命令参数(仅 executor="external_command" 携带) */ args?: string[]; /** 项目配置命令类型(仅 configured_command executor 使用) */ command_purpose?: "build" | "test" | "full"; /** REQ 覆盖适用维度(仅 req_coverage_check 使用;由规则声明,executor 不按 check id 猜领域) */ requirement_dimension?: "api" | "persistence" | "all"; /** 切片与原型绑定校验方向:forward=切片引用存在,reverse=原型页被切片承接。 */ prototype_binding_direction?: "forward" | "reverse"; /** 条目块完整性校验(仅 executor="document_structure" 携带,反退化硬兜底) */ block_check?: BlockCheckConfig; /** 不可豁免标志:true 时该 check 不可用豁免工具层绕过(安全/隐私/凭据类硬检查)。 * 与 block_check 区分:block_check 是 document_structure 的完整性配置对象(附带不可豁免), * 仅 document_structure executor 消费;non_waivable 是显式不可豁免声明,适用于任何 executor * (如 regex_pattern_scan 的 SEC 安全检查)——避免把 block_check 误当布尔标志致字段语义混淆 + 加载警告。 */ non_waivable?: boolean; /** existence 已委托专门 check 管(如 PROTO-STRUCT 的 existence 归 PROTO-EXISTS 管)。 * document_structure 文件不存在时跳过内容检查(passed:true),不重复阻断—— * 避免条件产物(无 UI 消费者项目无原型说明)被 content 检查误伤。 * 典型:原型说明 existence 由 prototype_existence_check(含 UI 消费者判断)管,PROTO-STRUCT 只查内容。 */ existence_delegated?: boolean; /** 审 evidence_required 附属文件(reference/companion 如 ADR)而非 required_artifact 本体(document_structure 专用)。 * required_artifact 仅用于 per-产物路由;典型:ADR-STRUCT。 */ audit_evidence?: boolean; } /** 单个检查项失败时的完整恢复信息 */ export interface BlockingDetail { /** 检查 ID */ check_id: string; /** 人类可读检查名称(来自 gate YAML 的 name 字段) */ name: string; /** 规则描述(来自 gate YAML 的 rule 字段) */ rule: string; /** 需要什么证据(来自 gate YAML 的 evidence_required 字段) */ evidence_required: string[]; /** executor 返回的技术原因 */ error: string; /** 引擎自动生成的恢复指引(大白话) */ recovery_guide: string; } /** 门禁评估结果 */ export interface GateResult { /** 门禁 ID(来源文件名) */ gate_id: string; /** 是否整体通过 */ passed: boolean; /** 纯验证结果;是否推进由 TaskService 根据证据决定。 */ outcome: "passed" | "warning" | "failed"; /** 各检查项结果 */ check_results: CheckResult[]; /** 阻断性错误列表(error 级未通过的 check id) */ blocking_errors: string[]; /** 阻断性错误的详细信息(含恢复指引) */ blocking_details: BlockingDetail[]; /** warning 级未通过的详细信息(含恢复指引,AI 可见) */ warning_details: BlockingDetail[]; /** 被豁免(waiver)的失败项详情:不阻断推进,但仍记录供审计/诊断展示(保留 passed=false 真相) */ waived_details: BlockingDetail[]; /** 本次评估应用的豁免(check_id → waiver_id + reason)。 */ applied_waivers: Array<{ check_id: string; waiver_id: string; reason: string; }>; /** 整体恢复摘要(一段大白话总览) */ recovery_summary: string; } /** 单个检查项结果 */ export interface CheckResult { /** 检查 ID */ check_id: string; /** 执行方式:code = 代码执行,ai = AI 评估 */ executed_by: "code" | "ai"; /** 是否通过 */ passed: boolean; /** 是否待 AI 评估(AI-only 检查项标记,避免虚假通过) */ pending?: boolean; /** 按技术栈跳过(非匹配语言的规则):passed=true,仅记录跳过原因。 */ skipped?: boolean; /** 证据(代码执行产出) */ evidence?: string; /** 错误信息(未通过时) */ error?: string; /** 单项检查的覆盖样本,供报告展示本检查已覆盖/总量;不跨不同语义的检查计算统一质量分。 */ metric?: { passed: number; total: number; deviation_rate?: number; unimplemented?: number; }; /** 验证性质(formal 确定性引擎判 / trace 留痕审计业务真伪归对抗审查+人工 / semantic AI 待审)。 * evaluateGate 从 check.check_type + executor 派生注入(单点 TRACE_AUDIT_EXECUTORS)。让结果层显式标注, * 用户知"形式过≠业务对"——trace 类通过仅证留痕闭环,业务真伪须对抗审查+人工确认。 */ verification_layer?: "formal" | "trace" | "semantic"; /** 失败性质,用于区分格式修复与内容修复的重试预算: * contract_format=产物结构/格式/契约不匹配(缺章节/表/字段/列头、占位符未填、缺产物文件)→ 不计 retry 配额; * content_quality=内容质量/业务正确性不足(代码违规/数据不一致/CRUD 缺失)→ 计 retry。 * 未标注时按 content_quality 处理。 */ failure_class?: "contract_format" | "content_quality"; /** 结构化失败项,用于逐 finding 匹配 waiver。 * executor 失败时输出(含 location),gate_engine 据此 + WaiverRecord.finding_location 精确豁免单个 finding * (如 CRUD-COMPLETE 只豁免 /orders 缺 DELETE,其他资源仍查;lazy_pattern 只豁免某文件空 catch,其他仍查)。 * 未输出时按 check 级匹配 waiver。 */ findings?: Array<{ location: string; pattern?: string; message: string; severity: "error" | "warning"; }>; /** deployment source binding:verify artifact revision vs deploy build revision(治 verify source ≠ deploy source)。 * MATCH=verify 过 source == deploy source;MISMATCH=verify ≠ deploy(FAIL);UNKNOWN=无 verify evidence(FAIL,不 silently PASS)。 */ deploymentBinding?: { verified_revision: string | null; build_revision: string | null; binding_status: "MATCH" | "MISMATCH" | "UNKNOWN"; /** per-service image binding:build image id vs container image id(不只依赖 label)。 * application image(build)=SOURCE_BOUND 校验 digest;external image(image-only)=DIGEST_ONLY tracking。 */ imageBindings?: Array<{ service: string; build_image_id: string | null; container_image_id: string | null; status: "MATCH" | "MISMATCH" | "UNKNOWN"; verification_mode: "SOURCE_BOUND" | "DIGEST_ONLY" | "UNVERIFIED"; }>; /** dist/build 产物新鲜度诊断(最低限度,不实现完整 build pipeline)。 */ build_artifacts?: { dist_present: boolean; build_present: boolean; dist_fingerprint?: string; build_fingerprint?: string; }; /** content binding(image 内容 vs source):治 image digest MATCH 但 image 内容 ≠ source。 * MATCH=image 内 package.json == source;MISMATCH=image 内 ≠ source(FAIL);UNKNOWN=路径不存在(application FAIL,external 无)。 */ contentBinding?: { source_fingerprint: string | null; runtime_fingerprint: string | null; status: "MATCH" | "MISMATCH" | "UNKNOWN"; }; }; } /** 评估上下文 */ export interface EvaluationContext { /** 项目根目录 */ projectRoot: string; /** 当前阶段 */ stage: string; /** 当前验证的产物路径;项目级检查没有单一产物时可能为 undefined。 * brownfield override 后是 resolved override 路径;greenfield = path_pattern。 * waiver 的 scope=exact 匹配依赖此字段(+ artifactPathPattern 双路径比对);undefined 时只匹配 scope=check_id。 */ artifactPath?: string; /** 当前验证产物的逻辑基准 path_pattern(contract 声明值,不受 brownfield override 影响)。 * matchWaiver 双路径比对用:waiver.artifact_path 可能是 path_pattern(用户从标准路径看到)或 resolved, * 两者都参与匹配,避免路径 override 后 waiver 静默失效。 */ artifactPathPattern?: string; /** 当前切片 ID(如有) */ sliceId?: string; /** 系统类型 */ systemType: SystemType; /** * 技术栈(来自 intent.yaml 和项目探测,由完整验证注入)。 * undefined/null/lang=unknown = 技术栈未识别 → executor 全跑所有规则(fail-safe,不漏检)。 * 识别后按规则的 languages 标签过滤,非匹配语言返回 skipped。 */ tech_stack?: ResolvedConfig["tech_stack"] | null; /** 项目声明或探测到的部署方式,用于声明式 deployment:* 适用性。 */ deploymentMethod?: NonNullable["method"]; /** 同一配置快照中的项目构建/测试命令。 */ buildCommands?: ResolvedConfig["build_commands"]; /** 同一配置快照中的命令超时。 */ verifyTimeout?: ResolvedConfig["verify_timeout"]; /** 源码扫描排除(intent.scan_exclude,glob/路径前缀)——完整源码集扫描 executor(lazy_pattern/ * regex_pattern_scan 等)与源码摘要按此过滤参考原型包/vendored 等非工程交付物。 */ scanExclude?: string[]; /** 按 taskId 查任务状态(依赖注入:闭包文件不得运行时依赖 core/task_context,实例由工具层构造注入)。 * D3 done 冻结用(origin task done/cancelled 且内容未变 → engine 轴不判 stale)。 */ taskStatusLookup?: (taskId: string) => Promise; /** 任务上下文 */ taskContext: TaskContext | null; /** 文件位置表 override(brownfield 声明实际位置;来自 config.project_map?.overrides)。 * executor 查表用 resolveFilePath(key, ctx.projectMapOverrides)。 * undefined = greenfield(使用当前 contract 默认值)。 */ projectMapOverrides?: Record; /** 当前验证产物的内容摘要(getArtifactBundleHash,与 EvidenceView.artifact_git_hash 同源)。 * waiver 内容维度过滤用:scope=exact waiver 的 artifact_content_digest_at_creation 须匹配此值才生效。 */ artifactGitHash?: string; }