dsh-standards 1.2.1 → 1.2.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/README.pt.md ADDED
@@ -0,0 +1,347 @@
1
+ <div align="center">
2
+
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/dsh-standards-flow-dark.svg">
5
+ <img src="docs/assets/dsh-standards-flow-light.svg" width="100%" alt="Fluxo do dsh-standards: diretório do plugin → dsh-standards (DSC-01…13 estáticas) → runtime L1–L3 → relatório (text/json/sarif, exit 0|1|2|3) → dsh-levels (ENTRY / FLOW / BOOST)">
6
+ </picture>
7
+
8
+ # dsh-standards
9
+
10
+ **Descubra em um único comando a compatibilidade, a usabilidade e a evidência de eficiência de um plugin DSH — o estático nunca se disfarça de runtime e `not-run` nunca conta como PASS.**
11
+
12
+ A sede de execução dos três níveis de adoção do DSH (ENTRY / FLOW / BOOST): o verificador, a auditoria de níveis e o texto normativo ficam aqui; o guia em prosa está em [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) e o texto das cláusulas de baixo nível continua em [dsh-plugin-spec](https://github.com/PerryLink/dsh-plugin-spec).
13
+
14
+ [Instalar](#instalação-em-três-passos) · [Configuração](#configuração) · [FAQ](#faq) · [简体中文](README.md) · [English](README.en.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
15
+
16
+ [![License](https://img.shields.io/badge/license-Apache--2.0%20%2B%20CC--BY--4.0-3366CC?style=flat-square&labelColor=2B3245)](LICENSE)
17
+ [![npm](https://img.shields.io/npm/v/dsh-standards?style=flat-square&labelColor=2B3245&color=CB3837)](https://www.npmjs.com/package/dsh-standards)
18
+ [![Node](https://img.shields.io/badge/node-%3E%3D24.9.0-339933?style=flat-square&labelColor=2B3245)](#instalação-em-três-passos)
19
+
20
+ [![Stars](https://img.shields.io/github/stars/PerryLink/dsh-standards?style=flat-square&labelColor=2B3245)](https://github.com/PerryLink/dsh-standards/stargazers)
21
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-standards?style=flat-square&labelColor=2B3245&color=CB3837)](https://www.npmjs.com/package/dsh-standards)
22
+ [![Gitee](https://img.shields.io/badge/Gitee-mirror-C71D23?style=flat-square&labelColor=2B3245&logo=gitee)](https://gitee.com/perrylink/dsh-standards)
23
+
24
+ ```sh
25
+ npm i -g dsh-standards # global: dsh-standards + dsh-levels
26
+ npx dsh-standards <plugin-dir> --scope entry --entry-claim static # ou sem instalar nada
27
+ ```
28
+
29
+ </div>
30
+
31
+ <sub>Projeto da comunidade, sem afiliação com a DeepSeek: não oficial, não é certificação nem auditoria de segurança, e não conta com endosso oficial. `DeepSeek Harness` é marca da DeepSeek; este projeto usa apenas a abreviação `DSH`. Repositório canônico: <https://github.com/PerryLink/dsh-standards> (o Gitee é um espelho).</sub>
32
+
33
+ ## O que é
34
+
35
+ Este repositório não publica plugins. Ele constrói a régua e depois mede com ela.
36
+
37
+ A profundidade de adoção do DSH tem três níveis, cada um com sua pergunta e seu vocabulário de evidência, e eles **nunca são fundidos em uma única pontuação**:
38
+
39
+ | Nível | Norma / prática | Que pergunta responde | Estado atual |
40
+ |---|---|---|---|
41
+ | 1 | **DSH-ENTRY, base de compatibilidade** | Um plugin existente pode ser reconhecido, instalado e iniciado sem alterar o código? | 18/18 `recognized`; base-only 10/18 com evidência de runtime (8 clean + 2 reject); o perfil web real 16/18 sem avisos e 2 rejeições de host-gate (autoavaliação, sem revisão independente); client 15/15 loaded; 18/18 clean não alcançado |
42
+ | 2 | **DSH-FLOW, fluidez de uso** | O usuário consegue instalar, configurar, usar, recuperar, atualizar e desinstalar o plugin sem surpresas? | draft; J1/J2/J4/J6 **12 PASS** em fixtures; J3/J7 runtime de fixture; J5/J8 preflight estático; 10 pacotes reais **78 PASS / 4 FAIL / 2 blocked / 66 not-run** |
43
+ | 3 | **DSH-BOOST, aceleração** | O plugin usa as primitivas do Cordis (effect, inject, volatile, eventos, seams, jobs, paralelismo limitado) para tornar o desenvolvimento e o uso mensuravelmente mais baratos? | draft; LEV-1–8 **8/8 measured** (loader / context / provider-capture / synthetic timer; não é linha de base de produção) |
44
+
45
+ Três coisas vivem aqui: `40-checker/` (o verificador DS-C e todos os scripts de evidência), `bin/` (dois pontos de entrada públicos, `dsh-standards` e `dsh-levels`) e `spec/` com o texto normativo nos documentos numerados `31`–`35`. As ferramentas apenas leem o pacote alvo e nunca modificam o que inspecionam; o veredito só aceita evidência, então `not-run`, `NA` e `static` jamais são escritos como PASS.
46
+
47
+ A antiga reserva de npm `dsh-standards@0.0.3` apenas ocupava o nome; esta linha 1.x a substitui (hoje `1.1.2`) e os dois bins são `dsh-standards` e `dsh-levels`.
48
+
49
+ Âncora fixa, registrada em `spec/levels.json` e em cada relatório: `repo=deepseek-ai/deepseek-harness`, `commit=ce7073d51254`, `dsh=0.2.2-alpha.2`, `cordis=4.0.6-alpha.1`. Se você passar outra versão de runtime, o relatório registra com qual régua mediu.
50
+
51
+ ### Números duros atuais
52
+
53
+ - 18 pacotes, entry static: **18/18 recognized, 0 clean**;
54
+ - 18 pacotes, DS-C static: **0 PASS / 9 WARN / 9 FAIL**;
55
+ - 18 pacotes, runtime base-only: **18/18 com JSON bruto; 10/18 G3 verified, 8 partial, 0 error**; após o host gate **8 clean + 2 reject + 8 partial**;
56
+ - runtime de client: **15/15 `client-module-loaded`** (Chromium real); web-app **4/4 loaded**;
57
+ - inutilizáveis: **0 plugin code FAIL; 2 rejeições de host-gate (telemetry/verification)**;
58
+ - autoteste do verificador: **128/128 tests** (localmente com `node --test 40-checker/test/*.test.mjs`; inclui governança, DCO, registros de avaliação, declarações, verificação, cadeia e deriva);
59
+ - J1: **6 PASS + 1 WARN**; LEV-3: volatile **0/20** contra controle **20/20** remount; LEV-6: prefixo estável **100%** contra volátil **0%**; LEV-7: **8.24×** (sintético, não é linha de base de produção).
60
+
61
+ Esses números são autoavaliação mais a cadeia de evidência do repositório, não uma revisão de terceiros: o campo `notClaimed` do relatório lista exatamente o que não é reivindicado (norma oficial, certificação, auditoria de segurança, ranking, linha de base de produção).
62
+
63
+ <details>
64
+ <summary>Mapa do repositório (as especificações numeradas 00–99 são escritas em chinês)</summary>
65
+
66
+ - [START-HERE.md](START-HERE.md) — a página de entrada para uma sessão nova
67
+ - [docs/DEVELOPER-JOURNEY.md](docs/DEVELOPER-JOURNEY.md) — ciclo de vida do plugin e cadeia de ferramentas
68
+ - [spec/levels.json](spec/levels.json) — fonte de verdade legível por máquina dos três níveis
69
+ - [scheme/SCHEME-v1.md](scheme/SCHEME-v1.md) — esquema de avaliação A–E / A–D e rubric
70
+ - [evidence/README.md](evidence/README.md) — cadeia de evidência somente-acréscimo e como reproduzi-la
71
+ - [GOVERNANCE.md](GOVERNANCE.md) · [CONTRIBUTING.md](CONTRIBUTING.md) · [SECURITY.md](SECURITY.md) · [MODIFICATION-POLICY.md](MODIFICATION-POLICY.md)
72
+ - [RENAMES.md](RENAMES.md) — mapa de nomes antigos para novos repositórios
73
+ - [P0-P2-STATUS.md](P0-P2-STATUS.md) — estado DONE / PARTIAL / REPLACED item por item
74
+
75
+ O índice completo de 51 documentos está no [README.md](README.md) em chinês.
76
+
77
+ </details>
78
+
79
+ ## Instalação em três passos
80
+
81
+ **1. Instalar** (duas opções; Node `>=24.9.0`):
82
+
83
+ ```sh
84
+ # instalação global: dsh-standards e dsh-levels ficam no PATH
85
+ npm i -g dsh-standards
86
+ # ou sem instalar nada
87
+ npx dsh-standards --version
88
+ npx -p dsh-standards dsh-levels --help
89
+ ```
90
+
91
+ Não há etapa de build: `bin/` e `40-checker/` são o artefato publicado. O segundo comando com npx precisa de `-p dsh-standards`, porque os nomes soltos `dsh-levels` e `dsh-plugin-verify` pertencem a outros projetos.
92
+
93
+ **2. Rodar uma verificação** (o alvo é um diretório de pacote com `package.json`):
94
+
95
+ ```sh
96
+ # compatibilidade de entrada: reconhecimento estático, sem reivindicar runtime
97
+ dsh-standards ./my-plugin --scope entry --entry-claim static
98
+
99
+ # DS-C completo (escopo padrão): relatórios JSON / SARIF 2.1.0
100
+ dsh-standards ./my-plugin --format json --out report.json
101
+ dsh-standards ./my-plugin --format sarif --out report.sarif
102
+
103
+ # auditoria de três níveis: ENTRY roda sozinho; FLOW / BOOST ficam not-run / not-measured sem arquivos de evidência
104
+ dsh-levels ./my-plugin --format json --out audit.json
105
+ ```
106
+
107
+ **3. Ler o veredito** — primeiro o exit code, depois o `status`:
108
+
109
+ ```text
110
+ 0 completed, no FAIL (PASS or WARN; WARN does not claim a clean PASS)
111
+ 1 completed, at least one FAIL
112
+ 2 incomplete: a mandatory check did not run, or the checker itself failed
113
+ 3 usage error
114
+ ```
115
+
116
+ Saída real no fixture deste repositório (recortada):
117
+
118
+ ```text
119
+ scope=entry profile=package status=pass exit=0
120
+ level: DSH-ENTRY recognized
121
+ DSC-01 PASS C-1 L0
122
+ DSC-14 NA C-14 L1 entry static claim: no runtime evidence
123
+ coverage: mandatory=5 pass=5 warn=0 fail=0 na=0 notRun=0
124
+ ```
125
+
126
+ No mesmo fixture, `dsh-levels` informa o estado dos três níveis — `entry.state=recognized`, `flow.state=not-run`, `boost.state=not-measured` — e acrescenta três linhas `nextActions` dizendo qual evidência falta.
127
+
128
+ ## Capacidades principais
129
+
130
+ - **Face estática (L0)**: não executa o alvo; lê o manifesto, a entrada, o patch e as fontes, e decide `DSC-01`–`DSC-03` e `DSC-10`–`DSC-13`.
131
+ - **Face de runtime (L1–L3)**: carrega o pacote em um runtime Cordis dentro de um **processo filho isolado** e verifica se ele chega a ACTIVE, se o `provide` declarado realmente se registra, se os effects formam topologia, se o unload volta a zero e se o restart é idempotente. Timeout é morte forçada, e morte é `not-run`, nunca PASS.
132
+ - **Face de relatório**: `text` / `json` / `sarif` (SARIF 2.1.0, pronto para o code scanning do GitHub); cada relatório carrega um `anchor` (commit do harness, versões de dsh e cordis) — mude a versão e você está com outra régua.
133
+ - **Auditoria de três níveis**: `dsh-levels` traduz o veredito do ENTRY em um estado de evidência e apenas lê arquivos de evidência J1–J8 (FLOW) e LEV-1–8 (BOOST); sem evidência informa `not-run` / `not-measured`.
134
+ - **Somente leitura**: não modifica o pacote inspecionado nem escreve nada no diretório alvo; os relatórios vão para stdout ou para `--out`.
135
+
136
+ ### Verificações
137
+
138
+ | ID | Cláusula | Camada | O que verifica |
139
+ |---|---|---|---|
140
+ | `DSC-01` | C-1 | L0 | `manifest`, `name`, `version`, `license`, entrada, `dsh.bundle.patch`, forma das exportações |
141
+ | `DSC-02` | C-2 | L0 | `engines.dsh` ou o peer `@deepseek-ai/dsh*`, satisfeito pelo runtime |
142
+ | `DSC-03` | C-3 | L0 | spec de instalação, entrada do índice de mercado, fixação da cadeia de suprimentos |
143
+ | `DSC-04` | C-4 | L1 | carrega até ACTIVE |
144
+ | `DSC-05` | C-5 | L1 | o `provide` declarado realmente se registra |
145
+ | `DSC-06` | C-6 | L1+L2 | topologia de effects, superfície de registro privada |
146
+ | `DSC-07` | C-7 | L2 | effects, stores e registros voltam a zero após o unload |
147
+ | `DSC-08` | C-8 | L3 | idempotência do restart e inicialização a frio |
148
+ | `DSC-09` | C-9 | L1 | contraste entre o declarado e o medido |
149
+ | `DSC-10` | C-10 | L0 | efeitos colaterais em tempo de import (advisory, nunca FAIL) |
150
+ | `DSC-11` | C-11 | L0 | `dsh.capabilities` e gatilhos de alto sinal |
151
+ | `DSC-12` | C-12 | L0 | arquivo de lastro da credencial, `listRecords`, seams globais; também lê a forma de `dsh.commitments` e `dsh.disclosure` |
152
+ | `DSC-13` | C-13 | L0 | `dsh.labels`, `upstream`, redação proibida |
153
+
154
+ `--scope mvp` cobre apenas 8 IDs (`DSC-03/10/11/12/13` ficam fora do MVP) e escreve `subset: "MVP-13"` com `level: null` — isso **não** é um passe de DS-C.
155
+
156
+ ### Qual ferramenta usar e quando
157
+
158
+ | Etapa | Comando | Ferramenta | Saída |
159
+ |---|---|---|---|
160
+ | Início | `dsh-dev new` / `dsh-start new` | dsh-plugin-start | esqueleto instalável |
161
+ | Pré-checagem estática | `dsh-dev check` / `dsh-ready` | dsh-plugin-ready | relatório estático (host `not-run`) |
162
+ | Contrato de host | `dsh-clinic --only R,K,X` | dsh-plugin-doctor/clinic | contrato de host |
163
+ | Instalação isolada | `dsh-test-drive` | dsh-test-drive | evidência C3 |
164
+ | Envio ao mercado | `entry-validate --host-evidence` | o `40-checker` deste repositório | C1–C8 + C3 |
165
+ | Gestão de ferramentas | `dsh-tools list/doctor/install` | dsh-plugin-tools | versões / orientação de instalação |
166
+
167
+ O percurso completo está em [docs/DEVELOPER-JOURNEY.md](docs/DEVELOPER-JOURNEY.md), a família de ferramentas em [dsh-plugin-devtools](https://github.com/PerryLink/dsh-plugin-devtools) e o mapa de nomes antigos em [RENAMES.md](RENAMES.md).
168
+
169
+ ## Configuração
170
+
171
+ Não existe arquivo de configuração: tudo é ajustado por linha de comando. Os dois comandos têm conjuntos distintos: `dsh-standards <package-dir>` delega ao verificador DS-C (`--help` imprime o uso completo) e `dsh-levels <package-dir>` delega à auditoria de três níveis.
172
+
173
+ Os oito que você realmente usa:
174
+
175
+ | Opção | Padrão | Significado |
176
+ |---|---|---|
177
+ | `<package-dir>` | `.` | diretório do pacote alvo com `package.json`; tarballs não são suportados |
178
+ | `--scope` | `ds-c` | `mvp` = 8 IDs do MVP; `ds-c` = declaração completa; `entry` = porta de compatibilidade |
179
+ | `--format` | `text` | `text` / `json` / `sarif` (SARIF 2.1.0) |
180
+ | `--entry-claim` | `runtime` | `runtime` exige evidência de runtime (DSC-14); `static` declara apenas reconhecimento estrutural |
181
+ | `--host` | — | `lib/index.js` do app-boot; obrigatório para o smoke G0–G3 do bundle |
182
+ | `--profile` | `package` | `package` / `listing` / `both`; vira `listing` quando `--market-index` é dado |
183
+ | `--no-exec` | `false` | pula L1–L3 por completo, informado como `not-run` (nunca PASS) |
184
+ | `--out` | — | grava o relatório em arquivo em vez de stdout |
185
+
186
+ <details>
187
+ <summary>Tabela completa de opções (todas as do dsh-standards)</summary>
188
+
189
+ | Opção | Padrão | Significado |
190
+ |---|---|---|
191
+ | `--format` | `text` | formato do relatório: `text` / `json` / `sarif` |
192
+ | `--scope` | `ds-c` | escopo: `mvp` / `ds-c` / `entry` |
193
+ | `--profile` | `package` | perfil de avaliação: `package` / `listing` / `both` |
194
+ | `--runtime` | — | caminho para o `lib/index.js` compilado de `@deepseek-ai/cordis`; ativa L1–L3 |
195
+ | `--runtime-version` | `0.2.2-alpha.2` | versão do dsh anotada no anchor, usada por C-2 |
196
+ | `--cordis-version` | `4.0.6-alpha.1` | versão do cordis anotada no anchor |
197
+ | `--commit` | `ce7073d51254` | commit do harness anotado no anchor |
198
+ | `--install-spec` | — | spec de instalação recomendada para C-3 |
199
+ | `--market-index` | — | JSON de índice de mercado formato 1; ativa o modo listing |
200
+ | `--plugin-name` | — | nome do plugin dentro do índice de mercado |
201
+ | `--timeout` | `10000` | timeout de L1–L3 em ms (100–120000) |
202
+ | `--no-exec` | `false` | pula L1–L3 por completo, informado como `not-run` / `NA` |
203
+ | `--static-only` | `false` | modo M1: só C-1/C-2/C-3/C-11/C-12/C-13 ficam no escopo, C-4–C-9 saem |
204
+ | `--treat-as-plugin` | `false` | roda L1–L3 contra a entrada de servidor de um bundle |
205
+ | `--entry-runtime` | `require` | porta de entry: G0–G3 completos ou proxy `server-entry` |
206
+ | `--entry-claim` | `runtime` | porta de entry: evidência de runtime (DSC-14) ou apenas reconhecimento estático |
207
+ | `--host` | — | `lib/index.js` do app-boot; ativa o smoke G0–G3 do bundle |
208
+ | `--base` | — | `cordis.patch.yml` base para o smoke do bundle |
209
+ | `--web` | — | `cordis.patch.yml` do web-app para o smoke do bundle |
210
+ | `--bare` | — | diretório base de bare-module para o host farm |
211
+ | `--out` | — | grava o relatório em arquivo em vez de stdout |
212
+ | `--help` / `--version` | — | imprime o uso / imprime `dsh-standards <versão> (checker 0.1.0)` |
213
+
214
+ Opções do `dsh-levels`:
215
+
216
+ | Opção | Padrão | Significado |
217
+ |---|---|---|
218
+ | `<package-dir>` | obrigatório | diretório do pacote alvo com `package.json` |
219
+ | `--host` | — | inicialização real G0–G3 para o ENTRY |
220
+ | `--base` | — | patch base para o smoke do bundle |
221
+ | `--bare` | — | fazenda de bare-module para o smoke do bundle |
222
+ | `--no-runtime` | `false` | mantém o ENTRY estático mesmo com `--host` |
223
+ | `--flow-evidence` | — | JSON de evidência J1–J8; cada entrada tem `status` em `pass` / `fail` / `not-run` |
224
+ | `--boost-evidence` | — | JSON de evidência LEV; linha só com status e sem cartão de evidência é rebaixada para `not-measured` |
225
+ | `--timeout` | `150000` | timeout do verificador em ms |
226
+ | `--format` | `text` | `text` / `json` |
227
+ | `--out` | — | grava o resultado em arquivo |
228
+
229
+ </details>
230
+
231
+ ## FAQ
232
+
233
+ <details>
234
+ <summary>Isto é uma certificação ou um ranking?</summary>
235
+
236
+ Não. O projeto se define como **não oficial, não é certificação e não é auditoria de segurança**, e não representa endosso da DeepSeek; não cobra, não vende níveis nem rankings. `A–D` são graus de qualidade de `scheme/`, ortogonais aos níveis `ENTRY` / `FLOW` / `BOOST`: nem os relatórios nem a documentação os fundem em uma única pontuação. Por mais forte que seja a evidência, é autoavaliação mais uma cadeia de evidência interna, e o campo `notClaimed` sempre lista «norma oficial / certificação / auditoria de segurança / ranking / linha de base de produção».
237
+
238
+ </details>
239
+
240
+ <details>
241
+ <summary>Qual é a diferença entre `18/18 recognized` e `18/18 clean`?</summary>
242
+
243
+ `recognized` é um passe de reconhecimento estático (`--entry-claim static`, apenas declaração estrutural, sem reivindicar runtime). `clean` exige evidência de runtime: base-only 10/18 com evidência de runtime (8 clean + 2 reject), o perfil web real 16/18 sem avisos e 2 rejeições de host-gate, e tudo isso é autoavaliação sem revisão independente; por isso **18/18 clean continua não alcançado** e nenhum documento afirma o contrário. Do mesmo modo, `client-module-loaded` não significa usabilidade de UI nem certificação.
244
+
245
+ </details>
246
+
247
+ <details>
248
+ <summary>O que acontece sem runtime do DSH? Passa em silêncio?</summary>
249
+
250
+ Não. L1–L3 precisam de `--runtime` (e um bundle precisa de `--host`); sem isso as verificações são informadas como `ERR` / `not-run` com a razão escrita ao lado (`no --runtime supplied; L1-L3 not run`), e no escopo package a conclusão passa a `incomplete` com exit `2`. `--scope entry --entry-claim static` ainda dá `DSH-ENTRY recognized`, mas isso é uma declaração estática; para um veredito de runtime passe `--runtime` ou `--host`.
251
+
252
+ </details>
253
+
254
+ <details>
255
+ <summary>Ele mexe no meu pacote? Pode quebrar meu código?</summary>
256
+
257
+ O verificador apenas lê o diretório alvo e nunca o modifica. Quando as verificações de runtime rodam, o carregamento acontece em um **processo filho** com morte forçada ao estourar o timeout (10 s por padrão, ajustável com `--timeout`); uma morte é registrada como `not-run`, não como PASS, e o filho não consegue ler o ambiente do próprio verificador. Adicione `--no-exec` para não executar nada, ou `--static-only` para um veredito apenas estático.
258
+
259
+ </details>
260
+
261
+ <details>
262
+ <summary>Como isso se relaciona com guide / doctor / cert / portal / catalog?</summary>
263
+
264
+ Este repositório é o texto normativo mais o verificador e a auditoria de níveis; o guia em prosa vive em `dsh-plugin-guide`, a medição do contrato de host em `dsh-plugin-doctor` (clinic), e as ferramentas de mercado e portal são independentes. A divisão de papéis e os caminhos de contribuição estão no documento chinês `39`, e a tabela de seleção acima resume quando usar cada ferramenta.
265
+
266
+ </details>
267
+
268
+ ## Limitações conhecidas
269
+
270
+ - **Sem certificação e sem auditoria de segurança.** Um relatório é um sinal de qualidade, não uma prova de conformidade; `A–D` são graus de qualidade, não `ENTRY` / `FLOW` / `BOOST`.
271
+ - **Sem cobrança, sem venda de níveis, sem venda de rankings.**
272
+ - **Nunca se escreve o estático como runtime.**
273
+ - **Nunca se escreve 10/18 base-only como 18/18 web/produção, nem `client-module-loaded` como UI ou certificação.**
274
+ - **Nunca se reivindica recomendação ou adoção oficial, certificação, acreditação ou auditoria de segurança.**
275
+ - **Lacuna de cobertura do MVP**: `--scope mvp` cobre apenas 8 IDs (`DSC-03/10/11/12/13` ficam fora); seu veredito é `subset: "MVP-13"` com `level: null` e não deve ser usado como selo DS-C.
276
+ - **Somente diretórios de pacote**: o alvo deve ser um diretório com `package.json`; suporte a tarball não faz parte do MVP.
277
+ - **Vereditos de runtime têm pré-requisitos**: sem `--runtime` ou `--host`, L1–L3 só podem ser `not-run`, e `--entry-claim static` nunca produz veredito de runtime.
278
+ - **Vereditos são ancorados em versões**: mude `commit` / `dsh` / `cordis` e você tem outra régua; um relatório antigo não é evidência para uma versão nova.
279
+ - **Números do BOOST não são linha de base de produção**: os 8/8 measured de LEV vêm de ambientes loader / context / provider-capture / synthetic timer, e o 8.24× do LEV-7 também.
280
+ - **Mudanças de texto precisam ser declaradas**: copiar ou modificar texto deste repositório exige um Change Notice visível (commit de origem, qual cláusula, o que mudou, por quê, data), veja [`MODIFICATION-POLICY.md`](MODIFICATION-POLICY.md); marcas e selos não são licenciados pelas licenças acima, veja `governance/mark-policy.md`.
281
+
282
+ ## Desenvolvimento
283
+
284
+ ```sh
285
+ git clone https://github.com/PerryLink/dsh-standards.git
286
+ cd dsh-standards
287
+
288
+ node --test 40-checker/test/*.test.mjs # 128/128
289
+ node bin/dsh-standards.mjs 40-checker/fixtures/good \
290
+ --scope entry --entry-claim static --format text # smoke do fixture
291
+ node bin/dsh-levels.mjs 40-checker/fixtures/good --format json
292
+
293
+ # direto ao verificador a partir de um checkout do código
294
+ node 40-checker/bin/dsh-plugin-verify.mjs <plugin-dir> --scope entry --entry-claim static
295
+ node 40-checker/bin/dsh-plugin-verify.mjs <bundle-dir> --scope entry \
296
+ --host /path/to/@deepseek-ai/dsh-app-boot/lib/index.js
297
+
298
+ node 40-checker/scripts/journey-runtime.mjs --package <dir> --json # jornada J1 de instalação/desinstalação
299
+ node 40-checker/scripts/governance-check.mjs # cláusulas de governança
300
+ node 40-checker/scripts/attestation-check.mjs # registros de avaliação
301
+ node 40-checker/scripts/claim-check.mjs # consistência de declarações
302
+ node 40-checker/scripts/dco-check.mjs --range HEAD~1..HEAD # DCO
303
+ node publish/verify.mjs --id DSH-ATT-2026-001 # verifica um registro de exemplo
304
+
305
+ cd examples/boost && node lev7-bench.mjs 64 20 # benchmark LEV-7 de paralelismo limitado
306
+ ```
307
+
308
+ As imagens do README são geradas por programa com [`scripts/gen-readme-assets.py`](scripts/gen-readme-assets.py) (Python + Pillow, SVG claro e escuro) e podem ser regeneradas a qualquer momento: `python scripts/gen-readme-assets.py`.
309
+
310
+ ### Estrutura
311
+
312
+ ```text
313
+ 00-99*.md documentos de norma / pesquisa / perfil / comunicação
314
+ bin/ dois pontos de entrada públicos: dsh-standards, dsh-levels
315
+ 40-checker/ verificador, jornadas J1, bundle smoke, amostras, resultados
316
+ governance/ papéis, termos de contribuição, política de marcas, apelações, COI, registro de decisões
317
+ adoption/ pacotes de adoção official / market / developer
318
+ spec/ levels.json + clauses.json + schemas (evidence / report / attestation)
319
+ scheme/ esquema de avaliação A–E / A–D e rubric
320
+ evidence/ cadeia de evidência somente-acréscimo e instruções de reprodução
321
+ examples/boost/ implementação de referência LEV-7 e benchmarks
322
+ publish/ exemplos de labels + JSON de registros de avaliação
323
+ docs/ documentos de longo prazo como DEVELOPER-JOURNEY e as imagens do README
324
+ ```
325
+
326
+ ### Governança e contribuição
327
+
328
+ - Papéis e permissões: `governance/roles.json`; resumo de uma página: [GOVERNANCE.md](GOVERNANCE.md)
329
+ - Contribuição: DCO 1.1 + DCT v1 (`dsh-ct/1`, uma licença e não uma cessão de direitos), veja [CONTRIBUTING.md](CONTRIBUTING.md)
330
+ - Marcas: `governance/mark-policy.md` (concessão automática, revogável, com aviso legal obrigatório)
331
+ - Apelações: `governance/appeals.md`; a IA apenas recebe, cronometra e revisa, a decisão é humana
332
+ - Três pacotes de adoção: `adoption/{official,market,developer}/`
333
+
334
+ ## Família e créditos
335
+
336
+ Este projeto é um membro do ecossistema DSH mantido por [PerryLink](https://github.com/PerryLink): este ramo cuida da régua — texto normativo, verificador e auditoria de níveis —, enquanto as ferramentas de guia, scaffolding, verificação e portal têm repositórios próprios. Se ele te poupou algumas verificações manuais, **deixe uma estrela** — não desbloqueia nada, mas ajuda a próxima pessoa que precisar verificar um plugin a encontrar este repositório.
337
+
338
+ O projeto anterior `dsh-plugin-standard` (lanbaolu) pertence ao mesmo ecossistema e não é afiliado a este projeto; qualquer referência ou comparação citará a fonte.
339
+
340
+ ## Licença
341
+
342
+ - **Texto / normas / documentação / traduções**: CC BY 4.0 ([`LICENSE-CC-BY`](LICENSE-CC-BY)); modificações devem trazer um Change Notice conforme [`MODIFICATION-POLICY.md`](MODIFICATION-POLICY.md);
343
+ - **Código / scripts / schemas**: Apache-2.0 ([`LICENSE-APACHE`](LICENSE-APACHE), incluindo concessão de patentes e terminação defensiva);
344
+ - **Marcas / selos**: regras próprias em `governance/mark-policy.md`, não concedidas pelas licenças acima;
345
+ - **Contribuições**: DCO 1.1 + DCT v1, sem cessão de direitos autorais.
346
+
347
+ <p align="center"><sub>CC BY 4.0 (texto) · Apache-2.0 (código) · projeto da comunidade, sem afiliação com a DeepSeek.</sub></p>
@@ -0,0 +1,38 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="400" viewBox="0 0 1200 400" role="img" aria-label="dsh-standards pipeline">
2
+ <title>dsh-standards pipeline</title>
3
+ <rect width="1200" height="400" rx="18" fill="#0d1117"/>
4
+ <text x="60" y="62" fill="#f0f6fc" font-family="ui-sans-serif,system-ui,sans-serif" font-size="30" font-weight="700">dsh-standards</text>
5
+ <text x="60" y="94" fill="#8b949e" font-family="ui-monospace,monospace" font-size="16">one package dir in, three adoption levels out - read-only, never modifies the target</text>
6
+ <line x1="60" y1="116" x2="1140" y2="116" stroke="#30363d"/>
7
+ <rect x="60" y="150" width="180" height="96" rx="14" fill="#161b22" stroke="#30363d" stroke-width="2"/>
8
+ <text x="150" y="190" fill="#f0f6fc" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">plugin dir</text>
9
+ <text x="150" y="216" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">package.json</text>
10
+ <text x="150" y="233" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">dsh.bundle.patch</text>
11
+ <path d="M246 198h33" stroke="#8b949e" stroke-width="3"/>
12
+ <path d="M277 191l10 7-10 7" fill="none" stroke="#8b949e" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
13
+ <rect x="285" y="150" width="180" height="96" rx="14" fill="#161b22" stroke="#4B67B4" stroke-width="2"/>
14
+ <text x="375" y="190" fill="#f0f6fc" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">dsh-standards</text>
15
+ <text x="375" y="216" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">DSC-01..13 - L0 static</text>
16
+ <path d="M471 198h33" stroke="#8b949e" stroke-width="3"/>
17
+ <path d="M502 191l10 7-10 7" fill="none" stroke="#8b949e" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
18
+ <rect x="510" y="150" width="180" height="96" rx="14" fill="#161b22" stroke="#30363d" stroke-width="2"/>
19
+ <text x="600" y="190" fill="#f0f6fc" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">L1-L3 runtime</text>
20
+ <text x="600" y="216" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">loads to ACTIVE</text>
21
+ <text x="600" y="233" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">effects / reload</text>
22
+ <path d="M696 198h33" stroke="#8b949e" stroke-width="3"/>
23
+ <path d="M727 191l10 7-10 7" fill="none" stroke="#8b949e" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
24
+ <rect x="735" y="150" width="180" height="96" rx="14" fill="#161b22" stroke="#30363d" stroke-width="2"/>
25
+ <text x="825" y="190" fill="#f0f6fc" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">report</text>
26
+ <text x="825" y="216" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">text|json|sarif</text>
27
+ <text x="825" y="233" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">exit 0|1|2|3</text>
28
+ <path d="M921 198h33" stroke="#8b949e" stroke-width="3"/>
29
+ <path d="M952 191l10 7-10 7" fill="none" stroke="#8b949e" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
30
+ <rect x="960" y="150" width="180" height="96" rx="14" fill="#161b22" stroke="#3fb950" stroke-width="2"/>
31
+ <text x="1050" y="190" fill="#f0f6fc" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">dsh-levels</text>
32
+ <text x="1050" y="216" fill="#8b949e" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">ENTRY - FLOW - BOOST</text>
33
+ <path d="M375 246v39" stroke="#4B67B4" stroke-width="2" stroke-dasharray="5 5"/>
34
+ <path d="M825 246v39" stroke="#4B67B4" stroke-width="2" stroke-dasharray="5 5"/>
35
+ <rect x="285" y="285" width="630" height="52" rx="12" fill="#161b22" stroke="#4B67B4" stroke-width="2"/>
36
+ <text x="600" y="318" fill="#f0f6fc" text-anchor="middle" font-family="ui-monospace,monospace" font-size="14">not-run != PASS - static != runtime - A-D != ENTRY/FLOW/BOOST</text>
37
+ <text x="60" y="378" fill="#8b949e" font-family="ui-monospace,monospace" font-size="13">dsh-standards 1.x umbrella - checker 0.1.0 - L1-L3 run in an isolated child with a hard timeout; a kill is not-run, never a pass</text>
38
+ </svg>
@@ -0,0 +1,38 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="400" viewBox="0 0 1200 400" role="img" aria-label="dsh-standards pipeline">
2
+ <title>dsh-standards pipeline</title>
3
+ <rect width="1200" height="400" rx="18" fill="#ffffff"/>
4
+ <text x="60" y="62" fill="#1f2328" font-family="ui-sans-serif,system-ui,sans-serif" font-size="30" font-weight="700">dsh-standards</text>
5
+ <text x="60" y="94" fill="#57606a" font-family="ui-monospace,monospace" font-size="16">one package dir in, three adoption levels out - read-only, never modifies the target</text>
6
+ <line x1="60" y1="116" x2="1140" y2="116" stroke="#d0d7de"/>
7
+ <rect x="60" y="150" width="180" height="96" rx="14" fill="#f6f8fa" stroke="#d0d7de" stroke-width="2"/>
8
+ <text x="150" y="190" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">plugin dir</text>
9
+ <text x="150" y="216" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">package.json</text>
10
+ <text x="150" y="233" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">dsh.bundle.patch</text>
11
+ <path d="M246 198h33" stroke="#57606a" stroke-width="3"/>
12
+ <path d="M277 191l10 7-10 7" fill="none" stroke="#57606a" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
13
+ <rect x="285" y="150" width="180" height="96" rx="14" fill="#f6f8fa" stroke="#4B67B4" stroke-width="2"/>
14
+ <text x="375" y="190" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">dsh-standards</text>
15
+ <text x="375" y="216" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">DSC-01..13 - L0 static</text>
16
+ <path d="M471 198h33" stroke="#57606a" stroke-width="3"/>
17
+ <path d="M502 191l10 7-10 7" fill="none" stroke="#57606a" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
18
+ <rect x="510" y="150" width="180" height="96" rx="14" fill="#f6f8fa" stroke="#d0d7de" stroke-width="2"/>
19
+ <text x="600" y="190" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">L1-L3 runtime</text>
20
+ <text x="600" y="216" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">loads to ACTIVE</text>
21
+ <text x="600" y="233" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">effects / reload</text>
22
+ <path d="M696 198h33" stroke="#57606a" stroke-width="3"/>
23
+ <path d="M727 191l10 7-10 7" fill="none" stroke="#57606a" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
24
+ <rect x="735" y="150" width="180" height="96" rx="14" fill="#f6f8fa" stroke="#d0d7de" stroke-width="2"/>
25
+ <text x="825" y="190" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">report</text>
26
+ <text x="825" y="216" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">text|json|sarif</text>
27
+ <text x="825" y="233" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">exit 0|1|2|3</text>
28
+ <path d="M921 198h33" stroke="#57606a" stroke-width="3"/>
29
+ <path d="M952 191l10 7-10 7" fill="none" stroke="#57606a" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
30
+ <rect x="960" y="150" width="180" height="96" rx="14" fill="#f6f8fa" stroke="#16a34a" stroke-width="2"/>
31
+ <text x="1050" y="190" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="16" font-weight="700">dsh-levels</text>
32
+ <text x="1050" y="216" fill="#57606a" text-anchor="middle" font-family="ui-monospace,monospace" font-size="12">ENTRY - FLOW - BOOST</text>
33
+ <path d="M375 246v39" stroke="#4B67B4" stroke-width="2" stroke-dasharray="5 5"/>
34
+ <path d="M825 246v39" stroke="#4B67B4" stroke-width="2" stroke-dasharray="5 5"/>
35
+ <rect x="285" y="285" width="630" height="52" rx="12" fill="#f6f8fa" stroke="#4B67B4" stroke-width="2"/>
36
+ <text x="600" y="318" fill="#1f2328" text-anchor="middle" font-family="ui-monospace,monospace" font-size="14">not-run != PASS - static != runtime - A-D != ENTRY/FLOW/BOOST</text>
37
+ <text x="60" y="378" fill="#57606a" font-family="ui-monospace,monospace" font-size="13">dsh-standards 1.x umbrella - checker 0.1.0 - L1-L3 run in an isolated child with a hard timeout; a kill is not-run, never a pass</text>
38
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-standards",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "DSH plugin standards and conformance checks: ENTRY/FLOW checks plus BOOST guidance. Non-official; no certification or ranking.",
5
5
  "type": "module",
6
6
  "main": "40-checker/src/index.mjs",
@@ -33,7 +33,7 @@
33
33
  "NOTICE"
34
34
  ],
35
35
  "scripts": {
36
- "test": "node --test 40-checker/test/*.test.mjs",
36
+ "test": "node 40-checker/scripts/run-tests.mjs",
37
37
  "test:fixtures": "node bin/dsh-standards.mjs 40-checker/fixtures/good --scope entry --entry-claim static --format text"
38
38
  },
39
39
  "engines": {
@@ -9,6 +9,9 @@ uninstall, diagnostics, client/server states.
9
9
  are static preflight or manual and never count as a runtime pass.
10
10
  - Evidence: `dsh-flow-evidence/2` ([../flow-evidence.schema.json](../flow-evidence.schema.json)).
11
11
  Collect it with `node 40-checker/bin/dsh-flow-collect.mjs --package <dir> --out flow-evidence.json`.
12
+ Use `--sandbox` (or `dsh-levels flow sandbox`) to run the runtime probe under
13
+ `unshare` (network), `prlimit` (nproc/as) and a process-group timeout that
14
+ kills the whole tree with an allowlisted, token-free environment.
12
15
 
13
16
  ## Evidence chain rules
14
17
 
@@ -21,13 +24,23 @@ uninstall, diagnostics, client/server states.
21
24
  `static` and `not-run` never count toward 8/8.
22
25
  - `static` preflight is not runtime: a static PASS is a preflight result only.
23
26
  - The collector copies the package to a temp dir, runs against the copy, and
24
- records `subject.treeSha256` before/after; a changed tree fails the run.
27
+ records `subject.treeSha256` before/after. A changed tree
28
+ (`treeStable: false` or a differing `treeSha256After`) is structurally
29
+ invalid, not just a warning.
25
30
  - Child environments are built from an allowlist; tokens/keys/secrets never
26
- reach the inspected plugin.
31
+ reach the inspected plugin. The sandbox mode additionally asserts that
32
+ `GH_TOKEN`, `NPM_TOKEN` and `GITHUB_TOKEN` are absent and aborts if one
33
+ survives.
27
34
  - `claims.claimLevel` is `self-attested` for a local collector run,
28
- `ci-attested` with `--ci`. Neither is `verified`, a certification, or a
29
- security audit; only a sandbox run may be described as runtime-attested.
35
+ `ci-attested` with `--ci`, and `sandbox-attested` only for `--sandbox` when
36
+ every isolation item is effective. None of them is a certification or a
37
+ security audit.
38
+ - `producer.kind` is `sandbox` only when the sandbox report has an empty
39
+ `degraded` list. Any missing item (`unshare-missing`, `prlimit-missing`,
40
+ `env-token-present`, `home-not-isolated`) switches it to `sandbox-degraded`;
41
+ that document remains structurally valid but is never FLOW runtime.
30
42
  - `level-audit.mjs` reports FLOW `runtime` only when `claims.claimLevel` is
31
43
  `sandbox-attested` or `producer.kind` is `sandbox`. A `self-attested`/
32
- `ci-attested` document keeps its `passed` count but is reported `not-run`;
33
- structural validation cannot prove where the commands ran.
44
+ `ci-attested`/`sandbox-degraded` document keeps its `passed` count but is
45
+ reported `not-run` (or its honest fail/blocked state), with the degraded
46
+ reasons in the audit reason.
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/PerryLink/dsh-standards/spec/flow-evidence.schema.json",
4
4
  "title": "DSH FLOW evidence chain",
5
- "description": "One collected FLOW result (J1-J8) bound to a package, a host, a timestamp, and a chain hash. Structural validation only: it does not prove the commands really ran. v1 (dsh-flow-journey/1, dsh-flow-runtime/1) and bare {Jx:{status}} documents are deprecated and never count as a pass. `level-audit.mjs --flow-evidence` accepts this document only, and reports `runtime` only when `claims.claimLevel` is `sandbox-attested` or `producer.kind` is `sandbox`; self-attested/ci-attested keeps its pass count but stays not-run.",
5
+ "description": "One collected FLOW result (J1-J8) bound to a package, a host, a timestamp, and a chain hash. Structural validation only: it does not prove the commands really ran. v1 (dsh-flow-journey/1, dsh-flow-runtime/1) and bare {Jx:{status}} documents are deprecated and never count as a pass. `level-audit.mjs --flow-evidence` accepts this document only, and reports `runtime` only when `claims.claimLevel` is `sandbox-attested` or `producer.kind` is `sandbox`; `sandbox-degraded` (any isolation item missing) and self-attested/ci-attested keep their pass count but stay not-run.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": [
@@ -43,8 +43,8 @@
43
43
  "format": "date-time"
44
44
  },
45
45
  "kind": {
46
- "enum": ["local", "ci", "sandbox"],
47
- "description": "`local`/`ci` are structural evidence only; `sandbox` may count toward FLOW runtime."
46
+ "enum": ["local", "ci", "sandbox", "sandbox-degraded"],
47
+ "description": "`local`/`ci` are structural evidence only; `sandbox` (every isolation item effective) may count toward FLOW runtime; `sandbox-degraded` never does."
48
48
  },
49
49
  "runner": { "type": "string" },
50
50
  "actor": { "type": "string" },
@@ -108,6 +108,72 @@
108
108
  "platform": { "type": "string", "minLength": 1 }
109
109
  }
110
110
  },
111
+ "sandbox": {
112
+ "type": "object",
113
+ "description": "Containment report from `flow collect --sandbox`. `mode` is `sandbox` only when every isolation item (env allowlist + token assertion, temporary HOME/DSH_HOME, network namespace, prlimit nproc/as, process-group tree kill) is effective. `producer.kind=sandbox` requires mode=sandbox and an empty `degraded` list.",
114
+ "required": ["mode", "degraded"],
115
+ "properties": {
116
+ "schema": { "const": "dsh-sandbox-report/1" },
117
+ "mode": { "enum": ["sandbox", "sandbox-degraded"] },
118
+ "degraded": {
119
+ "type": "array",
120
+ "items": { "type": "string", "minLength": 1 },
121
+ "description": "Missing isolation items, e.g. unshare-missing, prlimit-missing, env-token-present, home-not-isolated."
122
+ },
123
+ "platform": { "type": "string" },
124
+ "env": {
125
+ "type": "object",
126
+ "properties": {
127
+ "policy": { "type": "string" },
128
+ "checked": { "type": "array", "items": { "type": "string" } },
129
+ "absent": { "type": "boolean" },
130
+ "offenders": { "type": "array", "items": { "type": "string" } }
131
+ }
132
+ },
133
+ "home": {
134
+ "type": "object",
135
+ "properties": {
136
+ "isolated": { "type": "boolean" },
137
+ "mode": { "type": "string" }
138
+ }
139
+ },
140
+ "network": {
141
+ "type": "object",
142
+ "properties": {
143
+ "isolated": { "type": "boolean" },
144
+ "mechanism": { "type": "string" },
145
+ "reason": { "type": "string" },
146
+ "bin": { "type": "string" },
147
+ "args": { "type": "array", "items": { "type": "string" } },
148
+ "probe": { "type": "object" },
149
+ "attempts": { "type": "array", "items": { "type": "object" } }
150
+ }
151
+ },
152
+ "limits": {
153
+ "type": "object",
154
+ "properties": {
155
+ "available": { "type": "boolean" },
156
+ "bin": { "type": "string" },
157
+ "nproc": { "type": "integer", "minimum": 2 },
158
+ "asBytes": { "type": "integer", "minimum": 67108864 },
159
+ "applied": { "type": "array", "items": { "type": "string" } },
160
+ "observed": { "type": "object" },
161
+ "probe": { "type": "object" },
162
+ "reason": { "type": "string" }
163
+ }
164
+ },
165
+ "processTreeKill": {
166
+ "type": "object",
167
+ "properties": {
168
+ "available": { "type": "boolean" },
169
+ "mechanism": { "type": "string" }
170
+ }
171
+ },
172
+ "executed": { "type": "boolean", "description": "True when the sandboxed runtime probe actually ran." },
173
+ "execution": { "type": "object", "description": "Command, exit code, timeout/kill outcome, and process-tree clearing proof." },
174
+ "note": { "type": "string" }
175
+ }
176
+ },
111
177
  "journeys": {
112
178
  "type": "object",
113
179
  "additionalProperties": false,
@@ -118,7 +184,7 @@
118
184
  },
119
185
  "claims": {
120
186
  "type": "object",
121
- "description": "Attestation level of this evidence. Passing journeys are not runtime by themselves: `level-audit` may report `runtime` only when `claimLevel` is `sandbox-attested` (or `producer.kind` is `sandbox`). `self-attested` (local collector) and `ci-attested` (`--ci`) keep their `passed` count but are reported `not-run`, because structural validation cannot prove the commands ran, let alone in a sandbox.",
187
+ "description": "Attestation level of this evidence. Passing journeys are not runtime by themselves: `level-audit` may report `runtime` only when `claimLevel` is `sandbox-attested` (or `producer.kind` is `sandbox`). `self-attested` (local collector), `ci-attested` (`--ci`), and every `sandbox-degraded` document keep their `passed` count but are reported `not-run`, because structural validation cannot prove the commands ran, let alone in a fully isolated sandbox.",
122
188
  "additionalProperties": false,
123
189
  "required": ["claimLevel"],
124
190
  "properties": {