目录

Fpai-gate — FPAI 部署两段式硬门禁插件

给基于 Fpai-user 系列 skill 工作的 Agent 提供可靠的自动化验证门禁,替代”模型每次自己写测试脚本”。 对齐 one-model 两段流程:G1 编译段(模型编译+仿真)、G2 上板段(socket 运行); G1 首阶段为 audit(AI/导出环境可重建性,外部审查者语义:只信 pyproject+uv.lock,不信现存 .venv)。

核心机制

  • 干净环境执行:G1/G2 的所有子进程环境从注册表重建(HKLM 系统 env + HKCU 用户 env), 等价于人肉新开 PowerShell。会话内临时 set 的环境变量、临时追加的 DLL 路径全部不可见—— “在 Agent 会话里能跑、人上手就挂”的假阳性在此现形。DLL 部署必须落到系统可见位置。
  • 机器可查断言:每个阶段不是”命令没报错就算过”,而是断言产物落盘(imodel json/raw)、 四个 MODELZOO_*_TIME_MS 阶段标记齐全、输出目录有新增非空产物、socket 无连接错误。
  • 结构化结果:.fpai-ci/result-G1.json / result-G2.json + digest 摘要 + 分级退出码: 0=全过;1=阶段失败(改代码);2=环境类(先修环境);3=配置错误。
  • 新鲜度强制(v0.4 触发模型):PASS 时按段(audit/compile/runtime)记录输入指纹(sha256 + 集合差)。 PostToolUse 只对门禁输入级触碰武装(1_scripts/2_compile/3_deploy/pyproject/uv.lock)—— 改 README/文档/报告完全不触发;Stop hook 拦截收工(exit 2,15 分钟内最多 3 次防死循环), 消息点名脏段。执行可分段(gate1 自动只测脏段),放行要求全部适用段 FRESH。 G2 仅在 mark-board 显式标记后强制(yaml 配 board.ip 不再自动要求 G2); v0.3 旧版指纹升级后首次判 STALE,全量重跑一次即完成迁移。

命令

命令 作用
/Fpai-gate:gate1 G1:DLL 部署 → 干净环境 icraft compile 全程 → CRT 构建 → CRT/PYRT host 仿真
/Fpai-gate:gate2 G2:板卡 preflight(连通/版本一致/serve)→ socket 运行 CRT/PYRT
/Fpai-gate:gate G1 必跑;板可用再跑 G2
/Fpai-gate:report 最近 digest + 新鲜度(FRESH/STALE/NEVER)

CLI 直调:python <插件根>/scripts/fpai_ci/cli.py gate1 --project <工程>(子命令见 --help)。

工程配置 fpai-ci.yaml(放 <MODEL>_icraft/ 根,可省大部分)

arch: WL                      # 必填(或命令行 --arch)
mode: int8                    # 必填(或 --mode)
runtime: AUTO                 # AUTO=有 CRT 优先 CRT;CRT 构建失败记录后兜底 PYRT 但门禁仍红
tools:                        # 缺省从 PATH(注册表)/C:\Icraft 检索;env_snapshot 可接同事 env_check 输出
  icraft: C:/Icraft/CLI/bin/icraft.exe
  pyrt_python: <含 icraft 包的运行时解释器(跑 *_psin.py/分析脚本)——注意不是 1_scripts 导出环境;后者按公约=项目 .venv(uv),门禁暂不消费>
  cmake: cmake                # tools.python 为 pyrt_python 兼容别名
dlls:                         # 声明式 DLL 部署(拷贝+哈希留痕,幂等)
  - {src: build/Release/myop.dll, dst: [C:/Icraft/CLI/lib]}
board: {ip: 192.168.125.201, backend: wl170, ssh_user: root}   # 配了才可跑 G2
board_deploy: [{src: ..., dst: /opt/icraft/lib}]               # 可选:socket 前经 ssh/scp 上板
env_snapshot: <同事 env_check JSON 路径>                        # 可选:读 CliPath/Interpreter
audit:                                                       # AI/导出环境可重建性(uv 工程)
  rebuild: dry          # dry=lock检查+解析验证(秒级) | full=真隔离重建(.fpai-ci/venv-audit) | off
  scripts: false        # true 需 rebuild=full:在审计 venv 里实跑 1_scripts 三脚本
timeout: {compile: 3600, build: 1800, sim: 1800, socket: 1800, sync: 1800}

依赖:Python 3.8+;PyYAML 可选(缺失自动退回内置 miniyaml 子集编解码)。

目录

.zcode-plugin/plugin.json   清单(无 skills,纯 commands+hooks+scripts)
commands/                   4 个门禁命令模板(教 Agent 怎么调怎么读)
hooks/hooks.json            SessionStart/PostToolUse/Stop
scripts/fpai_ci/            CLI 本体(config/cleanenv/runner/result/deploy/cfggen/
                            phasetags/tomlscan/board/g1/g2/hooklib/miniyaml/cli)
tests/fixtures/             mini_icraft 夹具 + stub_icraft.cmd(冒烟测试用)

通用性模型(三层)

机器差异不允许靠猜——猜出来的必须在报告里留痕并告警:

层 内容 谁负责
机器层绑定 icraft CLI 绝对路径、含 icraft 的 PYRT 解释器、cmake 显式声明:fpai-ci.yaml tools.* 或同事 env_check 的 env snapshot(env_snapshot: 字段)
工程层配置 arch/mode、dlls 部署表、board、阈值、超时 fpai-ci.yaml
通用推导 modelzoo 目录布局、toml/cfg 四联命名、首样本列表、后端默认映射 插件内置,跨机器一致

未声明时的自动探测及其来源标记(digest 的 ---- bindings ---- 段可见):

  • icraft:registry PATH → C:\Icraft\CLI\bin(安装器默认)→ C:\Icraft 递归——最后两者自动触发告警;
  • PYRT 解释器:项目 .venv(须含 icraft)→ 祖先 .venvs/*icraft*/ 共享环境(非规范本机惯例,触发告警)→ 运行 CLI 的 python(多半无 icraft,预检直接报 ENV_MISSING 并给固化指引)。

自动探测只影响”这台机器能不能跑起来”,不影响判定标准本身;所有判定(产物断言/阶段标记/输出检查/新鲜度)与机器无关。

状态与已知边界(v0.4.0)

  • 分段验证(改哪测哪,v0.4 核心):G1 按 audit(pyproject/uv.lock/1_scripts)→ compile(config/toml/fmodel)→ runtime(3_deploy 运行时源 + imodel 产物)三段各自对上次 PASS 指纹,FRESH 段记 SKIP(FRESH) 不重跑。段间传播靠内容实测而非目录推断:audit 再生 fmodel 后重新度量 compile(内容变了才重编译);compile 产出 imodel 后重新度量 runtime(产物字节变了才重仿真)。--full 强制全量兜底;DLL 部署段恒跑(幂等+哈希校验)。 纯编译工程的 runtime 段做跟踪性记录(不验证),避免 NEVER 死循环。

  • armed 触发状态机(v0.4):触碰分级记录(scripts/compile/runtime/env 四 zone), 文档级触碰不记录不武装;旧格式 touched.json(v0.3 浮点)迁移后视为未武装。

  • v0.4 顺手修复:G2 资产段 CRT 现场构建时 icraft_abs 未定义先引用(NameError→exit 4); 指纹只比对记录内文件导致新增文件漏报 STALE(假 FRESH)——已改为内容比对+集合差。

  • 迁移:v0.3 指纹(扁平 schema)升级后首次判 STALE 提示全量重跑一次;hook 与门禁 共用 config.stage_patterns 同一口径,不会出现”hook 说 STALE、门禁实测 FRESH”的死循环。

  • 多后端多精度:fpai-ci.yaml 写 targets: 列表(每条 {arch, mode},可附 board_ip/backend),gate1/gate/gate2 循环执行、结果按 target 独立留痕(result-G1-<ARCH>-<mode>.json / fingerprints-* / .fpai-ci/out/<target>/<kind>/),退出码取最差;audit(uv 环境 + cfg 锚点巡检)与 target 无关只跑一次。

  • cfg 锚点巡检(cfg_anchor 阶段,零成本):cfg 相对路径按运行 cwd 解析,每个 cfg 必须在其书写锚点(CRT→build/、pyrt→pyrt/)下可解析——imodel.dir 须落 3_deploy 子树、dataset.list 须存在;所有锚点都解析不了即 FAIL。板端/评测类命名(board/rtapp/eval/socket)排除。

  • 门禁自产 cfg:fpai_ci_<target>_<kind>.yaml(文件名带 target 防多目标互覆),无条件重写 imodel.dir(TOML jr_path 权威来源),不跟踪进指纹(输出非输入)。

  • 深度巡检(CLI deep 子命令):在锚点 cwd 下真跑全部 host demo cfg(强制 show=false、输出重定向),入库前体检用,不进日常门禁节奏。

  • Stop hook 按 target 扫指纹:任一已声明目标的 G1 STALE/NEVER 拦截;旧版无 target 指纹(单目标时代)兼容识别。

  • 真机验证:PoseC3D(ZG/int8)0.3.0 全绿(audit full+scripts 33s + cfg_anchor + compile 324s + sim 33s,bindings 零告警);夹具多目标幂等闭环(改→拦→过→FRESH→放行)。

  • cleanenv 修复(重要):动态变量(SystemRoot)必须在 %VAR% 展开前注入,否则注册表 REG_EXPAND_SZ(如 ComSpec=%SystemRoot%...)留下未展开字面量,子进程 cmd 管道/子 shell 全部”系统找不到指定的路径”——此前未暴露只因 icraft/桩都不用管道。

  • 纯编译阶段工程支持(0.3.3):只有 2_compile、运行时未写的工程,G1 只跑 compile(运行时阶段 SKIP、不报配置错误)——2_compile 是工程识别的充分标识,3_deploy 可缺。

  • 当前验收基线 = G1 仿真通过(audit + compile + CRT 构建 + host 仿真);CRT 路径已于 2026-10-14 真机验证(yolov8)。G2 socket 代码就绪但暂不纳入验收——阻塞于板固件已知缺陷(dtb udmabuf 分段缺失致 icraft-serve 段错误,git-bug 2a4d168),板修复后即可启用。

  • 阶段标记默认 WARN(strict_phase_tags: true 恢复硬断言);PYRT 解释器解析顺序见通用性模型一节;禁用门禁:<工作区>/.zcode/fpai-ci/disabled 空文件。

  • TODO(git-bug):2943dd1 customop 一键编译/部署;0c21a55 本路线残余(CRT/板端验证)。

历史版本要点(v0.1.2 原文)

  • 已验证:真实工程 PoseC3D(ZG/int8, PYRT-only)G1 全绿——干净环境 icraft compile 全程 299s(json 6MB/raw 97MB 断言过)+ sim_pyrt 29.5s(解释器自动解析到共享 icraft39 venv)。 另有 stub 夹具冒烟:全链路/失败级联/STALE/Stop 拦截闭环/G2 错误路径。
  • 未真机验证:CRT(VS 构建)路径、G2 socket 板端运行(PYRT socket 与 G1 同机制,待板卡实测)。
  • 阶段标记:存量 modelzoo 工程普遍未打 MODELZOO_*_TIME_MS 点,默认缺标记记 WARN 不判败; fpai-ci.yaml 设 strict_phase_tags: true 恢复硬断言。
  • PYRT 解释器自动解析顺序:yaml tools.python > env_snapshot > 项目 .venv(须含 icraft)> 祖先目录 .venvs/*icraft*/ 共享环境(如 D:\ModelZoo.venvs\icraft39)> sys.executable。
  • 真机踩坑记录(都已固化进代码):
    1. 注册表 env 合并语义:PATH 是拼接(machine;user),不是用户覆盖机器——覆盖会丢 system32,icraft-parse 拿不到 VC 运行时秒败(exit 4294967295);
    2. icraft 内部 spawn icraft-parse/quantize 靠 PATH 解析;CLI 不在注册表 PATH 时自动前插 其 bin 目录(metrics.icraft_from 留痕);
    3. 超时必须杀进程树(taskkill /T /F):只杀父进程会留下孙进程握住 stdout 管道, 读取永久阻塞。
  • CRT 构建用 cmake -S/-B --config Release,假定 VS 生成器默认可用;特殊工程需调整时改 g1.build_crt。
  • 板 IP 只从 yaml/命令行取,绝不从模型 cfg 捞(陈旧 IP 高发)。
  • 禁用门禁:在 <工作区>/.zcode/fpai-ci/ 下创建 disabled 空文件。
  • TODO(git-bug 跟踪):为带 customop DLL 的上传工程提供客户侧一键编译/部署脚本。
关于

FPAI 部署硬门禁 ZCode 插件(非对话调用的 skill):干净环境分段验证(audit/compile/runtime 改哪测哪)+ host 仿真 + Stop hook 新鲜度强制;本文件为 GitLink 仓库说明。

86.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号