dsh-standards 1.2.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/40-checker/README.md +18 -1
  2. package/40-checker/scripts/build-offline-kit.mjs +284 -0
  3. package/40-checker/scripts/build-sidecar.mjs +714 -0
  4. package/40-checker/scripts/flow-collect.mjs +7 -1
  5. package/40-checker/scripts/level-audit.mjs +45 -7
  6. package/40-checker/scripts/run-tests.mjs +3 -7
  7. package/40-checker/src/author-cli.mjs +406 -0
  8. package/40-checker/src/author-report.mjs +271 -0
  9. package/40-checker/src/bundle-static.mjs +181 -0
  10. package/40-checker/src/cli.mjs +100 -11
  11. package/40-checker/src/client-shape.mjs +33 -3
  12. package/40-checker/src/declarations.mjs +53 -8
  13. package/40-checker/src/flow-evidence.mjs +106 -1
  14. package/40-checker/src/index.mjs +6 -4
  15. package/40-checker/src/manifest.mjs +87 -14
  16. package/40-checker/src/remediation.mjs +108 -7
  17. package/40-checker/src/report.mjs +203 -26
  18. package/40-checker/src/semver.mjs +112 -65
  19. package/40-checker/src/util.mjs +51 -8
  20. package/CHANGELOG.md +44 -0
  21. package/README.en.md +7 -2
  22. package/README.es.md +7 -2
  23. package/README.hi.md +7 -2
  24. package/README.md +35 -18
  25. package/README.pt.md +7 -2
  26. package/bin/dsh-standards.mjs +13 -2
  27. package/docs/assets/dsh-standards-flow-v3-dark.svg +87 -0
  28. package/docs/assets/dsh-standards-flow-v3-light.svg +87 -0
  29. package/docs/assets/dsh-standards-flow-v4-dark.svg +79 -0
  30. package/docs/assets/dsh-standards-flow-v4-light.svg +79 -0
  31. package/docs/assets/dsh-standards-hero-en-dark.webp +0 -0
  32. package/docs/assets/dsh-standards-hero-en-light.webp +0 -0
  33. package/docs/assets/dsh-standards-hero-zh-dark.webp +0 -0
  34. package/docs/assets/dsh-standards-hero-zh-light.webp +0 -0
  35. package/docs/coverage.md +82 -0
  36. package/package.json +1 -1
  37. package/spec/README.md +2 -0
  38. package/spec/coverage-contract.md +100 -0
  39. package/spec/dsc-clauses.json +766 -0
  40. package/spec/examples/boost-card.example.json +15 -0
  41. package/spec/examples/flow-evidence.example.json +113 -0
  42. package/spec/flow-evidence.schema.json +6 -2
  43. package/spec/remediation.json +54 -54
  44. package/spec/schemas/advice.schema.json +92 -0
  45. package/spec/schemas/boost-card.schema.json +107 -0
  46. package/spec/schemas/conformance.schema.json +848 -0
@@ -0,0 +1,92 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/PerryLink/dsh-standards/spec/schemas/advice.schema.json",
4
+ "title": "DSH advice entry array (dsh-advice/1)",
5
+ "description": "The additive `advice[]` field of a dsh-conformance/1 report. One entry per (check, key) finding; advice never changes the verdict. 13 fields are required; `ruleMissing` is an optional diagnostic emitted when spec/remediation.json has no rule for a key. `version` is the producing package version, not this schema version.",
6
+ "type": "array",
7
+ "items": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "required": [
11
+ "key",
12
+ "gate",
13
+ "severity",
14
+ "title",
15
+ "why",
16
+ "fix",
17
+ "docsUrl",
18
+ "source",
19
+ "version",
20
+ "evidence",
21
+ "reason",
22
+ "occurrences",
23
+ "advisory"
24
+ ],
25
+ "properties": {
26
+ "key": {
27
+ "type": "string",
28
+ "minLength": 1,
29
+ "description": "Clause or gate key the advice is attached to (for example C-2.2)."
30
+ },
31
+ "gate": {
32
+ "enum": ["FAIL", "WARN"],
33
+ "description": "Result of the owning check after report adjustments."
34
+ },
35
+ "severity": {
36
+ "enum": ["FAIL", "WARN"],
37
+ "description": "Rendered severity; follows `gate` in dsh-advice/1."
38
+ },
39
+ "title": {
40
+ "type": "string",
41
+ "minLength": 1,
42
+ "description": "Short human title; falls back to the key when the rule table has no title."
43
+ },
44
+ "why": {
45
+ "type": ["string", "null"],
46
+ "description": "Why the finding matters; null when the rule table has no explanation."
47
+ },
48
+ "fix": {
49
+ "type": ["string", "null"],
50
+ "description": "Concrete remediation; null when the rule table has no fix."
51
+ },
52
+ "docsUrl": {
53
+ "type": ["string", "null"],
54
+ "format": "uri",
55
+ "description": "Release-pinned documentation URL; null when the rule has no docs anchor."
56
+ },
57
+ "source": {
58
+ "type": "string",
59
+ "minLength": 1,
60
+ "description": "Check id that produced the finding (DSC-xx)."
61
+ },
62
+ "version": {
63
+ "type": "string",
64
+ "minLength": 1,
65
+ "description": "Version of the producing package (dsh-standards)."
66
+ },
67
+ "evidence": {
68
+ "type": "array",
69
+ "maxItems": 10,
70
+ "items": { "type": "string" },
71
+ "description": "Up to 10 deduplicated evidence references."
72
+ },
73
+ "reason": {
74
+ "type": "string",
75
+ "description": "Diagnostic reason(s); may be empty. Not used for the verdict."
76
+ },
77
+ "occurrences": {
78
+ "type": "integer",
79
+ "minimum": 1,
80
+ "description": "How many duplicate details were merged into this entry."
81
+ },
82
+ "advisory": {
83
+ "type": "boolean",
84
+ "description": "True when the owning check is advisory and never moves the verdict."
85
+ },
86
+ "ruleMissing": {
87
+ "type": "boolean",
88
+ "description": "Optional diagnostic: spec/remediation.json has no rule for `key`."
89
+ }
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,107 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/PerryLink/dsh-standards/spec/schemas/boost-card.schema.json",
4
+ "title": "DSH BOOST evidence card (dsh-boost-card/1)",
5
+ "description": "One evidence card per practice, per plugin. These are exactly the thirteen fields `40-checker/scripts/level-audit.mjs` requires (BOOST_CARD_FIELDS); a missing or malformed field downgrades the practice to not-measured. `expiresAt` must not precede `generatedAt`, and a past `expiresAt` makes the card stale; both rules need the run date, so they live in level-audit rather than in this schema. `recordHash` is sha256 over the card JSON without that field; the validator checks the shape, a reviewer recomputes it. The card may sit under `evidenceCard` or as an object under `evidence` in the LEV evidence file.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "subject",
10
+ "host",
11
+ "method",
12
+ "scope",
13
+ "command",
14
+ "result",
15
+ "negativeControl",
16
+ "generatedAt",
17
+ "expiresAt",
18
+ "recordHash",
19
+ "claimLevel",
20
+ "issuer",
21
+ "selfAssessed"
22
+ ],
23
+ "properties": {
24
+ "subject": {
25
+ "type": "string",
26
+ "minLength": 1,
27
+ "description": "What was measured, as name@version. Not the repository name."
28
+ },
29
+ "host": {
30
+ "type": "string",
31
+ "minLength": 1,
32
+ "description": "DSH / Cordis / Node versions and the platform, for example \"dsh 0.2.2-alpha.3 / cordis 4.0.6-alpha.2 / node 24.9 / linux-x64\"."
33
+ },
34
+ "method": {
35
+ "type": "string",
36
+ "minLength": 1,
37
+ "description": "How it was measured, including the run count or comparator and any caveat such as single-run."
38
+ },
39
+ "scope": {
40
+ "type": "string",
41
+ "minLength": 1,
42
+ "description": "Which LEV practice and which part of the plugin, for example \"LEV-6 stable prefix / assembly\"."
43
+ },
44
+ "command": {
45
+ "type": "string",
46
+ "minLength": 1,
47
+ "description": "The exact command that produced the result."
48
+ },
49
+ "result": {
50
+ "type": "string",
51
+ "minLength": 1,
52
+ "description": "Numbers, before -> after. No adjectives."
53
+ },
54
+ "negativeControl": {
55
+ "type": "string",
56
+ "minLength": 1,
57
+ "description": "The same measurement with the practice disabled or the plugin off; without it a number is not evidence."
58
+ },
59
+ "generatedAt": {
60
+ "type": "string",
61
+ "format": "date",
62
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
63
+ "description": "The day the measurement was run (YYYY-MM-DD)."
64
+ },
65
+ "expiresAt": {
66
+ "type": "string",
67
+ "format": "date",
68
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
69
+ "description": "When the measurement stops being current (YYYY-MM-DD), not before generatedAt. 180 days is a reasonable cap."
70
+ },
71
+ "recordHash": {
72
+ "type": "string",
73
+ "pattern": "^sha256:[0-9a-f]{64}$",
74
+ "description": "sha256 over the canonical card JSON without this field."
75
+ },
76
+ "claimLevel": {
77
+ "enum": ["self-reported", "self-assessed", "host-reviewed", "independent", "reference"],
78
+ "description": "Be honest; anything stronger than self-reported is not self-declared."
79
+ },
80
+ "issuer": {
81
+ "type": "string",
82
+ "minLength": 1,
83
+ "description": "Who ran it: author, an org, or a CI job."
84
+ },
85
+ "selfAssessed": {
86
+ "type": "boolean",
87
+ "description": "True only when the author ran and judged the measurement."
88
+ }
89
+ },
90
+ "examples": [
91
+ {
92
+ "subject": "@acme/dsh-hello@0.1.0",
93
+ "host": "dsh 0.2.2-alpha.3 / cordis 4.0.6-alpha.2 / node 24.9 / linux-x64",
94
+ "method": "single run: startup, reload, and tokens per turn; nonce arm as negative control",
95
+ "scope": "LEV-6 stable prefix / assembly - hello example tool and prompt declarations",
96
+ "command": "node bench/hello.mjs",
97
+ "result": "startup 180 -> 150 ms (-17%); reload 900 -> 600 ms (-33%); tokens 1200 -> 900/turn (-25%); loc 420 -> 380",
98
+ "negativeControl": "same bench with the nonce arm: prefix reuse 0%, first divergence at system byte 0",
99
+ "generatedAt": "2026-11-06",
100
+ "expiresAt": "2027-05-06",
101
+ "recordHash": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
102
+ "claimLevel": "self-assessed",
103
+ "issuer": "author",
104
+ "selfAssessed": true
105
+ }
106
+ ]
107
+ }