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 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 desconocido.*
7
+ *Las reglas deciden lo conocido. Un modelo revisor decide lo que no lo es.*
8
8
 
9
9
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
10
  [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
@@ -20,179 +20,200 @@
20
20
 
21
21
  ---
22
22
 
23
- ## Qué hace
23
+ ## Compatibility
24
24
 
25
- `dsh-permission-rules` coloca una lista ordenada de reglas **`allow` / `deny` / `ask`** delante de cada llamada a herramienta en el waterfall `tools/pre-execute`: determinista, instantánea, auditable y escrita por ti en YAML plano:
26
-
27
- - **`deny`** bloquea la llamada. El `reason` de la regla se convierte en el error visible para el modelo, para que el agente aprenda *por qué* en lugar de reintentar a ciegas.
28
- - **`ask`** usa el seam de aprobación oficial. Monta `dsh-auto-review` junto a él y una segunda modelo decide; si no, responde un humano; sin ninguno de los dos, el harness falla cerrado (fail-closed).
29
- - **`allow`** (y la ausencia de coincidencia) delega estrictamente mediante `next()`: los listeners posteriores nunca se cortocircuitan.
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
- - ✅ **Semántica de tres estados** — `allow`, `deny`, `ask`, evaluadas en orden de archivo; gana la primera coincidencia
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
- ## Inicio rápido
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
- ```sh
68
- # 1. instala el bundle en tu perfil
69
- dsh plugin --profile web add "github:PerryLink/dsh-permission-rules#main"
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
- # o desde un tarball empaquetado (artefactos compilados, sin permiso de build)
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
- # 2. reinicia
76
- dsh --profile web
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
- Luego crea el archivo de reglas de tu proyecto e inicia una sesión dentro de él:
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: "Prohibido push desde rutas protegidas"
55
+ reason: "No pushes from protected paths"
87
56
 
88
57
  - match: { tools: [edit, write] }
89
58
  action: ask
90
- reason: "La escritura de archivos necesita confirmación"
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
- dsh --profile web --dump-config | grep -A4 'id: permission-rules' # verifica la fila
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
- Una línea base de seguridad completa de 5 reglas y el esquema completo están en [docs/rules-format.en.md](docs/rules-format.en.md).
92
+ ## Install & uninstall
98
93
 
99
- ## Configuración
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
- Todos los ajustes son campos `Config` de Schemastery (modificables desde cordis.yml). Una sobrescritura dirigida por id reemplaza toda la fila: vuelve a escribir todas las claves que necesites.
99
+ ## Configuration
102
100
 
103
- | Clave | Predeterminado | Significado |
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` | *(ninguno)* | Archivo de reglas usado cuando la detección por cwd no encuentra nada; validado al montar |
107
- | `badFilePolicy` | `fail` | Archivo roto: `fail` hace fallar ruidosamente la llamada pendiente (las recargas conservan las reglas previas); `ignore-with-warning` advierte y continúa vacío |
108
- | `maxRules` | `256` | Límite duro de reglas en toda la cadena de fuentes efectiva; archivos mayores fallan la carga |
109
- | `maxCachedWorkspaces` | `512` | Límite duro de cargas de reglas por espacio de trabajo en caché; más allá se expulsa el menos usado recientemente (y su watcher) |
110
- | `patternMode` | `glob` | Tipo de patrón para `params`/`paths`/`when.env`: `glob` o `regex` (los nombres de herramienta siempre son globs) |
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` (`en`/`zh` son las traducciones de referencia) |
114
- | `caseInsensitivePaths` | *(win32)* | Los patrones de `paths` y la comparación con la raíz del workspace ignoran las mayúsculas ASCII; por defecto `true` en Windows, `false` en los demás |
115
- | `audit` | `all` | Granularidad de auditoría: `all` registra cada acierto Y cada paso; `hits` omite los eventos de paso |
116
- | `searchUp` | `false` | Recorre los directorios padre desde el cwd de la sesión y combina cada archivo de reglas encontrado, el más cercano primero |
117
- | `maxGlobStars` | `2` | Límite duro de cuantificadores `*`/`**` sin límite por patrón glob (cota del grado de backtracking) |
118
- | `enforce` | `true` | `false` = modo simulación: los aciertos deny/ask solo se registran en auditoría con un marcador `dryRun` (acción hipotética + resultado real posterior) y todas las llamadas pasan — prueba una política antes de aplicarla |
119
- | `allowUnmarkedAudit` | `false` | Los hosts cuyo `Session.append` es anterior al marcador `ignorable` (la línea `0.1.0-rc.6`) escriben eventos de auditoría sin marcar, haciendo las sesiones irrecuperables en builds más estrictos: el plugin los detecta y desactiva la auditoría del registro de sesión con un aviso único. Ponlo en `true` para reactivar el rastro en la sesión (repara los registros existentes con `scripts/repair-session-logs.mjs`) |
120
-
121
- ### Comandos de sesión
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 lista las reglas activas, sus archivos fuente y cualquier error de la última recarga
125
- /rules list alias explícito del listado simple
126
- /rules reload relee la cadena de archivos de reglas de este workspace
127
- /rules decisions [n] muestra las últimas n decisiones de permisos de esta sesión (por defecto 10)
128
- /rules test <tool> <json> evalúa en seco las reglas contra una llamada hipotética, p. ej. /rules test bash {"command":"git push origin main"}
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>` evalúa contra otro workspace, `--env CLAVE=VALOR` (repetible) sobrescribe el entorno para `when.env`, `--agent <selector>` (repetible) suministra candidatos de identidad para la dimensión `agents`, y `--platform <nombre>` sobrescribe la plataforma para `when.platform`. En cadenas de varios archivos (p. ej. `searchUp`), cada línea de regla se atribuye a su propio archivo fuente.
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
- La salida de los comandos es solo UI: el modelo aprende las reglas únicamente a través de los resultados de herramienta que producen. `language` elige el idioma de salida. Un JSON Schema del archivo de reglas se distribuye en [docs/rules-format.schema.json](docs/rules-format.schema.json) (conéctalo con `# yaml-language-server: $schema=...` para autocompletado en el editor).
152
+ ## Permissions & data
134
153
 
135
- ## Colaboración con dsh-auto-review
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
- - `dsh-permission-rules` produce `ask`; `dsh-auto-review` responde en el waterfall `approval/request` con un veredicto de un segundo modelo de solo lectura (o delega a humanos). Monta ambos para el bucle completo.
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
- ## Límites de seguridad
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
- - **Política, no kernel.** Los candidatos de `paths` provienen solo de un conjunto documentado de claves de argumentos, y solo coinciden rutas relativas al workspace.
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
- ## Trabajo relacionado
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
- - [Andy8647/dsh-auto-approval](https://github.com/Andy8647/dsh-auto-approval) — clasificador allow/deny de dos estados con auditoría en archivo propio; este plugin añade la semántica completa de tres estados, reglas YAML declarativas, auditoría en el log de sesión y delegación segura con `next()`.
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
- ## Limitaciones conocidas
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
- - `permissionRules/decision` se añade con el marcador de envoltura `ignorable: true`, de modo que cualquier build del harness carga el registro: los lectores que no conocen el tipo fuera del repositorio simplemente omiten el registro de auditoría en lugar de rechazar la sesión. Los hosts cuyo `Session.append` es anterior al marcador (la línea `0.1.0-rc.6`) lo DESCARTAN silenciosamente: el plugin los detecta en tiempo de ejecución (verificación previa de la versión del peer + una sonda del sobre añadido) y desactiva la auditoría del registro de sesión con un aviso único, para que los registros sigan siendo cargables en cualquier parte. Pon `allowUnmarkedAudit: true` para reactivar el rastro en la sesión; los registros ya escritos sin marcador pueden repararse con `scripts/repair-session-logs.mjs` antes de cargarlos en hosts con semántica required-on-read.
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
- ## Reparación de registros de sesión
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] # informa filas ajenas, sin cambios
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`). El contrato completo está en la cabecera del script.
188
+ `--home` por defecto es `$DSH_HOME/sessions` (o `~/.dsh/sessions`).
172
189
 
173
- ## Desarrollo
190
+ ## Development
174
191
 
175
192
  ```sh
176
- pnpm install # node ^22.19 || >=24
177
- pnpm run typecheck # tsc, src + tests
178
- pnpm run lint # eslint, src + tests + scripts
179
- pnpm test # vitest: 139 tests, 9 suites
180
- pnpm run test:coverage # puerta de cobertura (90/80/90/90)
181
- pnpm run build # declaraciones tsc + bundles tsdown (lib/)
182
- pnpm run pack:check # build + pack (el artefacto publicado)
183
- node scripts/check-readme-sync.mjs # puerta de sincronización de READMEs en cinco idiomas (también en CI)
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 headless de extremo a extremo (deny bloqueando una herramienta de shell, ask enrutado por el seam de aprobación, `--dump-config`).
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
- ## Colaboradores
209
+ ## Contributors
189
210
 
190
- - [@PerryLink](https://github.com/PerryLink) — creador y mantenedor: vocabulario y evaluación de reglas, runtime, vigilancia HMR, auditoría del registro de sesión y documentación en cinco idiomas.
191
- - [@22xuan](https://github.com/22xuan) — el detallado informe sobre los hosts rc.6 que descartan silenciosamente el marcador `ignorable` de los eventos de auditoría ([#2](https://github.com/PerryLink/dsh-permission-rules/issues/2)) y la discusión en el harness upstream; la detección de capacidades del host de v0.4.1 y la corrección de la documentación derivan directamente de ese análisis.
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 sirve, los demás probablemente también:
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
- ## Licencia
236
+ ## License
216
237
 
217
238
  [Apache License 2.0](LICENSE) © 2026 dsh-permission-rules contributors