dsh-permission-rules 0.7.21 → 0.7.22
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.
- package/CHANGELOG.md +7 -0
- package/README.en.md +504 -0
- package/README.es.md +504 -0
- package/README.hi.md +504 -0
- package/README.md +309 -245
- package/README.pt.md +504 -0
- package/docs/assets/dsh-permission-rules-flow-dark.svg +58 -0
- package/docs/assets/dsh-permission-rules-flow-light.svg +58 -0
- package/docs/assets/dsh-permission-rules-flow-v5-dark.svg +103 -0
- package/docs/assets/dsh-permission-rules-flow-v5-light.svg +103 -0
- package/docs/assets/dsh-permission-rules-hero-en-dark.webp +0 -0
- package/docs/assets/dsh-permission-rules-hero-en-light.webp +0 -0
- package/docs/assets/dsh-permission-rules-hero-zh-dark.webp +0 -0
- package/docs/assets/dsh-permission-rules-hero-zh-light.webp +0 -0
- package/docs/rules-format.en.md +5 -4
- package/docs/rules-format.md +5 -4
- package/lib/index.js +230 -40
- package/lib/types/config.d.ts +9 -4
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/prose.d.ts +6 -0
- package/lib/types/prose.d.ts.map +1 -1
- package/lib/types/rules.d.ts +74 -15
- package/lib/types/rules.d.ts.map +1 -1
- package/lib/types/runtime.d.ts +59 -12
- package/lib/types/runtime.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +9 -4
- package/src/prose.ts +21 -0
- package/src/rules.ts +131 -24
- package/src/runtime.ts +140 -24
- package/README-es.md +0 -443
- package/README-hi.md +0 -445
- package/README-pt.md +0 -443
- package/README-zh.md +0 -443
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="440" viewBox="0 0 1200 440" role="img" aria-label="dsh-permission-rules data flow">
|
|
2
|
+
<title>dsh-permission-rules data flow</title>
|
|
3
|
+
<rect width="1200" height="440" rx="18" fill="#ffffff"/>
|
|
4
|
+
<text x="56" y="60" fill="#1f2328" font-family="ui-sans-serif,system-ui,sans-serif" font-size="30" font-weight="700">dsh-permission-rules</text>
|
|
5
|
+
<text x="56" y="94" fill="#57606a" font-family="ui-monospace,monospace" font-size="15">tools/pre-execute · ordered allow / deny / ask · YAML</text>
|
|
6
|
+
<line x1="56" y1="118" x2="1144" y2="118" stroke="#d0d7de"/>
|
|
7
|
+
<rect x="30" y="140" width="130" height="104" rx="14" fill="#f6f8fa" stroke="#d0d7de" stroke-width="2"/>
|
|
8
|
+
<text x="95" y="180" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="14" font-weight="700">tool call</text>
|
|
9
|
+
<text x="95" y="208" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">arguments</text>
|
|
10
|
+
<path d="M169 192H182" stroke="#57606a" stroke-width="2.5"/>
|
|
11
|
+
<path d="M176 186l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
|
+
<rect x="196" y="140" width="145" height="104" rx="14" fill="#f6f8fa" stroke="#4B67B4" stroke-width="2"/>
|
|
13
|
+
<text x="268" y="180" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="13" font-weight="700">tools/pre-execute</text>
|
|
14
|
+
<text x="268" y="208" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">waterfall</text>
|
|
15
|
+
<path d="M350 192H363" stroke="#57606a" stroke-width="2.5"/>
|
|
16
|
+
<path d="M357 186l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
17
|
+
<rect x="377" y="140" width="145" height="104" rx="14" fill="#f6f8fa" stroke="#4B67B4" stroke-width="2"/>
|
|
18
|
+
<text x="449" y="180" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12" font-weight="700">.dsh/rules.yaml</text>
|
|
19
|
+
<text x="449" y="208" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">first match wins</text>
|
|
20
|
+
<path d="M531 192H544" stroke="#57606a" stroke-width="2.5"/>
|
|
21
|
+
<path d="M538 186l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
22
|
+
<rect x="558" y="140" width="190" height="104" rx="14" fill="#f6f8fa" stroke="#d0d7de" stroke-width="2"/>
|
|
23
|
+
<text x="653" y="180" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12" font-weight="700">allow · ask · deny</text>
|
|
24
|
+
<text x="653" y="208" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">next() · approval · reason</text>
|
|
25
|
+
<path d="M757 192H770" stroke="#57606a" stroke-width="2.5"/>
|
|
26
|
+
<path d="M764 186l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
27
|
+
<rect x="784" y="140" width="215" height="104" rx="14" fill="#f6f8fa" stroke="{'light': '#16a34a', 'dark': '#3fb950'}" stroke-width="2"/>
|
|
28
|
+
<text x="891" y="180" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="13" font-weight="700">permissionRules/decision</text>
|
|
29
|
+
<text x="891" y="208" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">audit · log-only</text>
|
|
30
|
+
<path d="M1008 192H1021" stroke="#57606a" stroke-width="2.5"/>
|
|
31
|
+
<path d="M1015 186l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
32
|
+
<rect x="1035" y="140" width="135" height="104" rx="14" fill="#f6f8fa" stroke="#d0d7de" stroke-width="2"/>
|
|
33
|
+
<text x="1102" y="180" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="13" font-weight="700">session log</text>
|
|
34
|
+
<text x="1102" y="208" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">ignorable</text>
|
|
35
|
+
<circle cx="627" cy="224" r="4.5" fill="#16a34a"/>
|
|
36
|
+
<circle cx="653" cy="224" r="4.5" fill="#bc4c00"/>
|
|
37
|
+
<circle cx="679" cy="224" r="4.5" fill="#dc2626"/>
|
|
38
|
+
<text x="56" y="278" fill="#57606a" font-family="ui-monospace,monospace" font-size="12">network policy</text>
|
|
39
|
+
<rect x="81" y="296" width="220" height="84" rx="12" fill="#f6f8fa" stroke="#d0d7de" stroke-width="1.5"/>
|
|
40
|
+
<text x="191" y="330" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="11.5" font-weight="700">shell child</text>
|
|
41
|
+
<text x="191" y="354" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">spawned process</text>
|
|
42
|
+
<path d="M309 338H339" stroke="#57606a" stroke-width="2.5"/>
|
|
43
|
+
<path d="M333 332l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
44
|
+
<rect x="357" y="296" width="220" height="84" rx="12" fill="#f6f8fa" stroke="#d0d7de" stroke-width="1.5"/>
|
|
45
|
+
<text x="467" y="330" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="11.5" font-weight="700">HTTP/CONNECT proxy</text>
|
|
46
|
+
<text x="467" y="354" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">127.0.0.1 · proxyPort</text>
|
|
47
|
+
<path d="M585 338H615" stroke="#57606a" stroke-width="2.5"/>
|
|
48
|
+
<path d="M609 332l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
49
|
+
<rect x="633" y="296" width="230" height="84" rx="12" fill="#f6f8fa" stroke="#d0d7de" stroke-width="1.5"/>
|
|
50
|
+
<text x="748" y="330" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="11.5" font-weight="700">domains · ips · ports · schemes</text>
|
|
51
|
+
<text x="748" y="354" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">network rules or mode</text>
|
|
52
|
+
<path d="M871 338H901" stroke="#57606a" stroke-width="2.5"/>
|
|
53
|
+
<path d="M895 332l7 6-7 6" fill="none" stroke="#57606a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
54
|
+
<rect x="919" y="296" width="200" height="84" rx="12" fill="#f6f8fa" stroke="#d0d7de" stroke-width="1.5"/>
|
|
55
|
+
<text x="1019" y="330" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="11.5" font-weight="700">403 · upstream</text>
|
|
56
|
+
<text x="1019" y="354" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="10.5">blocked | allowed</text>
|
|
57
|
+
<text x="56" y="418" fill="#57606a" font-family="ui-monospace,monospace" font-size="12">builtin · searchUp · watch · enforce: false · /rules test · /rules reload</text>
|
|
58
|
+
</svg>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1100" height="660" viewBox="0 0 1100 660" role="img" aria-labelledby="fig-title">
|
|
2
|
+
<title id="fig-title">dsh-permission-rules — dual-channel adjudication: tool calls and shell egress converge on one ordered rule chain, fork into two verdict banks, and close on two log-only audit events</title>
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#131a2a"/><stop offset="1" stop-color="#0c1016"/></linearGradient>
|
|
5
|
+
<filter id="soft" x="-30%" y="-30%" width="170%" height="185%"><feDropShadow dx="0" dy="8" stdDeviation="11" flood-color="#1b1735" flood-opacity="0.50"/></filter>
|
|
6
|
+
<marker id="arr" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0.5 0.5 L9.5 5 L0.5 9.5 z" fill="#8496f5"/></marker>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="1100" height="660" fill="url(#bg)"/>
|
|
9
|
+
<circle cx="1000" cy="80" r="230" fill="#8496f5" opacity="0.1"/>
|
|
10
|
+
<text x="44" y="52" fill="#eef2fa" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="23" font-weight="700" text-anchor="start">dsh-permission-rules · dual-channel adjudication</text>
|
|
11
|
+
<text x="44" y="80" fill="#a8b1c4" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="15" font-weight="400" text-anchor="start">tool calls and shell egress → one ordered rule chain → two log-only audit events</text>
|
|
12
|
+
<text x="1056" y="50" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">src/runtime.ts · src/rules.ts · src/proxy.ts</text>
|
|
13
|
+
<text x="1056" y="74" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">first match wins · enforce: false = dry-run</text>
|
|
14
|
+
<line x1="44" y1="96" x2="1056" y2="96" stroke="#242c3d" stroke-width="1.5" stroke-linecap="round"/>
|
|
15
|
+
<g filter="url(#soft)"><rect x="44" y="110" width="196" height="96" rx="16" fill="#1b2231" stroke="#2d364a" stroke-width="1.5"/></g>
|
|
16
|
+
<text x="64" y="138" fill="#eef2fa" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="17" font-weight="600" text-anchor="start">tool call</text>
|
|
17
|
+
<text x="64" y="162" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">name · params</text>
|
|
18
|
+
<text x="64" y="184" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">cwd · agent · env</text>
|
|
19
|
+
<g filter="url(#soft)"><rect x="44" y="330" width="196" height="96" rx="16" fill="#1b2231" stroke="#2d364a" stroke-width="1.5"/></g>
|
|
20
|
+
<text x="64" y="358" fill="#eef2fa" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="17" font-weight="600" text-anchor="start">shell child</text>
|
|
21
|
+
<text x="64" y="382" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">bash / pwsh</text>
|
|
22
|
+
<text x="64" y="404" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">HTTP · CONNECT</text>
|
|
23
|
+
<rect x="254" y="132" width="104" height="54" rx="14" fill="#232b40" stroke="#3c476f" stroke-width="1.2"/>
|
|
24
|
+
<text x="306" y="155" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="middle">waterfall</text>
|
|
25
|
+
<text x="306" y="177" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">pre-execute</text>
|
|
26
|
+
<rect x="254" y="352" width="104" height="54" rx="14" fill="#232b40" stroke="#3c476f" stroke-width="1.2"/>
|
|
27
|
+
<text x="306" y="375" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="middle">local proxy</text>
|
|
28
|
+
<text x="306" y="397" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">CONNECT</text>
|
|
29
|
+
<line x1="240" y1="158" x2="250" y2="158" stroke="#8496f5" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
30
|
+
<line x1="240" y1="378" x2="250" y2="378" stroke="#8496f5" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
31
|
+
<path d="M 358 158 H 364 M 358 378 H 364 M 364 158 V 378" fill="none" stroke="#8496f5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
32
|
+
<line x1="364" y1="280" x2="376" y2="280" stroke="#8496f5" stroke-width="2.4" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
33
|
+
<rect x="376" y="100" width="348" height="420" rx="18" fill="#1b2231" stroke="#3f4a75" stroke-width="1.6"/>
|
|
34
|
+
<text x="396" y="132" fill="#eef2fa" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="18" font-weight="700" text-anchor="start">ordered rule chain</text>
|
|
35
|
+
<text x="704" y="132" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">first match wins</text>
|
|
36
|
+
<line x1="396" y1="146" x2="704" y2="146" stroke="#242c3d" stroke-width="1.5" stroke-linecap="round"/>
|
|
37
|
+
<text x="396" y="170" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">.dsh/rules.yaml · searchUp</text>
|
|
38
|
+
<text x="396" y="192" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">nearest file first · fallbackPath</text>
|
|
39
|
+
<text x="396" y="214" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">builtin 16 rules</text>
|
|
40
|
+
<text x="704" y="214" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">appended last</text>
|
|
41
|
+
<line x1="396" y1="228" x2="704" y2="228" stroke="#242c3d" stroke-width="1.5" stroke-linecap="round"/>
|
|
42
|
+
<rect x="388" y="240" width="328" height="42" rx="12" fill="#2c2a39"/>
|
|
43
|
+
<text x="396" y="256" fill="#f08a9c" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">01</text>
|
|
44
|
+
<text x="420" y="255" fill="#eef2fa" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">bash · git push*</text>
|
|
45
|
+
<text x="420" y="273" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">paths **/secrets/**</text>
|
|
46
|
+
<rect x="644" y="246" width="60" height="26" rx="13" fill="#38303f"/>
|
|
47
|
+
<text x="674" y="264" fill="#f08a9c" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">deny</text>
|
|
48
|
+
<text x="396" y="302" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">02</text>
|
|
49
|
+
<text x="420" y="301" fill="#eef2fa" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="400" text-anchor="start">edit, write</text>
|
|
50
|
+
<text x="420" y="319" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tools glob</text>
|
|
51
|
+
<rect x="644" y="292" width="60" height="26" rx="13" fill="#363536"/>
|
|
52
|
+
<text x="674" y="310" fill="#e2ae57" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">ask</text>
|
|
53
|
+
<text x="396" y="348" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">03</text>
|
|
54
|
+
<text x="420" y="347" fill="#eef2fa" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="400" text-anchor="start">mcp__*</text>
|
|
55
|
+
<text x="420" y="365" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tools glob · namespaced</text>
|
|
56
|
+
<rect x="644" y="338" width="60" height="26" rx="13" fill="#263a42"/>
|
|
57
|
+
<text x="674" y="356" fill="#6fd3ac" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">allow</text>
|
|
58
|
+
<text x="396" y="394" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">04</text>
|
|
59
|
+
<text x="420" y="393" fill="#eef2fa" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="400" text-anchor="start">rm -rf /</text>
|
|
60
|
+
<text x="420" y="411" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">argv · builtin</text>
|
|
61
|
+
<rect x="644" y="384" width="60" height="26" rx="13" fill="#38303f"/>
|
|
62
|
+
<text x="674" y="402" fill="#f08a9c" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">deny</text>
|
|
63
|
+
<text x="396" y="440" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">later rules are not evaluated</text>
|
|
64
|
+
<text x="396" y="464" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">match dimensions</text>
|
|
65
|
+
<text x="396" y="486" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tools · agents · params · paths</text>
|
|
66
|
+
<text x="396" y="508" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">argv · when · network</text>
|
|
67
|
+
<g filter="url(#soft)"><rect x="752" y="110" width="312" height="182" rx="16" fill="#1b2231" stroke="#2d364a" stroke-width="1.5"/></g>
|
|
68
|
+
<text x="772" y="134" fill="#eef2fa" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="15" font-weight="700" text-anchor="start">tool call verdicts</text>
|
|
69
|
+
<text x="1044" y="134" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">3 verdicts</text>
|
|
70
|
+
<text x="772" y="166" fill="#6fd3ac" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">allow</text>
|
|
71
|
+
<text x="826" y="166" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ next()</text>
|
|
72
|
+
<text x="772" y="186" fill="#a8b1c4" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">delegates · never short-circuits</text>
|
|
73
|
+
<text x="772" y="214" fill="#e2ae57" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">ask</text>
|
|
74
|
+
<text x="809" y="214" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ approval seam</text>
|
|
75
|
+
<text x="772" y="234" fill="#a8b1c4" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">auto-review or human · fail closed</text>
|
|
76
|
+
<text x="772" y="262" fill="#f08a9c" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">deny</text>
|
|
77
|
+
<text x="818" y="262" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ reason</text>
|
|
78
|
+
<text x="772" y="282" fill="#a8b1c4" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">reason becomes the tool error</text>
|
|
79
|
+
<g filter="url(#soft)"><rect x="752" y="326" width="312" height="182" rx="16" fill="#1b2231" stroke="#2d364a" stroke-width="1.5"/></g>
|
|
80
|
+
<text x="772" y="350" fill="#eef2fa" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="15" font-weight="700" text-anchor="start">network egress</text>
|
|
81
|
+
<text x="1044" y="350" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">proxy</text>
|
|
82
|
+
<text x="772" y="382" fill="#6fd3ac" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">allow</text>
|
|
83
|
+
<text x="826" y="382" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ connect(adjudicated)</text>
|
|
84
|
+
<text x="772" y="402" fill="#a8b1c4" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">no second DNS resolution</text>
|
|
85
|
+
<text x="772" y="430" fill="#f08a9c" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">deny</text>
|
|
86
|
+
<text x="818" y="430" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ structured 403</text>
|
|
87
|
+
<text x="772" y="450" fill="#a8b1c4" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">never reaches upstream</text>
|
|
88
|
+
<text x="772" y="478" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">upstream</text>
|
|
89
|
+
<text x="850" y="478" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ allowed only</text>
|
|
90
|
+
<text x="772" y="498" fill="#a8b1c4" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">loopback / ips-scoped never chained</text>
|
|
91
|
+
<line x1="728" y1="280" x2="740" y2="280" stroke="#8496f5" stroke-width="2" stroke-linecap="round"/>
|
|
92
|
+
<path d="M 740 201 V 417" fill="none" stroke="#8496f5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
93
|
+
<line x1="740" y1="201" x2="752" y2="201" stroke="#8496f5" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
94
|
+
<line x1="740" y1="417" x2="752" y2="417" stroke="#8496f5" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
95
|
+
<g filter="url(#soft)"><rect x="44" y="544" width="1020" height="66" rx="16" fill="#1b2231" stroke="#2d364a" stroke-width="1.5"/></g>
|
|
96
|
+
<text x="64" y="570" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">permissionRules/decision</text>
|
|
97
|
+
<text x="280" y="570" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tool · action · outcome · dryRun</text>
|
|
98
|
+
<text x="1044" y="570" fill="#f08a9c" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="700" text-anchor="end">log-only · never in model context</text>
|
|
99
|
+
<text x="64" y="594" fill="#8496f5" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">permissionRules/network</text>
|
|
100
|
+
<text x="280" y="594" fill="#a8b1c4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">domain · port · mode · action</text>
|
|
101
|
+
<text x="1044" y="594" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">ignorable · session log</text>
|
|
102
|
+
<text x="44" y="640" fill="#737d92" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">Apache-2.0 · PerryLink DSH plugin family · first match wins · fail closed</text>
|
|
103
|
+
</svg>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1100" height="660" viewBox="0 0 1100 660" role="img" aria-labelledby="fig-title">
|
|
2
|
+
<title id="fig-title">dsh-permission-rules — dual-channel adjudication: tool calls and shell egress converge on one ordered rule chain, fork into two verdict banks, and close on two log-only audit events</title>
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#f9f6fd"/><stop offset="1" stop-color="#e4eaf8"/></linearGradient>
|
|
5
|
+
<filter id="soft" x="-30%" y="-30%" width="170%" height="185%"><feDropShadow dx="0" dy="8" stdDeviation="11" flood-color="#1b1735" flood-opacity="0.14"/></filter>
|
|
6
|
+
<marker id="arr" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0.5 0.5 L9.5 5 L0.5 9.5 z" fill="#4B67B4"/></marker>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="1100" height="660" fill="url(#bg)"/>
|
|
9
|
+
<circle cx="1000" cy="80" r="230" fill="#4B67B4" opacity="0.05"/>
|
|
10
|
+
<text x="44" y="52" fill="#17151f" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="23" font-weight="700" text-anchor="start">dsh-permission-rules · dual-channel adjudication</text>
|
|
11
|
+
<text x="44" y="80" fill="#4c5160" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="15" font-weight="400" text-anchor="start">tool calls and shell egress → one ordered rule chain → two log-only audit events</text>
|
|
12
|
+
<text x="1056" y="50" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">src/runtime.ts · src/rules.ts · src/proxy.ts</text>
|
|
13
|
+
<text x="1056" y="74" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">first match wins · enforce: false = dry-run</text>
|
|
14
|
+
<line x1="44" y1="96" x2="1056" y2="96" stroke="#ece8f5" stroke-width="1.5" stroke-linecap="round"/>
|
|
15
|
+
<g filter="url(#soft)"><rect x="44" y="110" width="196" height="96" rx="16" fill="#ffffff" stroke="#e5e0f2" stroke-width="1.5"/></g>
|
|
16
|
+
<text x="64" y="138" fill="#17151f" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="17" font-weight="600" text-anchor="start">tool call</text>
|
|
17
|
+
<text x="64" y="162" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">name · params</text>
|
|
18
|
+
<text x="64" y="184" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">cwd · agent · env</text>
|
|
19
|
+
<g filter="url(#soft)"><rect x="44" y="330" width="196" height="96" rx="16" fill="#ffffff" stroke="#e5e0f2" stroke-width="1.5"/></g>
|
|
20
|
+
<text x="64" y="358" fill="#17151f" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="17" font-weight="600" text-anchor="start">shell child</text>
|
|
21
|
+
<text x="64" y="382" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">bash / pwsh</text>
|
|
22
|
+
<text x="64" y="404" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">HTTP · CONNECT</text>
|
|
23
|
+
<rect x="254" y="132" width="104" height="54" rx="14" fill="#f0f2f9" stroke="#c5cee6" stroke-width="1.2"/>
|
|
24
|
+
<text x="306" y="155" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="middle">waterfall</text>
|
|
25
|
+
<text x="306" y="177" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">pre-execute</text>
|
|
26
|
+
<rect x="254" y="352" width="104" height="54" rx="14" fill="#f0f2f9" stroke="#c5cee6" stroke-width="1.2"/>
|
|
27
|
+
<text x="306" y="375" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="middle">local proxy</text>
|
|
28
|
+
<text x="306" y="397" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">CONNECT</text>
|
|
29
|
+
<line x1="240" y1="158" x2="250" y2="158" stroke="#4B67B4" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
30
|
+
<line x1="240" y1="378" x2="250" y2="378" stroke="#4B67B4" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
31
|
+
<path d="M 358 158 H 364 M 358 378 H 364 M 364 158 V 378" fill="none" stroke="#4B67B4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
32
|
+
<line x1="364" y1="280" x2="376" y2="280" stroke="#4B67B4" stroke-width="2.4" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
33
|
+
<rect x="376" y="100" width="348" height="420" rx="18" fill="#ffffff" stroke="#c0c9e4" stroke-width="1.6"/>
|
|
34
|
+
<text x="396" y="132" fill="#17151f" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="18" font-weight="700" text-anchor="start">ordered rule chain</text>
|
|
35
|
+
<text x="704" y="132" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">first match wins</text>
|
|
36
|
+
<line x1="396" y1="146" x2="704" y2="146" stroke="#ece8f5" stroke-width="1.5" stroke-linecap="round"/>
|
|
37
|
+
<text x="396" y="170" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">.dsh/rules.yaml · searchUp</text>
|
|
38
|
+
<text x="396" y="192" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">nearest file first · fallbackPath</text>
|
|
39
|
+
<text x="396" y="214" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">builtin 16 rules</text>
|
|
40
|
+
<text x="704" y="214" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">appended last</text>
|
|
41
|
+
<line x1="396" y1="228" x2="704" y2="228" stroke="#ece8f5" stroke-width="1.5" stroke-linecap="round"/>
|
|
42
|
+
<rect x="388" y="240" width="328" height="42" rx="12" fill="#f8eff0"/>
|
|
43
|
+
<text x="396" y="256" fill="#ad3a4e" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">01</text>
|
|
44
|
+
<text x="420" y="255" fill="#17151f" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">bash · git push*</text>
|
|
45
|
+
<text x="420" y="273" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">paths **/secrets/**</text>
|
|
46
|
+
<rect x="644" y="246" width="60" height="26" rx="13" fill="#f3e3e6"/>
|
|
47
|
+
<text x="674" y="264" fill="#ad3a4e" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">deny</text>
|
|
48
|
+
<text x="396" y="302" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">02</text>
|
|
49
|
+
<text x="420" y="301" fill="#17151f" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="400" text-anchor="start">edit, write</text>
|
|
50
|
+
<text x="420" y="319" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tools glob</text>
|
|
51
|
+
<rect x="644" y="292" width="60" height="26" rx="13" fill="#f2e9de"/>
|
|
52
|
+
<text x="674" y="310" fill="#a3681a" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">ask</text>
|
|
53
|
+
<text x="396" y="348" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">03</text>
|
|
54
|
+
<text x="420" y="347" fill="#17151f" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="400" text-anchor="start">mcp__*</text>
|
|
55
|
+
<text x="420" y="365" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tools glob · namespaced</text>
|
|
56
|
+
<rect x="644" y="338" width="60" height="26" rx="13" fill="#e0ece8"/>
|
|
57
|
+
<text x="674" y="356" fill="#24785f" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">allow</text>
|
|
58
|
+
<text x="396" y="394" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">04</text>
|
|
59
|
+
<text x="420" y="393" fill="#17151f" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="400" text-anchor="start">rm -rf /</text>
|
|
60
|
+
<text x="420" y="411" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">argv · builtin</text>
|
|
61
|
+
<rect x="644" y="384" width="60" height="26" rx="13" fill="#f3e3e6"/>
|
|
62
|
+
<text x="674" y="402" fill="#ad3a4e" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="700" text-anchor="middle">deny</text>
|
|
63
|
+
<text x="396" y="440" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">later rules are not evaluated</text>
|
|
64
|
+
<text x="396" y="464" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">match dimensions</text>
|
|
65
|
+
<text x="396" y="486" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tools · agents · params · paths</text>
|
|
66
|
+
<text x="396" y="508" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">argv · when · network</text>
|
|
67
|
+
<g filter="url(#soft)"><rect x="752" y="110" width="312" height="182" rx="16" fill="#ffffff" stroke="#e5e0f2" stroke-width="1.5"/></g>
|
|
68
|
+
<text x="772" y="134" fill="#17151f" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="15" font-weight="700" text-anchor="start">tool call verdicts</text>
|
|
69
|
+
<text x="1044" y="134" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">3 verdicts</text>
|
|
70
|
+
<text x="772" y="166" fill="#24785f" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">allow</text>
|
|
71
|
+
<text x="826" y="166" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ next()</text>
|
|
72
|
+
<text x="772" y="186" fill="#4c5160" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">delegates · never short-circuits</text>
|
|
73
|
+
<text x="772" y="214" fill="#a3681a" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">ask</text>
|
|
74
|
+
<text x="809" y="214" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ approval seam</text>
|
|
75
|
+
<text x="772" y="234" fill="#4c5160" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">auto-review or human · fail closed</text>
|
|
76
|
+
<text x="772" y="262" fill="#ad3a4e" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">deny</text>
|
|
77
|
+
<text x="818" y="262" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ reason</text>
|
|
78
|
+
<text x="772" y="282" fill="#4c5160" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">reason becomes the tool error</text>
|
|
79
|
+
<g filter="url(#soft)"><rect x="752" y="326" width="312" height="182" rx="16" fill="#ffffff" stroke="#e5e0f2" stroke-width="1.5"/></g>
|
|
80
|
+
<text x="772" y="350" fill="#17151f" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="15" font-weight="700" text-anchor="start">network egress</text>
|
|
81
|
+
<text x="1044" y="350" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">proxy</text>
|
|
82
|
+
<text x="772" y="382" fill="#24785f" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">allow</text>
|
|
83
|
+
<text x="826" y="382" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ connect(adjudicated)</text>
|
|
84
|
+
<text x="772" y="402" fill="#4c5160" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">no second DNS resolution</text>
|
|
85
|
+
<text x="772" y="430" fill="#ad3a4e" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">deny</text>
|
|
86
|
+
<text x="818" y="430" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ structured 403</text>
|
|
87
|
+
<text x="772" y="450" fill="#4c5160" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">never reaches upstream</text>
|
|
88
|
+
<text x="772" y="478" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">upstream</text>
|
|
89
|
+
<text x="850" y="478" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">→ allowed only</text>
|
|
90
|
+
<text x="772" y="498" fill="#4c5160" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="400" text-anchor="start">loopback / ips-scoped never chained</text>
|
|
91
|
+
<line x1="728" y1="280" x2="740" y2="280" stroke="#4B67B4" stroke-width="2" stroke-linecap="round"/>
|
|
92
|
+
<path d="M 740 201 V 417" fill="none" stroke="#4B67B4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
93
|
+
<line x1="740" y1="201" x2="752" y2="201" stroke="#4B67B4" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
94
|
+
<line x1="740" y1="417" x2="752" y2="417" stroke="#4B67B4" stroke-width="2" stroke-linecap="round" marker-end="url(#arr)"/>
|
|
95
|
+
<g filter="url(#soft)"><rect x="44" y="544" width="1020" height="66" rx="16" fill="#ffffff" stroke="#e5e0f2" stroke-width="1.5"/></g>
|
|
96
|
+
<text x="64" y="570" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">permissionRules/decision</text>
|
|
97
|
+
<text x="280" y="570" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">tool · action · outcome · dryRun</text>
|
|
98
|
+
<text x="1044" y="570" fill="#ad3a4e" font-family="Segoe UI, Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif" font-size="14" font-weight="700" text-anchor="end">log-only · never in model context</text>
|
|
99
|
+
<text x="64" y="594" fill="#4B67B4" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="15" font-weight="700" text-anchor="start">permissionRules/network</text>
|
|
100
|
+
<text x="280" y="594" fill="#4c5160" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">domain · port · mode · action</text>
|
|
101
|
+
<text x="1044" y="594" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="end">ignorable · session log</text>
|
|
102
|
+
<text x="44" y="640" fill="#8a8fa2" font-family="Consolas, SFMono-Regular, Menlo, monospace" font-size="14" font-weight="400" text-anchor="start">Apache-2.0 · PerryLink DSH plugin family · first match wins · fail closed</text>
|
|
103
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/rules-format.en.md
CHANGED
|
@@ -164,10 +164,11 @@ This plugin only produces `ask` decisions; the `ask` goes to the official `ctx.a
|
|
|
164
164
|
|
|
165
165
|
## Loading and hot reload
|
|
166
166
|
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
167
|
+
- Discovered lazily per session cwd: plugin mount and each session creation run a read-only probe first (for the startup notice only — no cache slot, no watchers), and the first `tools/pre-execute` loads and caches the chain (least-recently-used eviction beyond `maxCachedWorkspaces`); the cache key is the resolved cwd (case-folded on Windows), so differently-spelled paths share one entry.
|
|
168
|
+
- **File-level** errors (invalid YAML, an unknown top-level field, a `rules` value that is not a list, more than `maxRules` rules) still follow `badFilePolicy`: `fail` (default) makes the first tool call in that workspace fail loudly; `ignore-with-warning` warns and degrades to an empty rule set.
|
|
169
|
+
- A **single bad rule** (bad glob/regex, backtracking-prone pattern, unknown field/action, missing reason) no longer takes the file down: that rule is disabled, the report carries its 0-based position in the `rules` list and its source file, and every other rule keeps working. The degraded state is summarised when the plugin mounts and when each session is created, and `/rules` renders it as an error (red in the GUI) with one line per disabled rule (issue #49). Editor saves stay strict: a hand-written invalid rule is rejected with its error instead of being silently dropped.
|
|
170
|
+
- An absolute `rulesFile` or a configured `fallbackPath` is validated at plugin mount: missing or file-level invalid fails the mount; a single invalid rule inside the file only disables that rule.
|
|
171
|
+
- File changes reload through Chokidar with a debounce (`watch`, `watchStabilityThresholdMs`); a FILE-level failed reload keeps the previous rules and only warns — never crashes; a single bad rule only disables itself. `/rules reload` triggers the same path manually; `/rules decisions` and `/rules test` inspect the trail and dry-run the rules.
|
|
171
172
|
- Expected-but-absent rule files (the project file when it is not in effect, a fallback after it was deleted) are watched through their deepest existing ancestor directory: creating one mid-session is adopted automatically without a manual reload. Under `searchUp` only the immediate cwd-level candidate is watched — creating a rule file in a deeper ancestor still needs `/rules reload`.
|
|
172
173
|
- `/rules` lists the active rules (with `list` as an explicit alias); in multi-file chains every rule line is attributed to its own source file.
|
|
173
174
|
- `/rules test` accepts leading flags: `--cwd <dir>` evaluates against another workspace (rule discovery AND path normalization), `--env KEY=VALUE` (repeatable) overrides host env for `when.env`, `--agent <selector>` (repeatable) supplies identity candidates for the `agents` dimension, and `--platform <name>` overrides the host platform for `when.platform`.
|
package/docs/rules-format.md
CHANGED
|
@@ -162,10 +162,11 @@ rules:
|
|
|
162
162
|
|
|
163
163
|
## 加载与热更新
|
|
164
164
|
|
|
165
|
-
- 按会话 cwd
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
165
|
+
- 按会话 cwd 惰性发现:插件挂载与每个会话创建时先做一次只读探测(只用于启动提示,不占缓存、不装监听),首次 `tools/pre-execute` 时正式加载并缓存(超出 `maxCachedWorkspaces` 逐出最久未用项);缓存键为解析后的 cwd(Windows 上折叠大小写),同一目录的不同拼写共享同一条目。
|
|
166
|
+
- **文件级**错误(非法 YAML、未知顶层字段、`rules` 不是列表、超 `maxRules`)仍按 `badFilePolicy` 处理:`fail`(默认)时首个使用该工作区的工具调用响亮失败;`ignore-with-warning` 时告警并降级为空规则集。
|
|
167
|
+
- **单条规则**错误(坏 glob/正则、易回溯模式、未知字段/action、缺失 reason)不再连坐整份文件:该条被禁用,报错带上规则下标(`rules` 列表中的 0 基位置,显示为第 N 条)与所在文件,其余规则照常生效。插件挂载和每个会话创建时会把降级状态汇总到启动提示,`/rules` 以 error 状态(GUI 中显示为错误)逐条列出被禁用的规则(issue #49)。编辑器保存仍是严格校验:手写的非法规则会被拒绝并返回错误,不会被静默丢弃。
|
|
168
|
+
- 绝对 `rulesFile` 或配置的 `fallbackPath` 在插件挂载时即校验:缺失或文件级非法直接挂载失败;文件内单条规则非法只禁用该条。
|
|
169
|
+
- 文件变更后经 Chokidar 去抖重读(`watch`、`watchStabilityThresholdMs`);文件级重读失败保留旧规则、只告警,绝不崩溃;单条规则错误只禁用该条。`/rules reload` 手动触发同样路径;`/rules decisions` 回放审计轨迹,`/rules test` 对假设调用干跑规则。
|
|
169
170
|
- 预期存在但缺失的规则文件(未生效的项目文件、被删除后的 fallback)会通过其最近存在祖先目录被监听:会话中途创建即自动采纳,无需手动重载。`searchUp` 下只监听 cwd 层级的候选——更上层祖先新建规则文件仍需 `/rules reload`。
|
|
170
171
|
- `/rules` 列出当前规则(`list` 为显式别名);多文件链中每条规则行标注自己的来源文件。
|
|
171
172
|
- `/rules test` 支持前置标志:`--cwd <目录>` 换一个工作区求值(规则发现与路径归一化都切换);`--env 键=值`(可重复)覆盖宿主环境变量以测试 `when.env`;`--agent <选择器>`(可重复)为 `agents` 维度提供身份候选;`--platform <平台名>` 覆盖宿主平台以测试 `when.platform`。
|