configsentry 0.0.27 → 0.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,6 +102,7 @@ Tip: for machine output use `--format json` / `--format sarif`.
102
102
 
103
103
  ## Docs
104
104
 
105
+ - Proof in the wild (public repo tests): [`repo-tests/`](repo-tests/)
105
106
  - GitHub Action usage examples: [`docs/action-usage.md`](docs/action-usage.md)
106
107
  - Baselines (incremental adoption): [`docs/baselines.md`](docs/baselines.md)
107
108
  - Compatibility & scope: [`docs/compatibility.md`](docs/compatibility.md)
package/dist/rules.js CHANGED
@@ -263,6 +263,44 @@ export function runRules(compose, targetPath) {
263
263
  });
264
264
  }
265
265
  }
266
+ // Rule: depends_on without healthchecks / service_healthy
267
+ // Compose nuance: service_healthy requires healthchecks and is not universally used.
268
+ // We keep this as a gentle reliability warning.
269
+ const dependsOn = svc?.depends_on;
270
+ if (dependsOn != null) {
271
+ // Collect dependency service names.
272
+ const deps = [];
273
+ if (Array.isArray(dependsOn)) {
274
+ for (const d of dependsOn)
275
+ if (typeof d === 'string')
276
+ deps.push(d);
277
+ }
278
+ else if (dependsOn && typeof dependsOn === 'object') {
279
+ for (const k of Object.keys(dependsOn))
280
+ deps.push(k);
281
+ }
282
+ // Detect whether any condition: service_healthy is used.
283
+ let hasServiceHealthy = false;
284
+ if (dependsOn && typeof dependsOn === 'object' && !Array.isArray(dependsOn)) {
285
+ for (const v of Object.values(dependsOn)) {
286
+ if (v && typeof v === 'object' && String(v.condition ?? '').toLowerCase() === 'service_healthy') {
287
+ hasServiceHealthy = true;
288
+ }
289
+ }
290
+ }
291
+ const depsMissingHealthchecks = deps.filter((d) => services?.[d]?.healthcheck == null);
292
+ if (depsMissingHealthchecks.length > 0 || !hasServiceHealthy) {
293
+ findings.push({
294
+ id: 'compose.depends-on-without-health',
295
+ title: 'depends_on without healthcheck gating',
296
+ severity: 'low',
297
+ message: `Service '${serviceName}' uses depends_on without robust healthcheck gating.`,
298
+ service: serviceName,
299
+ path: `${targetPath}#services.${serviceName}.depends_on`,
300
+ suggestion: "Prefer adding healthchecks and (where supported) depends_on: { <svc>: { condition: service_healthy } } to avoid startup race conditions."
301
+ });
302
+ }
303
+ }
266
304
  // Rule: restart policy
267
305
  if (svc?.restart == null) {
268
306
  findings.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "configsentry",
3
- "version": "0.0.27",
3
+ "version": "0.0.28",
4
4
  "description": "Developer-first guardrails for docker-compose.yml (security + ops footguns).",
5
5
  "type": "module",
6
6
  "license": "MIT",