dsh-permission-rules 0.5.0 → 0.5.2
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 +17 -0
- package/README.es.md +139 -118
- package/README.hi.md +141 -120
- package/README.md +111 -90
- package/README.pt.md +140 -119
- package/README.zh.md +158 -137
- package/docs/rule-test-vectors/README.md +28 -0
- package/docs/rule-test-vectors/corpus.json +109 -0
- package/lib/client.js +4 -7
- package/lib/client.js.map +1 -1
- package/lib/index.js +10 -7
- package/lib/types/client/remote.d.ts +1 -1
- package/lib/types/client/section.d.ts +2 -2
- package/lib/types/config.d.ts +3 -3
- package/lib/types/index.d.ts +8 -8
- package/lib/types/network.d.ts +2 -2
- package/lib/types/proxy.d.ts +2 -2
- package/lib/types/remote-service.d.ts +2 -2
- package/lib/types/runtime.d.ts +14 -11
- package/lib/types/runtime.d.ts.map +1 -1
- package/lib/types/settings.d.ts +2 -2
- package/package.json +182 -178
- package/scripts/repair-session-logs.mjs +7 -2
- package/src/client/index.ts +5 -5
- package/src/runtime.ts +10 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to dsh-permission-rules are recorded here, newest first.
|
|
4
4
|
|
|
5
|
+
## v0.5.2 — 2026-08-19
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Client dictionaries survive hot-reload**: the browser half now holds the `locale.register` disposer through the plugin fiber's `ctx.effect` (the locale registry throws on a duplicate namespace). Disposing the client fiber unregisters the `settings.permissionRules` dictionaries; remounting re-registers cleanly instead of failing the mount until the next page refresh. Regression covered by a dispose-and-remount client test against a duplicate-strict locale registry.
|
|
10
|
+
|
|
11
|
+
## v0.5.1 — 2026-08-17
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Shared rule-syntax test vectors** (`docs/rule-test-vectors/`): an implementation-neutral conformance corpus (schema `dsh-rule-test-vectors/v1`) covering exact/glob tool matches, params globs and negation, path patterns, `when.platform`/`when.env`, the `agents` identity dimension, `absent`, first-match ordering, and disabled rules. `test/test-vectors.spec.ts` proves every case through the real parser/matcher — the reference implementation for the cross-gate corpus agreed with sjh9714 (issues #4/#5).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- `scripts/repair-session-logs.mjs` default target set now covers all five `autoReview/*` event types (`state`, `verdict`, `circuit`, `override`, `rejection`) in addition to `permissionRules/decision`, so sessions polluted by `dsh-auto-review` ≤ 0.5.0 on rc.6 hosts repair in one pass.
|
|
20
|
+
- The dsh-auto-review integration dependency moves to `vendor/dsh-auto-review-0.5.1.tgz` (its rc.6 audit-gating fix); the integration specs mount it with `allowUnmarkedAudit: true` so the asserted audit chain stays testable against the rc.6 peers.
|
|
21
|
+
|
|
5
22
|
## v0.5.0 — 2026-08-16
|
|
6
23
|
|
|
7
24
|
### Added
|
package/README.es.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Reglas de permisos declarativas estilo Claude Code para DeepSeek Harness.**
|
|
6
6
|
|
|
7
|
-
*Las reglas deciden lo conocido. Un modelo revisor decide lo
|
|
7
|
+
*Las reglas deciden lo conocido. Un modelo revisor decide lo que no lo es.*
|
|
8
8
|
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
[](https://github.com/topics/dsh-plugin)
|
|
@@ -20,179 +20,200 @@
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Compatibility
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Cada acierto **y** cada paso directo se audita como evento de sesión `permissionRules/decision` (solo registro, sin inyectar nada extra al contexto del modelo).
|
|
32
|
-
|
|
33
|
-
```text
|
|
34
|
-
waterfall tools/pre-execute waterfall approval/request (cadena de answerers)
|
|
35
|
-
│ │
|
|
36
|
-
dsh-permission-rules answerer dsh-auto-review
|
|
37
|
-
· primera coincidencia en orden ┌───────────────────┴──────────────┐
|
|
38
|
-
· deny/ask reclaman la llamada │ veredicto de IA (segundo modelo) │ no ── next() ──▶ UI humana
|
|
39
|
-
· allow/paso → next() └───────────────────┬──────────────┘
|
|
40
|
-
│ deny ──▶ resultado denegado │ allowed-once / rejected
|
|
41
|
-
│ ask ──▶ ctx.approval ─────────────────────────┘
|
|
42
|
-
│
|
|
43
|
-
auditoría: permissionRules/decision → approval/asked → autoReview/verdict → approval/decided
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## ¿Por qué reglas *y* un revisor?
|
|
47
|
-
|
|
48
|
-
Un segundo modelo responde *"¿es segura ESTA llamada?"* con criterio, pero cuesta un viaje de ida y vuelta y puede equivocarse. Las reglas declarativas responden de forma determinista, instantánea y sin modelo, pero solo cubren lo que un administrador escribió. Combinados obtienes el bucle **"primero reglas, IA de respaldo"**: las reglas deciden lo conocido, el revisor decide lo desconocido.
|
|
49
|
-
|
|
50
|
-
## Características
|
|
25
|
+
| Surface | Status |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Harness | DeepSeek Harness `0.1.0-rc.5`–`0.1.0-rc.6` |
|
|
28
|
+
| Node | `^22.19.0 || >=24.0.0` |
|
|
29
|
+
| Platforms | Todas (host + cliente web de settings) |
|
|
30
|
+
| Model | Cualquiera (las razones deny/ask se muestran a través de los resultados de herramienta) |
|
|
51
31
|
|
|
52
|
-
|
|
53
|
-
- ✅ **Coincidencia rica** — globs de nombre de herramienta (incluido `mcp__*`), selectores de identidad de agente (`main` / `subagent` / `preset:*`), globs **o** regex de clave/valor de argumentos (con negación `!pattern` y la dimensión de clave `absent`), globs de rutas relativas al workspace extraídos de claves de argumentos documentadas a **cualquier profundidad de anidamiento**, y condiciones de host `when` (variables de entorno, plataforma)
|
|
54
|
-
- ✅ **Archivos de reglas jerárquicos** — `searchUp` opcional combina cada `.dsh/rules.yaml` desde el cwd de la sesión hasta la raíz del sistema de archivos, el más cercano primero, para que un proyecto hijo pueda sobrescribir las reglas del padre
|
|
55
|
-
- ✅ **Metadatos de reglas** — `enabled: false`, `description`, `tags`; `/rules` advierte sobre reglas eclipsadas por un catch-all anterior
|
|
56
|
-
- ✅ **Seguro para el waterfall** — `allow`/paso siempre llaman a `next()`; solo `deny`/`ask` cortocircuitan
|
|
57
|
-
- ✅ **Seam de aprobación oficial** — `ask` fluye por `ctx.approval`; nunca reimplementado, nunca eludido
|
|
58
|
-
- ✅ **Auditoría completa** — los eventos `permissionRules/decision` llevan la acción de la regla, el cwd del workspace Y el resultado final de cada llamada; `/rules decisions` reproduce el rastro en la sesión; los hosts anteriores al marcador de envoltura de auditoría degradan a auditoría desactivada con un aviso único en lugar de escribir registros irrecuperables (`allowUnmarkedAudit` la reactiva)
|
|
59
|
-
- ✅ **Despliegue en simulación** — `enforce: false` audita lo que la política *haría* (acción hipotética + resultado real posterior, marcado `dryRun`) mientras deja pasar todas las llamadas; prueba segura de políticas en producción
|
|
60
|
-
- ✅ **Prueba en seco** — `/rules test <tool> <json-args>` evalúa las reglas activas sin ejecutar nada, con sobrescrituras `--cwd`, `--env`, `--agent` y `--platform` para cada dimensión
|
|
61
|
-
- ✅ **Recarga en caliente** — vigilancia Chokidar con debounce; una edición rota conserva las reglas previas, nunca falla; un archivo de reglas creado a mitad de sesión (el del proyecto o el fallback) se adopta automáticamente, sin recarga manual
|
|
62
|
-
- ✅ **Fallo ruidoso** — YAML inválido, acciones/campos desconocidos, globs/regex incorrectos, patrones propensos a backtracking o > `maxRules` hacen fallar la carga
|
|
63
|
-
- ✅ **Ruta caliente acotada** — matchers precompilados, O(reglas × patrones), limitado por `maxRules`; el grado de backtracking de glob limitado por `maxGlobStars`
|
|
32
|
+
## What you get
|
|
64
33
|
|
|
65
|
-
|
|
34
|
+
`dsh-permission-rules` antepone una lista ordenada de reglas **`allow` / `deny` / `ask`** a cada llamada de herramienta en la cascada `tools/pre-execute` — determinista, instantánea, auditable y escrita por ti en YAML plano:
|
|
66
35
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
36
|
+
- **`deny`** bloquea la llamada; la `reason` de la regla se convierte en el error visible para el modelo.
|
|
37
|
+
- **`ask`** usa la costura oficial de aprobación (monta `dsh-auto-review` para un answerer de segundo modelo, o responde un humano; sin ninguno, el harness falla cerrado).
|
|
38
|
+
- **`allow`** (y sin coincidencia) delega estrictamente vía `next()` — los listeners posteriores nunca se cortocircuitan.
|
|
70
39
|
|
|
71
|
-
|
|
72
|
-
pnpm pack
|
|
73
|
-
dsh plugin --profile web add ./dsh-permission-rules-0.4.1.tgz
|
|
40
|
+
Cada acierto **y** cada paso directo se registra como un evento de sesión `permissionRules/decision` (solo registro — nada extra se inyecta en el contexto del modelo).
|
|
74
41
|
|
|
75
|
-
|
|
76
|
-
dsh
|
|
77
|
-
|
|
42
|
+
- **Emparejamiento rico** — globs de nombre de herramienta (incl. `mcp__*`), selectores de identidad de agente (`main` / `subagent` / `preset:*`), globs **o** regexes de clave/valor de argumentos (con negación `!pattern` y una dimensión de clave `absent`), globs de ruta relativos al workspace a **cualquier profundidad de anidamiento**, y condiciones de host `when` (variables de entorno, plataforma).
|
|
43
|
+
- **Archivos de reglas jerárquicos** — `searchUp` opcional fusiona cada `.dsh/rules.yaml` desde el cwd de la sesión hasta la raíz del sistema de archivos, el más cercano primero.
|
|
44
|
+
- **Despliegue en dry-run** — `enforce: false` audita lo que la política *haría* mientras deja pasar cada llamada.
|
|
45
|
+
- **Recarga en caliente** — vigilancia Chokidar con debounce; una edición rota conserva las reglas anteriores, nunca falla.
|
|
46
|
+
- **Fallo ruidoso** — YAML inválido, acciones/campos desconocidos, globs/regexes malos, patrones propensos a backtracking o más de `maxRules` reglas fallan la carga.
|
|
78
47
|
|
|
79
|
-
|
|
48
|
+
## Rule syntax
|
|
80
49
|
|
|
81
50
|
```yaml
|
|
82
51
|
# <project>/.dsh/rules.yaml
|
|
83
52
|
rules:
|
|
84
53
|
- match: { tools: [bash, pwsh], params: { command: "git push*" }, paths: ["**/secrets/**"] }
|
|
85
54
|
action: deny
|
|
86
|
-
reason: "
|
|
55
|
+
reason: "No pushes from protected paths"
|
|
87
56
|
|
|
88
57
|
- match: { tools: [edit, write] }
|
|
89
58
|
action: ask
|
|
90
|
-
reason: "
|
|
59
|
+
reason: "File writes need confirmation"
|
|
91
60
|
```
|
|
92
61
|
|
|
62
|
+
- **Dimensiones de coincidencia** — `tools` (globs, incl. `mcp__*`), `agents` (`main` / `subagent` / `preset:<name>`; identidad desconocida nunca coincide — falla cerrado), `params` (globs o regexes de clave/valor, negación `!pattern`, dimensión de clave `absent`), `paths` (globs relativos al workspace extraídos a cualquier profundidad), `when` (globs/regexes de variables `env` + una lista `platform` cerrada), y `network` (`domains` / `ips` / `ports` / `schemes` — globs, comodines, CIDR, rangos de puertos).
|
|
63
|
+
- **Acciones** — `allow` / `deny` / `ask`, evaluadas en orden de archivo, la primera coincidencia gana.
|
|
64
|
+
- **Metadatos de regla** — `enabled: false` (visible pero inerte), `description`, `tags`; los campos desconocidos fallan la carga.
|
|
65
|
+
- **Schema** — un JSON Schema se distribuye en [docs/rules-format.schema.json](docs/rules-format.schema.json) (autocompletado de editor vía `# yaml-language-server: $schema=...`); el vocabulario completo y una línea base de 5 reglas viven en [docs/rules-format.en.md](docs/rules-format.en.md).
|
|
66
|
+
|
|
67
|
+
## Network policy
|
|
68
|
+
|
|
69
|
+
Una **política de red a nivel de proceso** estilo Codex: el tráfico de subprocesos de shell fluye a través de un **proxy HTTP/CONNECT** local integrado, y cada conexión se decide mediante reglas de red ordenadas o mediante tres modos mapeados sobre los presets oficiales del sandbox:
|
|
70
|
+
|
|
71
|
+
- **`deny-all`** — el preset de sandbox de solo lectura: bloquear todo el tráfico saliente.
|
|
72
|
+
- **`whitelist`** — el preset workspace-write: permitir los destinos listados, `unlisted: ask` (o `deny`) para el resto.
|
|
73
|
+
- **`allow-all`** — el preset danger-full-access: permitir todo.
|
|
74
|
+
- **`auto`** (por defecto) — sigue el preset del sandbox; en hosts sin el servicio de política de sandbox se resuelve a `autoFallback` (`allow-all`).
|
|
75
|
+
|
|
76
|
+
- **Emparejamiento** — `match.network` con `domains` / `ips` / `ports` / `schemes` (globs, comodines, CIDR, rangos de puertos; se aceptan puertos YAML numéricos). La extracción de candidatos URL en la ruta caliente `tools/pre-execute` se dispara sobre argumentos de herramientas web y URLs embebidas en texto de comandos bash/pwsh; los destinos de loopback pueden cortocircuitar reglas según la política `loopback`.
|
|
77
|
+
- **Auditoría** — las conexiones denegadas anexan `permissionRules/network` a la sesión propietaria (la misma puerta adaptativa `ignorable`), con contadores de bloqueo e intercepciones recientes en `/rules network` y la página de settings.
|
|
78
|
+
|
|
79
|
+
## Quick start
|
|
80
|
+
|
|
93
81
|
```sh
|
|
94
|
-
|
|
82
|
+
# 1. install the bundle into your profile
|
|
83
|
+
dsh plugin --profile web add "github:PerryLink/dsh-permission-rules#main"
|
|
84
|
+
|
|
85
|
+
# or from npm (published releases)
|
|
86
|
+
dsh plugin --profile web add dsh-permission-rules
|
|
87
|
+
|
|
88
|
+
# 2. restart and verify the row
|
|
89
|
+
dsh --profile web --dump-config | grep -A4 'id: permission-rules'
|
|
95
90
|
```
|
|
96
91
|
|
|
97
|
-
|
|
92
|
+
## Install & uninstall
|
|
98
93
|
|
|
99
|
-
|
|
94
|
+
- **canal git** (último `main`): `dsh plugin --profile web add "github:PerryLink/dsh-permission-rules#main"` — el script `prepare` compila solo con dependencias de producción.
|
|
95
|
+
- **canal npm** (versiones publicadas): `dsh plugin --profile web add dsh-permission-rules`.
|
|
96
|
+
- **canal tarball**: `pnpm pack` en este repo, luego `dsh plugin --profile web add ./dsh-permission-rules-<version>.tgz`.
|
|
97
|
+
- **desinstalar**: `dsh plugin --profile web remove dsh-permission-rules`.
|
|
100
98
|
|
|
101
|
-
|
|
99
|
+
## Configuration
|
|
102
100
|
|
|
103
|
-
|
|
101
|
+
Todos los parámetros son campos Schemastery `Config` (modificables desde cordis.yml). Una sobrescritura dirigida por id reemplaza toda la fila — reafirma cada clave que necesites.
|
|
102
|
+
|
|
103
|
+
| Key | Default | Meaning |
|
|
104
104
|
|---|---|---|
|
|
105
105
|
| `rulesFile` | `.dsh/rules.yaml` | Ubicación del archivo de reglas; relativo = resuelto contra el cwd de la sesión, absoluto = global y validado al montar |
|
|
106
|
-
| `fallbackPath` | *(
|
|
107
|
-
| `badFilePolicy` | `fail` | Archivo
|
|
108
|
-
| `maxRules` | `256` | Límite duro de reglas en
|
|
109
|
-
| `maxCachedWorkspaces` | `512` | Límite duro de cargas de reglas por
|
|
110
|
-
| `patternMode` | `glob` |
|
|
106
|
+
| `fallbackPath` | *(none)* | Archivo de reglas usado cuando la detección por cwd no encuentra nada; validado al montar |
|
|
107
|
+
| `badFilePolicy` | `fail` | Archivo de reglas malo: `fail` hace fallar la llamada pendiente ruidosamente; `ignore-with-warning` advierte y continúa vacío |
|
|
108
|
+
| `maxRules` | `256` | Límite duro de recuento de reglas en la cadena fuente efectiva |
|
|
109
|
+
| `maxCachedWorkspaces` | `512` | Límite duro de cargas de reglas por workspace en caché (evicción LRU) |
|
|
110
|
+
| `patternMode` | `glob` | Sabor de patrón `params`/`paths`/`when.env`: `glob` o `regex` (los nombres de herramienta siempre son globs) |
|
|
111
111
|
| `watch` | `true` | Vigilancia Chokidar + recarga al cambiar |
|
|
112
112
|
| `watchStabilityThresholdMs` | `200` | Ventana de debounce de recarga (ms) |
|
|
113
|
-
| `language` | `en` | Idioma de salida de `/rules`: `en`, `zh`, `es`, `pt`, `hi`
|
|
114
|
-
| `caseInsensitivePaths` | *(win32)* | Los patrones
|
|
115
|
-
| `audit` | `all` | Granularidad de auditoría: `all` registra cada acierto Y
|
|
116
|
-
| `searchUp` | `false` |
|
|
117
|
-
| `maxGlobStars` | `2` | Límite duro de cuantificadores `*`/`**`
|
|
118
|
-
| `enforce` | `true` | `false` = modo
|
|
119
|
-
| `allowUnmarkedAudit` | `false` | Los hosts
|
|
120
|
-
|
|
121
|
-
|
|
113
|
+
| `language` | `en` | Idioma de salida de `/rules`: `en`, `zh`, `es`, `pt`, `hi` |
|
|
114
|
+
| `caseInsensitivePaths` | *(win32)* | Los patrones `paths` y la comparación de raíz del workspace ignoran mayúsculas ASCII; `true` en Windows |
|
|
115
|
+
| `audit` | `all` | Granularidad de auditoría: `all` registra cada acierto Y paso directo; `hits` omite eventos de paso |
|
|
116
|
+
| `searchUp` | `false` | Recorrer directorios padre desde el cwd y fusionar cada archivo de reglas encontrado, el más cercano primero |
|
|
117
|
+
| `maxGlobStars` | `2` | Límite duro de cuantificadores `*`/`**` no acotados por patrón glob |
|
|
118
|
+
| `enforce` | `true` | `false` = modo dry-run: los aciertos deny/ask se registran con marcador `dryRun` y cada llamada pasa |
|
|
119
|
+
| `allowUnmarkedAudit` | `false` | Los hosts previos al marcador descartan el marcador `ignorable`; el plugin desactiva la auditoría de registro con una advertencia. Pon `true` para reactivar |
|
|
120
|
+
| `network.enabled` | `true` | Interruptor maestro del proxy, la inyección de entorno y los modos por defecto de herramienta web |
|
|
121
|
+
| `network.mode` | `auto` | Modo de política: `auto` sigue el preset del sandbox, o `deny-all` / `whitelist` / `allow-all` |
|
|
122
|
+
| `network.autoFallback` | `allow-all` | Modo usado cuando `auto` no tiene servicio de política de sandbox |
|
|
123
|
+
| `network.unlisted` | `ask` | Manejo en modo whitelist de destinos sin regla coincidente: `ask` o `deny` |
|
|
124
|
+
| `network.proxyBind` | `127.0.0.1` | Dirección de enlace del proxy local (solo loopback) |
|
|
125
|
+
| `network.proxyPort` | `0` | Puerto del proxy local; `0` elige un puerto efímero libre |
|
|
126
|
+
| `network.proxyMaxRecent` | `100` | Límite de registros de bloqueo recientes para la página de settings |
|
|
127
|
+
| `network.loopback` | `allow` | Destinos de loopback: `allow` (paridad Codex) o `policy` |
|
|
128
|
+
| `network.injectEnv` | `true` | Si se inyectan variables de entorno del proxy para subprocesos |
|
|
129
|
+
| `network.noProxy` | `clear` | Manejo de NO_PROXY en subprocesos: `clear` aplica la política o `preserve` |
|
|
130
|
+
|
|
131
|
+
## Tools & surfaces
|
|
132
|
+
|
|
133
|
+
| Surface | Kind | Notes |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| `tools/pre-execute` | listener | Reglas allow/deny/ask de primera coincidencia + extracción de candidatos URL de red |
|
|
136
|
+
| `/rules` | command | `list` · `reload` · `decisions [n]` · `test <tool> <json>` |
|
|
137
|
+
| `permissionRules/decision` | event | Auditoría solo de registro para cada acierto y paso directo |
|
|
138
|
+
| `permissionRules/network` | event | Auditoría de capa de proxy para conexiones bloqueadas |
|
|
139
|
+
| HTTP/CONNECT proxy | service | Proxy local integrado que gobierna el tráfico de subprocesos de shell |
|
|
140
|
+
| settings page | client | Editor de modo de red, editor de reglas, contadores de bloqueo, intercepciones recientes |
|
|
122
141
|
|
|
123
142
|
```
|
|
124
|
-
/rules
|
|
125
|
-
/rules list alias
|
|
126
|
-
/rules reload
|
|
127
|
-
/rules decisions [n]
|
|
128
|
-
/rules test <tool> <json>
|
|
143
|
+
/rules list the active rules, their source files, and any last-reload error
|
|
144
|
+
/rules list explicit alias for the bare listing
|
|
145
|
+
/rules reload re-read the rule-file chain for this workspace
|
|
146
|
+
/rules decisions [n] show the last n permission decisions of this session (default 10)
|
|
147
|
+
/rules test <tool> <json> dry-evaluate the rules against a hypothetical call
|
|
129
148
|
```
|
|
130
149
|
|
|
131
|
-
`/rules test` también acepta banderas iniciales: `--cwd <dir
|
|
150
|
+
`/rules test` también acepta banderas iniciales: `--cwd <dir>`, `--env KEY=VALUE` (repetible), `--agent <selector>` (repetible) y `--platform <name>`. En cadenas multi-archivo (p. ej. `searchUp`), cada línea de regla listada se atribuye a su propio archivo fuente.
|
|
132
151
|
|
|
133
|
-
|
|
152
|
+
## Permissions & data
|
|
134
153
|
|
|
135
|
-
|
|
154
|
+
- **Permissions**: el manifiesto de workshop declara `files:read`, `files:watch`, `files:write`, `session:append` y `network:outbound`. Las decisiones `ask` usan la costura oficial de aprobación — nada se reimplementa ni se evade.
|
|
155
|
+
- **Data**: los archivos de reglas se leen del disco; no se escribe ningún dato de reglas. Sin llamadas al modelo, sin subagentes revisores.
|
|
156
|
+
- **Session log**: `permissionRules/decision` nunca se inyecta en el contexto del modelo y se anexa con el marcador `ignorable: true` del sobre, de modo que cualquier build del harness carga el registro.
|
|
136
157
|
|
|
137
|
-
|
|
138
|
-
- Probado en integración (`test/integration.spec.ts`): `permissionRules/decision` → `approval/asked` → `autoReview/verdict` → `approval/decided`, con el revisor sustituido por un mock.
|
|
139
|
-
- La política de aprobación `never` y todas las garantías fail-closed del [harness oficial](https://github.com/deepseek-ai/deepseek-harness) permanecen intactas.
|
|
158
|
+
## Security boundaries
|
|
140
159
|
|
|
141
|
-
|
|
160
|
+
- **Política, no kernel.** Los candidatos `paths` provienen solo de un conjunto documentado de claves de argumento (a cualquier profundidad, con tope), y solo coinciden las rutas relativas al workspace.
|
|
161
|
+
- **Aquí no hay revisor.** El plugin nunca genera subagentes ni llama modelos — producir una decisión `ask` es el fin de su trabajo.
|
|
162
|
+
- **Sin cambios de sandbox.** La política de sandbox a nivel de SO pertenece a la costura del sandbox, no a este plugin.
|
|
163
|
+
- **Rechazo ruidoso de mala configuración.** Campos YAML desconocidos, acciones desconocidas y patrones malos se rechazan al cargar.
|
|
164
|
+
- **Límites de backtracking.** Los patrones glob se limitan a `maxGlobStars` expansiones de estrella no acotadas; los patrones regex rechazan cuantificadores anidados no acotados y alternancias literales solapadas cuantificadas.
|
|
142
165
|
|
|
143
|
-
|
|
144
|
-
- **Aquí no hay revisor.** El plugin nunca lanza subagentes ni llama modelos: producir una decisión `ask` es el final de su trabajo.
|
|
145
|
-
- **Sin cambios de sandbox.** La política de sandbox a nivel de SO pertenece al seam de sandbox, no a este plugin.
|
|
146
|
-
- **Mala configuración ruidosa.** Campos YAML desconocidos, acciones desconocidas y patrones incorrectos se rechazan al cargar, nunca se ignoran en silencio.
|
|
147
|
-
- **Límites de backtracking.** Los patrones glob están limitados a `maxGlobStars` expansiones de estrella sin límite; los patrones en modo regex rechazan cuantificadores anidados sin límite y alternancias literales superpuestas cuantificadas. (Las cadenas regex como `\d+\.\d+\.\d+` siguen permitidas: el modo regex es la válvula de escape, el modo glob es el predeterminado protegido.)
|
|
166
|
+
## Known limitations
|
|
148
167
|
|
|
149
|
-
|
|
168
|
+
- **Marcador de auditoría en hosts previos al marcador.** `permissionRules/decision` se anexa con `ignorable: true`; los hosts cuyo `Session.append` es anterior al marcador (la línea `0.1.0-rc.6`) lo descartan silenciosamente, por lo que el runtime desactiva la auditoría de registro con una advertencia única. Pon `allowUnmarkedAudit: true` para reactivar; repara registros ya escritos con `scripts/repair-session-logs.mjs`.
|
|
169
|
+
- **Los candidatos de ruta son heurísticos.** Solo las claves de argumento documentadas alimentan el emparejamiento de rutas, y el emparejamiento relativo al workspace es insensible a mayúsculas ASCII solo con `caseInsensitivePaths` activado.
|
|
170
|
+
- **Los globs son un subconjunto conservador.** Sin expansión de llaves — escribe dos patrones, o usa modo regex.
|
|
171
|
+
- **La guardia de backtracking de regex es estructural, no exhaustiva.** Prefiere el modo glob para archivos no confiables.
|
|
150
172
|
|
|
151
|
-
|
|
152
|
-
- `Drifter-yh/dsh-tool-policy` — política de herramientas deny-by-default; documentada aquí para evitar implementaciones duplicadas.
|
|
153
|
-
- `dsh-auto-review` — la mitad de respaldo de IA del bucle que este plugin encabeza.
|
|
173
|
+
## Collaborating with dsh-auto-review
|
|
154
174
|
|
|
155
|
-
|
|
175
|
+
- `dsh-permission-rules` produce `ask`; `dsh-auto-review` responde en la cascada `approval/request` con un veredicto de segundo modelo de solo lectura (o delega en humanos). Monta ambos para el bucle completo cerrado.
|
|
176
|
+
- Probado en integración: `permissionRules/decision` → `approval/asked` → `autoReview/verdict` → `approval/decided`, con el revisor reemplazado por un mock guionado.
|
|
177
|
+
- La política de aprobación `never` y toda garantía de fallo cerrado del harness oficial permanecen intactas.
|
|
156
178
|
|
|
157
|
-
|
|
158
|
-
- Los candidatos de `paths` son heurísticos: solo las claves de argumentos documentadas alimentan la coincidencia de rutas, y la coincidencia relativa al workspace ignora las mayúsculas ASCII solo cuando `caseInsensitivePaths` está activo.
|
|
159
|
-
- Los globs son un subconjunto conservador (sin expansión de llaves): escribe dos patrones o usa el modo regex.
|
|
160
|
-
- El guard de backtracking de regex es estructural, no exhaustivo: los casos de ambigüedad por alternancia sin prefijos literales (p. ej. lookarounds elaborados) son responsabilidad del autor; prefiere el modo glob para archivos no confiables.
|
|
179
|
+
## Session log repair
|
|
161
180
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
Los registros de sesión escritos antes del marcador `ignorable` pueden ser rechazados por builds más nuevos del harness (`SessionFormatUnsupportedError`). El `scripts/repair-session-logs.mjs` incluido reescribe solo las filas de auditoría objetivo para añadir `ignorable: true`, preservando los marcos, con copias de seguridad:
|
|
181
|
+
Los registros de sesión escritos antes de que existiera el marcador `ignorable` pueden ser rechazados por builds más nuevas del harness (`SessionFormatUnsupportedError`). El `scripts/repair-session-logs.mjs` distribuido reescribe solo las filas de auditoría objetivo para llevar `ignorable: true`, preservando marcos, con copias de seguridad:
|
|
165
182
|
|
|
166
183
|
```sh
|
|
167
|
-
node scripts/repair-session-logs.mjs scan [--home DIR] #
|
|
184
|
+
node scripts/repair-session-logs.mjs scan [--home DIR] # reporta filas ajenas, no cambia nada
|
|
168
185
|
node scripts/repair-session-logs.mjs repair [--home DIR] [--dry-run]
|
|
169
186
|
```
|
|
170
187
|
|
|
171
|
-
`--home` por defecto es `$DSH_HOME/sessions` (o `~/.dsh/sessions`).
|
|
188
|
+
`--home` por defecto es `$DSH_HOME/sessions` (o `~/.dsh/sessions`).
|
|
172
189
|
|
|
173
|
-
##
|
|
190
|
+
## Development
|
|
174
191
|
|
|
175
192
|
```sh
|
|
176
|
-
pnpm install
|
|
177
|
-
pnpm run typecheck
|
|
178
|
-
pnpm run lint
|
|
179
|
-
pnpm test
|
|
180
|
-
pnpm run test:coverage #
|
|
181
|
-
pnpm run build
|
|
182
|
-
pnpm run pack:check
|
|
183
|
-
node scripts/check-readme-sync.mjs
|
|
193
|
+
pnpm install # node ^22.19 || >=24
|
|
194
|
+
pnpm run typecheck # tsc, src + tests
|
|
195
|
+
pnpm run lint # eslint, src + tests + scripts
|
|
196
|
+
pnpm test # vitest: 139 tests, 9 suites
|
|
197
|
+
pnpm run test:coverage # coverage gate (90/80/90/90)
|
|
198
|
+
pnpm run build # tsc declarations + tsdown bundles (lib/)
|
|
199
|
+
pnpm run pack:check # build + pack (the published artifact)
|
|
200
|
+
node scripts/check-readme-sync.mjs # five-language README sync gate (also in CI)
|
|
184
201
|
```
|
|
185
202
|
|
|
186
|
-
Consulta [VERIFICATION.md](VERIFICATION.md) para el registro de verificación
|
|
203
|
+
Consulta [VERIFICATION.md](VERIFICATION.md) para el registro de verificación end-to-end sin cabeza.
|
|
204
|
+
|
|
205
|
+
## Topics
|
|
206
|
+
|
|
207
|
+
`dsh`, `dsh-plugin`, `deepseek-harness`, `permission`, `policy`, `allow-deny-ask`, `approval`, `safety`, `network`, `network-policy`, `proxy`
|
|
187
208
|
|
|
188
|
-
##
|
|
209
|
+
## Contributors
|
|
189
210
|
|
|
190
|
-
- [@PerryLink](https://github.com/PerryLink) — creador y mantenedor: vocabulario y evaluación de reglas, runtime, vigilancia HMR, auditoría
|
|
191
|
-
- [@22xuan](https://github.com/22xuan) — el detallado
|
|
211
|
+
- [@PerryLink](https://github.com/PerryLink) — creador y mantenedor: vocabulario y evaluación de reglas, runtime, vigilancia HMR, auditoría de registro de sesión, política de red + proxy, y la documentación en cinco idiomas.
|
|
212
|
+
- [@22xuan](https://github.com/22xuan) — el informe detallado sobre hosts rc.6 que descartan silenciosamente el marcador `ignorable` del evento de auditoría ([#2](https://github.com/PerryLink/dsh-permission-rules/issues/2)) y la discusión del harness upstream; la detección de capacidad de host en runtime v0.4.1 y la corrección de documentación se derivaron directamente de ese análisis.
|
|
192
213
|
|
|
193
214
|
## PerryLink DSH Plugin Family
|
|
194
215
|
|
|
195
|
-
Este proyecto es uno de los [15 plugins de DeepSeek Harness](https://github.com/PerryLink) mantenidos por [PerryLink](https://github.com/PerryLink). Si este te
|
|
216
|
+
Este proyecto es uno de los [15 plugins de DeepSeek Harness](https://github.com/PerryLink) mantenidos por [PerryLink](https://github.com/PerryLink). Si este te ayuda, los demás probablemente también:
|
|
196
217
|
|
|
197
218
|
| Plugin | One-liner |
|
|
198
219
|
|---|---|
|
|
@@ -212,6 +233,6 @@ Este proyecto es uno de los [15 plugins de DeepSeek Harness](https://github.com/
|
|
|
212
233
|
| [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) | Plugin-development knowledge base as an on-demand agent skill |
|
|
213
234
|
| [dsh-claude-move](https://github.com/PerryLink/dsh-claude-move) | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH |
|
|
214
235
|
|
|
215
|
-
##
|
|
236
|
+
## License
|
|
216
237
|
|
|
217
238
|
[Apache License 2.0](LICENSE) © 2026 dsh-permission-rules contributors
|