dsh-standards 1.2.1 → 1.3.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.
- package/40-checker/README.md +25 -3
- package/40-checker/bin/dsh-levels.mjs +7 -1
- package/40-checker/scripts/build-offline-kit.mjs +284 -0
- package/40-checker/scripts/build-sidecar.mjs +484 -0
- package/40-checker/scripts/flow-collect.mjs +147 -22
- package/40-checker/scripts/level-audit.mjs +57 -9
- package/40-checker/scripts/run-tests.mjs +17 -0
- package/40-checker/src/author-cli.mjs +139 -0
- package/40-checker/src/author-report.mjs +260 -0
- package/40-checker/src/cli.mjs +73 -8
- package/40-checker/src/flow-evidence.mjs +189 -3
- package/40-checker/src/index.mjs +3 -3
- package/40-checker/src/report.mjs +125 -24
- package/40-checker/src/sandbox-run.mjs +403 -0
- package/CHANGELOG.md +26 -0
- package/README.en.md +352 -0
- package/README.es.md +352 -0
- package/README.hi.md +352 -0
- package/README.md +300 -82
- package/README.pt.md +352 -0
- package/bin/dsh-standards.mjs +13 -2
- package/docs/assets/dsh-standards-flow-dark.svg +38 -0
- package/docs/assets/dsh-standards-flow-light.svg +38 -0
- package/docs/assets/dsh-standards-flow-v3-dark.svg +87 -0
- package/docs/assets/dsh-standards-flow-v3-light.svg +87 -0
- package/docs/assets/dsh-standards-flow-v4-dark.svg +79 -0
- package/docs/assets/dsh-standards-flow-v4-light.svg +79 -0
- package/docs/assets/dsh-standards-hero-en-dark.webp +0 -0
- package/docs/assets/dsh-standards-hero-en-light.webp +0 -0
- package/docs/assets/dsh-standards-hero-zh-dark.webp +0 -0
- package/docs/assets/dsh-standards-hero-zh-light.webp +0 -0
- package/package.json +2 -2
- package/spec/README.md +2 -0
- package/spec/flow/README.md +19 -6
- package/spec/flow-evidence.schema.json +76 -6
- package/spec/schemas/advice.schema.json +92 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1100" height="660" viewBox="0 0 1100 660" role="img" aria-label="dsh-standards pipeline">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="lineGrad" x1="0" y1="0" x2="1" y2="0">
|
|
4
|
+
<stop offset="0" stop-color="#4B67B4" stop-opacity=".15"/>
|
|
5
|
+
<stop offset=".5" stop-color="#4B67B4" stop-opacity=".9"/>
|
|
6
|
+
<stop offset="1" stop-color="#4B67B4" stop-opacity=".15"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<filter id="soft" x="-40%" y="-40%" width="180%" height="200%">
|
|
9
|
+
<feDropShadow dx="0" dy="9" stdDeviation="12" flood-color="#1b1735" flood-opacity="0.10"/>
|
|
10
|
+
</filter>
|
|
11
|
+
<pattern id="dots" width="28" height="28" patternUnits="userSpaceOnUse">
|
|
12
|
+
<circle cx="1.3" cy="1.3" r="1.3" fill="#f2f0f8"/>
|
|
13
|
+
</pattern>
|
|
14
|
+
</defs>
|
|
15
|
+
<rect width="1100" height="660" fill="#ffffff"/>
|
|
16
|
+
<rect width="1100" height="660" fill="url(#dots)" opacity=".5"/>
|
|
17
|
+
<text x="50" y="62" fill="#141419" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="32" font-weight="700">dsh-standards</text>
|
|
18
|
+
<text x="50" y="90" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="16">static checks, runtime measurement, one reproducible report</text>
|
|
19
|
+
<rect x="50" y="108" width="1000" height="1.6" rx="1" fill="#e6e3f0"/>
|
|
20
|
+
<g filter="url(#soft)">
|
|
21
|
+
<rect x="50" y="190" width="176" height="118" rx="17" fill="#fcfcfe" stroke="#e6e3f0" stroke-width="1.3"/>
|
|
22
|
+
</g>
|
|
23
|
+
<circle cx="74" cy="214" r="12" fill="#ece7f9"/>
|
|
24
|
+
<text x="74" y="219" text-anchor="middle" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="11.5" font-weight="700">01</text>
|
|
25
|
+
<text x="138.0" y="256" text-anchor="middle" fill="#141419" font-family="ui-monospace, monospace" font-size="15.5" font-weight="700">plugin dir</text>
|
|
26
|
+
<text x="138.0" y="282" text-anchor="middle" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">the repository</text>
|
|
27
|
+
<path d="M231 249.0 C241.0 249.0, 241.0 249.0, 251 249.0" stroke="url(#lineGrad)" stroke-width="2.2" fill="none"/>
|
|
28
|
+
<path d="M241 244.0 l8 5 -8 5" fill="none" stroke="#4B67B4" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
29
|
+
<g filter="url(#soft)">
|
|
30
|
+
<rect x="256" y="190" width="176" height="118" rx="17" fill="#fcfcfe" stroke="#4B67B4" stroke-width="2.6"/>
|
|
31
|
+
</g>
|
|
32
|
+
<circle cx="280" cy="214" r="12" fill="#ece7f9"/>
|
|
33
|
+
<text x="280" y="219" text-anchor="middle" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="11.5" font-weight="700">02</text>
|
|
34
|
+
<text x="344.0" y="256" text-anchor="middle" fill="#141419" font-family="ui-monospace, monospace" font-size="15.5" font-weight="700">DSC-01…13</text>
|
|
35
|
+
<text x="344.0" y="282" text-anchor="middle" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">static checks</text>
|
|
36
|
+
<path d="M437 249.0 C447.0 249.0, 447.0 249.0, 457 249.0" stroke="url(#lineGrad)" stroke-width="2.2" fill="none"/>
|
|
37
|
+
<path d="M447 244.0 l8 5 -8 5" fill="none" stroke="#4B67B4" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
38
|
+
<g filter="url(#soft)">
|
|
39
|
+
<rect x="462" y="190" width="176" height="118" rx="17" fill="#fcfcfe" stroke="#e6e3f0" stroke-width="1.3"/>
|
|
40
|
+
</g>
|
|
41
|
+
<circle cx="486" cy="214" r="12" fill="#ece7f9"/>
|
|
42
|
+
<text x="486" y="219" text-anchor="middle" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="11.5" font-weight="700">03</text>
|
|
43
|
+
<text x="550.0" y="256" text-anchor="middle" fill="#141419" font-family="ui-monospace, monospace" font-size="15.5" font-weight="700">L1–L3</text>
|
|
44
|
+
<text x="550.0" y="282" text-anchor="middle" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">runtime measurement</text>
|
|
45
|
+
<path d="M643 249.0 C653.0 249.0, 653.0 249.0, 663 249.0" stroke="url(#lineGrad)" stroke-width="2.2" fill="none"/>
|
|
46
|
+
<path d="M653 244.0 l8 5 -8 5" fill="none" stroke="#4B67B4" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
47
|
+
<g filter="url(#soft)">
|
|
48
|
+
<rect x="668" y="190" width="176" height="118" rx="17" fill="#fcfcfe" stroke="#e6e3f0" stroke-width="1.3"/>
|
|
49
|
+
</g>
|
|
50
|
+
<circle cx="692" cy="214" r="12" fill="#ece7f9"/>
|
|
51
|
+
<text x="692" y="219" text-anchor="middle" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="11.5" font-weight="700">04</text>
|
|
52
|
+
<text x="756.0" y="256" text-anchor="middle" fill="#141419" font-family="ui-monospace, monospace" font-size="15.5" font-weight="700">report</text>
|
|
53
|
+
<text x="756.0" y="282" text-anchor="middle" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">text / json / sarif</text>
|
|
54
|
+
<path d="M849 249.0 C859.0 249.0, 859.0 249.0, 869 249.0" stroke="url(#lineGrad)" stroke-width="2.2" fill="none"/>
|
|
55
|
+
<path d="M859 244.0 l8 5 -8 5" fill="none" stroke="#4B67B4" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
56
|
+
<g filter="url(#soft)">
|
|
57
|
+
<rect x="874" y="190" width="176" height="118" rx="17" fill="#fcfcfe" stroke="#16a34a" stroke-width="2.6"/>
|
|
58
|
+
</g>
|
|
59
|
+
<circle cx="898" cy="214" r="12" fill="#ece7f9"/>
|
|
60
|
+
<text x="898" y="219" text-anchor="middle" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="11.5" font-weight="700">05</text>
|
|
61
|
+
<text x="962.0" y="256" text-anchor="middle" fill="#141419" font-family="ui-monospace, monospace" font-size="15.5" font-weight="700">dsh-levels</text>
|
|
62
|
+
<text x="962.0" y="282" text-anchor="middle" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">ENTRY/FLOW/BOOST</text>
|
|
63
|
+
<g filter="url(#soft)">
|
|
64
|
+
<rect x="462" y="378" width="118" height="58" rx="14" fill="#fcfcfe" stroke="#16a34a" stroke-width="1.2"/>
|
|
65
|
+
</g>
|
|
66
|
+
<text x="486" y="404" fill="#16a34a" font-family="ui-monospace, monospace" font-size="16" font-weight="700">0</text>
|
|
67
|
+
<text x="486" y="423" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">exit pass</text>
|
|
68
|
+
<g filter="url(#soft)">
|
|
69
|
+
<rect x="592" y="378" width="118" height="58" rx="14" fill="#fcfcfe" stroke="#bc4c00" stroke-width="1.2"/>
|
|
70
|
+
</g>
|
|
71
|
+
<text x="616" y="404" fill="#bc4c00" font-family="ui-monospace, monospace" font-size="16" font-weight="700">1</text>
|
|
72
|
+
<text x="616" y="423" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">exit fail</text>
|
|
73
|
+
<g filter="url(#soft)">
|
|
74
|
+
<rect x="722" y="378" width="118" height="58" rx="14" fill="#fcfcfe" stroke="#bc4c00" stroke-width="1.2"/>
|
|
75
|
+
</g>
|
|
76
|
+
<text x="746" y="404" fill="#bc4c00" font-family="ui-monospace, monospace" font-size="16" font-weight="700">2</text>
|
|
77
|
+
<text x="746" y="423" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">exit config</text>
|
|
78
|
+
<g filter="url(#soft)">
|
|
79
|
+
<rect x="852" y="378" width="118" height="58" rx="14" fill="#fcfcfe" stroke="#bc4c00" stroke-width="1.2"/>
|
|
80
|
+
</g>
|
|
81
|
+
<text x="876" y="404" fill="#bc4c00" font-family="ui-monospace, monospace" font-size="16" font-weight="700">3</text>
|
|
82
|
+
<text x="876" y="423" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">exit runtime</text>
|
|
83
|
+
<rect x="50" y="476" width="1000" height="58" rx="15" fill="#fcfcfe" stroke="#e6e3f0"/>
|
|
84
|
+
<text x="74" y="502" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="13" font-weight="700">static ≠ runtime</text>
|
|
85
|
+
<text x="74" y="522" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="13">a static pass never substitutes for a runtime run; not-run is reported, never upgraded to PASS</text>
|
|
86
|
+
<text x="50" y="596" fill="#4d5261" font-family="ui-monospace, monospace" font-size="13">Apache-2.0 + CC-BY-4.0 · PerryLink DSH plugin family</text>
|
|
87
|
+
</svg>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1100" height="660" viewBox="0 0 1100 660" role="img" aria-label="dsh-standards dual-channel funnel">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="soft" x="-40%" y="-40%" width="180%" height="200%">
|
|
4
|
+
<feDropShadow dx="0" dy="9" stdDeviation="12" flood-color="#1b1735" flood-opacity="0.55"/>
|
|
5
|
+
</filter>
|
|
6
|
+
<pattern id="dots" width="28" height="28" patternUnits="userSpaceOnUse">
|
|
7
|
+
<circle cx="1.3" cy="1.3" r="1.3" fill="#182031"/>
|
|
8
|
+
</pattern>
|
|
9
|
+
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
10
|
+
<path d="M0 0 L10 5 L0 10 z" fill="#8496f5"/>
|
|
11
|
+
</marker>
|
|
12
|
+
</defs>
|
|
13
|
+
<rect width="1100" height="660" fill="#0d1117"/>
|
|
14
|
+
<rect width="1100" height="660" fill="url(#dots)" opacity=".5"/>
|
|
15
|
+
<text x="50" y="58" fill="#f0f3f9" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="32" font-weight="700">dsh-standards</text>
|
|
16
|
+
<text x="50" y="86" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="16">two channels, one report · static never pretends to be runtime</text>
|
|
17
|
+
<rect x="42" y="118" width="292" height="366" rx="20" fill="#121824" stroke="#2a3142"/>
|
|
18
|
+
<text x="62" y="146" fill="#8496f5" font-family="ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">STATIC · DSC-01...13</text>
|
|
19
|
+
<rect x="348" y="118" width="292" height="366" rx="20" fill="#121824" stroke="#2a3142"/>
|
|
20
|
+
<text x="368" y="146" fill="#3fb950" font-family="ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">RUNTIME · L1-L3</text>
|
|
21
|
+
|
|
22
|
+
<rect x="58" y="168" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
23
|
+
<circle cx="78" cy="199" r="8" fill="#8496f5"/>
|
|
24
|
+
<text x="96" y="194" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">contract</text>
|
|
25
|
+
<text x="96" y="214" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">cordis.patch.yml</text>
|
|
26
|
+
<rect x="58" y="244" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
27
|
+
<circle cx="78" cy="275" r="8" fill="#8496f5"/>
|
|
28
|
+
<text x="96" y="270" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">manifest</text>
|
|
29
|
+
<text x="96" y="290" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">package.json</text>
|
|
30
|
+
<rect x="58" y="320" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
31
|
+
<circle cx="78" cy="351" r="8" fill="#8496f5"/>
|
|
32
|
+
<text x="96" y="346" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">layout</text>
|
|
33
|
+
<text x="96" y="366" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">files + imports</text>
|
|
34
|
+
<rect x="58" y="396" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
35
|
+
<circle cx="78" cy="427" r="8" fill="#8496f5"/>
|
|
36
|
+
<text x="96" y="422" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">docs</text>
|
|
37
|
+
<text x="96" y="442" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">README + topics</text>
|
|
38
|
+
<rect x="364" y="168" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
39
|
+
<circle cx="384" cy="199" r="8" fill="#3fb950"/>
|
|
40
|
+
<text x="402" y="194" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">install</text>
|
|
41
|
+
<text x="402" y="214" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">cold profile</text>
|
|
42
|
+
<rect x="364" y="244" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
43
|
+
<circle cx="384" cy="275" r="8" fill="#3fb950"/>
|
|
44
|
+
<text x="402" y="270" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">smoke</text>
|
|
45
|
+
<text x="402" y="290" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">agent step</text>
|
|
46
|
+
<rect x="364" y="320" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
47
|
+
<circle cx="384" cy="351" r="8" fill="#3fb950"/>
|
|
48
|
+
<text x="402" y="346" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">perf</text>
|
|
49
|
+
<text x="402" y="366" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">p50 / p99</text>
|
|
50
|
+
<rect x="364" y="396" width="260" height="62" rx="13" fill="#161b26" stroke="#2a3142"/>
|
|
51
|
+
<circle cx="384" cy="427" r="8" fill="#3fb950"/>
|
|
52
|
+
<text x="402" y="422" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">evidence</text>
|
|
53
|
+
<text x="402" y="442" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">reproducible</text>
|
|
54
|
+
<path d="M188 484 V504 H672" stroke="#8496f5" stroke-width="2.4" fill="none" marker-end="url(#arr)" opacity=".85"/>
|
|
55
|
+
<path d="M494 484 V496 H672" stroke="#3fb950" stroke-width="2.4" fill="none" marker-end="url(#arr)" opacity=".85"/>
|
|
56
|
+
<rect x="680" y="380" width="176" height="120" rx="18" fill="#161b26" stroke="#8496f5" stroke-width="2.2" filter="url(#soft)"/>
|
|
57
|
+
<text x="700" y="408" fill="#8496f5" font-family="ui-monospace, monospace" font-size="13" font-weight="700">report</text>
|
|
58
|
+
<text x="700" y="436" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="12.5">text</text>
|
|
59
|
+
<text x="700" y="458" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="12.5">json</text>
|
|
60
|
+
<text x="700" y="480" fill="#f0f3f9" font-family="ui-monospace, monospace" font-size="12.5">sarif</text>
|
|
61
|
+
<path d="M856 440 H904" stroke="#8496f5" stroke-width="2.4" fill="none" marker-end="url(#arr)"/>
|
|
62
|
+
<text x="920" y="218" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="13" font-weight="700">EXIT</text>
|
|
63
|
+
<rect x="920" y="240" width="120" height="46" rx="12" fill="#161b26" stroke="#3fb950" stroke-width="1.5"/>
|
|
64
|
+
<text x="938" y="269" fill="#3fb950" font-family="ui-monospace, monospace" font-size="16" font-weight="700">0</text>
|
|
65
|
+
<text x="962" y="269" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">pass</text>
|
|
66
|
+
<rect x="920" y="298" width="120" height="46" rx="12" fill="#161b26" stroke="#d29922" stroke-width="1.5"/>
|
|
67
|
+
<text x="938" y="327" fill="#d29922" font-family="ui-monospace, monospace" font-size="16" font-weight="700">1</text>
|
|
68
|
+
<text x="962" y="327" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">fail</text>
|
|
69
|
+
<rect x="920" y="356" width="120" height="46" rx="12" fill="#161b26" stroke="#d29922" stroke-width="1.5"/>
|
|
70
|
+
<text x="938" y="385" fill="#d29922" font-family="ui-monospace, monospace" font-size="16" font-weight="700">2</text>
|
|
71
|
+
<text x="962" y="385" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">config</text>
|
|
72
|
+
<rect x="920" y="414" width="120" height="46" rx="12" fill="#161b26" stroke="#d29922" stroke-width="1.5"/>
|
|
73
|
+
<text x="938" y="443" fill="#d29922" font-family="ui-monospace, monospace" font-size="16" font-weight="700">3</text>
|
|
74
|
+
<text x="962" y="443" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">runtime</text>
|
|
75
|
+
<text x="680" y="540" fill="#8496f5" font-family="ui-monospace, monospace" font-size="13" font-weight="700">ENTRY / FLOW / BOOST</text>
|
|
76
|
+
<text x="680" y="562" fill="#a8b1c4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">dsh-levels: depth of adoption</text>
|
|
77
|
+
|
|
78
|
+
<text x="50" y="618" fill="#a8b1c4" font-family="ui-monospace, monospace" font-size="12.5">Apache-2.0 + CC-BY-4.0 · PerryLink DSH plugin family</text>
|
|
79
|
+
</svg>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1100" height="660" viewBox="0 0 1100 660" role="img" aria-label="dsh-standards dual-channel funnel">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="soft" x="-40%" y="-40%" width="180%" height="200%">
|
|
4
|
+
<feDropShadow dx="0" dy="9" stdDeviation="12" flood-color="#1b1735" flood-opacity="0.10"/>
|
|
5
|
+
</filter>
|
|
6
|
+
<pattern id="dots" width="28" height="28" patternUnits="userSpaceOnUse">
|
|
7
|
+
<circle cx="1.3" cy="1.3" r="1.3" fill="#f2f0f8"/>
|
|
8
|
+
</pattern>
|
|
9
|
+
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
10
|
+
<path d="M0 0 L10 5 L0 10 z" fill="#4B67B4"/>
|
|
11
|
+
</marker>
|
|
12
|
+
</defs>
|
|
13
|
+
<rect width="1100" height="660" fill="#ffffff"/>
|
|
14
|
+
<rect width="1100" height="660" fill="url(#dots)" opacity=".5"/>
|
|
15
|
+
<text x="50" y="58" fill="#141419" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="32" font-weight="700">dsh-standards</text>
|
|
16
|
+
<text x="50" y="86" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="16">two channels, one report · static never pretends to be runtime</text>
|
|
17
|
+
<rect x="42" y="118" width="292" height="366" rx="20" fill="#f7f5fc" stroke="#e6e3f0"/>
|
|
18
|
+
<text x="62" y="146" fill="#4B67B4" font-family="ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">STATIC · DSC-01...13</text>
|
|
19
|
+
<rect x="348" y="118" width="292" height="366" rx="20" fill="#f7f5fc" stroke="#e6e3f0"/>
|
|
20
|
+
<text x="368" y="146" fill="#16a34a" font-family="ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">RUNTIME · L1-L3</text>
|
|
21
|
+
|
|
22
|
+
<rect x="58" y="168" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
23
|
+
<circle cx="78" cy="199" r="8" fill="#4B67B4"/>
|
|
24
|
+
<text x="96" y="194" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">contract</text>
|
|
25
|
+
<text x="96" y="214" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">cordis.patch.yml</text>
|
|
26
|
+
<rect x="58" y="244" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
27
|
+
<circle cx="78" cy="275" r="8" fill="#4B67B4"/>
|
|
28
|
+
<text x="96" y="270" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">manifest</text>
|
|
29
|
+
<text x="96" y="290" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">package.json</text>
|
|
30
|
+
<rect x="58" y="320" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
31
|
+
<circle cx="78" cy="351" r="8" fill="#4B67B4"/>
|
|
32
|
+
<text x="96" y="346" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">layout</text>
|
|
33
|
+
<text x="96" y="366" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">files + imports</text>
|
|
34
|
+
<rect x="58" y="396" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
35
|
+
<circle cx="78" cy="427" r="8" fill="#4B67B4"/>
|
|
36
|
+
<text x="96" y="422" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">docs</text>
|
|
37
|
+
<text x="96" y="442" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">README + topics</text>
|
|
38
|
+
<rect x="364" y="168" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
39
|
+
<circle cx="384" cy="199" r="8" fill="#16a34a"/>
|
|
40
|
+
<text x="402" y="194" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">install</text>
|
|
41
|
+
<text x="402" y="214" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">cold profile</text>
|
|
42
|
+
<rect x="364" y="244" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
43
|
+
<circle cx="384" cy="275" r="8" fill="#16a34a"/>
|
|
44
|
+
<text x="402" y="270" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">smoke</text>
|
|
45
|
+
<text x="402" y="290" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">agent step</text>
|
|
46
|
+
<rect x="364" y="320" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
47
|
+
<circle cx="384" cy="351" r="8" fill="#16a34a"/>
|
|
48
|
+
<text x="402" y="346" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">perf</text>
|
|
49
|
+
<text x="402" y="366" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">p50 / p99</text>
|
|
50
|
+
<rect x="364" y="396" width="260" height="62" rx="13" fill="#ffffff" stroke="#e6e3f0"/>
|
|
51
|
+
<circle cx="384" cy="427" r="8" fill="#16a34a"/>
|
|
52
|
+
<text x="402" y="422" fill="#141419" font-family="ui-monospace, monospace" font-size="13.5" font-weight="700">evidence</text>
|
|
53
|
+
<text x="402" y="442" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">reproducible</text>
|
|
54
|
+
<path d="M188 484 V504 H672" stroke="#4B67B4" stroke-width="2.4" fill="none" marker-end="url(#arr)" opacity=".85"/>
|
|
55
|
+
<path d="M494 484 V496 H672" stroke="#16a34a" stroke-width="2.4" fill="none" marker-end="url(#arr)" opacity=".85"/>
|
|
56
|
+
<rect x="680" y="380" width="176" height="120" rx="18" fill="#ffffff" stroke="#4B67B4" stroke-width="2.2" filter="url(#soft)"/>
|
|
57
|
+
<text x="700" y="408" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="13" font-weight="700">report</text>
|
|
58
|
+
<text x="700" y="436" fill="#141419" font-family="ui-monospace, monospace" font-size="12.5">text</text>
|
|
59
|
+
<text x="700" y="458" fill="#141419" font-family="ui-monospace, monospace" font-size="12.5">json</text>
|
|
60
|
+
<text x="700" y="480" fill="#141419" font-family="ui-monospace, monospace" font-size="12.5">sarif</text>
|
|
61
|
+
<path d="M856 440 H904" stroke="#4B67B4" stroke-width="2.4" fill="none" marker-end="url(#arr)"/>
|
|
62
|
+
<text x="920" y="218" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="13" font-weight="700">EXIT</text>
|
|
63
|
+
<rect x="920" y="240" width="120" height="46" rx="12" fill="#ffffff" stroke="#16a34a" stroke-width="1.5"/>
|
|
64
|
+
<text x="938" y="269" fill="#16a34a" font-family="ui-monospace, monospace" font-size="16" font-weight="700">0</text>
|
|
65
|
+
<text x="962" y="269" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">pass</text>
|
|
66
|
+
<rect x="920" y="298" width="120" height="46" rx="12" fill="#ffffff" stroke="#bc4c00" stroke-width="1.5"/>
|
|
67
|
+
<text x="938" y="327" fill="#bc4c00" font-family="ui-monospace, monospace" font-size="16" font-weight="700">1</text>
|
|
68
|
+
<text x="962" y="327" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">fail</text>
|
|
69
|
+
<rect x="920" y="356" width="120" height="46" rx="12" fill="#ffffff" stroke="#bc4c00" stroke-width="1.5"/>
|
|
70
|
+
<text x="938" y="385" fill="#bc4c00" font-family="ui-monospace, monospace" font-size="16" font-weight="700">2</text>
|
|
71
|
+
<text x="962" y="385" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">config</text>
|
|
72
|
+
<rect x="920" y="414" width="120" height="46" rx="12" fill="#ffffff" stroke="#bc4c00" stroke-width="1.5"/>
|
|
73
|
+
<text x="938" y="443" fill="#bc4c00" font-family="ui-monospace, monospace" font-size="16" font-weight="700">3</text>
|
|
74
|
+
<text x="962" y="443" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12.5">runtime</text>
|
|
75
|
+
<text x="680" y="540" fill="#4B67B4" font-family="ui-monospace, monospace" font-size="13" font-weight="700">ENTRY / FLOW / BOOST</text>
|
|
76
|
+
<text x="680" y="562" fill="#4d5261" font-family="ui-sans-serif, system-ui, sans-serif" font-size="12">dsh-levels: depth of adoption</text>
|
|
77
|
+
|
|
78
|
+
<text x="50" y="618" fill="#4d5261" font-family="ui-monospace, monospace" font-size="12.5">Apache-2.0 + CC-BY-4.0 · PerryLink DSH plugin family</text>
|
|
79
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-standards",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
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
|
|
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": {
|
package/spec/README.md
CHANGED
|
@@ -16,6 +16,7 @@ Machine-readable:
|
|
|
16
16
|
- [reference-suite.json](reference-suite.json) — versioned samples, anchors, change rules.
|
|
17
17
|
- [remediation.json](remediation.json) — 68-key advice table for the additive `advice[]` report field (docs anchors + severity hints).
|
|
18
18
|
- [schemas/evidence.schema.json](schemas/evidence.schema.json) — `dsh-levels/1` record.
|
|
19
|
+
- [schemas/advice.schema.json](schemas/advice.schema.json) — `dsh-advice/1` entry array: the additive `advice[]` field of a `dsh-conformance/1` report (13 required fields; `why`/`fix`/`docsUrl` may be null; `evidence` ≤ 10; `gate`/`severity` ∈ {FAIL,WARN}).
|
|
19
20
|
- [flow-evidence.schema.json](flow-evidence.schema.json) — `dsh-flow-evidence/2` FLOW chain (J1–J8 checks, subject/host binding, `evidenceHash`). v1 and bare `{Jx:{status}}` rows are deprecated and never count as a pass.
|
|
20
21
|
- [schemas/attestation.schema.json](schemas/attestation.schema.json) — `dsh-attestation/1` quality record.
|
|
21
22
|
- [schemas/report.schema.json](schemas/report.schema.json) — `dsh-report/1` inspection report (no grade).
|
|
@@ -26,4 +27,5 @@ Rules:
|
|
|
26
27
|
|
|
27
28
|
- Levels depend on `common` only; do not import each other.
|
|
28
29
|
- A level is not a certification, badge, grade, or score.
|
|
30
|
+
- CI attribution (`producer.runUrl`/`repository`/`commit`) is read from the runner environment and is self-declared: **CI 归属 ≠ 证明**. It never upgrades `claims.claimLevel`, and `level-audit` reports it only as `attestation: ci | self-declared`.
|
|
29
31
|
- `dsh-standard` is an alias; `dsh-standards` is canonical.
|
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,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
|
|
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.
|
|
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
|
|
33
|
-
|
|
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
|
|
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,7 +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
|
+
"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. `provider`/`runId`/`repository`/`commit`/`runUrl` are copied from the runner environment (GITHUB_*) and are self-declared: CI attribution is not proof that the commands ran.",
|
|
33
33
|
"additionalProperties": false,
|
|
34
34
|
"required": ["command", "at"],
|
|
35
35
|
"properties": {
|
|
@@ -43,12 +43,16 @@
|
|
|
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" },
|
|
51
|
-
"runUrl": { "type": "string" }
|
|
51
|
+
"runUrl": { "type": "string", "description": "CI run URL. Self-declared, display-only." },
|
|
52
|
+
"provider": { "type": "string", "description": "CI provider id (for example github-actions). Self-declared." },
|
|
53
|
+
"runId": { "type": "string", "description": "CI run id (GITHUB_RUN_ID). Self-declared." },
|
|
54
|
+
"repository": { "type": "string", "description": "CI repository (GITHUB_REPOSITORY). Self-declared." },
|
|
55
|
+
"commit": { "type": "string", "pattern": "^[0-9a-f]{40}$", "description": "CI commit (GITHUB_SHA). Self-declared." }
|
|
52
56
|
}
|
|
53
57
|
},
|
|
54
58
|
"subject": {
|
|
@@ -108,6 +112,72 @@
|
|
|
108
112
|
"platform": { "type": "string", "minLength": 1 }
|
|
109
113
|
}
|
|
110
114
|
},
|
|
115
|
+
"sandbox": {
|
|
116
|
+
"type": "object",
|
|
117
|
+
"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.",
|
|
118
|
+
"required": ["mode", "degraded"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"schema": { "const": "dsh-sandbox-report/1" },
|
|
121
|
+
"mode": { "enum": ["sandbox", "sandbox-degraded"] },
|
|
122
|
+
"degraded": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"items": { "type": "string", "minLength": 1 },
|
|
125
|
+
"description": "Missing isolation items, e.g. unshare-missing, prlimit-missing, env-token-present, home-not-isolated."
|
|
126
|
+
},
|
|
127
|
+
"platform": { "type": "string" },
|
|
128
|
+
"env": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"properties": {
|
|
131
|
+
"policy": { "type": "string" },
|
|
132
|
+
"checked": { "type": "array", "items": { "type": "string" } },
|
|
133
|
+
"absent": { "type": "boolean" },
|
|
134
|
+
"offenders": { "type": "array", "items": { "type": "string" } }
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"home": {
|
|
138
|
+
"type": "object",
|
|
139
|
+
"properties": {
|
|
140
|
+
"isolated": { "type": "boolean" },
|
|
141
|
+
"mode": { "type": "string" }
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"network": {
|
|
145
|
+
"type": "object",
|
|
146
|
+
"properties": {
|
|
147
|
+
"isolated": { "type": "boolean" },
|
|
148
|
+
"mechanism": { "type": "string" },
|
|
149
|
+
"reason": { "type": "string" },
|
|
150
|
+
"bin": { "type": "string" },
|
|
151
|
+
"args": { "type": "array", "items": { "type": "string" } },
|
|
152
|
+
"probe": { "type": "object" },
|
|
153
|
+
"attempts": { "type": "array", "items": { "type": "object" } }
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"limits": {
|
|
157
|
+
"type": "object",
|
|
158
|
+
"properties": {
|
|
159
|
+
"available": { "type": "boolean" },
|
|
160
|
+
"bin": { "type": "string" },
|
|
161
|
+
"nproc": { "type": "integer", "minimum": 2 },
|
|
162
|
+
"asBytes": { "type": "integer", "minimum": 67108864 },
|
|
163
|
+
"applied": { "type": "array", "items": { "type": "string" } },
|
|
164
|
+
"observed": { "type": "object" },
|
|
165
|
+
"probe": { "type": "object" },
|
|
166
|
+
"reason": { "type": "string" }
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"processTreeKill": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"properties": {
|
|
172
|
+
"available": { "type": "boolean" },
|
|
173
|
+
"mechanism": { "type": "string" }
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"executed": { "type": "boolean", "description": "True when the sandboxed runtime probe actually ran." },
|
|
177
|
+
"execution": { "type": "object", "description": "Command, exit code, timeout/kill outcome, and process-tree clearing proof." },
|
|
178
|
+
"note": { "type": "string" }
|
|
179
|
+
}
|
|
180
|
+
},
|
|
111
181
|
"journeys": {
|
|
112
182
|
"type": "object",
|
|
113
183
|
"additionalProperties": false,
|
|
@@ -118,7 +188,7 @@
|
|
|
118
188
|
},
|
|
119
189
|
"claims": {
|
|
120
190
|
"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)
|
|
191
|
+
"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
192
|
"additionalProperties": false,
|
|
123
193
|
"required": ["claimLevel"],
|
|
124
194
|
"properties": {
|
|
@@ -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
|
+
}
|