@ploaness/governance 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/dist/a11y-hit-target.d.ts.map +1 -1
  2. package/dist/a11y-hit-target.js +1 -21
  3. package/dist/a11y-hit-target.js.map +1 -1
  4. package/dist/a11y-incomplete.d.ts.map +1 -1
  5. package/dist/a11y-incomplete.js +1 -18
  6. package/dist/a11y-incomplete.js.map +1 -1
  7. package/dist/access-boundary.d.ts +43 -1
  8. package/dist/access-boundary.d.ts.map +1 -1
  9. package/dist/access-boundary.js +146 -5
  10. package/dist/access-boundary.js.map +1 -1
  11. package/dist/admin-view-coverage.d.ts.map +1 -1
  12. package/dist/admin-view-coverage.js +1 -17
  13. package/dist/admin-view-coverage.js.map +1 -1
  14. package/dist/asset-policy.d.ts.map +1 -1
  15. package/dist/asset-policy.js +1 -23
  16. package/dist/asset-policy.js.map +1 -1
  17. package/dist/axe-coverage.d.ts +3 -4
  18. package/dist/axe-coverage.d.ts.map +1 -1
  19. package/dist/axe-coverage.js +18 -51
  20. package/dist/axe-coverage.js.map +1 -1
  21. package/dist/blocklist-entries.d.ts +36 -0
  22. package/dist/blocklist-entries.d.ts.map +1 -0
  23. package/dist/blocklist-entries.js +338 -0
  24. package/dist/blocklist-entries.js.map +1 -0
  25. package/dist/blocklist.d.ts +91 -0
  26. package/dist/blocklist.d.ts.map +1 -0
  27. package/dist/blocklist.js +187 -0
  28. package/dist/blocklist.js.map +1 -0
  29. package/dist/container-failure.d.ts.map +1 -1
  30. package/dist/container-failure.js +1 -18
  31. package/dist/container-failure.js.map +1 -1
  32. package/dist/container-files.d.ts +16 -0
  33. package/dist/container-files.d.ts.map +1 -1
  34. package/dist/container-files.js +23 -8
  35. package/dist/container-files.js.map +1 -1
  36. package/dist/container-images.d.ts +43 -0
  37. package/dist/container-images.d.ts.map +1 -0
  38. package/dist/container-images.js +157 -0
  39. package/dist/container-images.js.map +1 -0
  40. package/dist/dependency-freshness.d.ts +8 -0
  41. package/dist/dependency-freshness.d.ts.map +1 -1
  42. package/dist/dependency-freshness.js +2 -18
  43. package/dist/dependency-freshness.js.map +1 -1
  44. package/dist/doc-blocks.d.ts.map +1 -1
  45. package/dist/doc-blocks.js +1 -13
  46. package/dist/doc-blocks.js.map +1 -1
  47. package/dist/editorconfig-policy.d.ts +7 -0
  48. package/dist/editorconfig-policy.d.ts.map +1 -1
  49. package/dist/editorconfig-policy.js +19 -12
  50. package/dist/editorconfig-policy.js.map +1 -1
  51. package/dist/environment-coherence.d.ts.map +1 -1
  52. package/dist/environment-coherence.js +1 -23
  53. package/dist/environment-coherence.js.map +1 -1
  54. package/dist/environment-files.d.ts.map +1 -1
  55. package/dist/environment-files.js +1 -19
  56. package/dist/environment-files.js.map +1 -1
  57. package/dist/file-roles.d.ts +7 -2
  58. package/dist/file-roles.d.ts.map +1 -1
  59. package/dist/file-roles.js +10 -9
  60. package/dist/file-roles.js.map +1 -1
  61. package/dist/freshness-repair.d.ts +82 -0
  62. package/dist/freshness-repair.d.ts.map +1 -0
  63. package/dist/freshness-repair.js +91 -0
  64. package/dist/freshness-repair.js.map +1 -0
  65. package/dist/generated-denial.d.ts.map +1 -1
  66. package/dist/generated-denial.js +1 -9
  67. package/dist/generated-denial.js.map +1 -1
  68. package/dist/generated-drift.d.ts.map +1 -1
  69. package/dist/generated-drift.js +1 -12
  70. package/dist/generated-drift.js.map +1 -1
  71. package/dist/harness-package.d.ts +13 -0
  72. package/dist/harness-package.d.ts.map +1 -0
  73. package/dist/harness-package.js +20 -0
  74. package/dist/harness-package.js.map +1 -0
  75. package/dist/history-policy.d.ts.map +1 -1
  76. package/dist/history-policy.js +1 -7
  77. package/dist/history-policy.js.map +1 -1
  78. package/dist/image-assets.d.ts.map +1 -1
  79. package/dist/image-assets.js +1 -10
  80. package/dist/image-assets.js.map +1 -1
  81. package/dist/index.d.ts +12 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +12 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/install-policy.d.ts +21 -0
  86. package/dist/install-policy.d.ts.map +1 -1
  87. package/dist/install-policy.js +53 -1
  88. package/dist/install-policy.js.map +1 -1
  89. package/dist/jsx-accessibility-scope.d.ts +17 -0
  90. package/dist/jsx-accessibility-scope.d.ts.map +1 -0
  91. package/dist/jsx-accessibility-scope.js +36 -0
  92. package/dist/jsx-accessibility-scope.js.map +1 -0
  93. package/dist/jsx-accessibility.d.ts +13 -0
  94. package/dist/jsx-accessibility.d.ts.map +1 -0
  95. package/dist/jsx-accessibility.js +188 -0
  96. package/dist/jsx-accessibility.js.map +1 -0
  97. package/dist/network-policy.d.ts.map +1 -1
  98. package/dist/network-policy.js +1 -12
  99. package/dist/network-policy.js.map +1 -1
  100. package/dist/oxlint-policy.d.ts +16 -0
  101. package/dist/oxlint-policy.d.ts.map +1 -0
  102. package/dist/oxlint-policy.js +28 -0
  103. package/dist/oxlint-policy.js.map +1 -0
  104. package/dist/oxlint-report.d.ts +29 -0
  105. package/dist/oxlint-report.d.ts.map +1 -0
  106. package/dist/oxlint-report.js +84 -0
  107. package/dist/oxlint-report.js.map +1 -0
  108. package/dist/oxlint-scope.d.ts +13 -0
  109. package/dist/oxlint-scope.d.ts.map +1 -0
  110. package/dist/oxlint-scope.js +46 -0
  111. package/dist/oxlint-scope.js.map +1 -0
  112. package/dist/oxlint-suppressions.d.ts +17 -0
  113. package/dist/oxlint-suppressions.d.ts.map +1 -0
  114. package/dist/oxlint-suppressions.js +72 -0
  115. package/dist/oxlint-suppressions.js.map +1 -0
  116. package/dist/paired-assets.d.ts.map +1 -1
  117. package/dist/paired-assets.js.map +1 -1
  118. package/dist/payload-access.d.ts +6 -0
  119. package/dist/payload-access.d.ts.map +1 -1
  120. package/dist/payload-access.js +166 -9
  121. package/dist/payload-access.js.map +1 -1
  122. package/dist/payload-configs.d.ts +0 -1
  123. package/dist/payload-configs.d.ts.map +1 -1
  124. package/dist/payload-configs.js +36 -17
  125. package/dist/payload-configs.js.map +1 -1
  126. package/dist/payload-defaults.d.ts +128 -0
  127. package/dist/payload-defaults.d.ts.map +1 -0
  128. package/dist/payload-defaults.js +295 -0
  129. package/dist/payload-defaults.js.map +1 -0
  130. package/dist/payload-policy.d.ts +13 -0
  131. package/dist/payload-policy.d.ts.map +1 -1
  132. package/dist/payload-policy.js +81 -40
  133. package/dist/payload-policy.js.map +1 -1
  134. package/dist/relationship-cleanup.d.ts.map +1 -1
  135. package/dist/relationship-cleanup.js +16 -16
  136. package/dist/relationship-cleanup.js.map +1 -1
  137. package/dist/release-age.d.ts.map +1 -1
  138. package/dist/release-age.js +1 -16
  139. package/dist/release-age.js.map +1 -1
  140. package/dist/request-limits.d.ts.map +1 -1
  141. package/dist/request-limits.js +1 -11
  142. package/dist/request-limits.js.map +1 -1
  143. package/dist/route-map.d.ts.map +1 -1
  144. package/dist/route-map.js +1 -16
  145. package/dist/route-map.js.map +1 -1
  146. package/dist/run-plan.d.ts.map +1 -1
  147. package/dist/run-plan.js +1 -19
  148. package/dist/run-plan.js.map +1 -1
  149. package/dist/secret-policy.d.ts.map +1 -1
  150. package/dist/secret-policy.js +1 -11
  151. package/dist/secret-policy.js.map +1 -1
  152. package/dist/settings-layering.d.ts +8 -30
  153. package/dist/settings-layering.d.ts.map +1 -1
  154. package/dist/settings-layering.js +19 -48
  155. package/dist/settings-layering.js.map +1 -1
  156. package/dist/settings.d.ts +9 -2
  157. package/dist/settings.d.ts.map +1 -1
  158. package/dist/settings.js.map +1 -1
  159. package/dist/source-text.d.ts +2 -0
  160. package/dist/source-text.d.ts.map +1 -1
  161. package/dist/source-text.js +7 -16
  162. package/dist/source-text.js.map +1 -1
  163. package/dist/toolchain-pins.d.ts.map +1 -1
  164. package/dist/toolchain-pins.js +2 -19
  165. package/dist/toolchain-pins.js.map +1 -1
  166. package/dist/version-policy.d.ts +7 -8
  167. package/dist/version-policy.d.ts.map +1 -1
  168. package/dist/version-policy.js +15 -26
  169. package/dist/version-policy.js.map +1 -1
  170. package/dist/vulnerability-policy.d.ts.map +1 -1
  171. package/dist/vulnerability-policy.js +1 -11
  172. package/dist/vulnerability-policy.js.map +1 -1
  173. package/dist/wiring-policy.d.ts.map +1 -1
  174. package/dist/wiring-policy.js +4 -1
  175. package/dist/wiring-policy.js.map +1 -1
  176. package/dist/wiring-violation.d.ts.map +1 -1
  177. package/dist/wiring-violation.js +1 -6
  178. package/dist/wiring-violation.js.map +1 -1
  179. package/dist/workspace-policy.d.ts.map +1 -1
  180. package/dist/workspace-policy.js +3 -9
  181. package/dist/workspace-policy.js.map +1 -1
  182. package/dist/yaml-blocks.d.ts +10 -0
  183. package/dist/yaml-blocks.d.ts.map +1 -1
  184. package/dist/yaml-blocks.js +20 -0
  185. package/dist/yaml-blocks.js.map +1 -1
  186. package/package.json +2 -2
@@ -0,0 +1,187 @@
1
+ // The refusal rule: whether an image reference, an installed package, or a Dockerfile install line
2
+ // names something in `blocklist-entries.ts`, and the one place freshness has to defer to it.
3
+ //
4
+ // A reference is matched on its repository after normalisation, because the same image is written
5
+ // `mongo`, `docker.io/mongo`, `library/mongo`, and `docker.io/library/mongo`, and a list keyed on the
6
+ // spelling would refuse one of them and pull the other. The tag decides only where an entry carries a
7
+ // floor: a tag below the floor is the permissive release line and is left to the licence gate, and a
8
+ // tag that cannot be placed against the floor - `latest`, none, `7` against a floor of `7.4`, an
9
+ // `-alpine` suffix on a floating major - is refused, because a tag that may resolve past the floor
10
+ // tomorrow is not a proof that it sits below it today.
11
+ import { BLOCKED_IMAGES, BLOCKED_PACKAGES, BLOCKED_SYSTEM_PACKAGES, } from './blocklist-entries.js';
12
+ import { systemPackagesInDockerfile } from './container-images.js';
13
+ import { parseVersion } from './dependency-freshness.js';
14
+ import { asRecord, asText, isArray, isRecord, parseJsonc } from './json-shapes.js';
15
+ import { isLicenseAllowed } from './license-allowlist.js';
16
+ const DOCKER_HUB_HOSTS = new Set(['docker.io', 'index.docker.io']);
17
+ const OFFICIAL_NAMESPACE = 'library';
18
+ const LOCAL_HOST = 'localhost';
19
+ const MUTABLE_TAG = 'latest';
20
+ const WILDCARD = '*';
21
+ const NUMERIC_COMPONENTS = /^v?(?<components>\d+(?:\.\d+)*)/;
22
+ // A reference is a name-and-tag and at most one digest after the `@`.
23
+ const REFERENCE_PARTS = 2;
24
+ // A first path segment is a registry host when it carries a dot or a port, or is `localhost`; a Docker
25
+ // Hub namespace never does. The rule the docker CLI itself applies.
26
+ const isRegistryHost = (segment) => segment.includes('.') || segment.includes(':') || segment === LOCAL_HOST;
27
+ const splitHost = (segments) => {
28
+ const [first] = segments;
29
+ if (first === undefined || segments.length === 1 || !isRegistryHost(first)) {
30
+ return { host: undefined, path: segments };
31
+ }
32
+ return { host: DOCKER_HUB_HOSTS.has(first) ? undefined : first, path: segments.slice(1) };
33
+ };
34
+ const normaliseRepository = (name) => {
35
+ const { host, path } = splitHost(name.toLowerCase().split('/'));
36
+ if (host !== undefined) {
37
+ return [host, ...path].join('/');
38
+ }
39
+ return (path.length > 1 && path[0] === OFFICIAL_NAMESPACE ? path.slice(1) : path).join('/');
40
+ };
41
+ /**
42
+ * Split an image reference as a Dockerfile, a workflow, or a compose model writes it.
43
+ * @param raw the reference, such as `docker.io/library/redis:7.4.1@sha256:...`.
44
+ * @returns the normalised repository, and the tag and digest when present.
45
+ */
46
+ export const parseImageReference = (raw) => {
47
+ const [nameAndTag = '', digest] = raw.split('@', REFERENCE_PARTS);
48
+ const lastSlash = nameAndTag.lastIndexOf('/');
49
+ const colon = nameAndTag.lastIndexOf(':');
50
+ const hasTag = colon > lastSlash;
51
+ return {
52
+ raw,
53
+ repository: normaliseRepository(hasTag ? nameAndTag.slice(0, colon) : nameAndTag),
54
+ tag: hasTag ? nameAndTag.slice(colon + 1) : undefined,
55
+ digest,
56
+ };
57
+ };
58
+ /**
59
+ * Whether a reference may resolve to a different image tomorrow: no digest, and no tag or `latest`.
60
+ * @param raw the reference as written.
61
+ * @returns true when nothing in the reference pins what is pulled.
62
+ */
63
+ export const isMutableImageReference = (raw) => {
64
+ const reference = parseImageReference(raw);
65
+ return (reference.digest === undefined && (reference.tag === undefined || reference.tag === MUTABLE_TAG));
66
+ };
67
+ const matchesPattern = (pattern, name) => pattern.endsWith(WILDCARD)
68
+ ? name.startsWith(pattern.slice(0, -WILDCARD.length))
69
+ : name === pattern;
70
+ const compareCore = (one, other) => one.major - other.major || one.minor - other.minor || one.patch - other.patch;
71
+ const componentCount = (version) => (NUMERIC_COMPONENTS.exec(version)?.groups?.['components'] ?? '').split('.').filter(Boolean).length;
72
+ // Undecidable is refused: a version that cannot be placed against the floor is not below it.
73
+ const reachesFloor = (version, floor) => {
74
+ const parsed = version === undefined ? undefined : parseVersion(version);
75
+ const floorParsed = parseVersion(floor);
76
+ if (version === undefined || parsed === undefined || floorParsed === undefined) {
77
+ return true;
78
+ }
79
+ return componentCount(version) < componentCount(floor) || compareCore(parsed, floorParsed) >= 0;
80
+ };
81
+ const isAllowedTag = (entry, tag) => entry.allowedTag !== undefined && tag !== undefined && entry.allowedTag.test(tag);
82
+ const refusalOf = (subject, entry) => ({
83
+ subject,
84
+ reason: entry.reason,
85
+ replacement: entry.replacement,
86
+ });
87
+ /**
88
+ * Whether an image reference names a refused repository at a refused tag.
89
+ * @param raw the reference as written.
90
+ * @returns the refusal, or undefined when the image is not one ploaness refuses.
91
+ */
92
+ export const refuseImage = (raw) => {
93
+ const reference = parseImageReference(raw);
94
+ const entry = BLOCKED_IMAGES.find((candidate) => matchesPattern(candidate.repository, reference.repository));
95
+ if (entry === undefined || isAllowedTag(entry, reference.tag)) {
96
+ return undefined;
97
+ }
98
+ return entry.from !== undefined && !reachesFloor(reference.tag, entry.from)
99
+ ? undefined
100
+ : refusalOf(raw, entry);
101
+ };
102
+ /**
103
+ * Whether an installed package at a version is one ploaness refuses.
104
+ * @param name the package name.
105
+ * @param version the resolved version.
106
+ * @returns the refusal, or undefined when the package is not one ploaness refuses at that version.
107
+ */
108
+ export const refusePackage = (name, version) => {
109
+ const entry = BLOCKED_PACKAGES.find((candidate) => matchesPattern(candidate.name, name));
110
+ if (entry === undefined) {
111
+ return undefined;
112
+ }
113
+ return entry.from !== undefined && !reachesFloor(version, entry.from)
114
+ ? undefined
115
+ : refusalOf(`${name}@${version}`, entry);
116
+ };
117
+ /**
118
+ * The refused system packages a Dockerfile installs.
119
+ * @param text the Dockerfile body.
120
+ * @returns one refusal per refused package, in file order.
121
+ */
122
+ export const refuseSystemPackages = (text) => systemPackagesInDockerfile(text).flatMap((name) => {
123
+ const entry = BLOCKED_SYSTEM_PACKAGES.find((candidate) => candidate.name === name);
124
+ return entry === undefined ? [] : [refusalOf(name, entry)];
125
+ });
126
+ /**
127
+ * The resolved set as `pnpm licenses list --json` reports it: grouped by licence, each entry carrying
128
+ * the name and the versions installed.
129
+ * @param json the command's stdout.
130
+ * @returns every installed package, or undefined when the text is not that inventory.
131
+ */
132
+ export const packagesInLicenseInventory = (json) => {
133
+ const inventory = parseJsonc(json).value;
134
+ if (!isRecord(inventory) || isArray(inventory)) {
135
+ return undefined;
136
+ }
137
+ return Object.values(inventory).flatMap((group) => (isArray(group) ? group : []).map((entry) => {
138
+ const versions = asRecord(entry)['versions'];
139
+ return {
140
+ name: asText(asRecord(entry)['name']),
141
+ versions: (isArray(versions) ? versions : []).map((raw) => asText(raw)),
142
+ };
143
+ }));
144
+ };
145
+ /**
146
+ * The refusals across an installed set.
147
+ * @param packages the resolved set.
148
+ * @returns one refusal per refused name and version, in inventory order.
149
+ */
150
+ export const refuseInstalledPackages = (packages) => packages.flatMap((entry) => entry.versions.flatMap((version) => {
151
+ const refusal = refusePackage(entry.name, version);
152
+ return refusal === undefined ? [] : [refusal];
153
+ }));
154
+ // The one place the freshness bound defers to this rule. A package whose newest major is refused here,
155
+ // or is licensed outside the allowlist, would otherwise fall two majors behind and be failed for not
156
+ // upgrading into the very release the licence gate would then refuse.
157
+ const refusedLatestNote = (status) => {
158
+ const refusal = refusePackage(status.name, status.latest);
159
+ const newest = `${status.name}: the newest release ${status.latest}`;
160
+ if (refusal !== undefined) {
161
+ return `${newest} is refused (${refusal.reason}), so freshness stops short of it`;
162
+ }
163
+ const licence = status.latestLicense;
164
+ return licence === undefined || isLicenseAllowed(licence)
165
+ ? undefined
166
+ : `${newest} is licensed ${licence}, outside the allowlist, so freshness stops short of it`;
167
+ };
168
+ /**
169
+ * Split the declared coordinates into those freshness may measure and those whose newest release is
170
+ * refused, which freshness must not demand.
171
+ * @param statuses every declared coordinate with what the registry answered for it.
172
+ * @returns the measurable statuses, and the refused ones with the note the report prints.
173
+ */
174
+ export const scopeFreshness = (statuses) => statuses.reduce((scope, status) => {
175
+ const note = refusedLatestNote(status);
176
+ return note === undefined
177
+ ? { ...scope, measurable: [...scope.measurable, status] }
178
+ : { ...scope, refused: [...scope.refused, { status, note }] };
179
+ }, { measurable: [], refused: [] });
180
+ /**
181
+ * The refusals of a repository's own JSON summary, kept exported so the CLI prints the same words.
182
+ * @param refusal one refusal.
183
+ * @param location the file or inventory that carries the subject.
184
+ * @returns one finding line.
185
+ */
186
+ export const describeRefusal = (refusal, location) => `${location}: ${refusal.subject} - ${refusal.reason}; use ${refusal.replacement}`;
187
+ //# sourceMappingURL=blocklist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocklist.js","sourceRoot":"","sources":["../src/blocklist.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"container-failure.d.ts","sourceRoot":"","sources":["../src/container-failure.ts"],"names":[],"mappings":"AAmBA,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,2DAA2D;AAC3D,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,YAAY,GACZ,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,aAAa,CAAA;AAEjB,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAED,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,EAAE,MAAY,CAAA;AAyG5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,YAAY,YAAY,KACvB,aAAa,GAAG,SAalB,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,MAAM,EACZ,YAAY,YAAY,KACvB,aAAa,GAAG,SAOlB,CAAA"}
1
+ {"version":3,"file":"container-failure.d.ts","sourceRoot":"","sources":["../src/container-failure.ts"],"names":[],"mappings":"AAEA,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,2DAA2D;AAC3D,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,YAAY,GACZ,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,aAAa,CAAA;AAEjB,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAED,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,EAAE,MAAY,CAAA;AAyG5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,YAAY,YAAY,KACvB,aAAa,GAAG,SAalB,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,MAAM,EACZ,YAAY,YAAY,KACvB,aAAa,GAAG,SAOlB,CAAA"}
@@ -1,21 +1,4 @@
1
- // Why a containerised gate failed, told apart from what its analyzer reported.
2
- //
3
- // `docker run` passes the container's own exit code through, so a gate that reads every non-zero exit as
4
- // the tool's verdict reads a failure of Docker as a finding. The consequence was not cosmetic: a Docker
5
- // Hub pull-rate limit - 100 anonymous pulls per six hours per IP, which several teams behind one CI
6
- // egress reach - made the secret scan announce that it had found a secret in the git history. That is the
7
- // one verdict a project cannot dismiss on its own judgement, and the worst thing this harness can say. A
8
- // registry outage, an unreachable network, and a digest the registry no longer serves all landed the same
9
- // way.
10
- //
11
- // Two classifiers rather than one, and the split is the actual repair. `classifyImageFailure` reads
12
- // markers out of the output because it judges `docker image inspect` and `docker pull`, whose every byte
13
- // docker wrote. `classifyContainerExit` judges a run of the analyzer, whose output carries content the
14
- // PROJECT authored - a commit message, a Dockerfile, a workflow - so it reads the exit code and nothing
15
- // else. Matching `no such host` against a commit message would invert the same bug rather than fix it.
16
- //
17
- // The rules are pure so they are exercised against captured `docker` output rather than against a live
18
- // daemon: every branch below describes a failure that is expensive or impossible to stage on demand.
1
+ // Distinguish unavailable container infrastructure from analyzer findings so each failure names the right repair.
19
2
  /** The exit code a shell reports for a command it cannot find. */
20
3
  export const COMMAND_NOT_FOUND = 127;
21
4
  // `docker run` reserves these for a failure of docker itself, distinct from whatever the container exits
@@ -1 +1 @@
1
- {"version":3,"file":"container-failure.js","sourceRoot":"","sources":["../src/container-failure.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container-failure.js","sourceRoot":"","sources":["../src/container-failure.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,22 @@ export declare const isDockerfile: (file: string) => boolean;
17
17
  * @returns true when the file identifies a compose project.
18
18
  */
19
19
  export declare const isComposeFile: (file: string) => boolean;
20
+ /**
21
+ * Whether a tracked path is a GitHub Actions workflow.
22
+ * @param file the repo-relative path.
23
+ * @returns true for a YAML file directly under `.github/workflows`.
24
+ */
25
+ export declare const isWorkflowFile: (file: string) => boolean;
26
+ /**
27
+ * Every workflow the repository tracks.
28
+ *
29
+ * Discovered from the working tree rather than listed, for the reason `scripts/verify.sh` records about
30
+ * its own shell scripts: an enumeration is correct only at the moment it is written, and a workflow
31
+ * added later would be a workflow nothing reads.
32
+ * @param tracked the repo-relative paths of the tracked files.
33
+ * @returns the workflows, ordered so a report reads the same on every machine.
34
+ */
35
+ export declare const workflowsIn: (tracked: readonly string[]) => readonly string[];
20
36
  /**
21
37
  * Every Dockerfile the repository tracks.
22
38
  * @param tracked the repo-relative paths of the tracked files.
@@ -1 +1 @@
1
- {"version":3,"file":"container-files.d.ts","sourceRoot":"","sources":["../src/container-files.ts"],"names":[],"mappings":"AASA,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAqBD;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,OAG3C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,OAAuD,CAAA;AAMpG;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAGO,CAAA;AAEjF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,cAAc,EAcrF,CAAA"}
1
+ {"version":3,"file":"container-files.d.ts","sourceRoot":"","sources":["../src/container-files.ts"],"names":[],"mappings":"AAEA,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAqBD;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,OAG3C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,OAAuD,CAAA;AASpG;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OAG8B,CAAA;AAE5E;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAGS,CAAA;AAEjF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAGO,CAAA;AAEjF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,cAAc,EAcrF,CAAA"}
@@ -1,11 +1,4 @@
1
- // Which files in a tracked tree are container definitions, and which directories hold a compose project.
2
- //
3
- // Discovery is stated here for both kinds at once, because stating it for only one is how the two halves
4
- // drifted. The Dockerfile half already walked the tracked tree - a project may keep a Dockerfile in any
5
- // directory, and a hard-coded path would silently skip the ones it did not anticipate - while the compose
6
- // half looked at the repository root and nowhere else. A Payload project that keeps its application in a
7
- // member directory keeps its compose file beside it, so the gate linted that member's Dockerfile and
8
- // reported a pass having validated no compose project at all.
1
+ // Identify container definitions and compose projects from the working-tree inventory.
9
2
  // Sliced rather than split, so neither helper carries a case that cannot happen. `lastIndexOf`
10
3
  // returns -1 for a bare basename, which makes these the whole string and the empty string - the two
11
4
  // answers a repository-root file wants - without a fallback no input could reach.
@@ -40,6 +33,28 @@ export const isComposeFile = (file) => COMPOSE_BASENAMES.includes(basenameOf(fil
40
33
  // Where a name sits in compose's own precedence. Only ever asked of a file `isComposeFile` accepted,
41
34
  // so the -1 `indexOf` returns for anything else is unreachable rather than meaningful.
42
35
  const precedenceOf = (file) => COMPOSE_BASENAMES.indexOf(basenameOf(file));
36
+ const WORKFLOW_DIRECTORY = '.github/workflows/';
37
+ const WORKFLOW_SUFFIXES = ['.yml', '.yaml'];
38
+ /**
39
+ * Whether a tracked path is a GitHub Actions workflow.
40
+ * @param file the repo-relative path.
41
+ * @returns true for a YAML file directly under `.github/workflows`.
42
+ */
43
+ export const isWorkflowFile = (file) => file.startsWith(WORKFLOW_DIRECTORY) &&
44
+ !file.slice(WORKFLOW_DIRECTORY.length).includes('/') &&
45
+ WORKFLOW_SUFFIXES.some((suffix) => file.endsWith(suffix));
46
+ /**
47
+ * Every workflow the repository tracks.
48
+ *
49
+ * Discovered from the working tree rather than listed, for the reason `scripts/verify.sh` records about
50
+ * its own shell scripts: an enumeration is correct only at the moment it is written, and a workflow
51
+ * added later would be a workflow nothing reads.
52
+ * @param tracked the repo-relative paths of the tracked files.
53
+ * @returns the workflows, ordered so a report reads the same on every machine.
54
+ */
55
+ export const workflowsIn = (tracked) => tracked
56
+ .filter((file) => isWorkflowFile(file))
57
+ .toSorted((left, right) => left.localeCompare(right));
43
58
  /**
44
59
  * Every Dockerfile the repository tracks.
45
60
  * @param tracked the repo-relative paths of the tracked files.
@@ -1 +1 @@
1
- {"version":3,"file":"container-files.js","sourceRoot":"","sources":["../src/container-files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container-files.js","sourceRoot":"","sources":["../src/container-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Join backslash-continued lines, so a `RUN` split across lines reads as the one command it is.
3
+ * @param text the file body.
4
+ * @returns one entry per logical line.
5
+ */
6
+ export declare const logicalLines: (text: string) => readonly string[];
7
+ /**
8
+ * The images a Dockerfile pulls: every `FROM` that names a registry image rather than an earlier stage.
9
+ * @param text the Dockerfile body.
10
+ * @returns the references in file order, with `ARG` defaults substituted.
11
+ */
12
+ export declare const imageReferencesInDockerfile: (text: string) => readonly string[];
13
+ /**
14
+ * The system packages a Dockerfile installs through the base image's package manager.
15
+ * @param text the Dockerfile body.
16
+ * @returns every package name after an install verb, in file order.
17
+ */
18
+ export declare const systemPackagesInDockerfile: (text: string) => readonly string[];
19
+ /**
20
+ * The images a GitHub Actions workflow pulls: service containers, job containers, and Docker actions.
21
+ * @param text the workflow body.
22
+ * @returns the references in file order.
23
+ */
24
+ export declare const imageReferencesInWorkflow: (text: string) => readonly string[];
25
+ /** One service of a compose model and the image it pulls. */
26
+ export interface ComposeImage {
27
+ readonly service: string;
28
+ readonly image: string;
29
+ }
30
+ /**
31
+ * The images a rendered compose model pulls. A service with a `build` is judged through its Dockerfile,
32
+ * and its `image` is only the name the build is tagged with.
33
+ * @param json the output of `docker compose config --format json`.
34
+ * @returns the pulled images by service name, or undefined when the text is not a compose model.
35
+ */
36
+ export declare const imageReferencesInComposeModel: (json: string) => readonly ComposeImage[] | undefined;
37
+ /**
38
+ * Whether a reference still carries a variable nothing substituted, so no rule can say what it pulls.
39
+ * @param reference the reference as read.
40
+ * @returns true when a `$` remains in it.
41
+ */
42
+ export declare const hasUnresolvedVariable: (reference: string) => boolean;
43
+ //# sourceMappingURL=container-images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-images.d.ts","sourceRoot":"","sources":["../src/container-images.ts"],"names":[],"mappings":"AAuCA;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,SAAS,MAAM,EACX,CAAA;AAmEhD;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,MAAM,KAAG,SAAS,MAAM,EAK5D,CAAA;AAed;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GAAI,MAAM,MAAM,KAAG,SAAS,MAAM,EAQrE,CAAA;AASJ;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,MAAM,MAAM,KAAG,SAAS,MAAM,EAOlE,CAAA;AAEN,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,GACxC,MAAM,MAAM,KACX,SAAS,YAAY,EAAE,GAAG,SAc5B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,KAAG,OAAkC,CAAA"}
@@ -0,0 +1,157 @@
1
+ // Where a repository names the container images it pulls, read into plain references.
2
+ //
3
+ // Three files name an image: a Dockerfile in its `FROM` lines, a workflow in the `image:` of a service
4
+ // or job container and in a `docker://` action, and a compose file in `services.*.image`. The compose
5
+ // half is read from the model `docker compose config --format json` renders rather than from the YAML,
6
+ // because compose interpolates `${VARIABLE}` from the `.env` beside the file and resolves the override
7
+ // files it merges, and a reader of the source text would judge a reference the daemon never pulls.
8
+ //
9
+ // The Dockerfile and workflow readers are line readers over a known syntax, in the spirit of
10
+ // `yaml-blocks.ts`: what has to be recognised is one keyword and the token after it.
11
+ import { asRecord, asText, isArray, isRecord, parseJsonc } from './json-shapes.js';
12
+ import { withoutQuotes } from './yaml-blocks.js';
13
+ const CONTINUATION = /\\\r?\n/g;
14
+ // A keyword, horizontal space, then a value that starts with a non-space: the value pattern cannot
15
+ // exchange characters with the space run before it, which is what keeps the match linear.
16
+ const FROM_LINE = /^[ \t]*FROM[ \t]+(?<rest>\S.*)$/i;
17
+ const ARG_LINE = /^[ \t]*ARG[ \t]+(?<name>[A-Z_]\w*)=(?<value>\S+)/i;
18
+ const RUN_LINE = /^[ \t]*RUN[ \t]+(?<rest>\S.*)$/i;
19
+ const COMMENT_LINE = /^[ \t]*#/;
20
+ // A base image every multi-stage build may start from that no registry serves.
21
+ const SCRATCH = 'scratch';
22
+ const STAGE_KEYWORD = 'as';
23
+ const PLATFORM_OPTION = '--';
24
+ // The install verbs of the package managers a base image ships. `apt-get install`, `apk add`, and the
25
+ // Red Hat family; pip and npm are language installs and judged elsewhere.
26
+ const INSTALL_VERB = /\b(?:apt-get|apt|apk|dnf|microdnf|yum|zypper)[ \t]+(?:install|add)\b/;
27
+ const COMMAND_SEPARATOR = /&&|\|\||;|\|/;
28
+ // What ends a package name in an install token: apt's `=version` and `/suite`, apk's `=version` and
29
+ // `~version`. dnf's `-version` is indistinguishable from a hyphenated name and is left alone.
30
+ const PACKAGE_NAME_END = /[=/~]/;
31
+ const OPTION_PREFIX = '-';
32
+ const WORKFLOW_IMAGE = /^[ \t]*(?:-[ \t]*)?image:[ \t]*(?<value>[^\s#][^#]*)/;
33
+ const WORKFLOW_CONTAINER = /^[ \t]*container:[ \t]*(?<value>[^\s#{]+)/;
34
+ const WORKFLOW_DOCKER_ACTION = /uses:[ \t]*['"]?docker:\/\/(?<value>[^\s'"]+)/;
35
+ /**
36
+ * Join backslash-continued lines, so a `RUN` split across lines reads as the one command it is.
37
+ * @param text the file body.
38
+ * @returns one entry per logical line.
39
+ */
40
+ export const logicalLines = (text) => text.replaceAll(CONTINUATION, ' ').split('\n');
41
+ const contentLines = (text) => logicalLines(text).filter((line) => !COMMENT_LINE.test(line));
42
+ const readFrom = (rest) => {
43
+ const tokens = (rest ?? '')
44
+ .trim()
45
+ .split(/[ \t]+/)
46
+ .filter((token) => !token.startsWith(PLATFORM_OPTION));
47
+ const [first, keyword, stage] = tokens;
48
+ const reference = first ?? '';
49
+ if (reference.length === 0) {
50
+ return undefined;
51
+ }
52
+ return { reference, stage: keyword?.toLowerCase() === STAGE_KEYWORD ? stage : undefined };
53
+ };
54
+ // `FROM node:${NODE_VERSION}` is the common way to state a version once, and the ARG that gives it a
55
+ // default is the only place the value lives. Both spellings of a reference are substituted; an ARG with
56
+ // no default leaves the variable in place, and the rule reports it as a reference it cannot judge.
57
+ const substituteArguments = (reference, defaults) => [...defaults].reduce((resolved, [name, value]) => resolved
58
+ .replaceAll(`\${${name}}`, () => value)
59
+ .replaceAll(`$${name}`, () => value), reference);
60
+ const recordArgument = (walk, line) => {
61
+ const found = ARG_LINE.exec(line);
62
+ if (found?.groups === undefined) {
63
+ return undefined;
64
+ }
65
+ const defaults = new Map([
66
+ ...walk.defaults,
67
+ [found.groups['name'] ?? '', withoutQuotes(found.groups['value'] ?? '')],
68
+ ]);
69
+ return { ...walk, defaults };
70
+ };
71
+ const recordFrom = (walk, line) => {
72
+ const from = readFrom(FROM_LINE.exec(line)?.groups?.['rest']);
73
+ if (from === undefined) {
74
+ return walk;
75
+ }
76
+ const reference = substituteArguments(from.reference, walk.defaults);
77
+ const isRegistryImage = reference !== SCRATCH && !walk.stages.has(reference);
78
+ return {
79
+ defaults: walk.defaults,
80
+ stages: from.stage === undefined ? walk.stages : new Set([...walk.stages, from.stage]),
81
+ references: isRegistryImage ? [...walk.references, reference] : walk.references,
82
+ };
83
+ };
84
+ /**
85
+ * The images a Dockerfile pulls: every `FROM` that names a registry image rather than an earlier stage.
86
+ * @param text the Dockerfile body.
87
+ * @returns the references in file order, with `ARG` defaults substituted.
88
+ */
89
+ export const imageReferencesInDockerfile = (text) => contentLines(text).reduce((walk, line) => recordArgument(walk, line) ?? recordFrom(walk, line), { defaults: new Map(), stages: new Set(), references: [] }).references;
90
+ const packagesInCommand = (command) => {
91
+ const verb = INSTALL_VERB.exec(command);
92
+ if (verb === null) {
93
+ return [];
94
+ }
95
+ return command
96
+ .slice(verb.index + verb[0].length)
97
+ .trim()
98
+ .split(/[ \t]+/)
99
+ .filter((token) => token.length > 0 && !token.startsWith(OPTION_PREFIX))
100
+ .map((token) => token.split(PACKAGE_NAME_END)[0] ?? '');
101
+ };
102
+ /**
103
+ * The system packages a Dockerfile installs through the base image's package manager.
104
+ * @param text the Dockerfile body.
105
+ * @returns every package name after an install verb, in file order.
106
+ */
107
+ export const systemPackagesInDockerfile = (text) => contentLines(text).flatMap((line) => {
108
+ const rest = RUN_LINE.exec(line)?.groups?.['rest'];
109
+ return rest === undefined
110
+ ? []
111
+ : rest
112
+ .split(COMMAND_SEPARATOR)
113
+ .flatMap((command) => packagesInCommand(command));
114
+ });
115
+ const workflowReferenceIn = (line) => {
116
+ const found = WORKFLOW_DOCKER_ACTION.exec(line) ?? WORKFLOW_IMAGE.exec(line) ?? WORKFLOW_CONTAINER.exec(line);
117
+ const value = found?.groups?.['value'];
118
+ return value === undefined ? undefined : withoutQuotes(value.trim());
119
+ };
120
+ /**
121
+ * The images a GitHub Actions workflow pulls: service containers, job containers, and Docker actions.
122
+ * @param text the workflow body.
123
+ * @returns the references in file order.
124
+ */
125
+ export const imageReferencesInWorkflow = (text) => text
126
+ .split('\n')
127
+ .filter((line) => !COMMENT_LINE.test(line))
128
+ .flatMap((line) => {
129
+ const reference = workflowReferenceIn(line);
130
+ return reference === undefined || reference.length === 0 ? [] : [reference];
131
+ });
132
+ /**
133
+ * The images a rendered compose model pulls. A service with a `build` is judged through its Dockerfile,
134
+ * and its `image` is only the name the build is tagged with.
135
+ * @param json the output of `docker compose config --format json`.
136
+ * @returns the pulled images by service name, or undefined when the text is not a compose model.
137
+ */
138
+ export const imageReferencesInComposeModel = (json) => {
139
+ const model = parseJsonc(json).value;
140
+ if (!isRecord(model) || isArray(model) || !isRecord(model['services'])) {
141
+ return undefined;
142
+ }
143
+ return Object.entries(model['services'])
144
+ .flatMap(([service, definition]) => {
145
+ const image = asText(asRecord(definition)['image']);
146
+ const isBuilt = asRecord(definition)['build'] !== undefined;
147
+ return isBuilt || image.length === 0 ? [] : [{ service, image }];
148
+ })
149
+ .toSorted((one, other) => one.service.localeCompare(other.service));
150
+ };
151
+ /**
152
+ * Whether a reference still carries a variable nothing substituted, so no rule can say what it pulls.
153
+ * @param reference the reference as read.
154
+ * @returns true when a `$` remains in it.
155
+ */
156
+ export const hasUnresolvedVariable = (reference) => reference.includes('$');
157
+ //# sourceMappingURL=container-images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-images.js","sourceRoot":"","sources":["../src/container-images.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,14 @@ export interface DeclaredCoordinate {
53
53
  export interface DependencyStatus extends DeclaredCoordinate {
54
54
  /** The latest version published to the registry. */
55
55
  readonly latest: string;
56
+ /**
57
+ * The licence the registry records for that latest version, when it records one.
58
+ *
59
+ * Carried so the blocklist can keep the bound from demanding an upgrade into a release the licence
60
+ * gate would refuse: a package that changed licence at its newest major is still measured, but never
61
+ * past the last release a project may install.
62
+ */
63
+ readonly latestLicense?: string;
56
64
  }
57
65
  /** One parsed manifest, with the path a finding will name. */
58
66
  export interface ManifestSource {
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-freshness.d.ts","sourceRoot":"","sources":["../src/dependency-freshness.ts"],"names":[],"mappings":"AAqBA,kFAAkF;AAClF,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEvD,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,EAAE,MAAU,CAAA;AAE7C,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAQD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,aAAa,GAAG,SAW1D,CAAA;AA0BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,gBAUnE,CAAA;AAED,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qFAAqF;IACrF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAC9B;AAED,2EAA2E;AAC3E,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAClF,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAA;CACjD;AA6BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GACjC,OAAO,MAAM,GAAG,SAAS,EACzB,UAAU,gBAAgB,KACzB,SAAS,MAAM,EACkE,CAAA;AAEpF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,kBAAkB,GAC7B,WAAW,SAAS,cAAc,EAAE,KACnC,SAAS,kBAAkB,EAU3B,CAAA;AAEH,gGAAgG;AAChG,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAA;CACpC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAC/C;AAYD;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,SAAS,gBAAgB,EAAE,KAAG,eAiB/E,CAAA"}
1
+ {"version":3,"file":"dependency-freshness.d.ts","sourceRoot":"","sources":["../src/dependency-freshness.ts"],"names":[],"mappings":"AAKA,kFAAkF;AAClF,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEvD,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,EAAE,MAAU,CAAA;AAE7C,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAQD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,aAAa,GAAG,SAW1D,CAAA;AA0BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,gBAUnE,CAAA;AAED,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qFAAqF;IACrF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAC9B;AAED,2EAA2E;AAC3E,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAClF,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAA;CACjD;AA6BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GACjC,OAAO,MAAM,GAAG,SAAS,EACzB,UAAU,gBAAgB,KACzB,SAAS,MAAM,EACkE,CAAA;AAEpF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,kBAAkB,GAC7B,WAAW,SAAS,cAAc,EAAE,KACnC,SAAS,kBAAkB,EAU3B,CAAA;AAEH,gGAAgG;AAChG,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAA;CACpC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAC/C;AAYD;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,SAAS,gBAAgB,EAAE,KAAG,eAiB/E,CAAA"}
@@ -1,22 +1,6 @@
1
- // Dependency-freshness policy: the pure, unit-tested logic that reads the coordinates a repository
2
- // declares and classifies how far each has drifted from its latest published release. The `deps` gate in
3
- // packages/cli/src/checks/dependencies.ts reads the manifests and asks the registry.
4
- //
5
- // Policy: a declared dependency (transitive deps never count) whose current major version is
6
- // MAJOR_FAIL_THRESHOLD or more behind the latest published major FAILS the build; any lesser lag (a
7
- // single major behind, or a minor/patch behind) appears in the non-failing update report. The Biome config `$schema`
8
- // URL version is fed through the same classifier as a pseudo-dependency. There is no exemption list:
9
- // every declared dependency is MEASURED against the same bar, so a deliberately old pin that falls two
10
- // majors behind must be bumped or the pin dropped.
11
- //
12
- // One thing the bar does not decide is who the build stops. A coordinate an INHERITED manifest declares
13
- // is measured identically and reported at its real verdict, and it never fails the build: the version
14
- // belongs to ploaness, the project has no file in which to change it, and a gate that stopped every
15
- // consumer at once over a pin none of them can edit would be reporting ploaness's defect as theirs.
16
- // That is a statement about whose repair it is rather than an exemption from the measurement, which is
17
- // why the verdict survives into the report instead of being softened into an ordinary update.
1
+ // Compare declared coordinates with stable releases and apply the fixed major-version freshness bound.
2
+ import { isHarnessPackage } from './harness-package.js';
18
3
  import { declaredDependencies } from './json-shapes.js';
19
- import { isHarnessPackage } from './version-policy.js';
20
4
  /** Major-version gap (`latest.major - current.major`) at or above which the gate FAILS the build. */
21
5
  export const MAJOR_FAIL_THRESHOLD = 2;
22
6
  // A leading range operator (`^ ~ >= <= = v`) or whitespace is tolerated, then the numeric core is