dsh-standards 1.2.0 → 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/40-checker/README.md +8 -3
- package/40-checker/bin/dsh-levels.mjs +7 -1
- package/40-checker/scripts/flow-collect.mjs +140 -21
- package/40-checker/scripts/level-audit.mjs +43 -5
- package/40-checker/scripts/run-tests.mjs +21 -0
- package/40-checker/src/flow-evidence.mjs +107 -2
- package/40-checker/src/index.mjs +1 -1
- package/40-checker/src/remediation.mjs +14 -9
- package/40-checker/src/sandbox-run.mjs +403 -0
- package/CHANGELOG.md +8 -1
- package/README.en.md +347 -0
- package/README.es.md +347 -0
- package/README.hi.md +347 -0
- package/README.md +295 -82
- package/README.pt.md +347 -0
- package/docs/assets/dsh-standards-flow-dark.svg +38 -0
- package/docs/assets/dsh-standards-flow-light.svg +38 -0
- package/package.json +2 -3
- package/spec/flow/README.md +21 -4
- package/spec/flow-evidence.schema.json +73 -3
- package/40-checker/test/attestation.test.mjs +0 -59
- package/40-checker/test/checks.test.mjs +0 -414
- package/40-checker/test/claim.test.mjs +0 -28
- package/40-checker/test/client-shape.test.mjs +0 -35
- package/40-checker/test/dco.test.mjs +0 -51
- package/40-checker/test/entry-validate.test.mjs +0 -172
- package/40-checker/test/flow-evidence.test.mjs +0 -295
- package/40-checker/test/governance.test.mjs +0 -76
- package/40-checker/test/label.test.mjs +0 -97
- package/40-checker/test/level-audit.test.mjs +0 -99
- package/40-checker/test/levels.test.mjs +0 -31
- package/40-checker/test/ops.test.mjs +0 -117
- package/40-checker/test/permissions.test.mjs +0 -40
- package/40-checker/test/remediation.test.mjs +0 -300
- package/40-checker/test/semver.test.mjs +0 -32
- package/40-checker/test/verify.test.mjs +0 -57
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)
|
|
17
|
+
[](https://www.npmjs.com/package/dsh-standards)
|
|
18
|
+
[](#instalação-em-três-passos)
|
|
19
|
+
|
|
20
|
+
[](https://github.com/PerryLink/dsh-standards/stargazers)
|
|
21
|
+
[](https://www.npmjs.com/package/dsh-standards)
|
|
22
|
+
[](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.
|
|
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",
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"40-checker/scripts",
|
|
21
21
|
"40-checker/samples",
|
|
22
22
|
"40-checker/fixtures",
|
|
23
|
-
"40-checker/test",
|
|
24
23
|
"40-checker/package.json",
|
|
25
24
|
"40-checker/README.md",
|
|
26
25
|
"spec",
|
|
@@ -34,7 +33,7 @@
|
|
|
34
33
|
"NOTICE"
|
|
35
34
|
],
|
|
36
35
|
"scripts": {
|
|
37
|
-
"test": "node
|
|
36
|
+
"test": "node 40-checker/scripts/run-tests.mjs",
|
|
38
37
|
"test:fixtures": "node bin/dsh-standards.mjs 40-checker/fixtures/good --scope entry --entry-claim static --format text"
|
|
39
38
|
},
|
|
40
39
|
"engines": {
|
package/spec/flow/README.md
CHANGED
|
@@ -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,9 +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
|
|
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
|
|
29
|
-
|
|
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.
|
|
42
|
+
- `level-audit.mjs` reports FLOW `runtime` only when `claims.claimLevel` is
|
|
43
|
+
`sandbox-attested` or `producer.kind` is `sandbox`. A `self-attested`/
|
|
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.",
|
|
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": [
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"producer": {
|
|
31
31
|
"type": "object",
|
|
32
|
+
"description": "Who collected the evidence. `kind: sandbox` is the producer-side equivalent of `claims.claimLevel: sandbox-attested` and is one of the two ways a document may be reported as FLOW runtime.",
|
|
32
33
|
"additionalProperties": false,
|
|
33
34
|
"required": ["command", "at"],
|
|
34
35
|
"properties": {
|
|
@@ -42,7 +43,8 @@
|
|
|
42
43
|
"format": "date-time"
|
|
43
44
|
},
|
|
44
45
|
"kind": {
|
|
45
|
-
"enum": ["local", "ci", "sandbox"]
|
|
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."
|
|
46
48
|
},
|
|
47
49
|
"runner": { "type": "string" },
|
|
48
50
|
"actor": { "type": "string" },
|
|
@@ -106,6 +108,72 @@
|
|
|
106
108
|
"platform": { "type": "string", "minLength": 1 }
|
|
107
109
|
}
|
|
108
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
|
+
},
|
|
109
177
|
"journeys": {
|
|
110
178
|
"type": "object",
|
|
111
179
|
"additionalProperties": false,
|
|
@@ -116,11 +184,13 @@
|
|
|
116
184
|
},
|
|
117
185
|
"claims": {
|
|
118
186
|
"type": "object",
|
|
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.",
|
|
119
188
|
"additionalProperties": false,
|
|
120
189
|
"required": ["claimLevel"],
|
|
121
190
|
"properties": {
|
|
122
191
|
"claimLevel": {
|
|
123
|
-
"enum": ["self-attested", "ci-attested", "sandbox-attested"]
|
|
192
|
+
"enum": ["self-attested", "ci-attested", "sandbox-attested"],
|
|
193
|
+
"description": "`sandbox-attested` is the only claim level that can yield FLOW runtime; `self-attested` and `ci-attested` are never runtime."
|
|
124
194
|
},
|
|
125
195
|
"notClaimed": {
|
|
126
196
|
"type": "array",
|