dsh-permission-rules 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/LICENSE +201 -0
  3. package/README.es.md +182 -0
  4. package/README.hi.md +182 -0
  5. package/README.md +182 -0
  6. package/README.pt.md +182 -0
  7. package/README.zh.md +182 -0
  8. package/cordis.patch.yml +16 -0
  9. package/docs/rules-format.en.md +105 -0
  10. package/docs/rules-format.md +103 -0
  11. package/docs/rules-format.schema.json +117 -0
  12. package/lib/index.js +1606 -0
  13. package/lib/types/config.d.ts +83 -0
  14. package/lib/types/config.d.ts.map +1 -0
  15. package/lib/types/config.js +72 -0
  16. package/lib/types/config.js.map +1 -0
  17. package/lib/types/events.d.ts +68 -0
  18. package/lib/types/events.d.ts.map +1 -0
  19. package/lib/types/events.js +21 -0
  20. package/lib/types/events.js.map +1 -0
  21. package/lib/types/glob.d.ts +55 -0
  22. package/lib/types/glob.d.ts.map +1 -0
  23. package/lib/types/glob.js +307 -0
  24. package/lib/types/glob.js.map +1 -0
  25. package/lib/types/index.d.ts +25 -0
  26. package/lib/types/index.d.ts.map +1 -0
  27. package/lib/types/index.js +25 -0
  28. package/lib/types/index.js.map +1 -0
  29. package/lib/types/prose.d.ts +66 -0
  30. package/lib/types/prose.d.ts.map +1 -0
  31. package/lib/types/prose.js +143 -0
  32. package/lib/types/prose.js.map +1 -0
  33. package/lib/types/rules.d.ts +226 -0
  34. package/lib/types/rules.d.ts.map +1 -0
  35. package/lib/types/rules.js +581 -0
  36. package/lib/types/rules.js.map +1 -0
  37. package/lib/types/runtime.d.ts +175 -0
  38. package/lib/types/runtime.d.ts.map +1 -0
  39. package/lib/types/runtime.js +497 -0
  40. package/lib/types/runtime.js.map +1 -0
  41. package/package.json +103 -0
  42. package/scripts/repair-session-logs.mjs +327 -0
  43. package/src/config.ts +141 -0
  44. package/src/events.ts +75 -0
  45. package/src/glob.ts +303 -0
  46. package/src/index.ts +27 -0
  47. package/src/prose.ts +206 -0
  48. package/src/rules.ts +695 -0
  49. package/src/runtime.ts +504 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,50 @@
1
+ # Changelog
2
+
3
+ All notable changes to dsh-permission-rules are recorded here, newest first.
4
+
5
+ ## v0.2.0 — 2026-08-14
6
+
7
+ ### Rules vocabulary
8
+
9
+ - New match dimensions: `absent` (argument keys that must be missing) and `when` (host conditions: `env` var globs/regexes + a closed `platform` list), combined with the existing dimensions by AND.
10
+ - Negated param patterns: a `!`-prefixed pattern means the value must NOT match; a key with only negations matches when the key is present and no negation hits.
11
+ - Rule metadata: `enabled: false` (visible but inert, shown as disabled), `description`, and `tags`, all surfaced by `/rules`; unknown fields still fail the load loudly.
12
+ - Path candidates are now extracted at ANY nesting depth (capped at 8), so MCP-style `{ arguments: { path } }` shapes feed `paths` matching; nested scalar leaves feed `params` matching the same way.
13
+ - `searchUp: true` walks parent directories and merges every found rule file, nearest first (child rules override parent rules on first-match semantics); each rule's audit row names its own file.
14
+ - Windows path handling: workspace-root comparison and `paths` matching ignore ASCII case by default on Windows (`caseInsensitivePaths`, default = the host platform), closing the case-variant rule bypass.
15
+ - A JSON Schema for the rule file ships at `docs/rules-format.schema.json` (editor completion via `# yaml-language-server: $schema=...`).
16
+
17
+ ### Security hardening
18
+
19
+ - Catastrophic-backtracking guards at load time: glob patterns are capped at `maxGlobStars` (default 2) unbounded star expansions — the exact degree bound of the generated regex — and regex-mode patterns reject nested unbounded quantifiers (`(a+)+`) and quantified overlapping literal alternations (`(a|aa)+`). Chains of independent quantifiers (`\d+\.\d+\.\d+`) stay allowed by design; glob mode is the guarded default.
20
+ - Audit fidelity: `permissionRules/decision` now carries `outcome`, the FINAL pre-execute decision — an allow hit or passthrough followed by a downstream deny is logged as such instead of claiming the call was allowed.
21
+
22
+ ### Commands and observability
23
+
24
+ - `/rules decisions [n]` lists the session's audit trail (default 10, newest last).
25
+ - `/rules test <tool> <json-args>` dry-evaluates the active rules against a hypothetical call — no tool executes.
26
+ - `/rules` output localizes via the new `language` config (`en`/`zh`/`es`/`pt`/`hi`; `en`/`zh` are the reference translations) and warns about rules shadowed by an earlier catch-all rule.
27
+ - The runtime registers itself as `ctx.permissionRulesRuntime` (watcher/timer counts for host introspection and tests).
28
+
29
+ ### Runtime quality
30
+
31
+ - The per-workspace cache evicts least-recently-USED entries (LRU) instead of insertion-order entries; `maxCachedWorkspaces` bounds the cache (512 default).
32
+ - Watcher lifecycle: a source switch closes stale watchers; pruning a watcher also clears its pending debounce timer; `pendingReloadCount()` exposes the timers.
33
+ - `audit: 'hits'` logs only rule hits, skipping passthrough events for long sessions.
34
+ - The plugin now injects `tools` alongside `commands`, so a host without the tools service fails the mount loudly instead of silently never firing.
35
+
36
+ ### Engineering
37
+
38
+ - ESLint (flat config, `@eslint/js` + `typescript-eslint`); CI matrix (3 OS × Node 22/24) with a coverage gate (90/80/90/90) and `pack:check`.
39
+ - README sync gate (`scripts/check-readme-sync.mjs`, wired into CI): the five language READMEs must share section structure, config-table keys, and `/rules` command docs.
40
+ - Release workflow: tags build, pack, verify the changelog names the version, and attach the tarball to a GitHub Release.
41
+ - `package.json` hygiene: `CHANGELOG.md` ships in the npm files, `sideEffects: false` declared, `.gitattributes` for line endings.
42
+ - Test suite grown to 106 tests across 8 suites; coverage gate held (statements 95%+ / branches 89%+ / functions 99%+ / lines 95%+).
43
+
44
+ ## v0.1.0 — 2026-08-13
45
+
46
+ - First release: declarative `allow`/`deny`/`ask` rules on the `tools/pre-execute` waterfall with tool-name globs, argument glob/regex matching, and workspace-relative path matching.
47
+ - `permissionRules/decision` log-only audit for every hit and passthrough.
48
+ - `ask` rides the official approval seam (compose with `dsh-auto-review` for a second-model answerer).
49
+ - Per-workspace rule discovery (`<cwd>/.dsh/rules.yaml`), `fallbackPath`, Chokidar HMR with debounce, `/rules` session command.
50
+ - Fail-loud loading: invalid YAML, unknown fields/actions, bad globs/regexes, and rule counts over `maxRules` fail the load.
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 dsh-permission-rules contributors
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.es.md ADDED
@@ -0,0 +1,182 @@
1
+ <div align="center">
2
+
3
+ # 🛡️ dsh-permission-rules
4
+
5
+ **Reglas de permisos declarativas estilo Claude Code para DeepSeek Harness.**
6
+
7
+ *Las reglas deciden lo conocido. Un modelo revisor decide lo desconocido.*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-permission-rules/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-permission-rules/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-permission-rules?label=version)](https://github.com/PerryLink/dsh-permission-rules/releases)
14
+
15
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## Qué hace
22
+
23
+ `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:
24
+
25
+ - **`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.
26
+ - **`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).
27
+ - **`allow`** (y la ausencia de coincidencia) delega estrictamente mediante `next()`: los listeners posteriores nunca se cortocircuitan.
28
+
29
+ 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).
30
+
31
+ ```text
32
+ waterfall tools/pre-execute waterfall approval/request (cadena de answerers)
33
+ │ │
34
+ dsh-permission-rules answerer dsh-auto-review
35
+ · primera coincidencia en orden ┌───────────────────┴──────────────┐
36
+ · deny/ask reclaman la llamada │ veredicto de IA (segundo modelo) │ no ── next() ──▶ UI humana
37
+ · allow/paso → next() └───────────────────┬──────────────┘
38
+ │ deny ──▶ resultado denegado │ allowed-once / rejected
39
+ │ ask ──▶ ctx.approval ─────────────────────────┘
40
+ │
41
+ auditoría: permissionRules/decision → approval/asked → autoReview/verdict → approval/decided
42
+ ```
43
+
44
+ ## ¿Por qué reglas *y* un revisor?
45
+
46
+ 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.
47
+
48
+ ## Características
49
+
50
+ - ✅ **Semántica de tres estados** — `allow`, `deny`, `ask`, evaluadas en orden de archivo; gana la primera coincidencia
51
+ - ✅ **Coincidencia rica** — globs de nombre de herramienta (incluido `mcp__*`), 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)
52
+ - ✅ **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
53
+ - ✅ **Metadatos de reglas** — `enabled: false`, `description`, `tags`; `/rules` advierte sobre reglas eclipsadas por un catch-all anterior
54
+ - ✅ **Seguro para el waterfall** — `allow`/paso siempre llaman a `next()`; solo `deny`/`ask` cortocircuitan
55
+ - ✅ **Seam de aprobación oficial** — `ask` fluye por `ctx.approval`; nunca reimplementado, nunca eludido
56
+ - ✅ **Auditoría completa** — los eventos `permissionRules/decision` llevan la acción de la regla Y el resultado final de cada llamada; `/rules decisions` reproduce el rastro en la sesión
57
+ - ✅ **Prueba en seco** — `/rules test <tool> <json-args>` evalúa las reglas activas sin ejecutar nada
58
+ - ✅ **Recarga en caliente** — vigilancia Chokidar con debounce; una edición rota conserva las reglas previas, nunca falla
59
+ - ✅ **Fallo ruidoso** — YAML inválido, acciones/campos desconocidos, globs/regex incorrectos, patrones propensos a backtracking o > `maxRules` hacen fallar la carga
60
+ - ✅ **Ruta caliente acotada** — matchers precompilados, O(reglas × patrones), limitado por `maxRules`; el grado de backtracking de glob limitado por `maxGlobStars`
61
+
62
+ ## Inicio rápido
63
+
64
+ ```sh
65
+ # 1. instala el bundle en tu perfil
66
+ dsh plugin --profile web add "github:PerryLink/dsh-permission-rules#main"
67
+
68
+ # o desde un tarball empaquetado (artefactos compilados, sin permiso de build)
69
+ pnpm pack
70
+ dsh plugin --profile web add ./dsh-permission-rules-0.1.1.tgz
71
+
72
+ # 2. reinicia
73
+ dsh --profile web
74
+ ```
75
+
76
+ Luego crea el archivo de reglas de tu proyecto e inicia una sesión dentro de él:
77
+
78
+ ```yaml
79
+ # <project>/.dsh/rules.yaml
80
+ rules:
81
+ - match: { tools: [bash, pwsh], params: { command: "git push*" }, paths: ["**/secrets/**"] }
82
+ action: deny
83
+ reason: "Prohibido push desde rutas protegidas"
84
+
85
+ - match: { tools: [edit, write] }
86
+ action: ask
87
+ reason: "La escritura de archivos necesita confirmación"
88
+ ```
89
+
90
+ ```sh
91
+ dsh --profile web --dump-config | grep -A4 'id: permission-rules' # verifica la fila
92
+ ```
93
+
94
+ 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).
95
+
96
+ ## Configuración
97
+
98
+ 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
+
100
+ | Clave | Predeterminado | Significado |
101
+ |---|---|---|
102
+ | `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 |
103
+ | `fallbackPath` | *(ninguno)* | Archivo de reglas usado cuando la detección por cwd no encuentra nada; validado al montar |
104
+ | `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 |
105
+ | `maxRules` | `256` | Límite duro de reglas en toda la cadena de fuentes efectiva; archivos mayores fallan la carga |
106
+ | `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) |
107
+ | `patternMode` | `glob` | Tipo de patrón para `params`/`paths`/`when.env`: `glob` o `regex` (los nombres de herramienta siempre son globs) |
108
+ | `watch` | `true` | Vigilancia Chokidar + recarga al cambiar |
109
+ | `watchStabilityThresholdMs` | `200` | Ventana de debounce de recarga (ms) |
110
+ | `language` | `en` | Idioma de salida de `/rules`: `en`, `zh`, `es`, `pt`, `hi` (`en`/`zh` son las traducciones de referencia) |
111
+ | `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 |
112
+ | `audit` | `all` | Granularidad de auditoría: `all` registra cada acierto Y cada paso; `hits` omite los eventos de paso |
113
+ | `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 |
114
+ | `maxGlobStars` | `2` | Límite duro de cuantificadores `*`/`**` sin límite por patrón glob (cota del grado de backtracking) |
115
+
116
+ ### Comandos de sesión
117
+
118
+ ```
119
+ /rules lista las reglas activas, sus archivos fuente y cualquier error de la última recarga
120
+ /rules reload relee la cadena de archivos de reglas de este workspace
121
+ /rules decisions [n] muestra las últimas n decisiones de permisos de esta sesión (por defecto 10)
122
+ /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"}
123
+ ```
124
+
125
+ 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).
126
+
127
+ ## Colaboración con dsh-auto-review
128
+
129
+ - `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.
130
+ - Probado en integración (`test/integration.spec.ts`): `permissionRules/decision` → `approval/asked` → `autoReview/verdict` → `approval/decided`, con el revisor sustituido por un mock.
131
+ - 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.
132
+
133
+ ## Límites de seguridad
134
+
135
+ - **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.
136
+ - **Aquí no hay revisor.** El plugin nunca lanza subagentes ni llama modelos: producir una decisión `ask` es el final de su trabajo.
137
+ - **Sin cambios de sandbox.** La política de sandbox a nivel de SO pertenece al seam de sandbox, no a este plugin.
138
+ - **Mala configuración ruidosa.** Campos YAML desconocidos, acciones desconocidas y patrones incorrectos se rechazan al cargar, nunca se ignoran en silencio.
139
+ - **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.)
140
+
141
+ ## Trabajo relacionado
142
+
143
+ - [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()`.
144
+ - `Drifter-yh/dsh-tool-policy` — política de herramientas deny-by-default; documentada aquí para evitar implementaciones duplicadas.
145
+ - `dsh-auto-review` — la mitad de respaldo de IA del bucle que este plugin encabeza.
146
+
147
+ ## Limitaciones conocidas
148
+
149
+ - `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 rc.6 aceptan e ignoran el marcador, conservando exactamente el comportamiento anterior; las sesiones escritas en hosts rc.6 carecen del marcador y pueden necesitar `scripts/repair-session-logs.mjs` antes de cargarse en hosts con semántica required-on-read.)
150
+ - 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.
151
+ - Los globs son un subconjunto conservador (sin expansión de llaves): escribe dos patrones o usa el modo regex.
152
+ - 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.
153
+
154
+ ## Reparación de registros de sesión
155
+
156
+ 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:
157
+
158
+ ```sh
159
+ node scripts/repair-session-logs.mjs scan [--home DIR] # informa filas ajenas, sin cambios
160
+ node scripts/repair-session-logs.mjs repair [--home DIR] [--dry-run]
161
+ ```
162
+
163
+ `--home` por defecto es `$DSH_HOME/sessions` (o `~/.dsh/sessions`). El contrato completo está en la cabecera del script.
164
+
165
+ ## Desarrollo
166
+
167
+ ```sh
168
+ pnpm install # node ^22.19 || >=24
169
+ pnpm run typecheck # tsc, src + tests
170
+ pnpm run lint # eslint, src + tests + scripts
171
+ pnpm test # vitest: 106 tests, 8 suites
172
+ pnpm run test:coverage # puerta de cobertura (90/80/90/90)
173
+ pnpm run build # declaraciones tsc + bundles tsdown (lib/)
174
+ pnpm run pack:check # build + pack (el artefacto publicado)
175
+ node scripts/check-readme-sync.mjs # puerta de sincronización de READMEs en cinco idiomas (también en CI)
176
+ ```
177
+
178
+ 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`).
179
+
180
+ ## Licencia
181
+
182
+ [Apache License 2.0](LICENSE) © 2026 dsh-permission-rules contributors
package/README.hi.md ADDED
@@ -0,0 +1,182 @@
1
+ <div align="center">
2
+
3
+ # 🛡️ dsh-permission-rules
4
+
5
+ **DeepSeek Harness के लिए Claude Code-शैली की घोषणात्मक अनुमति नियम (permission rules)।**
6
+
7
+ *नियम ज्ञात को तय करते हैं। एक समीक्षक मॉडल अज्ञात को तय करता है।*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-permission-rules/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-permission-rules/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-permission-rules?label=version)](https://github.com/PerryLink/dsh-permission-rules/releases)
14
+
15
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## यह क्या करता है
22
+
23
+ `dsh-permission-rules` हर टूल कॉल के आगे `tools/pre-execute` waterfall पर एक क्रमबद्ध **`allow` / `deny` / `ask`** नियम-सूची रखता है — नियतात्मक, तात्कालिक, ऑडिट-योग्य, और आपके द्वारा सादे YAML में लिखी हुई:
24
+
25
+ - **`deny`** कॉल को रोक देता है। नियम का `reason` मॉडल को दिखने वाली त्रुटि बन जाता है, ताकि एजेंट आँख बंद करके दोबारा कोशिश करने के बजाय *कारण* सीखे।
26
+ - **`ask`** आधिकारिक approval seam से होकर जाता है। साथ में `dsh-auto-review` माउंट करें तो दूसरा मॉडल फ़ैसला करता है; वरना मानव उत्तर देता है; दोनों के न होने पर harness fail-closed रहता है।
27
+ - **`allow`** (और कोई मिलान न होने पर) सख़्ती से `next()` से सौंपता है — बाद वाले listeners कभी शॉर्ट-सर्किट नहीं होते।
28
+
29
+ हर मिलान **और** हर पास-थ्रू `permissionRules/decision` सेशन इवेंट के रूप में ऑडिट-लॉग होता है (केवल लॉग — मॉडल संदर्भ में कुछ अतिरिक्त नहीं डाला जाता)।
30
+
31
+ ```text
32
+ tools/pre-execute waterfall approval/request waterfall (answerer शृंखला)
33
+ │ │
34
+ dsh-permission-rules dsh-auto-review answerer
35
+ · फ़ाइल क्रम में पहला मिलान ┌───────────────┴──────────────┐
36
+ · deny/ask कॉल को अपनाते हैं │ AI निर्णय (दूसरा मॉडल) │ नहीं ── next() ──▶ मानव UI
37
+ · allow/पास-थ्रू → next() └───────────────┬──────────────┘
38
+ │ deny ──▶ अस्वीकृत टूल परिणाम │ allowed-once / rejected
39
+ │ ask ──▶ ctx.approval ────────────────────────┘
40
+ │
41
+ ऑडिट: permissionRules/decision → approval/asked → autoReview/verdict → approval/decided
42
+ ```
43
+
44
+ ## नियम *और* समीक्षक दोनों क्यों?
45
+
46
+ दूसरा मॉडल *"क्या यह कॉल सुरक्षित है?"* का उत्तर निर्णय-क्षमता से देता है, लेकिन इसमें एक राउंड-ट्रिप लगता है और यह ग़लत भी हो सकता है। घोषणात्मक नियम नियतात्मक, तात्कालिक और बिना मॉडल के उत्तर देते हैं — लेकिन केवल वही कवर करते हैं जो व्यवस्थापक ने लिखा। दोनों मिलकर **"पहले नियम, फिर AI सहारा"** चक्र बनाते हैं: नियम ज्ञात को तय करते हैं, समीक्षक अज्ञात को।
47
+
48
+ ## विशेषताएँ
49
+
50
+ - ✅ **तीन-अवस्था शब्दार्थ** — `allow`, `deny`, `ask`, फ़ाइल क्रम में मूल्यांकित; पहला मिलान जीतता है
51
+ - ✅ **समृद्ध मिलान** — टूल-नाम globs (`mcp__*` सहित), आर्गुमेंट कुंजी/मान globs **या** regex (`!pattern` निषेध और `absent` कुंजी आयाम के साथ), दस्तावेज़ित आर्गुमेंट कुंजियों से **किसी भी नेस्टिंग गहराई** पर निकाले गए workspace-सापेक्ष पथ globs, और `when` होस्ट शर्तें (env vars, प्लेटफ़ॉर्म)
52
+ - ✅ **पदानुक्रमित नियम फ़ाइलें** — वैकल्पिक `searchUp` सत्र cwd से फ़ाइलसिस्टम रूट तक हर `.dsh/rules.yaml` को मिलाता है, निकटतम पहले, ताकि चाइल्ड प्रोजेक्ट पैरेंट नियमों को ओवरराइड कर सके
53
+ - ✅ **नियम मेटाडेटा** — `enabled: false`, `description`, `tags`; `/rules` पहले किसी catch-all से छिपे नियमों की चेतावनी देता है
54
+ - ✅ **waterfall-सुरक्षित** — `allow`/पास-थ्रू हमेशा `next()` बुलाते हैं; केवल `deny`/`ask` शॉर्ट-सर्किट करते हैं
55
+ - ✅ **आधिकारिक approval seam** — `ask` `ctx.approval` से होकर जाता है; कभी पुनः-कार्यान्वित नहीं, कभी बायपास नहीं
56
+ - ✅ **पूर्ण ऑडिट** — `permissionRules/decision` इवेंट हर कॉल के लिए नियम क्रिया और अंतिम परिणाम दोनों रखते हैं; `/rules decisions` सत्र में रास्ता फिर चलाता है
57
+ - ✅ **dry-run परीक्षण** — `/rules test <tool> <json-args>` कुछ भी निष्पादित किए बिना सक्रिय नियमों का मूल्यांकन करता है
58
+ - ✅ **हॉट रीलोड** — debounce सहित Chokidar निगरानी; टूटा हुआ संपादन पिछले नियम रखता है, कभी क्रैश नहीं करता
59
+ - ✅ **ज़ोरदार विफलता** — अमान्य YAML, अज्ञात action/फ़ील्ड, ख़राब globs/regex, बैकट्रैकिंग-प्रवण पैटर्न, या `maxRules` से अधिक → लोड विफल
60
+ - ✅ **सीमित हॉट पथ** — पूर्व-संकलित matchers, O(नियम × पैटर्न), `maxRules` द्वारा सीमित; glob बैकट्रैकिंग डिग्री `maxGlobStars` द्वारा सीमित
61
+
62
+ ## त्वरित शुरुआत
63
+
64
+ ```sh
65
+ # 1. bundle को अपने प्रोफ़ाइल में इंस्टॉल करें
66
+ dsh plugin --profile web add "github:PerryLink/dsh-permission-rules#main"
67
+
68
+ # या पैक किए गए tarball से (बिल्ट आर्टिफ़ैक्ट, build अनुमति की ज़रूरत नहीं)
69
+ pnpm pack
70
+ dsh plugin --profile web add ./dsh-permission-rules-0.1.1.tgz
71
+
72
+ # 2. पुनः आरंभ करें
73
+ dsh --profile web
74
+ ```
75
+
76
+ फिर अपने प्रोजेक्ट के लिए नियम फ़ाइल बनाएँ और उसी में सेशन शुरू करें:
77
+
78
+ ```yaml
79
+ # <project>/.dsh/rules.yaml
80
+ rules:
81
+ - match: { tools: [bash, pwsh], params: { command: "git push*" }, paths: ["**/secrets/**"] }
82
+ action: deny
83
+ reason: "संरक्षित पथों से push मना है"
84
+
85
+ - match: { tools: [edit, write] }
86
+ action: ask
87
+ reason: "फ़ाइल लिखने के लिए पुष्टि चाहिए"
88
+ ```
89
+
90
+ ```sh
91
+ dsh --profile web --dump-config | grep -A4 'id: permission-rules' # पंक्ति सत्यापित करें
92
+ ```
93
+
94
+ 5 नियमों वाली पूरी सुरक्षा बेसलाइन और पूरा schema [docs/rules-format.en.md](docs/rules-format.en.md) में है।
95
+
96
+ ## कॉन्फ़िगरेशन
97
+
98
+ सभी ट्यूनेबल Schemastery `Config` फ़ील्ड हैं (cordis.yml से बदले जा सकते हैं)। id-लक्षित ओवरराइड पूरी पंक्ति बदल देता है — जिन कुंजियों की ज़रूरत हो उन्हें दोबारा लिखें।
99
+
100
+ | कुंजी | डिफ़ॉल्ट | अर्थ |
101
+ |---|---|---|
102
+ | `rulesFile` | `.dsh/rules.yaml` | नियम फ़ाइल का स्थान; सापेक्ष = कॉलिंग सेशन के cwd के विरुद्ध, निरपेक्ष = वैश्विक और माउंट पर सत्यापित |
103
+ | `fallbackPath` | *(कोई नहीं)* | cwd खोज में कुछ न मिलने पर प्रयुक्त नियम फ़ाइल; माउंट पर सत्यापित |
104
+ | `badFilePolicy` | `fail` | ख़राब फ़ाइल: `fail` लंबित टूल कॉल को ज़ोरदार त्रुटि देता है (रीलोड पिछले नियम रखते हैं); `ignore-with-warning` चेतावनी देकर ख़ाली चलता है |
105
+ | `maxRules` | `256` | प्रभावी स्रोत शृंखला में नियमों की कठोर सीमा; बड़ी फ़ाइलें लोड विफल करती हैं |
106
+ | `maxCachedWorkspaces` | `512` | कैश की गई प्रति-वर्कस्पेस नियम लोड की कठोर सीमा; इससे अधिक पर सबसे कम हाल में प्रयुक्त वर्कस्पेस (उसके watcher सहित) हटाया जाता है |
107
+ | `patternMode` | `glob` | `params`/`paths`/`when.env` पैटर्न शैली: `glob` या `regex` (टूल नाम हमेशा globs) |
108
+ | `watch` | `true` | Chokidar निगरानी + बदलाव पर रीलोड |
109
+ | `watchStabilityThresholdMs` | `200` | रीलोड debounce विंडो (ms) |
110
+ | `language` | `en` | `/rules` आउटपुट भाषा: `en`, `zh`, `es`, `pt`, `hi` (`en`/`zh` संदर्भ अनुवाद हैं) |
111
+ | `caseInsensitivePaths` | *(win32)* | `paths` पैटर्न और workspace-रूट तुलना ASCII केस अनदेखा करते हैं; Windows पर डिफ़ॉल्ट `true`, अन्यत्र `false` |
112
+ | `audit` | `all` | ऑडिट विवरण स्तर: `all` हर मिलान और पास-थ्रू लॉग करता है; `hits` पास-थ्रू इवेंट छोड़ता है |
113
+ | `searchUp` | `false` | सत्र cwd से पैरेंट निर्देशिकाओं पर चलकर हर मिली नियम फ़ाइल मिलाता है, निकटतम पहले |
114
+ | `maxGlobStars` | `2` | प्रति glob पैटर्न असीमित `*`/`**` क्वांटिफ़ायर की कठोर सीमा (बैकट्रैकिंग-डिग्री सीमा) |
115
+
116
+ ### सेशन कमांड
117
+
118
+ ```
119
+ /rules सक्रिय नियम, उनकी स्रोत फ़ाइलें और अंतिम रीलोड त्रुटि दिखाता है
120
+ /rules reload इस workspace की नियम-फ़ाइल शृंखला दोबारा पढ़ता है
121
+ /rules decisions [n] इस सत्र की अंतिम n अनुमति निर्णय दिखाता है (डिफ़ॉल्ट 10)
122
+ /rules test <tool> <json> काल्पनिक कॉल के विरुद्ध नियमों का dry-मूल्यांकन, जैसे /rules test bash {"command":"git push origin main"}
123
+ ```
124
+
125
+ कमांड आउटपुट केवल UI के लिए है — मॉडल नियमों को केवल उनके उत्पन्न टूल परिणामों से ही सीखता है। `language` आउटपुट भाषा चुनता है। नियम फ़ाइल का JSON Schema [docs/rules-format.schema.json](docs/rules-format.schema.json) पर साथ आता है (संपादक पूर्णता के लिए `# yaml-language-server: $schema=...` से जोड़ें)।
126
+
127
+ ## dsh-auto-review के साथ सहयोग
128
+
129
+ - `dsh-permission-rules` `ask` उत्पन्न करता है; `dsh-auto-review` `approval/request` waterfall पर केवल-पठन दूसरे मॉडल के निर्णय से उत्तर देता है (या मानवों को सौंपता है)। पूर्ण चक्र के लिए दोनों माउंट करें।
130
+ - एकीकरण-परीक्षित (`test/integration.spec.ts`): `permissionRules/decision` → `approval/asked` → `autoReview/verdict` → `approval/decided`, समीक्षक की जगह स्क्रिप्टेड mock।
131
+ - [आधिकारिक harness](https://github.com/deepseek-ai/deepseek-harness) की `never` अनुमोदन नीति और हर fail-closed गारंटी अछूती रहती हैं।
132
+
133
+ ## सुरक्षा सीमाएँ
134
+
135
+ - **नीति, कर्नेल नहीं।** `paths` उम्मीदवार केवल दस्तावेज़ित आर्गुमेंट-कुंजी समूह से आते हैं, और केवल workspace-सापेक्ष पथ मिलते हैं।
136
+ - **यहाँ कोई समीक्षक नहीं।** प्लगइन कभी सबएजेंट नहीं चलाता, मॉडल नहीं बुलाता — `ask` निर्णय देना ही उसके काम का अंत है।
137
+ - **sandbox में कोई बदलाव नहीं।** OS-स्तरीय sandbox नीति sandbox seam का काम है, इस प्लगइन का नहीं।
138
+ - **ग़लत कॉन्फ़िगरेशन पर ज़ोरदार अस्वीकृति।** अज्ञात YAML फ़ील्ड, अज्ञात action और ख़राब पैटर्न लोड पर अस्वीकृत होते हैं, कभी चुपचाप अनदेखे नहीं।
139
+ - **बैकट्रैकिंग सीमाएँ।** glob पैटर्न `maxGlobStars` असीमित स्टार विस्तार तक सीमित हैं; regex-मोड पैटर्न नेस्टेड असीमित क्वांटिफ़ायर और क्वांटिफ़ाइड ओवरलैपिंग शाब्दिक विकल्पों को अस्वीकार करते हैं। (`\d+\.\d+\.\d+` जैसी regex शृंखलाएँ अनुमत रहती हैं — regex मोड एस्केप हैच है, glob मोड संरक्षित डिफ़ॉल्ट है।)
140
+
141
+ ## संबंधित कार्य
142
+
143
+ - [Andy8647/dsh-auto-approval](https://github.com/Andy8647/dsh-auto-approval) — दो-अवस्था allow/deny वर्गीकारक, अपनी फ़ाइल-लॉग ऑडिट के साथ; यह प्लगइन पूर्ण तीन-अवस्था शब्दार्थ, घोषणात्मक YAML नियम, सेशन-लॉग ऑडिट और `next()`-सुरक्षित सौंप जोड़ता है।
144
+ - `Drifter-yh/dsh-tool-policy` — deny-by-default टूल नीति; दोहराने से बचने के लिए यहाँ दस्तावेज़ित।
145
+ - `dsh-auto-review` — इस चक्र का AI-सहारा आधा भाग, जिसका यह प्लगइन अग्रिम छोर है।
146
+
147
+ ## ज्ञात सीमाएँ
148
+
149
+ - `permissionRules/decision` एन्वेलप के `ignorable: true` मार्कर के साथ जोड़ा जाता है, इसलिए कोई भी harness बिल्ड लॉग लोड कर लेता है — जो पाठक इस आउट-ऑफ-रेपो प्रकार को नहीं जानते वे सत्र अस्वीकार करने के बजाय केवल ऑडिट रिकॉर्ड छोड़ देते हैं। (rc.6 होस्ट मार्कर को स्वीकार कर अनदेखा करते हैं, पहले जैसा ही व्यवहार बना रहता है; rc.6 होस्ट पर लिखे सत्रों में मार्कर नहीं होता और required-on-read शब्दार्थ वाले होस्ट पर लोड से पहले `scripts/repair-session-logs.mjs` की ज़रूरत पड़ सकती है।)
150
+ - `paths` उम्मीदवार ह्यूरिस्टिक हैं: केवल दस्तावेज़ित आर्गुमेंट-कुंजियाँ पथ मिलान में आती हैं, और workspace-सापेक्ष मिलान केवल तभी ASCII-केस-असंवेदनशील होता है जब `caseInsensitivePaths` चालू हो।
151
+ - globs एक रूढ़िवादी उपसमुच्चय हैं (brace विस्तार नहीं) — दो पैटर्न लिखें या regex मोड इस्तेमाल करें।
152
+ - regex बैकट्रैकिंग गार्ड संरचनात्मक है, संपूर्ण नहीं: शाब्दिक उपसर्ग के बिना विकल्प-अस्पष्टता के मामले (जैसे कृत्रिम lookarounds) लेखक की ज़िम्मेदारी हैं; अविश्वसनीय फ़ाइलों के लिए glob मोड पसंद करें।
153
+
154
+ ## सत्र लॉग मरम्मत
155
+
156
+ `ignorable` मार्कर से पहले लिखे गए सत्र लॉग को नए harness बिल्ड अस्वीकार कर सकते हैं (`SessionFormatUnsupportedError`)। शामिल `scripts/repair-session-logs.mjs` केवल लक्षित ऑडिट पंक्तियों में `ignorable: true` जोड़ता है, फ़्रेम सुरक्षित रखते हुए, बैकअप के साथ:
157
+
158
+ ```sh
159
+ node scripts/repair-session-logs.mjs scan [--home DIR] # बाहरी पंक्तियों की रिपोर्ट, कोई बदलाव नहीं
160
+ node scripts/repair-session-logs.mjs repair [--home DIR] [--dry-run]
161
+ ```
162
+
163
+ `--home` डिफ़ॉल्ट रूप से `$DSH_HOME/sessions` (या `~/.dsh/sessions`) है। पूरा अनुबंध स्क्रिप्ट के शीर्ष में है।
164
+
165
+ ## विकास
166
+
167
+ ```sh
168
+ pnpm install # node ^22.19 || >=24
169
+ pnpm run typecheck # tsc, src + tests
170
+ pnpm run lint # eslint, src + tests + scripts
171
+ pnpm test # vitest: 106 tests, 8 suites
172
+ pnpm run test:coverage # कवरेज द्वार (90/80/90/90)
173
+ pnpm run build # tsc डिक्लेरेशन + tsdown bundles (lib/)
174
+ pnpm run pack:check # build + pack (प्रकाशित आर्टिफ़ैक्ट)
175
+ node scripts/check-readme-sync.mjs # पाँच-भाषा README सिंक द्वार (CI में भी)
176
+ ```
177
+
178
+ headless एंड-टू-एंड सत्यापन रिकॉर्ड (deny द्वारा shell टूल रोकना, ask का approval seam से गुज़रना, `--dump-config`) [VERIFICATION.md](VERIFICATION.md) में देखें।
179
+
180
+ ## लाइसेंस
181
+
182
+ [Apache License 2.0](LICENSE) © 2026 dsh-permission-rules contributors