Files
2026-08-14 14:28:28 +08:00

104 lines
35 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lskj.AgentBridge
同事快速启动请先看 [STARTUP_GUIDE_CN.md](STARTUP_GUIDE_CN.md)。该指南把源码测试、Windows 只读桥联调、AstrBot/桌宠启动和商用验收分开,并明确每次调用必须绑定完整 ERP 会话范围。
桥协议 1.1 的 `sessionScopeToken` 绑定数据库指纹、用户、用户名、账套、子系统和管理员状态;能力、计划和执行请求必须携带,ERP 服务端在业务处理前重新核验。
`Lskj.AgentBridge` 是运行在 ERP Windows 进程内的本机命令桥,不是让模型直接操作数据库的后门。
数据库、ERP 用户、账套和子系统不属于 CLI 或模型可自由传入的自然语言参数。启动器和 CLI 必须精确绑定当前已登录 ERP 的 PID、启动时间及会话令牌;桥从该 ERP 进程的 `ERPInfo` 与当前真实连接派生受信任范围。业务命令只接收其 Schema 声明的业务输入,不能携带服务器、数据库名、连接串或覆盖登录身份。桌宠只显示账套、子系统、用户与数据库指纹短前缀供本机人员核对;计划、执行前后以及写事务提交前仍由宿主、桥和数据库适配器分别重新验证完整范围。
当前协议使用仅授予当前 Windows 用户和 LocalSystem 的命名管道,采用 4 字节小端长度前缀加 UTF-8 JSON;单条消息最大 1 MB。写操作的标准流程为:
1. `command.plan` 生成只读预览。只有有效的 `navigate/write/critical` 计划会标记 `executionAllowed=true` 并在服务端保存;`read/draft` 的结果直接包含在预览中,不产生可执行计划。
2. `command.execute` 由 ERP 进程显示原生确认窗口;确认令牌在进程内签发,不交给模型生成。
3. `CommandDispatcher` 再次检查可信桌宠客户端会话、ERP 用户、账套、子系统、权限、计划版本、输入指纹、有效期、幂等键和确认令牌。数据库作用域指纹同时绑定 ERP 配置端点、当前 `DbConnection.DataSource` 实际端点、实际数据库和提供者;切换到另一台服务器上的同名库、连接被替换或登录后修改配置都会使旧计划、签名验收和幂等作用域失效。采购/请假过程以及通用低代码 Lookup、新增、更新还会在真实 `DbCommand` 前后和写事务提交前,把参数中的用户、账套、子系统、数据库指纹与 `ERPInfo``SqlHelper._connection` 当前实例及实际端点重新逐字核对;期间漂移会丢弃读取结果或回滚事务,而不是依赖桌宠事后发现。幂等作用域还包含账套、子系统、ERP 用户、命令和 key;同一 key 对应不同输入会拒绝而不是误重放。
4. 业务处理器只调用已验收的固定事务入口:专用工作流复用 `BillSave``BillApply``SaveBasePanelData``ApplyBaseData` 等原生链;通用新增调用客户实施的 `p_lserp_agent_module_create_v2`。两者都不接受模型选择的 SQL、表、字段或过程。
5. 审计日志只记录身份、命令、计划、结果和关联 ID,不记录口令、确认令牌、字段值或原始 SQL。
每个 ERP 启动实例使用独立审计文件 `%LOCALAPPDATA%\Langsu\Lserp\AgentBridge\Audit\audit-p<PID>-s<UTC ticks>.jsonl`,文件以 `CreateNew` 建立,启动时先验证目录可写,避免多开 ERP 争写同一个日志。单文件上限 64 MB,目录预留上限 512 MB、最多 256 个实例文件;记录以严格 UTF-8 和 WriteThrough 完整追加,尾部损坏、实例文件重名、容量满或待归档文件超限都会失败关闭,不会覆盖、自动删除或无审计继续执行。运维必须在达到门限前把完整关闭实例的文件移入受控归档并按客户留存策略签章;不得移动仍在运行进程对应的文件。
桥启动时还会严格读取进程级运维保护参数。`LSERP_AGENT_DISABLED_COMMANDS` 是最多 64 个逗号分隔的精确命令名,并在全部业务门禁完成后与本次实际注册表逐项核对;未知或当前未注册的名称会阻止桥发布,避免拼写错误造成“看似已停用”。命中的命令不会出现在 capabilities,直接规划以及服务端已有计划的执行复核都会返回 `command_disabled``LSERP_AGENT_RATE_LIMIT_PER_MINUTE` 默认 120、范围 1-6000`LSERP_AGENT_RATE_LIMIT_SESSIONS` 默认 256、范围 1-4096;每个桌宠会话使用固定一分钟窗口,状态五分钟无活动后释放,容量满或超限分别稳定失败关闭。`LSERP_AGENT_CIRCUIT_FAILURE_THRESHOLD` 默认 5`LSERP_AGENT_CIRCUIT_WINDOW_SECONDS` 默认 60`LSERP_AGENT_CIRCUIT_OPEN_SECONDS` 默认 30;只有数据库、审计、幂等、计划容量和适配器协议等白名单基础设施故障参与熔断,输入错误、业务阻断、权限拒绝和用户取消不会误触发或治愈熔断。冷却后只允许一个半开探测,成功才关闭。任一参数非法会阻止桥启动和发现文件发布;配置在 ERP 启动时固定,变更停用列表需重启 ERP,重启同时清空全部进程内计划。`health` 只投影限额、停用数、已跟踪会话数和打开熔断数,不输出会话或命令明细。
运维控制不会形成审计盲区:首次 `command_disabled`、限流、会话容量和熔断拒绝,以及 `command_circuit_opened/closed` 状态转换,会写入同一个进程绑定 JSONL,包含时间、关联 ID、桌宠会话、ERP 身份作用域、桥方法、命令、阶段和稳定结果码,不记录 payload、字段值、幂等键或异常文本。同一会话限流和全局容量拒绝每分钟最多各记一次;同一命令/阶段/结果的重复拒绝每分钟最多一次,去重状态最多 512 项并在五分钟后回收,避免攻击者用拒绝洪泛填满审计文件。运维事件追加失败不会把原本应拒绝的请求放行;正常计划/执行仍由强制命令审计失败关闭。
## 商用命令发布范围
采购附件可信链升级后,现场发布策略必须将 `purchase.invoice.resolve``purchase.invoice.create` 都精确锁定到 `commandVersion=1.4`。仍锁定 `1.2/1.3` 的旧策略会在 ERP 发布桥之前因命令契约漂移失败关闭。
启用生产桥不再等于把注册表中的全部能力交给所有 ERP 用户。`LSERP_AGENT_BRIDGE_ENABLED=1` 时,ERP 启动过程强制要求同时设置 `LSERP_AGENT_ROLLOUT_CONFIG``LSERP_AGENT_ROLLOUT_SHA256``LSERP_AGENT_ROLLOUT_CUSTOMER_ID`;配置缺失、SHA-256 不匹配、客户部署标识不一致、根级 `schemaVersion` 不是 `1.1`、数据库作用域指纹无效或根级 `defaultAction` 不是 `deny` 时,ERP 主程序仍可运行,但不会发布 AgentBridge 发现文件。配置必须是最多 256 KB 的普通严格 UTF-8 JSON 文件,根级 `databaseScopeFingerprint` 必须是实施人员从当前批准 ERP 会话核准的 64 位指纹;文件拒绝链接、注释、重复/未知字段、控制字符、重复值、超过 128 条命令规则或每个范围超过 64 个值。参考文件是 `Deployment/command-rollout.example.json`;部署时应复制到包外受 Windows ACL 保护的只读目录,人工复核后对原始字节计算 SHA-256,三个环境变量必须在启动 ERP 前由同一进程环境继承。
每条规则精确绑定 `command + commandVersion + requiredPermission`,再用显式的 `accountBooks``subSystemIds``audience` 缩小范围。账套允许干净的 Unicode 显示名;子系统和用户必须是精确标识符。范围对象必须明确选择 `all=true, values=[]`,或 `all=false` 并列出 1-64 个精确值,不支持模糊匹配。`audience=all_authorized` 只表示继续使用原 ERP 权限,`administrators` 只接受 ID 为 `1` 且名称精确为“管理员”的内置账号,`users` 必须列出精确 `userIds`。旧 ERP 的 `GroupId` 是菜单分组而不是可信角色 ID,所以发布策略不伪造“按 GroupId 授权”;真正的角色边界仍由命令 `requiredPermission`、当前菜单查看/编辑权限及数据库行级权限决定,发布策略只能进一步收窄,不能授予权限。
规则会在所有业务门禁完成后与本次实际命令注册表核对。引用未注册命令、版本漂移或权限契约变化都会阻止桥发布,避免拼错命令或升级后沿用旧范围。通过校验后策略在本次 ERP 进程内不可热改;每次能力发现、规划和执行先核对当前数据库作用域指纹,随后再按账套、子系统和用户规则收窄。`capabilities.list` 会隐藏范围外命令,`command.plan``command.execute` 仍分别复核并以 `command_rollout_denied` 失败,计划/执行拒绝进入普通关联审计。修改配置必须重启 ERP,进程内旧计划会随之清空。`health.rolloutPolicy` 只返回 `configured/failClosed/customerId/databaseScopeFingerprint/sourceSha256/defaultAction/ruleCount` 七个证明字段,供签名 CLI 和商用预检核对目标进程实际加载的策略;不返回配置路径、账套、子系统、用户、权限或规则内容。
`command.plan` 的安全投影会返回服务端计算的 `inputFingerprint` 和稳定 `outcomeCode`;业务处理器的原始预览仍位于 `plan.data`。成功执行的 `result` 同时返回 `transactionEvidenceId``businessAuditId`,供受信任验收工具关联事务和审计,不再要求从日志文本猜测。写计划成功后即被消费;相同幂等请求的重放需要重新生成计划,也会再次经过 ERP 原生确认。采购/请假 create 的规范化业务指纹仅排除顶层精确 `resolutionProof`,避免重新 resolve 的随机 nonce 把相同业务误判成冲突;其余业务字段和来源附件双摘要仍完整绑定,且每个新计划仍须通过当前凭证校验。
失败响应固定携带 `data.recovery`,并且只允许 `action/retryable/planInvalidated/message` 四个字段。`action` 是固定枚举,不是模型文本或任意命令;恢复说明不包含 SQL、表字段、连接信息或原始异常。`duplicate_invoice`、采购来源变化、请假日历/规则变化、动态配置漂移和服务器凭证过期都会在返回错误前从 ERP 计划仓撤销旧计划;`user_cancelled` 保留计划,`bridge_timeout/workflow_database_error` 保留同一幂等计划供结果核对式重试。桌宠 Host 会再次白名单投影该结构和按错误码固定的主文案,并同步撤销自己的可信计划;客户请假过程返回的自由 `reason` 不进入计划警告或执行错误,未知字段或动作不能进入 WebView。CLI 仍可依据同一稳定错误码和关联 ID 进行审计查询。
ERP Bridge、AstrBot 插件和桌宠宿主共同使用版本化线协议 [erp-agent-wire-contract-v1.json](../Contracts/erp-agent-wire-contract-v1.json)。协议固定计划投影的 15 个顶层字段,并提供采购解析到创建、请假解析到创建、请假二次提交、只读模块诊断、初始化追踪、动态模块新增、动态模块并发修改和模块导航八个无客户数据样本。核心测试用真实 `AgentBridgeRuntime` 对照该协议,AstrBot、宿主和桌宠分别消费同一文件;缺字段、未知字段、错误指纹/结果码、展示字段与 `data` 不一致、超过 15 分钟的有效期或风险与 `executionAllowed` 不一致都会失败关闭。商用包把该文件放入 `Contracts/`,现场预检再次校验其精确结构。
`WorkflowWriteCaseObservationProjector` 可在离线状态把受限目录中的 CLI 原始观察清单投影成单个脱敏验收用例,也可通过严格文件索引分别读取同目录下的命令输入、计划响应和执行响应。它会重新计算并比对输入指纹、固定场景结果码和解析问题码;采购提交、幂等重放和审计关联还必须使用完整且通过 `purchase.invoice.create` Schema 的发票头/明细、双摘要与预处理契约来源输入,至少包含一份 `pdfium_minimax_pages_v1` 电子 PDF,携带结构完整的 `rp1` 服务器凭证和明确成功的业务结果,并让计划内 `sourceDocumentCount/sourceDocumentSetSha256` 与命令输入逐字对应。投影只公开有序的 `sourceDocumentPreprocessContracts`,不公开文件名或内容;提交、重放和审计三项必须一致。所有业务标识只输出 SHA-256,并用 `CreateNew` 语义防止覆盖;索引拒绝绝对路径、目录穿越、链接和重复引用。离线投影只校验凭证结构,密码学真实性由同一受信任 ERP 进程在规划和执行时校验;它不会连接 ERP 或数据库,也不能替代 DBA 对业务变更数、审计数和来源写入绑定的现场观察。
客户 Windows 验收先用 `Deployment/New-WorkflowWriteUatCampaign.ps1` 从签名短时授权生成固定 13+19 项活动清单;生成器和 `Test-WorkflowWriteUatCampaign.ps1` 都会复核随包 `workflow-write-uat-case-catalog.v1.json` 的内置 SHA-256,活动清单也绑定同一目录版本、管理员验签 CLI 与受限运行 CLI。每次恢复由检查器使用 `lserp-cli.exe` 离线验签、使用 `lserp-agent-cli.exe` 执行 `version` 和桥 `health`,并只读复核目录、ERP PID、令牌库 ACL/覆盖和已有脱敏证据;活动层没有 execute 路由,禁止批量写库。逐项运行 `Deployment/Invoke-WorkflowWriteCaseCapture.ps1` 时,管理员 CLI 仅验证授权和投影证据,所有桥调用只能由签名、版本和 SHA-256 均与授权一致的运行 CLI 发起。原始文件位于仅当前用户和 LocalSystem 可访问的临时目录并在结束时删除;最终只发布绑定运行 CLI 身份的脱敏用例。成功创建场景可同时生成使用同一计划、关联 ID、事务和审计哈希的 `*_audit_correlated` 观察,避免为了审计证明再次写业务数据。三项确认后漂移场景使用交互式计划后停点,由 DBA/配置人员完成场景变更,采集器不会自行修改数据或配置。
同一投影器还能读取仅包含同目录安全文件名的用例索引,按采购 13 项/请假 19 项固定顺序生成用例数组,并在生成前运行完整跨用例关系校验。这样最终报告不依赖人工复制 JSON,也不能把不同账次的提交、重放、冲突或审计观察拼成一套证据。
公开方法:`health``capabilities.list``context.get``command.plan``command.execute`。CommandKernel 注册表先验证并固定每个命令的名称、版本、权限、风险、确认/幂等语义和有界输入 Schema;处理器或调用方后续修改原对象不会改变已注册合同。`capabilities.list` 再用当前 ERP 登录上下文逐项过滤权限;未授权命令不会暴露给模型。AstrBot 对能力描述符做第二次独立失败关闭校验,只接受不重复命令、固定风险语义以及深度、节点数、属性数均有上限的 Schema 子集,未知关键字或开放额外属性不能进入模型。`context.get` 返回活动页和最多 50 个已打开模块,AstrBot 客户端会在数据进入模型前严格校验字段全集、标识格式、控制字符、数量/截断一致性,以及非截断时活动模块必须属于打开集合;不完整或被篡改的 `navigationCode` 不能用于 `module.help/module.navigate`
`adapters.status` 始终作为 ERP 管理员只读命令注册。采购或请假写命令因配置、低代码字段、数据库契约、行级权限、验收哈希或 TrustedPeople 签名而未注册时,它返回固定 `code/category/severity/message/nextAction` 和白名单业务语义。若严格客户画像仍有阻断项,`profileActivation` 还会列出当前工作流真实开放的 5 项采购或 4 项请假稳定码,并为每项投影下一步动作;它不会返回画像证据正文、模块物理字段、数据库名或路径。未知安全代码只给通用处置,任意物理字段名、异常消息、配置路径、SQL 和业务值都不会进入结果。普通用户的能力列表中不包含该命令。
## 采购与请假适配器
启动时只有设置 `LSERP_BUSINESS_ADAPTER_CONFIG` 后才会读取严格 JSON 配置。当前配置版本为 `1.1`;只要启用采购或请假,就必须设置 `customerProfilePath` 指向客户只读画像。先在客户 Windows 环境运行 `lserp-cli adapters inspect <purchase|leave> <moduleCode>`,人工复核生成的字段候选,再用 `adapters validate-fields` 验证。参考配置位于 `Deployment/business-adapters.example.json`
SQL Server 专用采购/请假先依次部署 `001_agent_business_idempotency.sql``002_workflow_adapter_contract.sql`、仅供 DBA/发布流水线使用的 `003_record_workflow_acceptance.sql``006_workflow_readiness_v3.sql`;通用低代码 Lookup/新增和更新另部署 `004_dynamic_module_adapter_contract.sql``005_dynamic_module_update_contract.sql`。这些基线只创建证据表、就绪查询、拒绝服务占位过程,或只读核对实际过程,不会猜表或写业务数据。客户实施必须替换两个专用固定过程并完成 Windows 集成测试,最后通过 003 的参数化过程写入 V2 证据;否则注册门禁不会暴露 `purchase.invoice.resolve/create``hr.leave.resolve/create/submit`
`purchase.invoice.resolve` 通过固定只读动作把 OCR 供应商名称/税号、币种和物料原文确定性转换为 ERP 编码,并把受信任 Tool 自动注入的附件类型、净化文件名、大小、源文件 SHA-256、精确预处理包 SHA-256 和 `preprocessContract` 一并绑定到解析凭证及 XML v3 写入 payload;视觉请求和文档 worker 还必须让本次实际读取的单一字节快照逐字命中识别前来源摘要,不能在校验路径后换入另一份附件。客户采购过程必须把两种摘要、处理契约与来源凭据关联到同一业务审计记录。`hr.leave.resolve` 把“我/事假/明天下午”或两端时段明确的多日区间转换为当前员工、唯一假别编码、员工日历时间范围、日历总工时和用户明确选择的有效流转配置行 id;多日只从两端日历取得边界,完整工时仍由客户 `leave.calculate_hours` 对整段重新核算,流程候选不唯一时只返回候选并追问。模型只能把服务器返回的 `resolvedInput` 原样交给各自的 create 预览。
compat100 请假写草案还会在数据库保存前把 ERP 用户与当前员工上下文绑定,重新检查菜单 `16629` 的编辑权限(只读 `16629|` 不通过),并按账套、子系统、用户、命令和幂等键获取事务级应用锁。这样 UI 确认后的权限变化和多个客户端同时重试都不能绕过数据库层门禁;草稿创建与审批提交仍是两次独立确认、幂等和审计操作。
compat100 采购写草案除菜单权限外,还要求每一批来源采购单具有一致且有效的组织、部门和采购员,并与当前账套、子系统、ERP 用户命中 `p_agent_purchase_row_scope` 中一个带有效期和审批哈希的精确元组。表默认空、所有范围列非空、没有通配符,管理员也不绕过。包装过程会先校验范围表/币种表关键列与过滤唯一索引,结构漂移固定返回 `purchase_agent_evidence_schema_missing`;未授权固定返回 `purchase_row_scope_denied`
当前客户端只通过 `p_lserp_agent_workflow_readiness_v3` 读取按账套/子系统隔离的 `p_agent_workflow_adapter_evidence_v2`。V3 会核对当前兼容级别实际选用的读写过程、完整有序参数签名和最后修改时间;过程缺失、参数名/类型/顺序漂移,或过程修改时间晚于验收行都会返回零行并关闭工作流。数据库布尔值本身不能启用写命令:每个启用工作流还必须配置 `acceptanceEvidencePath`,清单内容哈希要与 V2 行一致,并由 Windows `TrustedPeople` 中当前有效的 RSA CSP 证书签名。清单同时绑定 ERP 启动时实际读取的 `business-adapters.json``customerProfilePath`、字段映射、只读契约和写集成证据的原始字节 SHA-256。客户画像使用严格 1.2 合同,采购 5 个与请假 4 个阻断码必须精确齐全;`open` 项只能有 `resolution=null``resolved` 项必须绑定代码指定的字段映射或写集成制品哈希、批准人和 UTC 时间。签发脚本与 ERP 启动/计划/确认执行都会把每个解决哈希与签名清单的精确制品哈希比较;不一致时返回 `profile_workflow_resolution_mismatch`。画像中的采购选定模块或请假模块还必须与签名清单 `moduleCode` 逐字一致,否则在数据库探测前返回 `profile_workflow_module_mismatch`。本工作流只要仍有 `status=open` 的阻断项就返回 `profile_workflow_activation_blocked`;采购还必须把目标选择同步批准为 `selected_and_activation_approved/activationAllowed=true`。ERP 会用当前已打开连接运行固定的 `DB_NAME/SERVERPROPERTY/sys.*` 两个只读结果集,重新比较数据库身份、兼容级别、关键表列和旧保存过程参数;哈希替换、字段/参数漂移、目录协议异常或连接不可用都会失败关闭。Agent 支撑对象只有 8 张表与 8 个过程全部存在且类型正确时才显示为完整;普通对象总数仍仅供管理员发现环境变化。签收后更改过程、字段映射、金额模式、容差、开关、路径、格式、阻断状态或画像都会让旧清单失效。签发与部署流程见 [WRITE_ACCEPTANCE.md](Deployment/WRITE_ACCEPTANCE.md)。每次写前就绪复核还会重新打开 `LSERP_BUSINESS_ADAPTER_CONFIG` 指向的普通文件并校验 `runtimeConfigurationSha256`;配置被修改、替换或无法安全读取时分别以 `runtime_configuration_changed``runtime_configuration_unavailable` 阻断写入。就绪过程本身也会捕获当前用户、用户名、账套、子系统和数据库作用域指纹,在调用前后重新核对真实 ERP 连接,并拒绝返回作用域不一致的证据行;因此“就绪检查”不能被跨登录或跨数据库复用。
现场关闭阻断项不再依赖手工改 JSON。`lserp-cli adapters prepare-profile-activation` 只允许当前 ERP 内置管理员执行,在同一会话重新验证最终字段映射、只读契约、写集成报告、发布哈希和关键目录后,以 `CreateNew` 输出未签名画像候选;输入变化、跨模块/跨账套证据或已有输出都会失败,且候选本身始终不能注册写命令。
`WorkflowContractVerifier``lserp-cli adapters verify-contract` 提供客户只读过程验收:采购探针检查供应商/币种/物料唯一解析、发票去重、开放来源返回契约和确定性唯一匹配;请假探针检查当前员工、日期表达、假别候选、流转类别候选、员工日历、工时、冲突与可提交草稿。验证器只依赖 `IWorkflowProcedureGateway.Read`,结果不复制探针业务值,且证据包固定 `registrationReady=false`。离线复核结果会投影账套、子系统和验证用户;签发脚本要求 `verified=true` 并与本次工作流、模块和 ERP 范围完全一致,同时使用同一 ERP 身份重新执行最终字段映射校验。过程内部参数化、写事务、幂等、权限复核和 Windows 集成仍需独立证据。网关会读取当前数据库兼容级别:低于 `130` 时只读调用改用固定标量过程 `p_lserp_agent_workflow_read_compat100`;ERP 进程严格解析完整草稿。兼容网关只固定动作、过程名和强类型载荷形状,不再在客户端固定业务模块号或子系统;实际 `moduleCode` 来自最终 `business-adapters.json`,子系统来自当前 ERP 会话,两者在每次计划与执行前都由配置哈希、签名清单、数据库 V2/V3 证据和客户过程同时重新绑定。客户采购写路径把服务器生成的分配结果用 `XmlWriter` 编码为固定结构、限量且数据库再次校验的 XML 行集,模型原始 JSON/XML/SQL 均不会下传。采购和请假兼容写路径虽然已接入固定网关分派,但只有严格运行配置、数据库 V2 就绪证据、完整 Windows 集成证据和 TrustedPeople 签名清单全部通过后才会出现在 CLI 或桌宠 capabilities;当前客户采购草案及两道 SQL 审核开关仍固定关闭。写调用会跳过旧保存链产生的调试结果集,只接受列集合完全匹配固定写契约的唯一结果集;缺失或重复均回滚。
客户包装过程抛出的异常只允许从代码内固定白名单投影为稳定业务码和本地固定中文说明;原始 SQL Server 消息、对象名、行号、连接信息及业务值不会进入桥、AstrBot 或 MiniMax,未知异常统一为 `workflow_database_error`。Windows 写集成证据使用严格 `schemaVersion=1.6`,固定覆盖采购 13 项和请假 19 项;逐用例绑定同一份 `schemaVersion=1.2` 签名短时 UAT 授权、唯一用例令牌、实际运行 CLI 的版本/SHA-256/签发者、ERP 上下文关联 ID、账套/子系统/用户编号哈希/用户名哈希/数据库作用域/管理员状态以及实际命令名、版本、模块、风险和计划有效期,并校验授权时间窗、真实结果码、精确解析问题码、确认阶段、来源附件贯通以及提交/重放/冲突/审计之间的哈希关系。报告通过仍固定 `registrationReady=false`,不能代替运行时门禁。
管理员可通过 `adapters.status` 的计划预览查看启动门禁状态。结果仅包含安全问题码、固定分类/说明/下一步动作、画像当前开放阻断码及白名单业务语义,不返回配置内容、画像证据正文、物理字段、SQL、参数值或凭据。
当前已注册:
- `module.search`:只搜索当前用户和子系统已经过滤的菜单,确定性排序且最多返回 10 个候选。
- `module.help`:输出当前用户可访问模块的业务字段标签和界面用途,不暴露表、SQL、物理字段、DLL 或启动参数。
- `module.parameters` `1.1`:从当前登录数据库实时读取低代码主表/明细字段,为全部可见参数生成稳定的不透明 `parameterId`、类型、格式、必填、只读、默认值、Lookup、`maximumEncodedBytes`(旧 ERP `LimitLen`,按 ERP 进程默认编码字节数)和数值 `maximumDecimalPlaces`(旧 ERP `DataDec`,缺省 2)规则。`inputMode=scalar` 只覆盖显式评审的普通标量,`lookup-single` 必须由服务器唯一解析;多选、设备、动态 SQL、计算、回填多行、单据来源及未知控件固定为 `inputMode=unsupported``requiresDedicatedAdapter=true`,不能因为能显示文本就被通用 Agent 写入。复选框公开输入保持 `true/false`,受信任写请求按旧控件规范化为 `1/0`。合同绑定当前用户、账套、子系统、数据库作用域及完整配置指纹,不暴露表、SQL、物理字段或 Lookup 实现。非法约束配置、超长、超小数位或未支持控件输入在预演阶段失败关闭。只有当前模块命中当前数据库证据与 TrustedPeople 签名清单时才返回 `genericWriteExecutionAvailable=true``writeCommand=module.record.create`;否则仅允许发现/预演。
旧模块返回控件 `116/117/160/161` 必须由当前配置 `IsRadio=1` 证明单选才进入通用 Lookup;缺失或 false 视为多选。旧显式单选编号 `42/171/172` 保留单选语义,编号 `43` 与会联动多个目标字段的扩展返回 `173/174` 固定要求专用适配器。模式变化会改变配置/合同指纹并使旧计划失效。
半天日期 `445` 对 Agent 使用 `yyyy-MM-dd|am-or-pm`,服务端在受信任写边界转换成旧 WinForms 的 `yyyy-MM-dd 上午/下午`;本地化存储值不进入模型合同。
- `module.record.prepare-create`:接受当前合同的 `contractFingerprint`、主表参数和明细行参数,服务端重新读取当前数据库配置并把不透明 ID 映射回字段;跨会话/跨账套/配置漂移、未知、重复、只读、密码/图片、类型格式错误和未解析 Lookup 全部失败关闭。命令风险固定为 `draft`,只返回不含物理字段的参数预演,不保存计划、不弹确认、不调用数据库写入。
- `module.record.resolve-create`:只在客户验收固定只读过程后注册;按当前配置唯一解析 Lookup,签发作用域绑定的短期凭证,并由服务端声明后续是 `module.record.create` 还是无副作用的 `prepare-create` 回退。
- `module.record.create`:只在 `004` 固定事务入口、当前模块/配置/数据库证据和 TrustedPeople RSA-SHA256 清单全部通过后注册。完整动态参数会先投影到桌宠确认;确认后再重读权限/配置/Lookup/证据,以 `Serializable` 事务、持久幂等与审计执行。验收见 [DYNAMIC_MODULE_WRITE_ACCEPTANCE.md](Deployment/DYNAMIC_MODULE_WRITE_ACCEPTANCE.md)。
- `module.navigate`:使用精确模块编号或搜索结果的 `navigationCode` 复用当前用户菜单权限打开模块;模块加载器内部失败时返回稳定错误,不再误报成功。
- `module.diagnose`:管理员读取低代码元数据并执行静态配置诊断。
- `module.trace-initialization` `1.2`:管理员经 ERP 原生确认后复现当前 ERP 托管 UI 线程内的模块初始化,按有界证据窗口采集 `Lskj.Core.SqlHelper` 的脱敏 SQL Trace,并在同一线程短时观察旧 `LogHelper` 中已被模块捕获的异常。只有异常链中真实存在 `DbException` 才能在缺少失败 SQL 事件时归类为数据库原因;普通异常即使消息伪装成 SQL 错误也只给推断性的客户端配置结论。模块直接调用 ADO.NET 时只能取得其同线程日志中的数据库异常分类,不能声称取得了 SQL 文本、参数或完整调用覆盖;后台线程、独立进程、网页和旧原生模块仍不在该追踪范围。
初始化追踪计划不会把 `MenuId/DllName/PurviewId/UrlParams` 发送给模型;这些启动参数只保存在服务端计划状态中。独立 EXE、网页/外部资源、旧版原生 LSP 和动态启动目标不属于当前进程 Trace 的可信边界,会在计划阶段失败关闭;确认后会重新解析当前菜单配置、复核追踪资格与管理员权限并确认模块仍处于关闭状态,配置变化、边界变化或提前打开都会使计划失效。模块加载器内部已经捕获并弹窗的 DLL/控件初始化异常,会由仅在当前 UI 线程生效的临时观察器取回;20 秒只限制证据采集窗口,不能安全强制终止已经卡住的旧模块初始化。数据库分类只接受失败 SQL Trace 或最多八层异常链中的真实 `DbException`,普通客户端异常中的相似文字不会被升级成数据库结论。结果以 `diagnosticId/outcome/primaryFindingCode/findings/events/staticDiagnosis` 返回;重复故障按 SQL 指纹归并,`confidence=inferred``truncated=true` 时 Agent 必须明确证据边界。原始模块异常、CLR 类型和参数值不进入桥响应。
每次追踪还会在 `Log/AgentBridge/diagnostics/<diagnosticId>.json``CreateNew` 写入不超过 2 MB 的脱敏证据,内容绑定关联 ID、ERP 用户/账套/子系统、模块和诊断结果,并带 SHA-256 内容哈希;同一诊断 ID 重试只接受作用域及哈希一致的现有文件。证据写入失败不会通过抛错诱发模块再次打开,而是返回 `*_evidence_unavailable``evidencePersisted=false`,普通命令审计会保留该稳定结果码。SHA-256 只用于完整性检查,不代表数字签名;客户验收包仍需代码签名、访问控制和外部归档签章。
ERP 桥返回的丰富追踪结果不会原样进入桌宠或模型。Host 只接受四个固定成功结果码和精确诊断字段,再投影稳定分类、计数、哈希、固定说明及不可反查别名;原始事件数组、异常文字、SQL 结构和客户自由消息均被丢弃。该投影最多保留十分钟且最多一条,只绑定下一次成功完成的 AstrBot 对话;流失败可重试,消费后不再注入,ERP 会话漂移立即清除。用户正文不能伪造宿主保留的诊断证据标记。
`hr.leave.create` 成功且服务端草稿标记了 `submitAfterSave` 时,桥会用新的执行上下文规划并保存一个 `hr.leave.submit` 后续计划,在响应的 `followupPlan` 中返回安全预览。创建事务已经完成时,即使后续规划失败也不会伪装成创建失败;响应只带稳定的 `followupCode`,提交保持未执行。后续计划拥有新的计划号、输入指纹和幂等键,并再次经过桌宠确认、ERP 原生确认、权限/状态复核、事务和审计。
证据可用 `lserp-cli diagnostics verify-evidence --input <file>` 完全离线验证。验证器拒绝重解析点、超过 2 MB、重复属性、注释、未知字段、事件/结论/静态诊断计数不一致和哈希或身份范围不一致,只返回作用域与诊断汇总,不回显脱敏 SQL 事件本身。
SQL Server 的数据库幂等表基线位于 `Deployment/SqlServer/001_agent_business_idempotency.sql`。真实适配器必须把幂等占用、来源锁定/复核、原 ERP 保存链、业务审计/Outbox 和完成证据放在同一个数据库事务中;成功结果必须返回事务证据号、业务审计号、实际幂等键和输入指纹,这些内部证据只进入服务端审计,不返回模型。
桥仍由 `LSERP_AGENT_BRIDGE_ENABLED=1` 显式启用,默认不监听;启用时必须同时通过默认拒绝的客户命令发布策略。该总开关与发布范围、命令级停用、限流和熔断共同构成运行保护。商用发布前还需完成采购、请假业务适配器的客户配置、达梦等实际数据库方言和 Windows 集成测试;未注册的模块绝不退化为直接 SQL。
常驻进程内状态也有明确边界:ERP 桥最多保存 128 个未过期执行计划;调度器最多保存 4096 个进程内幂等回放项,成功项默认保留 24 小时后清理,执行中的项不会被过期清理。达到容量上限时固定失败关闭,不驱逐尚在执行或待确认的状态。该内存层只减少重复确认并提供短期回放,客户数据库事务中的持久幂等记录仍是业务防重的最终依据。
命名管道只允许启动 ERP 时固定捕获的当前 Windows 用户和 LocalSystemACL 不继承父对象,也不授予 Everyone 或全部已认证用户;`NetworkSid``AnonymousSid` 具有显式拒绝 ACE,因此即使另一台电脑使用相同域账号并猜到 PID,也不能经 SMB 访问管道。CLI、桌宠宿主和 AstrBot 在连接成功后、发送任何协议字节前都会调用 Windows `GetNamedPipeServerProcessId`,要求实际管道服务端 PID 等于发现文档中的 ERP PID,并再次核对进程启动时间;同用户程序替换发现文件并建立假管道也会失败关闭。最多同时占用 4 个连接槽。每个请求的 4 字节长度头和正文共用 15 秒总读取期限,响应头和正文共用 15 秒总写入期限;超时会关闭底层异步管道并释放连接槽。请求和响应都使用不允许替换回退的严格 UTF-8,畸形字节或未配对代理项不会被静默改写成另一份业务输入。`Start` 只有在 ACL 已成功应用且真实异步监听实例就绪后才返回,因此 ERP 不会提前发布发现文件;发现文档还会绑定精确进程号,先以 `CreateNew + WriteThrough + Flush(true)` 写入同目录隐藏临时文件,再通过 `File.Replace/File.Move` 原子发布,读取方不会看到半份 JSON。停止会唤醒监听、关闭全部已连接客户端并有界等待接收线程结束,已释放实例不能重新启动。异常客户端因此不能通过首次连接竞态、残缺发现文件、假服务端进程、非法编码、只连接不发送、慢速分片或不读取响应无限占用线程。