dsh-approval-review 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,127 @@
1
+ # dsh-approval-review bundle layer.
2
+ #
3
+ # A YAML array of row verbs; `insert` adds plugin rows to the composed config.
4
+ # A row's `id` is unique within the layer stack, and `name` resolves the plugin
5
+ # module through the installed package (`package.json#main`).
6
+ #
7
+ # Layer semantics: an id-targeted override REPLACES this whole config row, so a
8
+ # deployment that overrides any key must restate every key it still wants.
9
+ # Dropping `reviewTools` returns the tool table to its schema default, and
10
+ # dropping `defaultPolicy` returns unlisted tools to `human` — i.e. back to the
11
+ # ordinary approval prompt.
12
+ - insert:
13
+ - id: approval-review
14
+ name: dsh-approval-review
15
+ config:
16
+ # Master switch. `false` mounts the plugin but claims nothing; the
17
+ # per-session `/approval-review on|off` switch is the runtime lever.
18
+ enabled: true
19
+ # Session-start default for that switch.
20
+ enabledByDefault: true
21
+ # Tool names routed to the reviewer model. Everything else falls through
22
+ # to `defaultPolicy`, whose default delegates to the human answerer.
23
+ # `edit` is deliberately absent: in-place modification of an existing
24
+ # file is the highest-consequence routine action, so it keeps the human
25
+ # prompt until a deployment decides otherwise.
26
+ reviewTools:
27
+ - bash
28
+ - pwsh
29
+ - write
30
+ defaultPolicy: human
31
+ # Ordered regex rules, evaluated before the tool table. `field` selects
32
+ # what the pattern is matched against: `reason` (default), `toolName`, or
33
+ # `arguments`.
34
+ rules: []
35
+ # Reviewer model, prompt, and size limits. `provider`/`model` unset means
36
+ # the reviewer inherits the calling agent's own route.
37
+ reviewer:
38
+ timeoutMs: 60000
39
+ maxTokens: 1024
40
+ temperature: 0
41
+ argumentMaxChars: 4000
42
+ argumentsBudgetChars: 16000
43
+ # policyText: | # replaces the shipping ruling policy
44
+ # <your policy wording>
45
+ # guidance: <extra deployment-specific guidance>
46
+ # Transcript evidence handed to the reviewer; `turns: 0` sends none.
47
+ context:
48
+ turns: 2
49
+ maxChars: 6000
50
+ includeAssistant: true
51
+ includeToolActivity: true
52
+ # Risk gate: an allow verdict above this grade is not auto-allowed.
53
+ maxAutoAllowRisk: medium
54
+ onRiskExceeded: delegate
55
+ # Reviewer said it could not decide.
56
+ onUncertain: delegate
57
+ # Reviewer crashed, timed out, or answered off-schema. `rejected` is the
58
+ # fail-closed stance; `delegate` hands the request to the human chain.
59
+ onReviewerFailure: rejected
60
+ # Per-turn reviewer budget, so a loop cannot bill unlimited reviews.
61
+ budget:
62
+ maxReviewsPerTurn: 20
63
+ onExhausted: delegate
64
+ # Rejection circuit breaker, matching Codex's per-turn denial breaker:
65
+ # stop escalating after repeated refusals instead of looping.
66
+ circuitBreaker:
67
+ consecutiveDenials: 3
68
+ windowDenials: 10
69
+ windowSize: 50
70
+ action: delegate
71
+ # One-shot `/approval-review approve [n]` authorization.
72
+ override:
73
+ ttlMs: 300000
74
+ maxPending: 10
75
+ reasonMaxChars: 2000
76
+ # Append the reviewer's rationale to the refused tool result the model
77
+ # reads. This is also what makes the card's rationale durable, so turning
78
+ # it off costs the model its explanation AND the card its reason line.
79
+ feedReasonToModel: true
80
+ # Append the ALLOW verdict to the accepted tool result. An approval
81
+ # outcome is a closed vocabulary, so the tool result is the only channel
82
+ # this plugin can write durably without inventing a session event type;
83
+ # without it an allowed row shows THAT an action ran but never WHY. The
84
+ # cost is one short marker block in the model's context per auto-allowed
85
+ # call; turning it off empties the "rationale" line of allowed rows.
86
+ recordAllowedVerdicts: true
87
+ language: en
88
+
89
+ # --- "Approve for me" as a PEER access-mode option -------------------------
90
+ #
91
+ # The access-mode menu is data-driven from this table, so a fourth entry shows up
92
+ # beside 仅可查看 / 工作区内修改 / 完全权限 with no client change.
93
+ #
94
+ # Why this works even though the bundle is identical to `workspace-write`:
95
+ # `PermissionPresetService.derive()` checks the RECORDED selection first and
96
+ # returns it when its knobs still match, so the remembered preset key wins over
97
+ # the first table match. Selecting "Approve for me" therefore stays selected.
98
+ #
99
+ # An id-targeted override REPLACES the whole row, so the shipped three entries
100
+ # must be restated here verbatim.
101
+ - id: permission
102
+ config:
103
+ presets:
104
+ read-only:
105
+ sandbox: read-only
106
+ approval: ask
107
+ name: 仅可查看
108
+ description: 只能读取,任何修改都需要批准。
109
+ workspace-write:
110
+ sandbox: workspace-write
111
+ approval: ask
112
+ name: 工作区内修改
113
+ description: 可在工作区与临时目录内修改;更宽的操作需要批准。
114
+ danger-full-access:
115
+ sandbox: danger-full-access
116
+ approval: never
117
+ name: 完全权限
118
+ description: 不受限的文件与网络访问,不再弹审批。
119
+ # The fourth peer option. Its knobs deliberately match `workspace-write`:
120
+ # the difference is WHO answers the approval — this plugin's reviewer
121
+ # instead of a human prompt. `dsh-approval-review` only claims requests
122
+ # while this preset is the active one.
123
+ approve-for-me:
124
+ sandbox: workspace-write
125
+ approval: ask
126
+ name: 替我审批
127
+ description: 与"工作区内修改"相同的边界,但需要批准的动作先交给复核模型,只有危险或不确定的才转人工。