@geonosis/doctor 2.12.0 → 2.13.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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @geonosis/doctor
2
2
 
3
+ ## 2.13.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f422aea]
8
+ - Updated dependencies [f422aea]
9
+ - Updated dependencies [f422aea]
10
+ - Updated dependencies [f422aea]
11
+ - Updated dependencies [ae995df]
12
+ - @geonosis/ratchet@2.13.0
13
+ - @geonosis/release@2.13.0
14
+ - @geonosis/lint-parity@2.13.0
15
+
3
16
  ## 2.12.0
4
17
 
5
18
  ### Patch Changes
@@ -1,196 +1,11 @@
1
1
  #!/usr/bin/env node
2
- // Every packages/*/bin shim is packages/cli/bin/geonosis.mjs with its own name and entry: edit that
3
- // one, then `pnpm generate:shims`. Committed so `pnpm install` can link the bin on a fresh clone,
4
- // before `pnpm build` has made dist/. In the repo `src/` sits beside `dist/`, and a dist older
5
- // than src answered for a fix it did not carry once (#62); the published package ships no src, so
6
- // there the check is skipped.
7
- import { createHash } from 'node:crypto'
8
- import {
9
- existsSync,
10
- mkdirSync,
11
- readdirSync,
12
- readFileSync,
13
- realpathSync,
14
- statSync,
15
- writeFileSync
16
- } from 'node:fs'
17
- import { dirname, join } from 'node:path'
18
- import { fileURLToPath } from 'node:url'
2
+ // Generated by pnpm generate:shims. In the kit's own tree src/ sits beside dist/, and a dist older
3
+ // than src once answered for a fix it did not carry (#62); a published package ships no src/.
4
+ import { existsSync } from 'node:fs'
19
5
 
20
- const here = dirname(fileURLToPath(import.meta.url))
21
- const own = join(here, '..')
22
- // tsup never reads a test file, so one counting as source made every bin refuse a build that had
23
- // not gone stale (#399).
24
- const NOT_SOURCE = (name) =>
25
- name.endsWith('.test.ts') ||
26
- name.endsWith('.test.tsx') ||
27
- name === '__tests__' ||
28
- name === '__fixtures__'
29
- const newest = (dir, skip) =>
30
- existsSync(dir)
31
- ? readdirSync(dir, { withFileTypes: true }).reduce((most, entry) => {
32
- if (skip !== undefined && skip(entry.name)) return most
33
- const at = join(dir, entry.name)
34
- return Math.max(most, entry.isDirectory() ? newest(at, skip) : statSync(at).mtimeMs)
35
- }, 0)
36
- : 0
37
- const digestOf = (dir, hash) => {
38
- for (const name of readdirSync(dir).toSorted()) {
39
- if (NOT_SOURCE(name)) continue
40
- const at = join(dir, name)
41
- if (statSync(at).isDirectory()) {
42
- digestOf(at, hash)
43
- continue
44
- }
45
- hash.update(name).update('\0').update(readFileSync(at)).update('\0')
46
- }
47
- return hash
48
- }
49
- const digest = (...dirs) => {
50
- const hash = createHash('sha256')
51
- for (const dir of dirs) if (existsSync(dir)) digestOf(dir, hash)
52
- return hash.digest('hex')
53
- }
54
- // mtime says a source file was WRITTEN, not that it CHANGED. A checkout rewrites it with the same
55
- // content, and the next `pnpm build` is a cache hit that leaves the current dist exactly as it
56
- // was — so every bin refused with "run pnpm build", the action that had just changed nothing and
57
- // would change nothing again. So a digest of the sources is kept from the last run that found
58
- // dist current: the same digest later is the same sources, whatever their timestamps say, and a
59
- // different one is the staleness this guard exists for. The newest mtime is kept beside it so a
60
- // run over untouched sources need not hash them again. The second line is the same record for
61
- // the dists of the workspace dependencies this build read (row 584, below).
62
- const recordOf = (pkg) => join(pkg, '.turbo', 'geonosis-src-digest')
63
- const recorded = (pkg) => {
64
- try {
65
- const [first = '', second = ''] = readFileSync(recordOf(pkg), 'utf8').split('\n')
66
- const [seen = '', sum = ''] = first.trim().split(' ')
67
- const [depsSeen = '', depsSum = ''] = second.trim().split(' ')
68
- return { depsSeen: Number(depsSeen), depsSum, seen: Number(seen), sum }
69
- } catch {
70
- return { depsSeen: 0, depsSum: '', seen: 0, sum: '' }
71
- }
72
- }
73
- const remember = (pkg, known) => {
74
- try {
75
- mkdirSync(dirname(recordOf(pkg)), { recursive: true })
76
- writeFileSync(recordOf(pkg), `${known.seen} ${known.sum}\n${known.depsSeen} ${known.depsSum}\n`)
77
- } catch {
78
- // A record nothing could write costs one more hash next time, never a wrong answer.
79
- }
80
- }
81
- // The refusal names a package for turbo's --filter. A manifest that cannot be read costs the
82
- // name, never the decision: the first digest shim threw here — exit 1 and a node:fs frame — over a
83
- // tree with no package.json, and a guard that throws neither answers nor refuses.
84
- const manifestOf = (pkg) => {
85
- try {
86
- return JSON.parse(readFileSync(join(pkg, 'package.json'), 'utf8'))
87
- } catch {
88
- return {}
89
- }
90
- }
91
- const refuse = (sentence) => {
92
- process.stderr.write(`geonosis-doctor: ${sentence}\n`)
93
- process.exit(2)
94
- }
95
- // Whether one package's dist reflects its src: 'unbuilt', 'stale' or 'current'. The same reading
96
- // for this package and for each workspace dependency, off that package's own record.
97
- const standing = (pkg) => {
98
- const src = join(pkg, 'src')
99
- const dist = join(pkg, 'dist')
100
- if (!existsSync(src)) return 'current'
101
- const built = newest(dist)
102
- if (built === 0) return 'unbuilt'
103
- const written = newest(src, NOT_SOURCE)
104
- const known = recorded(pkg)
105
- if (written > built) {
106
- const sum = known.seen === written ? known.sum : digest(src)
107
- if (sum !== known.sum) return 'stale'
108
- if (known.seen !== written) remember(pkg, { ...known, seen: written, sum })
109
- } else if (known.seen !== written) {
110
- remember(pkg, { ...known, seen: written, sum: digest(src) })
111
- }
112
- return 'current'
113
- }
114
- // Row 584: a dist current against its own src can still have been built against an OLDER
115
- // dependency's dist — literally, when tsup inlined a workspace devDependency into it — and a
116
- // dependency whose src has moved past its dist is read by this dist stale, inlined or imported.
117
- // So every workspace dependency this manifest names (`workspace:`, resolved through the link pnpm
118
- // made, transitively) is held to the same reading as this package, and this dist must not be
119
- // older than any of theirs — by content: a dependency rebuilt to the same bytes is the same build,
120
- // so the `--force --filter` escape below cannot poison the tree it was run in.
121
- const workspaceDependencies = (pkg, found = new Map()) => {
122
- const manifest = manifestOf(pkg)
123
- for (const block of [
124
- manifest.dependencies,
125
- manifest.devDependencies,
126
- manifest.optionalDependencies,
127
- manifest.peerDependencies
128
- ]) {
129
- for (const [name, range] of Object.entries(block ?? {})) {
130
- if (typeof range !== 'string' || !range.startsWith('workspace:')) continue
131
- let dir
132
- try {
133
- dir = realpathSync(join(pkg, 'node_modules', name))
134
- } catch {
135
- continue // Not linked: the import will say so far more loudly than this guard can.
136
- }
137
- if (found.has(dir)) continue
138
- found.set(dir, name)
139
- workspaceDependencies(dir, found)
140
- }
141
- }
142
- return found
143
- }
144
- // `newest` answers 0 for a directory that is NOT THERE and for one that is merely old, so the
145
- // two conditions were one comparison and one sentence — and the staleness sentence was printed
146
- // over trees that had never been built at all, blocking a turn in a fresh git worktree, which
147
- // has no dist because dist is not committed (#357). Only the second is evidence of a mistake.
148
- if (existsSync(join(own, 'src'))) {
149
- const built = newest(join(own, 'dist'))
150
- if (built === 0) {
151
- refuse(
152
- 'this tree has never been built — run pnpm build. No dist here at all, which is what a fresh clone or a linked git worktree starts with; nothing is stale.'
153
- )
154
- }
155
- const name = manifestOf(own).name ?? '<this package>'
156
- if (standing(own) === 'stale') {
157
- refuse(
158
- `dist is older than src — run pnpm build before trusting this bin. If that build just said FULL TURBO, the cache hit left a current dist with its old timestamp and this bin had not yet recorded the sources it was current for: pnpm build --force --filter=${name} rebuilds this one package and clears it.`
159
- )
160
- }
161
- const dependencies = workspaceDependencies(own)
162
- const dists = new Map()
163
- for (const [dir, dependency] of dependencies) {
164
- const state = standing(dir)
165
- if (state === 'unbuilt') {
166
- refuse(
167
- `${dependency}, which this dist reads, has never been built — run pnpm build. No dist there at all; nothing is stale.`
168
- )
169
- }
170
- if (state === 'stale') {
171
- refuse(
172
- `${dependency}'s dist is older than its src, and this dist reads that dist — run pnpm build before trusting this bin. If that build just said FULL TURBO, the cache hit left that dist current with its old timestamp and nothing had yet recorded the sources it was current for: pnpm build --force --filter=${dependency} rebuilds that one package and clears it.`
173
- )
174
- }
175
- dists.set(join(dir, 'dist'), dependency)
176
- }
177
- if (dists.size > 0) {
178
- const known = recorded(own)
179
- const theirs = [...dists.keys()].toSorted()
180
- const depsNewest = theirs.reduce((most, dist) => Math.max(most, newest(dist)), 0)
181
- if (depsNewest > built) {
182
- const depsSum = known.depsSeen === depsNewest ? known.depsSum : digest(...theirs)
183
- if (depsSum !== known.depsSum) {
184
- const newer = theirs.filter((dist) => newest(dist) > built).map((dist) => dists.get(dist))
185
- refuse(
186
- `dist was built before the current dist of ${newer.join(', ')}, which it reads — run pnpm build before trusting this bin. If that build just said FULL TURBO, the dependency was rebuilt alone and this bin had not yet recorded the build it was current against: pnpm build --force --filter=${name} rebuilds this one package against it.`
187
- )
188
- }
189
- if (known.depsSeen !== depsNewest) remember(own, { ...known, depsSeen: depsNewest, depsSum })
190
- } else if (known.depsSeen !== depsNewest) {
191
- remember(own, { ...known, depsSeen: depsNewest, depsSum: digest(...theirs) })
192
- }
193
- }
6
+ if (existsSync(new URL('../src', import.meta.url))) {
7
+ const { guardBuild } = await import('../../../tooling/bin-guard.mjs')
8
+ guardBuild(new URL('..', import.meta.url), 'geonosis-doctor')
194
9
  }
195
10
 
196
11
  await import('../dist/doctor-cli.js')
@@ -253,153 +253,58 @@ var checkBaseline = ({ ref, root }) => {
253
253
  };
254
254
 
255
255
  // src/deployed.ts
256
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
256
+ import { existsSync as existsSync2 } from "fs";
257
257
  import { join as join4 } from "path";
258
- var DEPLOYED_FILE = ".geonosis/deployed.json";
259
- var NOT_WRITTEN = "no .geonosis/deployed.json \u2014 it is written by the pipeline after promote, and its absence is not a pass";
258
+ import { DEPLOYED_FILE, NOTHING_SAYS, runDeployed } from "@geonosis/release";
259
+ var finding2 = findingMaker("deployed");
260
260
  var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
261
- var listOf = (found) => Array.isArray(found) ? found.filter((one) => typeof one === "string") : [];
262
- var make = findingMaker("deployed");
263
- var finding2 = (verdict, subject, message) => make(subject, verdict, message);
264
- var parseJsonc = (source) => {
265
- let out = "";
266
- for (let index = 0; index < source.length; index += 1) {
267
- const char = source[index] ?? "";
268
- if (char === '"') {
269
- const start = index;
270
- index += 1;
271
- for (; index < source.length; index += 1) {
272
- if (source[index] === "\\") {
273
- index += 1;
274
- continue;
275
- }
276
- if (source[index] === '"') break;
277
- }
278
- out += source.slice(start, index + 1);
279
- continue;
280
- }
281
- if (char === "/" && source[index + 1] === "/") {
282
- const end = source.indexOf("\n", index);
283
- index = end === -1 ? source.length : end - 1;
284
- continue;
285
- }
286
- if (char === "/" && source[index + 1] === "*") {
287
- const end = source.indexOf("*/", index + 2);
288
- index = end === -1 ? source.length : end + 1;
289
- continue;
290
- }
291
- out += char;
292
- }
293
- return JSON.parse(out.replaceAll(/,(\s*[\]}])/g, "$1"));
294
- };
295
- var BINDING_LISTS = [
296
- "ai",
297
- "analytics_engine_datasets",
298
- "browser",
299
- "d1_databases",
300
- "dispatch_namespaces",
301
- "durable_objects",
302
- "hyperdrive",
303
- "kv_namespaces",
304
- "mtls_certificates",
305
- "queues",
306
- "r2_buckets",
307
- "send_email",
308
- "services",
309
- "vectorize",
310
- "version_metadata",
311
- "workflows"
312
- ];
313
- var bindingsOf = (found) => {
314
- if (Array.isArray(found)) return found.flatMap(bindingsOf);
315
- if (!isRecord(found)) return [];
316
- const named2 = found["binding"] ?? found["name"];
317
- return [
318
- ...typeof named2 === "string" ? [named2] : [],
319
- ...Object.entries(found).filter(([key]) => key === "bindings" || key === "producers" || key === "consumers").flatMap(([, one]) => bindingsOf(one))
320
- ];
321
- };
322
- var declaredIn = (config) => {
323
- const triggers = config["triggers"];
324
- const one = config["route"];
325
- const listed = [
326
- ...Array.isArray(config["routes"]) ? config["routes"] : [],
327
- ...typeof one === "string" ? [one] : []
328
- ];
329
- return {
330
- bindings: BINDING_LISTS.flatMap((key) => bindingsOf(config[key])),
331
- crons: isRecord(triggers) ? listOf(triggers["crons"]) : [],
332
- routes: listed.map((route) => isRecord(route) ? route["pattern"] : route).filter((pattern) => typeof pattern === "string")
333
- };
334
- };
335
- var differences = (kind, declared, deployed) => {
336
- const missing = declared.filter((name) => !deployed.includes(name));
337
- const extra = deployed.filter((name) => !declared.includes(name));
338
- return [
339
- ...missing.length === 0 ? [] : [`declared but not deployed ${kind}: ${missing.join(", ")}`],
340
- ...extra.length === 0 ? [] : [`deployed but not declared ${kind}: ${extra.join(", ")}`]
341
- ];
342
- };
261
+ var declaresNothing = (release) => !isRecord(release) || ["wrangler", "secrets"].every((key) => {
262
+ const listed = release[key];
263
+ return !Array.isArray(listed) || listed.length === 0;
264
+ });
343
265
  var checkDeployed = ({ root }) => {
344
266
  const read = readGeonosisFile(root);
345
267
  if (read.kind === "absent") return [];
346
268
  if (read.kind === "unreadable") return [unreadableGeonosis("deployed", read.error)];
347
- const release = isRecord(read.config["release"]) ? read.config["release"] : {};
348
- const configs = listOf(release["wrangler"]);
349
- const secrets = listOf(release["secrets"]);
350
- if (configs.length === 0 && secrets.length === 0) {
269
+ if (declaresNothing(read.config["release"])) {
351
270
  return [
352
271
  finding2(
353
- "SKIP",
354
272
  "geonosis.json",
273
+ "SKIP",
355
274
  "release.wrangler and release.secrets are both empty \u2014 this repo has declared nothing a deployment is supposed to carry"
356
275
  )
357
276
  ];
358
277
  }
359
- const env = typeof release["wranglerEnv"] === "string" ? release["wranglerEnv"] : void 0;
360
- const declared = { bindings: [], crons: [], routes: [] };
361
- for (const relative of configs) {
362
- let parsed;
363
- try {
364
- parsed = parseJsonc(readFileSync3(join4(root, relative), "utf8"));
365
- } catch (error) {
366
- return [finding2("FAIL", relative, `could not be read: ${error.message}`)];
367
- }
368
- if (!isRecord(parsed)) return [finding2("FAIL", relative, "is not a wrangler configuration")];
369
- const environments = parsed["env"];
370
- const block = env !== void 0 && isRecord(environments) && isRecord(environments[env]) ? environments[env] : parsed;
371
- const one = declaredIn(block);
372
- declared.bindings.push(...one.bindings);
373
- declared.crons.push(...one.crons);
374
- declared.routes.push(...one.routes);
375
- }
376
- const path = join4(root, DEPLOYED_FILE);
377
- if (!existsSync2(path)) return [finding2("SKIP", DEPLOYED_FILE, NOT_WRITTEN)];
378
- let reported;
278
+ if (!existsSync2(join4(root, DEPLOYED_FILE))) return [finding2(DEPLOYED_FILE, "SKIP", NOTHING_SAYS)];
279
+ let report;
379
280
  try {
380
- reported = JSON.parse(readFileSync3(path, "utf8"));
281
+ report = runDeployed({ root });
381
282
  } catch (error) {
382
- return [finding2("FAIL", DEPLOYED_FILE, `is not readable JSON: ${error.message}`)];
383
- }
384
- if (!isRecord(reported)) return [finding2("FAIL", DEPLOYED_FILE, "is not an object")];
385
- const triggers = isRecord(reported["triggers"]) ? reported["triggers"] : {};
386
- const drift = [
387
- ...differences("crons", declared.crons, listOf(triggers["crons"])),
388
- ...differences("routes", declared.routes, listOf(triggers["routes"])),
389
- ...differences("bindings", declared.bindings, listOf(reported["bindings"])),
390
- ...differences("secrets", secrets, listOf(reported["secrets"]))
391
- ];
283
+ return [finding2(DEPLOYED_FILE, "FAIL", error instanceof Error ? error.message : String(error))];
284
+ }
285
+ if (report.ok) {
286
+ return [
287
+ finding2(
288
+ DEPLOYED_FILE,
289
+ "OK",
290
+ `what the tree declares is what the pipeline reported${report.at === void 0 ? "" : ` at ${report.at}`}`
291
+ )
292
+ ];
293
+ }
392
294
  return [
393
- drift.length === 0 ? finding2(
394
- "OK",
295
+ finding2(
395
296
  DEPLOYED_FILE,
396
- `what the tree declares is what the pipeline reported${typeof reported["at"] === "string" ? ` at ${reported["at"]}` : ""}`
397
- ) : finding2("FAIL", DEPLOYED_FILE, drift.join("; "))
297
+ "FAIL",
298
+ report.drift.flatMap(({ extra, kind, missing }) => [
299
+ ...missing.length === 0 ? [] : [`declared but not deployed ${kind}: ${missing.join(", ")}`],
300
+ ...extra.length === 0 ? [] : [`deployed but not declared ${kind}: ${extra.join(", ")}`]
301
+ ]).join("; ")
302
+ )
398
303
  ];
399
304
  };
400
305
 
401
306
  // src/resolve.ts
402
- import { existsSync as existsSync3, readFileSync as readFileSync4, realpathSync as realpathSync2 } from "fs";
307
+ import { existsSync as existsSync3, readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
403
308
  import { createRequire } from "module";
404
309
  import { dirname, join as join5 } from "path";
405
310
  import { pathToFileURL } from "url";
@@ -460,7 +365,7 @@ var packageDirOf = (entry, name) => {
460
365
  const manifest = join5(dir, "package.json");
461
366
  if (existsSync3(manifest)) {
462
367
  try {
463
- const parsed = JSON.parse(readFileSync4(manifest, "utf8"));
368
+ const parsed = JSON.parse(readFileSync3(manifest, "utf8"));
464
369
  if (parsed.name === name) return dir;
465
370
  } catch {
466
371
  }
@@ -544,17 +449,17 @@ var real2 = (path) => {
544
449
  var relativeToRoot = (root, path) => relativePath(real2(root), real2(path));
545
450
 
546
451
  // src/group.ts
547
- import { readFileSync as readFileSync7 } from "fs";
452
+ import { readFileSync as readFileSync6 } from "fs";
548
453
  import { join as join8 } from "path";
549
454
 
550
455
  // src/callers.ts
551
- import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
456
+ import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
552
457
  import { join as join6, resolve } from "path";
553
458
  var WORKFLOWS = ".github/workflows";
554
459
  var A_WORKFLOW = (name) => name.endsWith(".yml") || name.endsWith(".yaml");
555
460
  var readOr = (path) => {
556
461
  try {
557
- return readFileSync5(path, "utf8");
462
+ return readFileSync4(path, "utf8");
558
463
  } catch {
559
464
  return "";
560
465
  }
@@ -617,7 +522,7 @@ var scriptFilesNamedBy = (root, lines) => {
617
522
  };
618
523
 
619
524
  // src/hooks.ts
620
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
525
+ import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "fs";
621
526
  import { join as join7 } from "path";
622
527
  var HOOK_FILES = ["lefthook.yml", "lefthook.yaml", ".lefthook.yml", ".lefthook.yaml"];
623
528
  var HOOK_DIRS = [".husky", ".githooks"];
@@ -627,7 +532,7 @@ var hookLines = (root) => {
627
532
  const found = [];
628
533
  const read = (path) => {
629
534
  const at = relativePath(root, path);
630
- for (const line of readFileSync6(path, "utf8").split("\n")) {
535
+ for (const line of readFileSync5(path, "utf8").split("\n")) {
631
536
  if (line.trim() !== "") found.push({ at, line });
632
537
  }
633
538
  };
@@ -708,7 +613,7 @@ var versionOf = (dir, name, root) => {
708
613
  }
709
614
  try {
710
615
  const manifest = JSON.parse(
711
- readFileSync7(join8(packageDirOf(entry, name), "package.json"), "utf8")
616
+ readFileSync6(join8(packageDirOf(entry, name), "package.json"), "utf8")
712
617
  );
713
618
  return typeof manifest.version === "string" ? { kind: "read", version: manifest.version } : { kind: "unreadable", why: "its package.json declares no version" };
714
619
  } catch (error) {
@@ -740,7 +645,7 @@ var DOORS = ["@geonosis/cli", "geonosis"];
740
645
  var manifestOf = (root, name) => {
741
646
  try {
742
647
  return JSON.parse(
743
- readFileSync7(join8(packageDirOf(resolveFrom(root, name, root), name), "package.json"), "utf8")
648
+ readFileSync6(join8(packageDirOf(resolveFrom(root, name, root), name), "package.json"), "utf8")
744
649
  );
745
650
  } catch {
746
651
  return void 0;
@@ -750,7 +655,7 @@ var binNamesOf = (manifest, name) => {
750
655
  const declared = manifest?.bin;
751
656
  return typeof declared === "string" ? [name.replace(/^@[^/]+\//, "")] : Object.keys(declared ?? {});
752
657
  };
753
- var declaredIn2 = (manifest) => [...dependencyNamesOf(manifest)];
658
+ var declaredIn = (manifest) => [...dependencyNamesOf(manifest)];
754
659
  var calls = (lines, bin) => new RegExp(`(?:^|[\\s;&|(/'"\`])${bin}(?:[\\s;&|)'"\`,\\]]|$)`).test(lines);
755
660
  var workspaceCaller = (workspaces, bins) => {
756
661
  for (const workspace of workspaces) {
@@ -764,7 +669,7 @@ var workspaceCaller = (workspaces, bins) => {
764
669
  var rootDeclarations = (root, workspaces) => {
765
670
  const here = workspaces.find((one) => one.relative === "");
766
671
  if (here === void 0) return [];
767
- const declared = declaredIn2(here.manifest);
672
+ const declared = declaredIn(here.manifest);
768
673
  const door = DOORS.find((name) => declared.includes(name));
769
674
  if (door === void 0) return [];
770
675
  const owned = new Set(
@@ -893,7 +798,7 @@ var checkGroup = ({
893
798
  };
894
799
 
895
800
  // src/drift.ts
896
- import { closeSync, existsSync as existsSync6, openSync, readdirSync as readdirSync4, readFileSync as readFileSync8, readSync } from "fs";
801
+ import { closeSync, existsSync as existsSync6, openSync, readdirSync as readdirSync4, readFileSync as readFileSync7, readSync } from "fs";
897
802
  import { homedir } from "os";
898
803
  import { join as join9, sep as sep3 } from "path";
899
804
 
@@ -976,7 +881,7 @@ var ci = (root) => {
976
881
  }
977
882
  return filesUnder(dir, (name) => name.endsWith(".yml") || name.endsWith(".yaml")).map((path) => {
978
883
  const at = relativePath(root, path);
979
- return SWITCHED_OFF.test(readFileSync8(path, "utf8")) ? finding4(
884
+ return SWITCHED_OFF.test(readFileSync7(path, "utf8")) ? finding4(
980
885
  at,
981
886
  "FAIL",
982
887
  "a job or step here is switched off by a condition that can never be true \u2014 every gate downstream of it reports green having run nothing"
@@ -1170,7 +1075,7 @@ var law = (root, config) => {
1170
1075
  if (!existsSync6(path)) {
1171
1076
  return [finding4(file, "SKIP", "there is no law file here to measure")];
1172
1077
  }
1173
- const source = readFileSync8(path, "utf8");
1078
+ const source = readFileSync7(path, "utf8");
1174
1079
  const lines = source.split("\n").length - (source.endsWith("\n") ? 1 : 0);
1175
1080
  if (typeof declared.maxLines !== "number") {
1176
1081
  return [
@@ -1194,7 +1099,7 @@ var KIT_PLUGIN = "geonosis";
1194
1099
  var enablesKit = (path) => {
1195
1100
  if (!existsSync6(path)) return false;
1196
1101
  try {
1197
- const parsed = JSON.parse(readFileSync8(path, "utf8"));
1102
+ const parsed = JSON.parse(readFileSync7(path, "utf8"));
1198
1103
  const enabled = parsed.enabledPlugins;
1199
1104
  if (typeof enabled !== "object" || enabled === null) return false;
1200
1105
  return Object.entries(enabled).some(
@@ -1230,7 +1135,7 @@ var ALLOW_BUILDS_KEY = "allowBuilds";
1230
1135
  var allowedBuilds = (root) => {
1231
1136
  const path = join9(root, WORKSPACE_YAML);
1232
1137
  if (!existsSync6(path)) return void 0;
1233
- const lines = readFileSync8(path, "utf8").split("\n");
1138
+ const lines = readFileSync7(path, "utf8").split("\n");
1234
1139
  const at = lines.findIndex((line) => new RegExp(`^${ALLOW_BUILDS_KEY}\\s*:`).test(line));
1235
1140
  if (at < 0) return void 0;
1236
1141
  const names = [];
@@ -1387,7 +1292,7 @@ var composedHere = (root, workspaces) => {
1387
1292
  for (const path of filesUnder(root, (name) => SOURCE_FILE.test(name))) {
1388
1293
  let body;
1389
1294
  try {
1390
- body = readFileSync8(path, "utf8");
1295
+ body = readFileSync7(path, "utf8");
1391
1296
  } catch {
1392
1297
  continue;
1393
1298
  }
@@ -1422,7 +1327,7 @@ var doorBringing = (root, name, declared) => DOORS.filter((door) => declared.has
1422
1327
  var dependenciesOf = (root, name) => {
1423
1328
  try {
1424
1329
  return JSON.parse(
1425
- readFileSync8(
1330
+ readFileSync7(
1426
1331
  join9(packageDirOf(resolveFrom(root, name, root), name), "package.json"),
1427
1332
  "utf8"
1428
1333
  )
@@ -1567,7 +1472,7 @@ var pluginDirs = (root) => {
1567
1472
  const governs = layerOver(layers, root, relative);
1568
1473
  if (governs === void 0) continue;
1569
1474
  const key = governs.registry.join(", ");
1570
- const registry = source.get(key) ?? governs.registry.map((half) => readFileSync8(join9(root, half), "utf8")).join("\n");
1475
+ const registry = source.get(key) ?? governs.registry.map((half) => readFileSync7(join9(root, half), "utf8")).join("\n");
1571
1476
  source.set(key, registry);
1572
1477
  const hasManifest = governs.manifests.some((name) => existsSync6(join9(at, entry.name, name)));
1573
1478
  if (!hasManifest || registry.includes(entry.name)) continue;
@@ -1597,7 +1502,7 @@ var pnpmMajorOf = (manifest) => {
1597
1502
  var pnpmBlock = (root) => {
1598
1503
  let manifest;
1599
1504
  try {
1600
- manifest = JSON.parse(readFileSync8(join9(root, "package.json"), "utf8"));
1505
+ manifest = JSON.parse(readFileSync7(join9(root, "package.json"), "utf8"));
1601
1506
  } catch {
1602
1507
  return [];
1603
1508
  }
@@ -1635,7 +1540,7 @@ var HOIST_REPAIR = "rm -rf node_modules/.modules.yaml node_modules/.pnpm-workspa
1635
1540
  var hoistPatterns = (root) => {
1636
1541
  const path = join9(root, WORKSPACE_YAML);
1637
1542
  if (!existsSync6(path)) return void 0;
1638
- const lines = readFileSync8(path, "utf8").split("\n");
1543
+ const lines = readFileSync7(path, "utf8").split("\n");
1639
1544
  const at = lines.findIndex((line) => new RegExp(`^${HOIST_KEY}\\s*:`).test(line));
1640
1545
  if (at < 0) return void 0;
1641
1546
  const patterns = [];
@@ -1759,7 +1664,7 @@ import {
1759
1664
  existsSync as existsSync7,
1760
1665
  mkdirSync,
1761
1666
  mkdtempSync,
1762
- readFileSync as readFileSync9,
1667
+ readFileSync as readFileSync8,
1763
1668
  rmSync,
1764
1669
  writeFileSync
1765
1670
  } from "fs";
@@ -1938,7 +1843,7 @@ var throughProbes = ({
1938
1843
  refused.set(rule, String(error.message));
1939
1844
  }
1940
1845
  }
1941
- const probeConfig = JSON.parse(readFileSync9(config.path, "utf8"));
1846
+ const probeConfig = JSON.parse(readFileSync8(config.path, "utf8"));
1942
1847
  const configDir = dirname2(config.path);
1943
1848
  probeConfig.jsPlugins = (probeConfig.jsPlugins ?? []).map(
1944
1849
  (spec) => spec.startsWith(".") || spec.startsWith("/") ? resolve2(configDir, spec) : packageDirOf(resolveFrom(configDir, spec, root), spec)
@@ -2098,15 +2003,16 @@ var checkExercised = async ({
2098
2003
  };
2099
2004
 
2100
2005
  // src/envelope.ts
2101
- import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync10 } from "fs";
2006
+ import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
2102
2007
  import { join as join11 } from "path";
2103
- var ENVELOPES_DIR = ".geonosis/envelopes";
2008
+ import { ENVELOPES_DIR } from "@geonosis/ratchet";
2009
+ import { ENVELOPES_DIR as ENVELOPES_DIR2 } from "@geonosis/ratchet";
2104
2010
  var THIS_TOOL = "doctor";
2105
2011
  var OWN = `${THIS_TOOL}.json`;
2106
2012
  var NO_ENVELOPES = "no .geonosis/envelopes/*.json \u2014 the tools write one per run, so an absent envelope is a run nobody has made here yet, and it is not a balanced one (this run\u2019s own doctor.json is not one of them: it is written after these checks, and balanced at write time)";
2107
2013
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2108
- var make2 = findingMaker("envelope");
2109
- var finding6 = (verdict, subject, message) => make2(subject, verdict, message);
2014
+ var make = findingMaker("envelope");
2015
+ var finding6 = (verdict, subject, message) => make(subject, verdict, message);
2110
2016
  var lengthOf = (value) => Array.isArray(value) ? value.length : void 0;
2111
2017
  var NEXT = "Next: re-run the tool that wrote it and read the numbers it prints \u2014 a run that has lost count of its own inputs is a bug in that tool, not in this tree";
2112
2018
  var judge = (subject, name, parsed) => {
@@ -2164,7 +2070,7 @@ var checkEnvelopes = ({ root }) => {
2164
2070
  const subject = `${ENVELOPES_DIR}/${name}`;
2165
2071
  let parsed;
2166
2072
  try {
2167
- parsed = JSON.parse(readFileSync10(join11(dir, name), "utf8"));
2073
+ parsed = JSON.parse(readFileSync9(join11(dir, name), "utf8"));
2168
2074
  } catch (error) {
2169
2075
  return finding6("FAIL", subject, `is not readable JSON: ${error.message}. ${NEXT}`);
2170
2076
  }
@@ -2173,7 +2079,7 @@ var checkEnvelopes = ({ root }) => {
2173
2079
  };
2174
2080
 
2175
2081
  // src/exams.ts
2176
- import { existsSync as existsSync9, readFileSync as readFileSync11 } from "fs";
2082
+ import { existsSync as existsSync9, readFileSync as readFileSync10 } from "fs";
2177
2083
  import { dirname as dirname3, join as join12 } from "path";
2178
2084
  var SCOPE = "@geonosis/";
2179
2085
  var EXAM = /(?:^|[^$\w])([$\w]*Conformance)\b/g;
@@ -2200,7 +2106,7 @@ var declaredBy = (workspaces) => {
2200
2106
  var declarationsOf = (dir) => {
2201
2107
  const at = join12(dir, "package.json");
2202
2108
  if (!existsSync9(at)) return "";
2203
- const manifest = JSON.parse(readFileSync11(at, "utf8"));
2109
+ const manifest = JSON.parse(readFileSync10(at, "utf8"));
2204
2110
  const entries = [];
2205
2111
  const walk2 = (value) => {
2206
2112
  if (typeof value === "string" && value.endsWith(".d.ts")) entries.push(value);
@@ -2211,7 +2117,7 @@ var declarationsOf = (dir) => {
2211
2117
  walk2({ exports: manifest["exports"], types: manifest["types"] });
2212
2118
  return [...new Set(entries)].map((entry) => {
2213
2119
  try {
2214
- return readFileSync11(join12(dir, entry), "utf8");
2120
+ return readFileSync10(join12(dir, entry), "utf8");
2215
2121
  } catch {
2216
2122
  return "";
2217
2123
  }
@@ -2237,7 +2143,7 @@ var checkExams = ({
2237
2143
  root,
2238
2144
  workspaces
2239
2145
  }) => {
2240
- const tests = testFilesUnder(root).map((path) => ({ path, source: readFileSync11(path, "utf8") }));
2146
+ const tests = testFilesUnder(root).map((path) => ({ path, source: readFileSync10(path, "utf8") }));
2241
2147
  const found = [];
2242
2148
  for (const { from, name } of declaredBy(workspaces)) {
2243
2149
  const exams = examsShippedBy(from, name, root);
@@ -2263,7 +2169,7 @@ var checkExams = ({
2263
2169
  };
2264
2170
 
2265
2171
  // src/claude-plugin.ts
2266
- import { existsSync as existsSync10, readFileSync as readFileSync12, realpathSync as realpathSync3 } from "fs";
2172
+ import { existsSync as existsSync10, readFileSync as readFileSync11, realpathSync as realpathSync3 } from "fs";
2267
2173
  import { homedir as homedir2 } from "os";
2268
2174
  import { join as join13, resolve as resolve3 } from "path";
2269
2175
  var INSTALLED_PLUGINS = ".claude/plugins/installed_plugins.json";
@@ -2274,7 +2180,7 @@ var installedPlugins = (home, name) => {
2274
2180
  if (!existsSync10(at)) return [];
2275
2181
  let record;
2276
2182
  try {
2277
- record = JSON.parse(readFileSync12(at, "utf8"));
2183
+ record = JSON.parse(readFileSync11(at, "utf8"));
2278
2184
  } catch {
2279
2185
  return [];
2280
2186
  }
@@ -2380,7 +2286,7 @@ var checkClaudePlugin = ({
2380
2286
  };
2381
2287
 
2382
2288
  // src/loaded.ts
2383
- import { readFileSync as readFileSync13 } from "fs";
2289
+ import { readFileSync as readFileSync12 } from "fs";
2384
2290
  import { join as join14, sep as sep4 } from "path";
2385
2291
  var SCOPE2 = "@geonosis/";
2386
2292
  var NOT_THE_SCOPE_DIRECTORY = "Deleting only the scope directory inside that node_modules is a repair no pnpm install undoes \u2014 the tree is then missing the package and every install stays green.";
@@ -2529,7 +2435,7 @@ var shipperOf = (root, bin) => {
2529
2435
  const name = bin === "geonosis" ? "@geonosis/cli" : `@geonosis/${bin.replace(/^geonosis-/, "")}`;
2530
2436
  try {
2531
2437
  const manifest = JSON.parse(
2532
- readFileSync13(join14(packageDirOf(resolveFrom(root, name, root), name), "package.json"), "utf8")
2438
+ readFileSync12(join14(packageDirOf(resolveFrom(root, name, root), name), "package.json"), "utf8")
2533
2439
  );
2534
2440
  const declared = manifest.bin;
2535
2441
  return typeof declared === "object" && !Object.hasOwn(declared, bin) ? "" : name;
@@ -2637,13 +2543,13 @@ var trainVersion = async (root, specifiers) => {
2637
2543
  };
2638
2544
 
2639
2545
  // src/observability.ts
2640
- import { readFileSync as readFileSync14 } from "fs";
2546
+ import { readFileSync as readFileSync13 } from "fs";
2641
2547
  import { join as join15 } from "path";
2642
2548
  var REACHES_NOTHING = /* @__PURE__ */ new Set(["console", "memory", "noop", "none", "null", "swallowing"]);
2643
2549
  var DEFAULT_MAX_AGE_SECONDS = 3600;
2644
2550
  var HEAD_TIMEOUT_MS = 3e3;
2645
- var make3 = findingMaker("observability");
2646
- var finding9 = (verdict, subject, message) => make3(subject, verdict, message);
2551
+ var make2 = findingMaker("observability");
2552
+ var finding9 = (verdict, subject, message) => make2(subject, verdict, message);
2647
2553
  var readGeonosis = (root) => {
2648
2554
  const read = readGeonosisFile(root);
2649
2555
  if (read.kind === "unreadable") return { error: read.error, present: false };
@@ -2721,7 +2627,7 @@ var ageFinding = (config, root, now) => {
2721
2627
  const maxAgeSeconds = typeof config.maxAgeSeconds === "number" && config.maxAgeSeconds > 0 ? config.maxAgeSeconds : DEFAULT_MAX_AGE_SECONDS;
2722
2628
  let record;
2723
2629
  try {
2724
- record = JSON.parse(readFileSync14(join15(root, file), "utf8"));
2630
+ record = JSON.parse(readFileSync13(join15(root, file), "utf8"));
2725
2631
  } catch (error) {
2726
2632
  return finding9(
2727
2633
  "FAIL",
@@ -2865,7 +2771,7 @@ var checkRequiredOptions = async ({
2865
2771
  };
2866
2772
 
2867
2773
  // src/runner.ts
2868
- import { readFileSync as readFileSync15 } from "fs";
2774
+ import { readFileSync as readFileSync14 } from "fs";
2869
2775
  import { resolve as resolve4 } from "path";
2870
2776
  var TEST_FAILURES = "testFailures";
2871
2777
  var RUNS_A_RUNNER = /(?:^|[\s;&|(])(?:npx\s+|bunx\s+|pnpm\s+(?:exec\s+)?)?(?:vitest|bun\s+test)(?:\s|$)/;
@@ -2875,7 +2781,7 @@ var wrapperNamedBy = (script, dir) => {
2875
2781
  for (const token of script.split(/[\s'"]+/)) {
2876
2782
  if (!A_SCRIPT_FILE.test(token)) continue;
2877
2783
  try {
2878
- return { source: readFileSync15(resolve4(dir, token), "utf8"), where: token };
2784
+ return { source: readFileSync14(resolve4(dir, token), "utf8"), where: token };
2879
2785
  } catch {
2880
2786
  continue;
2881
2787
  }
@@ -3145,7 +3051,7 @@ var checkPathGrants = ({
3145
3051
  };
3146
3052
 
3147
3053
  // src/rails.ts
3148
- import { existsSync as existsSync12, readFileSync as readFileSync16 } from "fs";
3054
+ import { existsSync as existsSync12, readFileSync as readFileSync15 } from "fs";
3149
3055
  import { join as join18 } from "path";
3150
3056
  var PROJECT = ".claude/settings.json";
3151
3057
  var LOCAL = ".claude/settings.local.json";
@@ -3169,7 +3075,7 @@ var sourceAt = (path, label) => {
3169
3075
  if (!existsSync12(path)) return { network: void 0, path: label, unreadable: false };
3170
3076
  try {
3171
3077
  return {
3172
- network: networkIn(JSON.parse(readFileSync16(path, "utf8"))),
3078
+ network: networkIn(JSON.parse(readFileSync15(path, "utf8"))),
3173
3079
  path: label,
3174
3080
  unreadable: false
3175
3081
  };
@@ -3198,7 +3104,7 @@ var deniedEgress = (root) => {
3198
3104
  }
3199
3105
  let parsed;
3200
3106
  try {
3201
- parsed = JSON.parse(readFileSync16(at, "utf8"));
3107
+ parsed = JSON.parse(readFileSync15(at, "utf8"));
3202
3108
  } catch (error) {
3203
3109
  return [
3204
3110
  finding12(
@@ -3533,7 +3439,6 @@ export {
3533
3439
  defaultRef,
3534
3440
  checkBaseline,
3535
3441
  DEPLOYED_FILE,
3536
- NOT_WRITTEN,
3537
3442
  checkDeployed,
3538
3443
  resolveFrom,
3539
3444
  packageDirOf,
@@ -3551,9 +3456,9 @@ export {
3551
3456
  missingOptionOf,
3552
3457
  enabledRulesOf,
3553
3458
  checkExercised,
3554
- ENVELOPES_DIR,
3555
3459
  NO_ENVELOPES,
3556
3460
  checkEnvelopes,
3461
+ ENVELOPES_DIR2 as ENVELOPES_DIR,
3557
3462
  checkExams,
3558
3463
  INSTALLED_PLUGINS,
3559
3464
  PLUGIN_NAME,
@@ -4,82 +4,15 @@ import {
4
4
  formatDoctor,
5
5
  formatJson,
6
6
  runDoctor
7
- } from "./chunk-VWMNCBDP.js";
7
+ } from "./chunk-IJXJ2EF4.js";
8
8
 
9
9
  // src/doctor-cli.ts
10
10
  import { fstatSync, statSync } from "fs";
11
- import { resolve as resolve2 } from "path";
11
+ import { resolve } from "path";
12
12
 
13
13
  // src/envelope-write.ts
14
- import { mkdirSync, readFileSync, writeFileSync } from "fs";
15
- import { dirname, join, resolve } from "path";
16
- import { fileURLToPath } from "url";
17
- var envelopePath = (root, tool) => join(root, ENVELOPES_DIR, `${tool}.json`);
18
- var UnbalancedEnvelope = class extends Error {
19
- constructor(message) {
20
- super(message);
21
- this.name = "UnbalancedEnvelope";
22
- }
23
- };
24
- var isCount = (value) => Number.isSafeInteger(value) && value >= 0;
25
- var unbalancedMessage = (envelope, next) => `${envelope.tool}: considered ${envelope.considered} but accounts for ${envelope.read + envelope.refused.length + envelope.excused.length} \u2014 ${envelope.read} read + ${envelope.refused.length} refused + ${envelope.excused.length} excused. A run that has lost count of its own inputs cannot say what it measured, so no verdict was rendered and no envelope was written. Next: ${next}`;
26
- var FORBIDDEN_ROOT = "GEONOSIS_ENVELOPES_FORBIDDEN_ROOT";
27
- var refuseForbiddenRoot = (root) => {
28
- const forbidden = process.env[FORBIDDEN_ROOT];
29
- if (forbidden === void 0 || resolve(forbidden) !== resolve(root)) return;
30
- throw new UnbalancedEnvelope(
31
- `${root} is off limits to envelope writers in this process (${FORBIDDEN_ROOT}) \u2014 a run that writes one into a shared root races every other run reading it, and leaves a file the next one takes for real. Point this at a scratch root of its own: tooling/scratch-dir.ts.`
32
- );
33
- };
34
- var writeEnvelope = ({
35
- envelope,
36
- next,
37
- root
38
- }) => {
39
- if (envelope.tool.trim() === "") {
40
- throw new UnbalancedEnvelope(
41
- `an envelope with no tool name cannot be filed or reported against. Next: ${next}`
42
- );
43
- }
44
- if (envelope.version.trim() === "") {
45
- throw new UnbalancedEnvelope(
46
- `${envelope.tool}: an envelope that cannot name the build that wrote it dates nothing, and a stale one reads exactly like a fresh one. Next: ${next}`
47
- );
48
- }
49
- if (!isCount(envelope.considered) || !isCount(envelope.read)) {
50
- throw new UnbalancedEnvelope(
51
- `${envelope.tool}: considered ${envelope.considered} and read ${envelope.read} \u2014 a census is a whole number of things, and arithmetic over anything else balances by accident. Next: ${next}`
52
- );
53
- }
54
- if (envelope.considered !== envelope.read + envelope.refused.length + envelope.excused.length) {
55
- throw new UnbalancedEnvelope(unbalancedMessage(envelope, next));
56
- }
57
- refuseForbiddenRoot(root);
58
- const at = envelopePath(root, envelope.tool);
59
- mkdirSync(dirname(at), { recursive: true });
60
- writeFileSync(at, `${JSON.stringify(envelope, void 0, 2)}
61
- `);
62
- return at;
63
- };
64
- var UNKNOWN = "unknown";
65
- var versionIn = (dir) => {
66
- try {
67
- const manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
68
- return typeof manifest.version === "string" ? manifest.version : void 0;
69
- } catch {
70
- return void 0;
71
- }
72
- };
73
- var versionOf = (moduleUrl) => {
74
- let dir = dirname(fileURLToPath(moduleUrl));
75
- for (; ; ) {
76
- const found = versionIn(dir);
77
- if (found !== void 0) return found;
78
- const up = dirname(dir);
79
- if (up === dir) return UNKNOWN;
80
- dir = up;
81
- }
82
- };
14
+ import { versionOf } from "@geonosis/ratchet";
15
+ import { envelopePath, UnbalancedEnvelope, versionOf as versionOf2, writeEnvelope } from "@geonosis/ratchet";
83
16
  var DOCTOR_TOOL = "doctor";
84
17
  var DOCTOR_NEXT = "geonosis-doctor --json and count the checks it printed \u2014 this run considered every question the tool has, and a check nobody asked for is excused by name rather than left out of the denominator";
85
18
  var doctorEnvelope = ({
@@ -247,8 +180,8 @@ var parseDoctorArgs = (argv, cwd) => {
247
180
  ...baseline === void 0 ? {} : { baseline },
248
181
  json,
249
182
  ...only === void 0 || only.length === 0 ? {} : { only },
250
- ...read["--oxlint"] === void 0 ? {} : { oxlint: resolve2(cwd, read["--oxlint"]) },
251
- root: resolve2(cwd, read["--root"] ?? cwd),
183
+ ...read["--oxlint"] === void 0 ? {} : { oxlint: resolve(cwd, read["--oxlint"]) },
184
+ root: resolve(cwd, read["--root"] ?? cwd),
252
185
  strict
253
186
  };
254
187
  };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ export { DEPLOYED_FILE } from '@geonosis/release';
2
+ export { ENVELOPES_DIR } from '@geonosis/ratchet';
3
+
1
4
  type Overrides = {
2
5
  files: readonly string[];
3
6
  rules: Record<string, unknown>;
@@ -135,20 +138,6 @@ declare const checkBaseline: ({ ref, root }: {
135
138
  root: string;
136
139
  }) => Finding[];
137
140
 
138
- /**
139
- * The `loaded` lie one layer out: what a pipeline SAID it deployed, against what the tree declares.
140
- *
141
- * `wrangler versions upload` applies no triggers, so a cron or a route edited in the config is
142
- * silently ignored in production for ever, with a green pipeline; `wrangler secret put` creates and
143
- * deploys a version outside the gate entirely. Nothing in either consumer measured any of it.
144
- *
145
- * This reads the FILE the consumer's pipeline writes after promote — `.geonosis/deployed.json` —
146
- * and imports nothing of `@geonosis/release`, the same discipline `observability` follows: a check
147
- * that needed the package it checks cannot run in the tree where that package is missing. The
148
- * comparison is duplicated on purpose; it is set differences over four lists.
149
- */
150
- declare const DEPLOYED_FILE = ".geonosis/deployed.json";
151
- declare const NOT_WRITTEN = "no .geonosis/deployed.json \u2014 it is written by the pipeline after promote, and its absence is not a pass";
152
141
  declare const checkDeployed: ({ root }: {
153
142
  root: string;
154
143
  }) => Finding[];
@@ -200,22 +189,6 @@ declare const checkDrift: ({ readers, root, userSettings, workspaces }: {
200
189
  workspaces: Workspace[];
201
190
  }) => Finding[];
202
191
 
203
- /**
204
- * The one line that catches a denominator bug: for every envelope a tool wrote,
205
- * `considered === read + refused + excused`.
206
- *
207
- * Four of them landed in one day, all green — a migrations run that reported on three of four
208
- * files, a plan check that printed `PASS — 0 plan(s)` over a directory of twenty-one, a parity run
209
- * over a tree the second config had ignored, a validator that walked a list it had already
210
- * filtered. Every one published a numerator and no denominator, so nothing could be wrong.
211
- *
212
- * This READS the files and imports nothing of the tools that wrote them — the same discipline
213
- * `deployed` and `observability` follow. A check that needed the package it checks cannot run in
214
- * the tree where that package is missing, which is the first case it exists to find; and this one
215
- * has to work over a consumer's `.geonosis/` with no kit installed at all. The arithmetic is
216
- * duplicated here on purpose: it is one comparison over three numbers, and it is the check.
217
- */
218
- declare const ENVELOPES_DIR = ".geonosis/envelopes";
219
192
  declare const NO_ENVELOPES = "no .geonosis/envelopes/*.json \u2014 the tools write one per run, so an absent envelope is a run nobody has made here yet, and it is not a balanced one (this run\u2019s own doctor.json is not one of them: it is written after these checks, and balanced at write time)";
220
193
  declare const checkEnvelopes: ({ root }: {
221
194
  root: string;
@@ -519,4 +492,4 @@ declare const checkRunner: ({ ratchet, root, workspaces }: {
519
492
  workspaces: Workspace[];
520
493
  }) => Finding[];
521
494
 
522
- export { APPARATUS_KEY, CHECKS, COMPOSITION_ROOT, CONFIG_FILE, type CheckName, DEPLOYED_FILE, type DiscoveredConfig, DoctorError, type DoctorOptions, type DoctorReport, ENVELOPES_DIR, FIXED_GROUP, FLOOR_PACKAGES, type Finding, GEONOSIS_FILE, type HeldTogether, INSTALLED_PLUGINS, type InstalledPlugin, KIT_GROUP, type LastEventRecord, MANIFEST_FILE, type Manifest, NOT_WRITTEN, NO_ENVELOPES, type ObservabilityConfig, PLUGIN_NAME, RATCHET_FILE, READERS, type RatchetConfig, SCOPE, type Verdict, type Workspace, checkBaseline, checkClaudePlugin, checkDeployed, checkDrift, checkEnvelopes, checkExams, checkExercised, checkGroup, checkLoaded, checkObservability, checkRequiredOptions, checkRunner, corpusOfPlugin, declaredApparatusOf, declaredFor, declaredGroupsOf, defaultRef, discoverConfigs, discoverWorkspaces, enabledRulesOf, evidenceHolding, formatDoctor, formatJson, installedPluginVersions, installedPlugins, loadedAt, missingOptionOf, packageDirOf, pluginVersionOf, readConfig, readRatchet, relativePath, relativeToRoot, repoCorpusOf, resolveFrom, runDoctor, satisfies };
495
+ export { APPARATUS_KEY, CHECKS, COMPOSITION_ROOT, CONFIG_FILE, type CheckName, type DiscoveredConfig, DoctorError, type DoctorOptions, type DoctorReport, FIXED_GROUP, FLOOR_PACKAGES, type Finding, GEONOSIS_FILE, type HeldTogether, INSTALLED_PLUGINS, type InstalledPlugin, KIT_GROUP, type LastEventRecord, MANIFEST_FILE, type Manifest, NO_ENVELOPES, type ObservabilityConfig, PLUGIN_NAME, RATCHET_FILE, READERS, type RatchetConfig, SCOPE, type Verdict, type Workspace, checkBaseline, checkClaudePlugin, checkDeployed, checkDrift, checkEnvelopes, checkExams, checkExercised, checkGroup, checkLoaded, checkObservability, checkRequiredOptions, checkRunner, corpusOfPlugin, declaredApparatusOf, declaredFor, declaredGroupsOf, defaultRef, discoverConfigs, discoverWorkspaces, enabledRulesOf, evidenceHolding, formatDoctor, formatJson, installedPluginVersions, installedPlugins, loadedAt, missingOptionOf, packageDirOf, pluginVersionOf, readConfig, readRatchet, relativePath, relativeToRoot, repoCorpusOf, resolveFrom, runDoctor, satisfies };
package/dist/index.js CHANGED
@@ -12,7 +12,6 @@ import {
12
12
  INSTALLED_PLUGINS,
13
13
  KIT_GROUP,
14
14
  MANIFEST_FILE,
15
- NOT_WRITTEN,
16
15
  NO_ENVELOPES,
17
16
  PLUGIN_NAME,
18
17
  RATCHET_FILE,
@@ -55,7 +54,7 @@ import {
55
54
  resolveFrom,
56
55
  runDoctor,
57
56
  satisfies
58
- } from "./chunk-VWMNCBDP.js";
57
+ } from "./chunk-IJXJ2EF4.js";
59
58
  export {
60
59
  APPARATUS_KEY,
61
60
  CHECKS,
@@ -70,7 +69,6 @@ export {
70
69
  INSTALLED_PLUGINS,
71
70
  KIT_GROUP,
72
71
  MANIFEST_FILE,
73
- NOT_WRITTEN,
74
72
  NO_ENVELOPES,
75
73
  PLUGIN_NAME,
76
74
  RATCHET_FILE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geonosis/doctor",
3
- "version": "2.12.0",
3
+ "version": "2.13.0",
4
4
  "types": "./dist/index.d.ts",
5
5
  "description": "The adoption doctor — declared ≠ loaded, enabled ≠ exercised, a baseline that grew, a runner whose exit code is the only verdict.",
6
6
  "keywords": [
@@ -36,10 +36,9 @@
36
36
  "dist"
37
37
  ],
38
38
  "dependencies": {
39
- "@geonosis/lint-parity": "2.12.0"
40
- },
41
- "devDependencies": {
42
- "@geonosis/ratchet": "2.12.0"
39
+ "@geonosis/lint-parity": "2.13.0",
40
+ "@geonosis/ratchet": "2.13.0",
41
+ "@geonosis/release": "2.13.0"
43
42
  },
44
43
  "peerDependencies": {
45
44
  "oxlint": ">=1.77"