Skip to content

Commit c9455b4

Browse files
wspwsp1911
authored andcommitted
feat(permissions): add model approval
Evaluate permission asks with a configured chat or Jev model, then route uncertain results through the existing approval policy. Expose model, endpoint, credential, and timeout settings across Desktop, CLI, and remote config surfaces.
1 parent fb06e1d commit c9455b4

67 files changed

Lines changed: 2895 additions & 170 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Cargo.lock‎

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎docs/interactive-capabilities/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ OpenBitFun Playbook currently contains **22 features**, **22 settings pages**, a
2727
- Generated per-item interaction audit: `docs/interactive-capabilities/technical/product-control-open-audit.json`
2828
- Generated low-level audit map: `docs/interactive-capabilities/technical/tauri-command-map.json`
2929

30-
说明书、网站、搜索和智能体只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **699** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。
30+
说明书、网站、搜索和智能体只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **702** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。
3131

32-
Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **699** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.
32+
Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **702** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.
3333

3434
## 控制边界 / Control boundary
3535

‎docs/interactive-capabilities/capabilities.json‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"title": "OpenBitFun Playbook",
55
"origin": "https://playbook.openbitfun.com",
66
"source": "src/shared/interactive-capabilities/catalog.json",
7-
"digest": "5370adbf2ff3746a6d89704d38498047e3430850234e4abc1cd6bb5eea2aac49",
7+
"digest": "778506ae9a8c979c4cea4de5c575be1bde0517def6ee5854dba203665098fa29",
88
"ownerDigest": "31d6371f7765bde7bee88e22a6a4f03c2c5370e138cf49975bdc88f3c5eeb052",
99
"searchAcceptance": [
1010
{
@@ -29394,7 +29394,7 @@
2939429394
"JSON repair"
2939529395
],
2939629396
"highlightsZh": [
29397-
"询问、自动批准与完全访问策略",
29397+
"询问、自动审批与完全访问策略",
2939829398
"子智能体并行度和工具超时",
2939929399
"Computer Use、浏览器连接与工具参数修复"
2940029400
],
@@ -29406,8 +29406,8 @@
2940629406
"items": [
2940729407
{
2940829408
"id": "permission-mode",
29409-
"titleZh": "选择询问、自动批准或完全访问权限模式,并确认高风险警告",
29410-
"titleEn": "Choose Ask, Auto-approve, or Full Access permission mode and acknowledge high-risk warnings",
29409+
"titleZh": "选择询问、自动审批或完全访问权限模式,并确认高风险警告",
29410+
"titleEn": "Choose Ask, Automatic approval, or Full Access permission mode and acknowledge high-risk warnings",
2941129411
"destination": {
2941229412
"kind": "settings",
2941329413
"pageId": "tools.execution",
@@ -29416,8 +29416,8 @@
2941629416
"control": {
2941729417
"kind": "open",
2941829418
"reasonCode": "unstructuredInteraction",
29419-
"reasonZh": "“选择询问、自动批准或完全访问权限模式,并确认高风险警告”由多个实时状态相关步骤组成,目前没有一个能确定完成整个流程的单一结构化 Command;智能体会打开精确入口,并把后续交互保留在用户可见界面。",
29420-
"reasonEn": "“Choose Ask, Auto-approve, or Full Access permission mode and acknowledge high-risk warnings” spans multiple live-state-dependent steps and currently has no single structured Command that can deterministically complete the whole workflow; the Agent opens the exact entry and keeps the remaining interaction visible to the user."
29419+
"reasonZh": "“选择询问、自动审批或完全访问权限模式,并确认高风险警告”由多个实时状态相关步骤组成,目前没有一个能确定完成整个流程的单一结构化 Command;智能体会打开精确入口,并把后续交互保留在用户可见界面。",
29420+
"reasonEn": "“Choose Ask, Automatic approval, or Full Access permission mode and acknowledge high-risk warnings” spans multiple live-state-dependent steps and currently has no single structured Command that can deterministically complete the whole workflow; the Agent opens the exact entry and keeps the remaining interaction visible to the user."
2942129421
}
2942229422
},
2942329423
{
@@ -29844,14 +29844,14 @@
2984429844
"computer use",
2984529845
"browser control",
2984629846
"JSON repair",
29847-
"询问、自动批准与完全访问策略",
29847+
"询问、自动审批与完全访问策略",
2984829848
"子智能体并行度和工具超时",
2984929849
"Computer Use、浏览器连接与工具参数修复",
2985029850
"Ask, auto-approve, and full-access policies",
2985129851
"Subagent concurrency and tool timeouts",
2985229852
"Computer Use, browser connection, and tool-argument repair",
29853-
"选择询问、自动批准或完全访问权限模式,并确认高风险警告",
29854-
"Choose Ask, Auto-approve, or Full Access permission mode and acknowledge high-risk warnings",
29853+
"选择询问、自动审批或完全访问权限模式,并确认高风险警告",
29854+
"Choose Ask, Automatic approval, or Full Access permission mode and acknowledge high-risk warnings",
2985529855
"控制权限模式选择器是否显示在聊天输入框下方",
2985629856
"Choose whether the permission-mode selector appears below the chat composer",
2985729857
"创建、排序和保存全局或项目级 Allow、Ask、Deny 规则",

‎docs/interactive-capabilities/capabilities/setting.tools.execution.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ Manage agent tool permissions, presentation mode, concurrency, timeouts, deferre
1717

1818
## 完整功能清单 / Everything included
1919

20-
- **智能体可定位入口,需交互完成 / Agent opens; interaction required** · 选择询问、自动批准或完全访问权限模式,并确认高风险警告
21-
- Choose Ask, Auto-approve, or Full Access permission mode and acknowledge high-risk warnings
20+
- **智能体可定位入口,需交互完成 / Agent opens; interaction required** · 选择询问、自动审批或完全访问权限模式,并确认高风险警告
21+
- Choose Ask, Automatic approval, or Full Access permission mode and acknowledge high-risk warnings
2222
- **智能体可直接控制 / Direct Agent control** · 控制权限模式选择器是否显示在聊天输入框下方
2323
- Choose whether the permission-mode selector appears below the chat composer
2424
- **智能体可定位入口,需交互完成 / Agent opens; interaction required** · 创建、排序和保存全局或项目级 Allow、Ask、Deny 规则

‎docs/interactive-capabilities/technical/product-control-open-audit.json‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schemaVersion": 1,
33
"generatedFrom": "src/shared/interactive-capabilities/catalog.json",
4-
"catalogDigest": "5370adbf2ff3746a6d89704d38498047e3430850234e4abc1cd6bb5eea2aac49",
4+
"catalogDigest": "778506ae9a8c979c4cea4de5c575be1bde0517def6ee5854dba203665098fa29",
55
"count": 196,
66
"reasonCounts": {
77
"externalAuth": 4,
@@ -2780,11 +2780,11 @@
27802780
{
27812781
"capabilityId": "setting.tools.execution",
27822782
"itemId": "permission-mode",
2783-
"titleZh": "选择询问、自动批准或完全访问权限模式,并确认高风险警告",
2784-
"titleEn": "Choose Ask, Auto-approve, or Full Access permission mode and acknowledge high-risk warnings",
2783+
"titleZh": "选择询问、自动审批或完全访问权限模式,并确认高风险警告",
2784+
"titleEn": "Choose Ask, Automatic approval, or Full Access permission mode and acknowledge high-risk warnings",
27852785
"reasonCode": "unstructuredInteraction",
2786-
"reasonZh": "“选择询问、自动批准或完全访问权限模式,并确认高风险警告”由多个实时状态相关步骤组成,目前没有一个能确定完成整个流程的单一结构化 Command;智能体会打开精确入口,并把后续交互保留在用户可见界面。",
2787-
"reasonEn": "“Choose Ask, Auto-approve, or Full Access permission mode and acknowledge high-risk warnings” spans multiple live-state-dependent steps and currently has no single structured Command that can deterministically complete the whole workflow; the Agent opens the exact entry and keeps the remaining interaction visible to the user.",
2786+
"reasonZh": "“选择询问、自动审批或完全访问权限模式,并确认高风险警告”由多个实时状态相关步骤组成,目前没有一个能确定完成整个流程的单一结构化 Command;智能体会打开精确入口,并把后续交互保留在用户可见界面。",
2787+
"reasonEn": "“Choose Ask, Automatic approval, or Full Access permission mode and acknowledge high-risk warnings” spans multiple live-state-dependent steps and currently has no single structured Command that can deterministically complete the whole workflow; the Agent opens the exact entry and keeps the remaining interaction visible to the user.",
27882788
"presentationTarget": {
27892789
"kind": "settings",
27902790
"pageId": "tools.execution",

‎docs/interactive-capabilities/technical/tauri-command-map.json‎

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"schemaVersion": 2,
33
"generatedFrom": "src/shared/interactive-capabilities/catalog.json",
4-
"catalogDigest": "5370adbf2ff3746a6d89704d38498047e3430850234e4abc1cd6bb5eea2aac49",
5-
"commandCount": 699,
4+
"catalogDigest": "778506ae9a8c979c4cea4de5c575be1bde0517def6ee5854dba203665098fa29",
5+
"commandCount": 702,
66
"coverage": {
7-
"commandCount": 699,
7+
"commandCount": 702,
88
"documentedCommandCount": 637,
9-
"implementationCommandCount": 62,
10-
"implementationDigest": "39288402985a24c84852570c8137b888b15b3d9e1b40448d974085b25c0fcf46"
9+
"implementationCommandCount": 65,
10+
"implementationDigest": "1e1e2b424a391bd866585162da35a043dcca3d6f67e0a770a8f8c886007b677a"
1111
},
1212
"commands": [
1313
{
@@ -1074,6 +1074,20 @@
10741074
"signature": "fn cleanup_invalid_workspaces( state: State<'_, AppState>, app: tauri::AppHandle, startup_trace: State<'_, DesktopStartupTrace>, ) -> Result<usize, String>",
10751075
"remoteWorkspacePolicy": "LegacyUnaudited"
10761076
},
1077+
{
1078+
"id": "clear_decision_model_credential",
1079+
"moduleId": "config",
1080+
"capabilityId": "setting.application.general",
1081+
"capabilityIds": [
1082+
"setting.application.general"
1083+
],
1084+
"documentedItemIds": [],
1085+
"visibility": "implementation",
1086+
"rustPath": "clear_decision_model_credential",
1087+
"sourceFile": "src/apps/desktop/src/api/config_api.rs",
1088+
"signature": "fn clear_decision_model_credential( _state: State<'_, AppState>, _request: GetDecisionModelCredentialStatusRequest, ) -> Result<openbitfun_core::service::decision_model::DecisionModelCredentialStatus, String>",
1089+
"remoteWorkspacePolicy": "WorkspaceAgnostic"
1090+
},
10771091
{
10781092
"id": "clear_mcp_remote_auth",
10791093
"moduleId": "mcp",
@@ -3107,6 +3121,20 @@
31073121
"signature": "fn get_custom_agent_detail( state: State<'_, AppState>, request: GetCustomAgentDetailRequest, ) -> Result<CustomAgentDetail, String>",
31083122
"remoteWorkspacePolicy": "LegacyUnaudited"
31093123
},
3124+
{
3125+
"id": "get_decision_model_credential_status",
3126+
"moduleId": "config",
3127+
"capabilityId": "setting.application.general",
3128+
"capabilityIds": [
3129+
"setting.application.general"
3130+
],
3131+
"documentedItemIds": [],
3132+
"visibility": "implementation",
3133+
"rustPath": "get_decision_model_credential_status",
3134+
"sourceFile": "src/apps/desktop/src/api/config_api.rs",
3135+
"signature": "fn get_decision_model_credential_status( _state: State<'_, AppState>, _request: GetDecisionModelCredentialStatusRequest, ) -> Result<openbitfun_core::service::decision_model::DecisionModelCredentialStatus, String>",
3136+
"remoteWorkspacePolicy": "WorkspaceAgnostic"
3137+
},
31103138
{
31113139
"id": "get_default_review_team_definition",
31123140
"moduleId": "agentic",
@@ -8606,6 +8634,20 @@
86068634
"signature": "fn save_cloud_speech_config( state: State<'_, AppState>, request: SaveCloudSpeechConfigRequest, ) -> Result<SaveCloudSpeechConfigResult, String>",
86078635
"remoteWorkspacePolicy": "WorkspaceAgnostic"
86088636
},
8637+
{
8638+
"id": "save_decision_model_credential",
8639+
"moduleId": "config",
8640+
"capabilityId": "setting.application.general",
8641+
"capabilityIds": [
8642+
"setting.application.general"
8643+
],
8644+
"documentedItemIds": [],
8645+
"visibility": "implementation",
8646+
"rustPath": "save_decision_model_credential",
8647+
"sourceFile": "src/apps/desktop/src/api/config_api.rs",
8648+
"signature": "fn save_decision_model_credential( _state: State<'_, AppState>, request: openbitfun_core::service::decision_model::SaveDecisionModelCredentialRequest, ) -> Result<openbitfun_core::service::decision_model::DecisionModelCredentialStatus, String>",
8649+
"remoteWorkspacePolicy": "WorkspaceAgnostic"
8650+
},
86098651
{
86108652
"id": "save_git_repo_history",
86118653
"moduleId": "git",

‎scripts/check-core-boundaries.test.mjs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ test('runtime-ports async dependencies stay behind their exact port owners', ()
640640
);
641641
assert.deepEqual(
642642
ownersByDependency.get('tokio-util'),
643-
new Set(['workspace-ports']),
643+
new Set(['permission', 'ts', 'workspace-ports']),
644644
);
645645
assert.deepEqual(
646646
ownersByDependency.get('tokio'),
@@ -815,7 +815,7 @@ const RUNTIME_PORT_FEATURE_PROFILES = {
815815
'agent-api': ['dep:openbitfun-core-types'],
816816
'git-port': [],
817817
'hook-function-runtime': [],
818-
permission: ['dep:openbitfun-product-domains'],
818+
permission: ['dep:openbitfun-product-domains', 'dep:tokio-util'],
819819
'plugin-runtime': [],
820820
'product-search': ['dep:openbitfun-product-domains'],
821821
'ptc-runtime': [],
@@ -827,6 +827,7 @@ const RUNTIME_PORT_FEATURE_PROFILES = {
827827
'tool-runtime-handles': ['workspace-ports', 'terminal-port', 'remote-exec-port'],
828828
ts: [
829829
'dep:ts-rs',
830+
'dep:tokio-util',
830831
'agent-api',
831832
'permission',
832833
'openbitfun-core-types/ts',
@@ -1914,6 +1915,7 @@ const CLI_REVIEWED_CORE_FEATURES = [
19141915
'workspace-icons',
19151916
'tools-pages',
19161917
...ACP_REVIEWED_CORE_FEATURES,
1918+
'decision-model-credentials',
19171919
'product-search',
19181920
'remote-connect',
19191921
'file-watch',

‎scripts/core-boundaries/cargo-dependency-boundaries.mjs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,7 @@ export function findProductEntrypointCoreFeatureViolations(
14561456
'workspace-icons',
14571457
'tools-pages',
14581458
...coreCompatibilityReviewedFeatures,
1459+
'decision-model-credentials',
14591460
'product-search',
14601461
'remote-connect',
14611462
// The CLI Peer Host answers `start_file_watch` / `stop_file_watch` for an
@@ -1529,6 +1530,7 @@ export function findProductEntrypointCoreFeatureViolations(
15291530
'workspace-icons',
15301531
'tools-pages',
15311532
...acpActiveCoreFeatures,
1533+
'decision-model-credentials',
15321534
'i18n-runtime',
15331535
'plugin-runtime',
15341536
'product-search',

‎scripts/core-boundaries/rules/feature-rules.mjs‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export const optionalDependencyFeatureOwnerRules = [
127127
{ depName: 'openbitfun-core-types', ownerFeatures: ['agent-api', 'remote-workspace-ports', 'ts'] },
128128
{ depName: 'openbitfun-product-domains', ownerFeatures: ['permission', 'product-search', 'ts'] },
129129
{ depName: 'tokio', ownerFeatures: ['remote-exec-port', 'terminal-port', 'workspace-ports'] },
130-
{ depName: 'tokio-util', ownerFeatures: ['workspace-ports'] },
130+
{ depName: 'tokio-util', ownerFeatures: ['permission', 'ts', 'workspace-ports'] },
131131
{ depName: 'ts-rs', ownerFeatures: ['ts'] },
132132
],
133133
},
@@ -405,7 +405,7 @@ export const capabilityContractDependencyRules = [
405405
'agent-api': ['dep:openbitfun-core-types'],
406406
'git-port': [],
407407
'hook-function-runtime': [],
408-
permission: ['dep:openbitfun-product-domains'],
408+
permission: ['dep:openbitfun-product-domains', 'dep:tokio-util'],
409409
'plugin-runtime': [],
410410
'product-search': ['dep:openbitfun-product-domains'],
411411
'ptc-runtime': [],
@@ -418,6 +418,7 @@ export const capabilityContractDependencyRules = [
418418
'web-search-port': [],
419419
ts: [
420420
'dep:ts-rs',
421+
'dep:tokio-util',
421422
'agent-api',
422423
'permission',
423424
'openbitfun-core-types/ts',
@@ -481,6 +482,9 @@ export const capabilityContractDependencyRules = [
481482
capabilityEdge(['hook-function-runtime', 'plugin-runtime']),
482483
capabilityEdge(['script-tool-runtime'], { kind: 'dev' }),
483484
])],
485+
['openbitfun-ai-adapters', capabilityConsumer([
486+
capabilityEdge(['permission']),
487+
])],
484488
['openbitfun-opencode-plugin-host', capabilityConsumer([
485489
capabilityEdge(['hook-function-runtime']),
486490
])],
@@ -729,6 +733,7 @@ export const coreProductFullFeatureAssemblyRule = {
729733
featureName: 'product-full',
730734
requiredFeatureRefs: [
731735
'agent-runtime',
736+
'decision-model-credentials',
732737
'product-search',
733738
'diagnostics',
734739
'diff',
@@ -955,6 +960,13 @@ export const coreClosedFeatureProfileRules = [
955960
reason:
956961
'openbitfun-core agent-runtime is the reviewed Core Agent Runtime owner closure, not a product-full alias',
957962
},
963+
{
964+
manifestPath: 'src/crates/assembly/core/Cargo.toml',
965+
featureName: 'decision-model-credentials',
966+
requiredFeatureRefs: ['openbitfun-services-core/credential-vault'],
967+
exact: true,
968+
reason: 'decision-model-credentials must be the only Core owner of decision-model secrets',
969+
},
958970
{
959971
manifestPath: 'src/crates/assembly/core/Cargo.toml',
960972
featureName: 'product-search',

‎src/apps/cli/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ openbitfun-computer-use = { path = "../../crates/services/computer-use" }
3333
# Internal crates
3434
openbitfun-core = { path = "../../crates/assembly/core", features = [
3535
"agent-runtime",
36+
"decision-model-credentials",
3637
"workspace-icons",
3738
"product-search",
3839
"document-read",

0 commit comments

Comments
 (0)