# 语言无关模块协议 v2(底座 v0.17) 模块业务、H5、权限、API 路由和数据库能力与开发语言分离。公开接口为 JSON-RPC 2.0 双向调用;Go 的 net/rpc/gob 协议 v1 保持兼容,作为可选 Go 适配通道。Python 不需要导入 Go SDK,也不需要实现 gob。Go 也可使用 v2 的 modulekit.ServeJSON。其他语言遵守同一协议即可;解释器/虚拟机必须有运维启用的运行配置。 ## 传输与方法 使用进程 stdin/stdout(Docker 为 attach 的标准输入输出),每行一个 UTF-8 JSON 对象,JSON 字符串内换行必须转义,单帧小于 4MiB。stdout 专供协议,日志写 stderr。v2 容器禁用 Docker 标准输出日志持久化,只在底座保存有界 stderr;避免协议中的业务报文进入日志。当前实现是 JSON-RPC 2.0 的受控配置:仅字符串 id、命名对象 params、单请求;不接受 batch、notification 或任意方法。基础规范:[JSON-RPC 2.0](https://www.jsonrpc.org/specification)。 底座发送: ```json {"jsonrpc":"2.0","id":"h-...","method":"module.describe"} {"jsonrpc":"2.0","id":"h-...","method":"module.execute","params":{"context_id":"随机本次上下文","request":{"action":"create","actor_id":"可信用户","request_id":"业务幂等号","payload":{"title":"内容"}}}} ``` describe 返回 result 为 `{id,name,version,protocol:2,description,actions}`。execute 返回 result 为 `{data:对象或数组,code:错误码,error:可读错误}`;正常成功可省略 code/error。协议失败用 JSON-RPC error;不要在错误里暴露连接凭据或业务正文。模块描述与清单 ID、版本和协议必须匹配。 模块在执行期间可反向发送: ```json {"jsonrpc":"2.0","id":"m-1","method":"host.call","params":{"context_id":"原样传回本次上下文","request":{"service":"identity.get","actor_id":"可信用户","request_id":"原业务幂等号"}}} ``` 底座返回同一个 id,result 是 `{data,code,error}`。records.list/create 等还带 collection、payload、record_id,字段与 SDK HostRequest 一致。database.connect 返回的凭据只能留在模块后端,不能返回 H5 或日志。 context_id 每次调用新生成,与业务 request_id 不同。底座校验上下文、ActorID、RequestID、批准能力、当前角色与 Key 权限;旧上下文和伪造身份不能调用宿主服务。每次执行最多 64 个反向调用。模块不能复用旧 Host、在返回后继续回调,或依赖后台线程保有用户身份。当前两种协议仍各模块一个执行槽位,跨模块可并行;v2 没有自动开启模块内多请求并发。 超时、进程退出、无效/超大帧会中断连接并触发原有监督恢复。写入被中断可能已提交,必须查询或用原业务 request_id 重试;不能把超时当作回滚。通用传输的成本需要实际压测,不能宣称 Go 通道或企业版一定更快。 ## 清单与运行配置 ```json { "id":"python-notes","name":"Python 便笺","version":"1.0.0","protocol":2, "entry":"main.py", "runtime":{"profile":"python3","files":["code/oa_module.py"]}, "capabilities":["identity.get","records.list","records.create"], "ui":{"mode":"h5","entry":"ui/index.html","bridge_version":1,"files":["ui/index.html","ui/app.js"]} } ``` 上传 ZIP 包只包含 manifest.json、入口文件、simulation.json、声明的 code/ 文件、H5 和数据库 SQL。code/ 最多 64 份,每份 8MiB,总包沿用 64MiB。路径、重复文件、缺文件、额外未声明文件会被拒绝。不得把数据库密码、Key、.env 或 SSH 私钥放入包。 profile 是运维管理的固定运行配置名,不是语言白名单。native 是已有原生可执行文件镜像,可用于 Go/Rust/C 等的 Linux 原生程序;python3 为首次提供的解释器配置。Java21 已通过 java-assets 资产台账的独立 JAR 和受控 JRE 配置接入,源码及协议封装位于 examples/java-assets;Node 等可由运维提供运行配置后接入,目前未提供 Node SDK 或验收样例。使用非 native 配置要求 Linux Docker;未启用的配置直接拒绝,不回退宿主解释器。 运维以 OA_RUNTIME_PROFILES 指向受保护配置文件,例如: ```json {"python3":{"image":"python@sha256:<运维实际批准摘要>","command":["/usr/local/bin/python3","-B","-u"],"environment":{"PYTHONPATH":"/code","PYTHONNOUSERSITE":"1","PYTHONDONTWRITEBYTECODE":"1"}}} ``` 底座固定挂载入口为 /module、额外声明源码为 /code(只读);解释器参数由运维给定,入口由底座追加,不执行 shell 拼接。应用不能选择镜像、启动命令、环境变量、Docker socket、网络和挂载。镜像预先拉取并固定摘要,运行 --pull never;只读根、非 root、断网、能力撤销、内存/CPU/PID 等限制与旧模块相同。数据库批准后仍只挂专用 Unix socket。 依赖须预装于经审核的镜像或随包放入声明的 code/;运行时禁止 pip/npm 联网安装。当前 python3 镜像仅 Python 标准库;连接 PostgreSQL 所需驱动须另经运维审核并制作锁定依赖的配置,Python 示例使用底座 records.*。镜像配置变更须按部署流程重启底座;它不是应用包可自行修改的配置。管理员可 GET /api/runtime-profiles 查看启用配置及镜像。 ## SDK、样例与性能 /devkit.zip?v=0.20.4 包含 Python SDK `python-sdk/oa_module.py`、Go `modulekit.ServeJSON` 和本协议说明。仓库 examples/python-notes 是 Python + H5 + records.* 完整样例;cmd/jsonrpc-example 是使用相同公开协议的 Go 样例。候选包仍需通过模拟测试、能力审批和正式发布,不因使用某种语言绕过审核。 通用层负责身份/策略/生命周期,业务语言负责状态规则和本地事务。Go 专用适配可以继续优化编解码、连接复用或并发;这些应作为经过压测的可选优化,不能把用户身份隔离、事务、超时和模块边界绕开。企业功能可围绕治理、审计、可用性和支持扩展,公开协议应保持一致。