From 57e814aa6613c25497629f9328954e26feea67d5 Mon Sep 17 00:00:00 2001 From: "agent.develop" Date: Wed, 30 Sep 2026 18:15:27 +0800 Subject: [PATCH] =?UTF-8?q?approve:=20=E4=BF=AE=E5=A4=8D=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E8=BF=AD=E4=BB=A3=202=20=E4=B8=AA=E5=8A=9F=E8=83=BD=20Bug?= =?UTF-8?q?=EF=BC=88pbls-=E5=88=9D=E5=A7=8B=E8=BF=AD=E4=BB=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pbl_agent_runtime.egg-info/PKG-INFO | 13 ++++++ pbl_agent_runtime.egg-info/SOURCES.txt | 32 +++++++++++++++ .../dependency_links.txt | 1 + pbl_agent_runtime.egg-info/requires.txt | 3 ++ pbl_agent_runtime.egg-info/top_level.txt | 1 + scripts/check_contract_sync.py | 2 +- scripts/load_path.py | 38 +++++++++++++----- scripts/m4a_contract_selftest.py | 2 +- var/m4a_contract.sqlite3 | Bin 110592 -> 118784 bytes 9 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 pbl_agent_runtime.egg-info/PKG-INFO create mode 100644 pbl_agent_runtime.egg-info/SOURCES.txt create mode 100644 pbl_agent_runtime.egg-info/dependency_links.txt create mode 100644 pbl_agent_runtime.egg-info/requires.txt create mode 100644 pbl_agent_runtime.egg-info/top_level.txt diff --git a/pbl_agent_runtime.egg-info/PKG-INFO b/pbl_agent_runtime.egg-info/PKG-INFO new file mode 100644 index 0000000..fdc0914 --- /dev/null +++ b/pbl_agent_runtime.egg-info/PKG-INFO @@ -0,0 +1,13 @@ +Metadata-Version: 2.4 +Name: pbl_agent_runtime +Version: 1.0.0 +Summary: PBL Designer/Critic Agent 运行时与 fail-closed 工具裁决(M4a:Agent 定义 + 13/9 工具注册 + 8 步裁决 + 四类强制人工审批) +Author: pbls dev team +License: Proprietary +Keywords: pbl,agent-runtime,designer,critic,fail-closed,tool-adjudication +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Provides-Extra: dev +Requires-Dist: pytest>=7.0; extra == "dev" + +契约说明(3,893B,含真图):4 表 + 图1 九关 fail-closed 裁决链(qwen-image-3.0-pro 生成) + 九关错误码对照表 + 13 启用工具表(含 kind/domain/允许角色) + 9 禁用工具及理由表 + 用法示例 + 留痕与脱敏说明 + self_check/runtime_self_check 自检说明 diff --git a/pbl_agent_runtime.egg-info/SOURCES.txt b/pbl_agent_runtime.egg-info/SOURCES.txt new file mode 100644 index 0000000..f54efea --- /dev/null +++ b/pbl_agent_runtime.egg-info/SOURCES.txt @@ -0,0 +1,32 @@ +README.md +pyproject.toml +pbl_agent_runtime/__init__.py +pbl_agent_runtime/_store.py +pbl_agent_runtime/fallback.py +pbl_agent_runtime/init.py +pbl_agent_runtime/llm_router.py +pbl_agent_runtime/m4a.py +pbl_agent_runtime/m4a_adjudicate.py +pbl_agent_runtime/m4a_api.py +pbl_agent_runtime/m4a_approval.py +pbl_agent_runtime/m4a_backend.py +pbl_agent_runtime/m4a_contract.py +pbl_agent_runtime/m4a_critic.py +pbl_agent_runtime/m4a_designer.py +pbl_agent_runtime/m4a_init.py +pbl_agent_runtime/m4a_kernel.py +pbl_agent_runtime/m4a_registry.py +pbl_agent_runtime/m4a_smoke_compat.py +pbl_agent_runtime/m4a_store.py +pbl_agent_runtime/m4a_tables.py +pbl_agent_runtime/m4a_toolset.py +pbl_agent_runtime/m4a_trace.py +pbl_agent_runtime/prompt_guard.py +pbl_agent_runtime/trace_store.py +pbl_agent_runtime.egg-info/PKG-INFO +pbl_agent_runtime.egg-info/SOURCES.txt +pbl_agent_runtime.egg-info/dependency_links.txt +pbl_agent_runtime.egg-info/requires.txt +pbl_agent_runtime.egg-info/top_level.txt +pbl_agent_runtime/../sql/m4a_contract_addon.sql +pbl_agent_runtime/../sql/m4a_ddl.sql \ No newline at end of file diff --git a/pbl_agent_runtime.egg-info/dependency_links.txt b/pbl_agent_runtime.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pbl_agent_runtime.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/pbl_agent_runtime.egg-info/requires.txt b/pbl_agent_runtime.egg-info/requires.txt new file mode 100644 index 0000000..9a62782 --- /dev/null +++ b/pbl_agent_runtime.egg-info/requires.txt @@ -0,0 +1,3 @@ + +[dev] +pytest>=7.0 diff --git a/pbl_agent_runtime.egg-info/top_level.txt b/pbl_agent_runtime.egg-info/top_level.txt new file mode 100644 index 0000000..209716c --- /dev/null +++ b/pbl_agent_runtime.egg-info/top_level.txt @@ -0,0 +1 @@ +pbl_agent_runtime diff --git a/scripts/check_contract_sync.py b/scripts/check_contract_sync.py index 5b7198b..1e5ba39 100644 --- a/scripts/check_contract_sync.py +++ b/scripts/check_contract_sync.py @@ -111,7 +111,7 @@ def main(): full = os.path.join(ROOT, "wwwroot", rel_in_module) if not os.path.isfile(full): problems.append("load_path points to missing file: %s" % path) - if role not in ("any", "user", "admin"): + if role not in ("any", "logined", "admin"): problems.append("load_path bad role %r for %s" % (role, path)) # 3)+4) dspy 内容审计 diff --git a/scripts/load_path.py b/scripts/load_path.py index 7deb258..7a0a5e8 100644 --- a/scripts/load_path.py +++ b/scripts/load_path.py @@ -8,25 +8,45 @@ 角色约定 -------- * ``any`` :登录前可访问(本模块无此类文件) -* ``user`` :普通登录用户(只读查询类) +* ``logined`` :普通登录用户(只读查询类) * ``admin`` :租户管理员(写类 / 审批裁决 / 注册表变更) + +角色名必须是**平台可解析口径**,不得自造 +-------------------------------------- +写入工具 ``set_role_perm.py`` 的角色解析规则(pipeline-app/set_role_perm.py): + +* ``any`` / ``anonymous`` / ``logined`` 是特殊角色,直接用字面 id; +* 其余角色按 ``[orgtypeid.]name`` 查 role 表,缺省 ``orgtypeid='*'``;查不到即 + ``exit(1)``,宿主 ``load_path.py register()`` 记为 PENDING,端点上线即 403。 + +本模块原用自造词 ``user``(语义即「普通登录用户」),但 role 表里 ``user`` 只有 +``orgtypeid='customer'`` 一行、**没有 ``orgtypeid='*'``**,故按缺省口径查零命中 → +8 条路径恒 PENDING(2026-09-29 build_run9 实测:total=308 ok=300 pending=8)。 +平台表达「普通登录用户」的既有词就是 ``logined``(role 表有 id='logined' 与 +orgtypeid='*' 两行),故归一到 ``logined``,语义不变且可解析。 + +注意:``admin`` 之所以能注册成功,是因为 role 表恰好存在 ``orgtypeid='*'`` 的 +admin 行(id=zxje5CL8jCroLL35piNXG)。角色是运行时可增删的(role/orgtypes 有 +CRUD),所以**任何模块都不应依赖某个具体角色行恰好存在**——只读的普通登录态 +统一用特殊角色 ``logined``,写类/管理类若要用具名角色,必须带 orgtype 前缀 +(如 ``owner.superuser``)并确认该行由种子保证存在。 """ # (路径, 角色) —— 路径相对模块 wwwroot,运行时前缀 /pbl_agent_runtime/ PATHS = [ # 模块入口页 - ("/pbl_agent_runtime/index.ui", "user"), + ("/pbl_agent_runtime/index.ui", "logined"), # 10 个契约端点(与 pbl_agent_runtime.m4a_contract.CONTRACT_FUNCTIONS 同源) ("/pbl_agent_runtime/api/pbl_agent_designer_run.dspy", "admin"), - ("/pbl_agent_runtime/api/pbl_agent_critic_run.dspy", "user"), - ("/pbl_agent_runtime/api/pbl_agent_trace_write.dspy", "user"), - ("/pbl_agent_runtime/api/pbl_agent_trace_list.dspy", "user"), - ("/pbl_agent_runtime/api/pbl_tool_registry_list.dspy", "user"), + ("/pbl_agent_runtime/api/pbl_agent_critic_run.dspy", "logined"), + ("/pbl_agent_runtime/api/pbl_agent_trace_write.dspy", "logined"), + ("/pbl_agent_runtime/api/pbl_agent_trace_list.dspy", "logined"), + ("/pbl_agent_runtime/api/pbl_tool_registry_list.dspy", "logined"), ("/pbl_agent_runtime/api/pbl_tool_registry_save.dspy", "admin"), - ("/pbl_agent_runtime/api/pbl_tool_adjudicate.dspy", "user"), - ("/pbl_agent_runtime/api/pbl_approval_create.dspy", "user"), + ("/pbl_agent_runtime/api/pbl_tool_adjudicate.dspy", "logined"), + ("/pbl_agent_runtime/api/pbl_approval_create.dspy", "logined"), ("/pbl_agent_runtime/api/pbl_approval_decide.dspy", "admin"), - ("/pbl_agent_runtime/api/pbl_approval_list.dspy", "user"), + ("/pbl_agent_runtime/api/pbl_approval_list.dspy", "logined"), ] MODULE_NAME = "pbl_agent_runtime" diff --git a/scripts/m4a_contract_selftest.py b/scripts/m4a_contract_selftest.py index 33ce520..e87256b 100644 --- a/scripts/m4a_contract_selftest.py +++ b/scripts/m4a_contract_selftest.py @@ -211,7 +211,7 @@ def t_qc4_load_path(): rel = path.lstrip("/").split("/", 1)[1] full = os.path.join(ROOT, "wwwroot", rel) assert os.path.isfile(full), "PATHS 指向不存在文件: %s" % path - assert role in ("any", "user", "admin"), (path, role) + assert role in ("any", "logined", "admin"), (path, role) if path.endswith(".dspy"): dspy_paths.append(path) assert len(dspy_paths) == 10, dspy_paths diff --git a/var/m4a_contract.sqlite3 b/var/m4a_contract.sqlite3 index 82d50b4dcd2227f09eecd01fed1b760916b7e8e5..e399b2ea728f2ffad8e3b568abb7531d90343b69 100644 GIT binary patch delta 7583 zcmc&(Yit}x9lwq5e16>y!7^%Tom^8=B}(GX&dxr@C4w{$E5gJ;5|xL`b!TVSIcn}K zpDh%kXnTk90YY)pD{&u$CV(nI3(gf4(k}#2qzd&z6$uGw#8V0iMM$82D2Ol2?%jD` zW1EPgezCm&ncMlz@BjME>?42ZedJ>Pu{(0vOeQmWuJ|D-+j{7tH}HQ4 zld4R0R1+!KQVmm~7TDf1CC$;^Dd=3r`;3aM=)TV;k} zVn&f=*y=!P7S$-#k!rgtW7x73Vq&L1nB_%xY3sUbC`3_-=3uIFN;K4$dYKCyMKKsw z2|^f~ibZrYpPHpv7Bp4OfhOOcVj%vP_NHbz<3uIYbyUS5I)+%YsA1+((};px?jqMz zErxZ)q{zWp?!LusK!zFc9pHiqxgtZb1DpYW0{!xo{HFXGctw6eeza8|ki9KguvdZ$ z^LELErp=%QnGG4nmPs9jfpC~2!(t3#Obi1Jbc1`CS{k)YS_p?- z6&nu1mID>OX$mQ`=@1|GI*T*n*oMU&s`3ai4Vx1L2g9E;2pKU<%jWcB-Lg!Zuz_&c zCI+z_gL~2CYpBRHh}|C!^O&S6auL%w1Of?B80>2gd;ZRe>Ohs*mSJibJ3O{*6XnC7 zW2O*lV+C54gPBcCRYkqwFv6Nnbl1VI%lOXyM9^~KFyWjKUD3G{U5=gSlx1XBhnw}Y zBh8W*9Q3R-UOi^OfpYZP7k4wot9ko@)N|^<7?eH-bpt z1IZplii$dp;W$S1;i2}*cW)lqes6MROu0V{*QUI_U{zJ9YQkV;QG|C_=Ge#P7U^uc zcH-3O0|$?M%7;*LyoyC<9rm&NC&!LWO-+s+IDB;9{gVd|WbaACQtDd=16a53+B|YE zNy1VvPawvDVFO{FL{vk1085lv_I!DvY|~k9(V3esR~E*;zzt3tS-Ug`hEmP0&N)81 zeG>D{GH;Iu=j zrJ-IQ=Ecbm7opQsjUuKZs42FMnd|VS+w6!6M|b60b(#Q{R^QsUj?)ZeL5&iH_ZkE1 zP&0Y)3J4Jutarj``_jze`e=R~r!lPgWe@49t6`#Pmdi_UfKgO6yVMDswj5ttHO3XC zKHR&G(+D;+rV*QH2F12!5~R1;5f$X_%D3vY(?wu6ry&K5;dbPbpoe-IyI7MB#g)sm=6!pQ~fVef7JZc#g!+CW78 zifVO7{jMpVBl1^NuR{4-5*3x6kQh;NZyM#i_4@_8`PY?^7yo|v(qKgUEgw54y%95z z$E9D!47W9ZnZpI8RoR?mV8OqDj<(T0EPfFj48LmAk z{UB!e%2U!)F~iu?(n`#5^J(dOF~fytq^mK*%r~UxV}{WS(obTBKVL|^CN!BH@0vCl2CvTZFm-IfzC&s_II zEzsn_Of#5T3=9uDC-+ABlW!|Vo{QyLk(FzKjvp^Bf8@MGnoCRX%Q?QZZ+?Giizkwp zkr()<0RfoC^gxG!+tml_+dn?y>`E{ox}j(@5IgPW+sECWCRn=7TXh1&;cgR~rL(cN z7n}!*?Uq_(9j=-4&6j7q8?a-xP}rMgfoSBmq_Ou4o&f3movLr?Sc(h)C&6QYU!I!!_~kD0mDNZ!Dd=apg-luAceJrRC3@ zmv+W7X{#r=hl#vTNC+g2>HG$XB)WGC2uWP*^aeLO(M0n1ZmzlaM8v)uiImtuuz>_D zF>Pk!Q15CSi4#e55gE`H_G~Y_@!B|%{IkWHTt*{52&AZC{X`1kglM9_77*Y=X-wx< z2@ofeBe-G>2#Bc?uY0GrVI|?Ks%sJu3G`t9k>^`Yq%B?yU6^xZVs|-ks?D(X0r9ENW=7r5R7OYIIVXf?&zU zw7j}caW09z0|onx9eupchl359lE11FZZxsaNT>(fj6C0ZF2w+L@I_uIW<+UB7dFTx z(KoMvk@#sZ-~Lt-HYi@)c;M%Z7k#t9Bj5YhB(?b*aR*yMX+&bXfi+@u*w>~2 delta 448 zcmYMtze@sf7zXg~+xa6EeGwW2kqlabiX$h7C|abc!N!J$KwA12(#96kZ+ZT@yh4I3 zwCku8E1_DNObC(=DsBjAX>II6U)ny;`#kW*6?^={w&S-7j4^*II0u5ds%(1PW)xfz z=4rXX6;Tsm*Hxqm4NLmT;uJ8+Fo_qaYu;c2`OV5OZ_5s@l-A6y%&?3G-kV(pxma~d zTTK|@ceMqxtTX(>$_Q zC(LXxG&Jvg7d7KMcEC3Rj-gOUT28?$Ih=-PvX4WZtaErHKkUL6xv>X5@@WRn$?FoF zk;k)eNbY2zO5V;vuJ0LXIuA8+FAo*6T!0oiR)iCBK!#iLr~JP!?87nLmr8In@TCG{ M*mp>ptij{Jzk8XI`2YX_