5.6 KiB
2026-10-27 实际 PHP transport 验证路径
本审查仅做配置诊断与准备。没有执行上游 GET、生成、停止、模型调用、患者查询或共享服务修改。没有打印凭据、配置 URL、临床正文或 task/run/user/request 标识。新增文件都在 artifacts/,没有新增公开路由。
已证实的 CLI 与 FastCGI 差异
server/config/prescription_ai.php 经同一 ThinkPHP .env 加载方式读取,在本次受限 CLI 中:
- AI 已启用;base URL 语法与路径有效;没有 URL 认证、查询参数、片段或控制字符。
- qwen/openai 服务端 key 均存在并满足状态适配器格式要求。
required_attachment_upload.ca_file为非空字符串,没有控制字符;is_file=true,但is_readable=false。- CLI 的
curl.cainfo、openssl.cafile均为空。
经主代理授权,唯一一次 config-only loopback FastCGI 调用取得 cgi-fcgi 结果:以上配置判断相同,唯独 CA 的 is_readable=true。FastCGI 同样没有上述两个 ini CA 值。此调用 15.659ms、无 FastCGI stderr,没有触发 Dify。
因此此前 CLI 的 RUN_STATUS_CONFIG_INVALID 精确归因于受限 CLI 无法读取已存在的配置 CA。实际 FastCGI worker 能读该 CA。不能由 CLI 的拒绝推断 Dify 运行状态,也不应通过清空 CA 或关闭 TLS 验证绕过。
已核对本地 nginx 承接工作站的 vhost:root 为 D:/web/zyt/server/public,FastCGI 为 127.0.0.1:9002。受限 Python 本地 socket 报 WinError 10013;同一已授权命令提升执行后成功。后续 loopback driver 同样需允许本地 socket 的执行环境。
新增私有入口
private_ai_runtime_config_20261027.php:只输出配置类型、有效性和 CA 存在/可读布尔值,无网络调用。CLI 或 loopback FastCGI 可运行。private_ai_runtime_status_20261027.php:仅接受 loopback FastCGI 的空 POST,固定选择唯一 2026-10-27 10:17:23 +08:00 原始控制文件,同时要求原错误/校验拒绝/producer stopped/persisted running/2 次查询/1 次 submission。只对原绑定 identity 执行一次生产DifyWorkflowRunStatus::lookup(...,1000),输出状态或固定错误码、耗时及原文件 hash 未变布尔值;不导出 identity/hash,不构造或更新控制对象。private_ai_runtime_synthetic_20261027.php:仅接受 loopback FastCGI JSON POST,只有 profile 与 mode 两字段,使用全新内部随机 identity。直接调用生产DifyChatService::streamChat,不加载患者数据、诊单权限、既存临床 fixture 或数据库。复用当前 Controller 的 submission、task/run binding、stop、terminal、timeout、transfer-close、独立 lookup、finish/recovery 语义。自己的控制文件放server/runtime/ai-synthetic-runtime-20261027/controls。每次最多 1 次 submission;complete/cancel 最多 30s 生成预算,timeout 为 1s,保留生产停止/查询有界预算。输出只有枚举、布尔、计数、字节数和相对时间;正文只存在内存,输出 stream/final hash 相等布尔值,无 hash 或正文。private_ai_runtime_driver_20261027.py:固定连接127.0.0.1:9002,固定上述脚本,POST 实际 PHP worker;42s 绝对接收截止,输出上限 64KiB。不会输出原始 FastCGI stderr、错误页面或异常文本。每次命令只执行一个动作,不自动重试或启动后继。
精确命令
以下命令从 D:\web\zyt 前台执行。status-original 会产生一次只读上游状态调用;synthetic 会调用对应既有 Dify 模型应用。审查者未执行这两类动作,交由主代理按当前授权执行。
php artifacts\private_ai_runtime_config_20261027.php
python artifacts\private_ai_runtime_driver_20261027.py config
python artifacts\private_ai_runtime_driver_20261027.py status-original
python artifacts\private_ai_runtime_driver_20261027.py synthetic --profile qwen --mode complete
python artifacts\private_ai_runtime_driver_20261027.py synthetic --profile qwen --mode cancel-before
python artifacts\private_ai_runtime_driver_20261027.py synthetic --profile qwen --mode cancel-after
python artifacts\private_ai_runtime_driver_20261027.py synthetic --profile qwen --mode timeout
另一已发布 profile 用 --profile openai,其余参数不变。需要逐次阅读结果;independent_terminal_pass=false 或 pending 计数大于零时,不应继续下一个生成来伪装为已清理。单独的 full_answer_pass 仅表示这次合成 transport 成功并且所有 delta 与最终正文 hash 相等;不能代替当前工作站真实完整回答验收。取消模式预期 service ok=false 并带取消错误码,仍需 terminal-pass 和零 pending 作为清理成功证据。timeout 没捕获 run 时可能安全保留 pending,不能把无身份当已停止。
cancel-before 在真实 task 首次绑定后提出取消;cancel-after 收到首个真实 delta 后提出取消,下一轮生产 transport 执行实际 stop。没有人工 usleep 扩大窗口,没有分别启动第二个模型请求。既有 legacy local_cancel_probe.php 使用旧式 clearTask 路径,未接当前 submission/producer terminal/独立持久状态证明,不能用于本次验收。
本次静态验证
三个 PHP 文件均通过 php -l;Python driver 通过 python -m py_compile。直接 CLI 调用 synthetic 入口,在 bootstrap 前返回 PRIVATE_FASTCGI_POST_REQUIRED。原始控制文件选择经只读检查只有一个候选,未输出其文件名或内容。没有执行 status-original 或 synthetic 的 FastCGI 请求;只有前述一次 config-only FastCGI 成功。