@pleri/olam-cli 0.1.106 → 0.1.107
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/dist/commands/diagnose.d.ts +16 -0
- package/dist/commands/diagnose.d.ts.map +1 -1
- package/dist/commands/diagnose.js +16 -0
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/doctor.d.ts +60 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +144 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/kg-status.d.ts.map +1 -1
- package/dist/commands/kg-status.js +1 -2
- package/dist/commands/kg-status.js.map +1 -1
- package/dist/image-digests.json +1 -1
- package/dist/index.js +463 -132
- package/dist/index.js.map +1 -1
- package/dist/lib/health-probes.d.ts +116 -0
- package/dist/lib/health-probes.d.ts.map +1 -0
- package/dist/lib/health-probes.js +390 -0
- package/dist/lib/health-probes.js.map +1 -0
- package/dist/lib/kg-caps.d.ts +19 -0
- package/dist/lib/kg-caps.d.ts.map +1 -0
- package/dist/lib/kg-caps.js +19 -0
- package/dist/lib/kg-caps.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,+DAA+D,CAAC;KAC5E,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;AAE7B,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,sEAAsE;AACtE,yEAAyE;AACzE,0EAA0E;AAC1E,wEAAwE;AACxE,mBAAmB,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;AAC/D,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE1B,0EAA0E;AAC1E,6EAA6E;AAC7E,yEAAyE;AACzE,wBAAwB;AAExB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,+DAA+D,CAAC;KAC5E,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;AAE7B,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,sEAAsE;AACtE,yEAAyE;AACzE,0EAA0E;AAC1E,wEAAwE;AACxE,mBAAmB,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;AAC/D,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE1B,0EAA0E;AAC1E,6EAA6E;AAC7E,yEAAyE;AACzE,wBAAwB;AAExB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* health-probes.ts — Shared host-health probe module.
|
|
3
|
+
*
|
|
4
|
+
* Phase A1 of olam-operator-onboarding-parity (plan
|
|
5
|
+
* ~/.claude/plans/olam-operator-onboarding-parity.md).
|
|
6
|
+
*
|
|
7
|
+
* The Seam (Decision 3): `olam doctor` + `olam diagnose` both consume
|
|
8
|
+
* these probes. No probe writes to disk; no probe spawns long-running
|
|
9
|
+
* processes; each is independently safe to run in parallel.
|
|
10
|
+
*
|
|
11
|
+
* Probe contract:
|
|
12
|
+
* - Each returns ProbeResult: { ok: true, message } | { ok: false, message, remedy }
|
|
13
|
+
* - Each is async; can run in parallel via Promise.all
|
|
14
|
+
* - Each accepts injectable deps (docker exec / fetch / OLAM_HOME) for testability
|
|
15
|
+
*
|
|
16
|
+
* Cap thresholds (probeKgStorage) mirror packages/cli/src/commands/kg-status.ts:
|
|
17
|
+
* - 1.5 GB soft-cap → ok:true with "soft-warn" message
|
|
18
|
+
* - 5.0 GB hard-cap → ok:false with prune remedy
|
|
19
|
+
*
|
|
20
|
+
* Daemon-reachability rule (Risk T5): callers that probe per-image
|
|
21
|
+
* presence MUST call probeDockerDaemon first and fast-fail on its
|
|
22
|
+
* failure. Image probes throw confusing "404 no such image" errors
|
|
23
|
+
* when the daemon is paused mid-check.
|
|
24
|
+
*/
|
|
25
|
+
export type ProbeResult = {
|
|
26
|
+
readonly ok: true;
|
|
27
|
+
readonly message: string;
|
|
28
|
+
} | {
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly message: string;
|
|
31
|
+
readonly remedy: string;
|
|
32
|
+
};
|
|
33
|
+
export interface DockerExecResult {
|
|
34
|
+
readonly status: number | null;
|
|
35
|
+
readonly stdout: string;
|
|
36
|
+
readonly stderr: string;
|
|
37
|
+
}
|
|
38
|
+
export type DockerExec = (cmd: string, args: ReadonlyArray<string>) => DockerExecResult;
|
|
39
|
+
export type FetchLike = (input: string, init?: {
|
|
40
|
+
signal?: AbortSignal;
|
|
41
|
+
}) => Promise<Response>;
|
|
42
|
+
/**
|
|
43
|
+
* Verify docker daemon is reachable via `docker info --format`.
|
|
44
|
+
*
|
|
45
|
+
* MUST be called first by callers that probe per-image presence; image
|
|
46
|
+
* probes throw confusing "404 no such image" errors when the daemon is
|
|
47
|
+
* paused mid-check (Risk T5 mitigation).
|
|
48
|
+
*/
|
|
49
|
+
export declare function probeDockerDaemon(dockerExec?: DockerExec): Promise<ProbeResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Verify each ref is present locally via `docker image inspect`.
|
|
52
|
+
*
|
|
53
|
+
* Fast-fail: returns the first missing image; subsequent refs NOT
|
|
54
|
+
* probed. Caller decides ordering of refs.
|
|
55
|
+
*/
|
|
56
|
+
export declare function probeImagePresence(refs: ReadonlyArray<string>, dockerExec?: DockerExec): Promise<ProbeResult>;
|
|
57
|
+
/**
|
|
58
|
+
* GET http://127.0.0.1:19000/health with 5s timeout; expect HTTP 200
|
|
59
|
+
* AND a JSON envelope matching the host-cp shape (defends against
|
|
60
|
+
* false-positives from a port-collision with some other 19000-bound
|
|
61
|
+
* process — audit finding HIGH body-shape).
|
|
62
|
+
*
|
|
63
|
+
* Real envelope (per `packages/host-cp/src/server.mjs:665-688`):
|
|
64
|
+
* { status: 'ok', phase, uptime_seconds: number, cache: {...},
|
|
65
|
+
* mode: { deployment, world_host }, registry: {...}, auth: {...} }
|
|
66
|
+
*
|
|
67
|
+
* Probe asserts three orthogonal fields (`phase` + `cache` object +
|
|
68
|
+
* `mode.deployment`) that no random web server would carry together.
|
|
69
|
+
* Substring-on-the-token-path was an earlier fragile heuristic; this
|
|
70
|
+
* version pins to actual server contract.
|
|
71
|
+
*
|
|
72
|
+
* Aborts via AbortController on timeout; failure mode is captured in
|
|
73
|
+
* the error path with reason ("timeout" / "ECONNREFUSED" / etc.).
|
|
74
|
+
*
|
|
75
|
+
* Always consumes the response body before returning (avoids undici
|
|
76
|
+
* socket leak when the probe is invoked in a loop).
|
|
77
|
+
*/
|
|
78
|
+
export declare function probeHostCpHealth(fetchImpl?: FetchLike): Promise<ProbeResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Read the canonical credentials vault at `<OLAM_HOME>/auth-data/accounts.json`
|
|
81
|
+
* (matching `packages/auth-service/src/store.ts:LOCAL_DATA_DIR` and
|
|
82
|
+
* `scripts/audit-credentials.mjs:resolveAccountsPath`); count active
|
|
83
|
+
* `claude` credentials.
|
|
84
|
+
*
|
|
85
|
+
* Vault shape (per packages/auth-service/src/types.ts): a flat JSON array
|
|
86
|
+
* of account objects. Each account has:
|
|
87
|
+
* - provider: 'claude' | 'codex' | ...
|
|
88
|
+
* - state?: 'active' | 'cooldown' | 'disabled'
|
|
89
|
+
* - rateLimited?: boolean (legacy fallback for state)
|
|
90
|
+
* - expiresAt?: number (epoch ms)
|
|
91
|
+
* - rateLimitResetsAt?: string (ISO 8601)
|
|
92
|
+
*
|
|
93
|
+
* Predicate mirrors `effectiveState()` from scripts/audit-credentials.mjs
|
|
94
|
+
* inline (the canonical helper is a .mjs script that we can't import from
|
|
95
|
+
* this TS module). If the canonical predicate evolves (new fields, new
|
|
96
|
+
* state literals), this mirror MUST be updated.
|
|
97
|
+
*
|
|
98
|
+
* Override: `OLAM_AUTH_DATA_PATH` env var lets CI/test fixtures point
|
|
99
|
+
* at an alternate accounts.json. Matches the canonical helper.
|
|
100
|
+
*/
|
|
101
|
+
export declare function probeAuthVault(olamHomeOverride?: string): Promise<ProbeResult>;
|
|
102
|
+
/**
|
|
103
|
+
* Cumulative KG storage under OLAM_HOME (pristines + overlays).
|
|
104
|
+
* Soft warn at 1.5 GB; hard fail at 5 GB.
|
|
105
|
+
*
|
|
106
|
+
* Layout (mirrors packages/cli/src/commands/kg-status.ts):
|
|
107
|
+
* - Pristines: ~/.olam/kg/<workspace>/graphify-out/
|
|
108
|
+
* - Overlays: ~/.olam/worlds/<world>/<clone>/graphify-out/
|
|
109
|
+
*
|
|
110
|
+
* Cap constants duplicated rather than imported from kg-status.ts to
|
|
111
|
+
* keep this module self-contained (the Seam decision — see plan
|
|
112
|
+
* decision 3). A future PR may extract them to a single source if
|
|
113
|
+
* a third consumer lands.
|
|
114
|
+
*/
|
|
115
|
+
export declare function probeKgStorage(olamHomeOverride?: string): Promise<ProbeResult>;
|
|
116
|
+
//# sourceMappingURL=health-probes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-probes.d.ts","sourceRoot":"","sources":["../../src/lib/health-probes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAQH,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAM9E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,gBAAgB,CAAC;AAExF,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AA+B9F;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,GAAE,UAA8B,GACzC,OAAO,CAAC,WAAW,CAAC,CAUtB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,UAAU,GAAE,UAA8B,GACzC,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,GAAE,SAAwB,GAClC,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAwBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqCpF;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAuBpF"}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* health-probes.ts — Shared host-health probe module.
|
|
3
|
+
*
|
|
4
|
+
* Phase A1 of olam-operator-onboarding-parity (plan
|
|
5
|
+
* ~/.claude/plans/olam-operator-onboarding-parity.md).
|
|
6
|
+
*
|
|
7
|
+
* The Seam (Decision 3): `olam doctor` + `olam diagnose` both consume
|
|
8
|
+
* these probes. No probe writes to disk; no probe spawns long-running
|
|
9
|
+
* processes; each is independently safe to run in parallel.
|
|
10
|
+
*
|
|
11
|
+
* Probe contract:
|
|
12
|
+
* - Each returns ProbeResult: { ok: true, message } | { ok: false, message, remedy }
|
|
13
|
+
* - Each is async; can run in parallel via Promise.all
|
|
14
|
+
* - Each accepts injectable deps (docker exec / fetch / OLAM_HOME) for testability
|
|
15
|
+
*
|
|
16
|
+
* Cap thresholds (probeKgStorage) mirror packages/cli/src/commands/kg-status.ts:
|
|
17
|
+
* - 1.5 GB soft-cap → ok:true with "soft-warn" message
|
|
18
|
+
* - 5.0 GB hard-cap → ok:false with prune remedy
|
|
19
|
+
*
|
|
20
|
+
* Daemon-reachability rule (Risk T5): callers that probe per-image
|
|
21
|
+
* presence MUST call probeDockerDaemon first and fast-fail on its
|
|
22
|
+
* failure. Image probes throw confusing "404 no such image" errors
|
|
23
|
+
* when the daemon is paused mid-check.
|
|
24
|
+
*/
|
|
25
|
+
import { spawnSync } from 'node:child_process';
|
|
26
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
27
|
+
import { homedir } from 'node:os';
|
|
28
|
+
import path from 'node:path';
|
|
29
|
+
import { SOFT_CAP_BYTES, HARD_CAP_BYTES } from './kg-caps.js';
|
|
30
|
+
const HEALTH_TIMEOUT_MS = 5_000;
|
|
31
|
+
/**
|
|
32
|
+
* Default Docker exec implementation. Consumers MUST inject their own
|
|
33
|
+
* `exec` parameter in tests — this default reaches real
|
|
34
|
+
* `node:child_process.spawnSync` and will shell out to a real `docker`
|
|
35
|
+
* binary on the test runner (green on dev laptops with Docker running;
|
|
36
|
+
* red on CI runners without daemon). Audit finding HIGH-2.
|
|
37
|
+
*/
|
|
38
|
+
const defaultDockerExec = (cmd, args) => {
|
|
39
|
+
const r = spawnSync(cmd, [...args], {
|
|
40
|
+
encoding: 'utf-8',
|
|
41
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
status: r.status,
|
|
45
|
+
stdout: r.stdout ?? '',
|
|
46
|
+
stderr: r.stderr ?? '',
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Default fetch implementation. Consumers MUST inject their own
|
|
51
|
+
* `fetchImpl` parameter in tests — this default reaches the global
|
|
52
|
+
* `fetch` and will make real network calls on the test runner.
|
|
53
|
+
* Audit finding HIGH-2.
|
|
54
|
+
*/
|
|
55
|
+
const defaultFetch = (input, init) => fetch(input, init);
|
|
56
|
+
// ── Probes ─────────────────────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* Verify docker daemon is reachable via `docker info --format`.
|
|
59
|
+
*
|
|
60
|
+
* MUST be called first by callers that probe per-image presence; image
|
|
61
|
+
* probes throw confusing "404 no such image" errors when the daemon is
|
|
62
|
+
* paused mid-check (Risk T5 mitigation).
|
|
63
|
+
*/
|
|
64
|
+
export async function probeDockerDaemon(dockerExec = defaultDockerExec) {
|
|
65
|
+
const r = dockerExec('docker', ['info', '--format', '{{.ServerVersion}}']);
|
|
66
|
+
if (r.status === 0 && r.stdout.trim().length > 0) {
|
|
67
|
+
return { ok: true, message: `docker ${r.stdout.trim()} reachable` };
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
message: 'docker daemon not reachable',
|
|
72
|
+
remedy: 'Start Docker Desktop (or your docker daemon) and re-run.',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Verify each ref is present locally via `docker image inspect`.
|
|
77
|
+
*
|
|
78
|
+
* Fast-fail: returns the first missing image; subsequent refs NOT
|
|
79
|
+
* probed. Caller decides ordering of refs.
|
|
80
|
+
*/
|
|
81
|
+
export async function probeImagePresence(refs, dockerExec = defaultDockerExec) {
|
|
82
|
+
for (const ref of refs) {
|
|
83
|
+
const r = dockerExec('docker', ['image', 'inspect', '--format', '{{.Id}}', ref]);
|
|
84
|
+
if (r.status !== 0) {
|
|
85
|
+
return {
|
|
86
|
+
ok: false,
|
|
87
|
+
message: `image ${ref} not present locally`,
|
|
88
|
+
remedy: 'Run `olam bootstrap` to pull the published image, or build locally.',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { ok: true, message: `${refs.length} image(s) present` };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* GET http://127.0.0.1:19000/health with 5s timeout; expect HTTP 200
|
|
96
|
+
* AND a JSON envelope matching the host-cp shape (defends against
|
|
97
|
+
* false-positives from a port-collision with some other 19000-bound
|
|
98
|
+
* process — audit finding HIGH body-shape).
|
|
99
|
+
*
|
|
100
|
+
* Real envelope (per `packages/host-cp/src/server.mjs:665-688`):
|
|
101
|
+
* { status: 'ok', phase, uptime_seconds: number, cache: {...},
|
|
102
|
+
* mode: { deployment, world_host }, registry: {...}, auth: {...} }
|
|
103
|
+
*
|
|
104
|
+
* Probe asserts three orthogonal fields (`phase` + `cache` object +
|
|
105
|
+
* `mode.deployment`) that no random web server would carry together.
|
|
106
|
+
* Substring-on-the-token-path was an earlier fragile heuristic; this
|
|
107
|
+
* version pins to actual server contract.
|
|
108
|
+
*
|
|
109
|
+
* Aborts via AbortController on timeout; failure mode is captured in
|
|
110
|
+
* the error path with reason ("timeout" / "ECONNREFUSED" / etc.).
|
|
111
|
+
*
|
|
112
|
+
* Always consumes the response body before returning (avoids undici
|
|
113
|
+
* socket leak when the probe is invoked in a loop).
|
|
114
|
+
*/
|
|
115
|
+
export async function probeHostCpHealth(fetchImpl = defaultFetch) {
|
|
116
|
+
const controller = new AbortController();
|
|
117
|
+
const timeout = setTimeout(() => controller.abort(), HEALTH_TIMEOUT_MS);
|
|
118
|
+
try {
|
|
119
|
+
const res = await fetchImpl('http://127.0.0.1:19000/health', { signal: controller.signal });
|
|
120
|
+
const body = await res.text().catch(() => '');
|
|
121
|
+
if (res.status !== 200) {
|
|
122
|
+
return {
|
|
123
|
+
ok: false,
|
|
124
|
+
message: `host-cp /health returned ${res.status}`,
|
|
125
|
+
remedy: 'Restart host-cp via `olam host-cp start`; verify port 19000 is bound to 127.0.0.1.',
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (isHostCpHealthEnvelope(body)) {
|
|
129
|
+
return { ok: true, message: 'host-cp /health returned 200' };
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
ok: false,
|
|
133
|
+
message: 'host-cp /health returned 200 but body did not match the host-cp envelope (possible port collision on :19000)',
|
|
134
|
+
remedy: 'Check `lsof -iTCP:19000`; another process may have bound the port. Restart host-cp via `olam host-cp start`.',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
const e = err;
|
|
139
|
+
const reason = e.name === 'AbortError' ? `timeout (${HEALTH_TIMEOUT_MS}ms)` : e.message;
|
|
140
|
+
return {
|
|
141
|
+
ok: false,
|
|
142
|
+
message: `host-cp /health unreachable: ${reason}`,
|
|
143
|
+
remedy: 'Restart host-cp via `olam host-cp start`; verify port 19000 is bound to 127.0.0.1.',
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
clearTimeout(timeout);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Match three orthogonal fields from host-cp's real /health envelope.
|
|
152
|
+
* Returns true only when ALL match (a random 19000-bound web server is
|
|
153
|
+
* very unlikely to ship all three in one response by accident).
|
|
154
|
+
*/
|
|
155
|
+
function isHostCpHealthEnvelope(body) {
|
|
156
|
+
let parsed;
|
|
157
|
+
try {
|
|
158
|
+
parsed = JSON.parse(body);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (!parsed || typeof parsed !== 'object')
|
|
164
|
+
return false;
|
|
165
|
+
const obj = parsed;
|
|
166
|
+
if (typeof obj.phase !== 'string')
|
|
167
|
+
return false;
|
|
168
|
+
if (!obj.cache || typeof obj.cache !== 'object')
|
|
169
|
+
return false;
|
|
170
|
+
const mode = obj.mode;
|
|
171
|
+
if (!mode || typeof mode !== 'object')
|
|
172
|
+
return false;
|
|
173
|
+
if (typeof mode.deployment !== 'string')
|
|
174
|
+
return false;
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Read the canonical credentials vault at `<OLAM_HOME>/auth-data/accounts.json`
|
|
179
|
+
* (matching `packages/auth-service/src/store.ts:LOCAL_DATA_DIR` and
|
|
180
|
+
* `scripts/audit-credentials.mjs:resolveAccountsPath`); count active
|
|
181
|
+
* `claude` credentials.
|
|
182
|
+
*
|
|
183
|
+
* Vault shape (per packages/auth-service/src/types.ts): a flat JSON array
|
|
184
|
+
* of account objects. Each account has:
|
|
185
|
+
* - provider: 'claude' | 'codex' | ...
|
|
186
|
+
* - state?: 'active' | 'cooldown' | 'disabled'
|
|
187
|
+
* - rateLimited?: boolean (legacy fallback for state)
|
|
188
|
+
* - expiresAt?: number (epoch ms)
|
|
189
|
+
* - rateLimitResetsAt?: string (ISO 8601)
|
|
190
|
+
*
|
|
191
|
+
* Predicate mirrors `effectiveState()` from scripts/audit-credentials.mjs
|
|
192
|
+
* inline (the canonical helper is a .mjs script that we can't import from
|
|
193
|
+
* this TS module). If the canonical predicate evolves (new fields, new
|
|
194
|
+
* state literals), this mirror MUST be updated.
|
|
195
|
+
*
|
|
196
|
+
* Override: `OLAM_AUTH_DATA_PATH` env var lets CI/test fixtures point
|
|
197
|
+
* at an alternate accounts.json. Matches the canonical helper.
|
|
198
|
+
*/
|
|
199
|
+
export async function probeAuthVault(olamHomeOverride) {
|
|
200
|
+
const vaultPath = resolveAccountsPath(olamHomeOverride);
|
|
201
|
+
if (!existsSync(vaultPath)) {
|
|
202
|
+
return {
|
|
203
|
+
ok: false,
|
|
204
|
+
message: `auth vault missing at ${vaultPath}`,
|
|
205
|
+
remedy: 'Run `olam auth up && olam auth login` to provision the vault.',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
let parsed;
|
|
209
|
+
try {
|
|
210
|
+
parsed = JSON.parse(readFileSync(vaultPath, 'utf-8'));
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
return {
|
|
214
|
+
ok: false,
|
|
215
|
+
message: `auth vault malformed: ${err.message}`,
|
|
216
|
+
remedy: 'Inspect the accounts.json file; restore from backup or re-run `olam auth up`.',
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (!Array.isArray(parsed)) {
|
|
220
|
+
return {
|
|
221
|
+
ok: false,
|
|
222
|
+
message: 'auth vault malformed: expected JSON array at top level',
|
|
223
|
+
remedy: 'Restore the vault from backup or re-run `olam auth up && olam auth login`.',
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const accounts = parsed.filter((a) => a !== null && typeof a === 'object');
|
|
227
|
+
const now = Date.now();
|
|
228
|
+
const activeClaude = accounts.filter((a) => a.provider === 'claude' && effectiveState(a, now) === 'active');
|
|
229
|
+
if (activeClaude.length === 0) {
|
|
230
|
+
return {
|
|
231
|
+
ok: false,
|
|
232
|
+
message: `no active claude credentials (vault has ${accounts.length} account(s))`,
|
|
233
|
+
remedy: 'Run `olam auth login` to add a credential, or wait for the next reset.',
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
return { ok: true, message: `${activeClaude.length} active claude credential(s)` };
|
|
237
|
+
}
|
|
238
|
+
function resolveAccountsPath(olamHomeOverride) {
|
|
239
|
+
// OLAM_AUTH_DATA_PATH is the explicit override (matches the canonical
|
|
240
|
+
// helper at scripts/audit-credentials.mjs). Honoured first for CI fixtures.
|
|
241
|
+
const explicit = process.env.OLAM_AUTH_DATA_PATH;
|
|
242
|
+
if (explicit)
|
|
243
|
+
return explicit;
|
|
244
|
+
const olamHome = olamHomeOverride ?? process.env.OLAM_HOME ?? path.join(homedir(), '.olam');
|
|
245
|
+
return path.join(olamHome, 'auth-data', 'accounts.json');
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Inline mirror of `effectiveState()` from scripts/audit-credentials.mjs.
|
|
249
|
+
*
|
|
250
|
+
* IMPORTANT: keep this in sync with the canonical helper. If the helper
|
|
251
|
+
* changes, this copy MUST change too (no compile-time link between them).
|
|
252
|
+
*/
|
|
253
|
+
function effectiveState(account, now) {
|
|
254
|
+
const persisted = account.state ?? (account.rateLimited ? 'cooldown' : 'active');
|
|
255
|
+
if (persisted === 'disabled')
|
|
256
|
+
return 'disabled';
|
|
257
|
+
if (typeof account.expiresAt === 'number' && account.expiresAt <= now)
|
|
258
|
+
return 'expired';
|
|
259
|
+
if (persisted === 'cooldown') {
|
|
260
|
+
const reset = account.rateLimitResetsAt ? new Date(account.rateLimitResetsAt).getTime() : 0;
|
|
261
|
+
if (reset > 0 && reset <= now)
|
|
262
|
+
return 'active';
|
|
263
|
+
}
|
|
264
|
+
return persisted;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Cumulative KG storage under OLAM_HOME (pristines + overlays).
|
|
268
|
+
* Soft warn at 1.5 GB; hard fail at 5 GB.
|
|
269
|
+
*
|
|
270
|
+
* Layout (mirrors packages/cli/src/commands/kg-status.ts):
|
|
271
|
+
* - Pristines: ~/.olam/kg/<workspace>/graphify-out/
|
|
272
|
+
* - Overlays: ~/.olam/worlds/<world>/<clone>/graphify-out/
|
|
273
|
+
*
|
|
274
|
+
* Cap constants duplicated rather than imported from kg-status.ts to
|
|
275
|
+
* keep this module self-contained (the Seam decision — see plan
|
|
276
|
+
* decision 3). A future PR may extract them to a single source if
|
|
277
|
+
* a third consumer lands.
|
|
278
|
+
*/
|
|
279
|
+
export async function probeKgStorage(olamHomeOverride) {
|
|
280
|
+
const olamHome = olamHomeOverride ?? process.env.OLAM_HOME ?? path.join(homedir(), '.olam');
|
|
281
|
+
const kgRoot = path.join(olamHome, 'kg');
|
|
282
|
+
const worldsRoot = path.join(olamHome, 'worlds');
|
|
283
|
+
const kgBytes = enumerateGraphifyOut(kgRoot, 'pristine');
|
|
284
|
+
const overlayBytes = enumerateGraphifyOut(worldsRoot, 'overlay');
|
|
285
|
+
const totalBytes = kgBytes + overlayBytes;
|
|
286
|
+
if (totalBytes >= HARD_CAP_BYTES) {
|
|
287
|
+
return {
|
|
288
|
+
ok: false,
|
|
289
|
+
message: `KG storage ${formatBytes(totalBytes)} exceeds 5 GB hard cap`,
|
|
290
|
+
remedy: 'Prune stale pristines: `rm -rf ~/.olam/kg/<workspace>` after operator review.',
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
if (totalBytes >= SOFT_CAP_BYTES) {
|
|
294
|
+
return {
|
|
295
|
+
ok: true,
|
|
296
|
+
message: `KG storage ${formatBytes(totalBytes)} (soft-warn — exceeds 1.5 GB; consider pruning)`,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
return { ok: true, message: `KG storage ${formatBytes(totalBytes)} (under cap)` };
|
|
300
|
+
}
|
|
301
|
+
function enumerateGraphifyOut(root, layout) {
|
|
302
|
+
if (!existsSync(root))
|
|
303
|
+
return 0;
|
|
304
|
+
let total = 0;
|
|
305
|
+
let entries;
|
|
306
|
+
try {
|
|
307
|
+
entries = readdirSync(root, { withFileTypes: true });
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
return 0;
|
|
311
|
+
}
|
|
312
|
+
for (const entry of entries) {
|
|
313
|
+
if (!entry.isDirectory())
|
|
314
|
+
continue;
|
|
315
|
+
if (layout === 'pristine') {
|
|
316
|
+
total += dirSizeBytes(path.join(root, entry.name, 'graphify-out'));
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
const worldDir = path.join(root, entry.name);
|
|
320
|
+
let clones;
|
|
321
|
+
try {
|
|
322
|
+
clones = readdirSync(worldDir, { withFileTypes: true });
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
for (const clone of clones) {
|
|
328
|
+
if (!clone.isDirectory())
|
|
329
|
+
continue;
|
|
330
|
+
total += dirSizeBytes(path.join(worldDir, clone.name, 'graphify-out'));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return total;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Recursive byte sum over a directory.
|
|
338
|
+
*
|
|
339
|
+
* Symlink policy: short-circuited via `entry.isSymbolicLink()` in the
|
|
340
|
+
* common case. KNOWN FALSE-POSITIVE CLASS (audit finding HIGH-3): on
|
|
341
|
+
* filesystems that don't populate `d_type` (some network mounts, FUSE,
|
|
342
|
+
* exotic overlay FS), `Dirent` flags report `UV_DIRENT_UNKNOWN` and
|
|
343
|
+
* both `isSymbolicLink()` and `isDirectory()` return `false`. Such an
|
|
344
|
+
* entry is then `statSync`'d as a file; if it's actually a symlink to
|
|
345
|
+
* a giant file, the target's bytes are counted. Probability is low on
|
|
346
|
+
* APFS/ext4; impact is "doctor false-fail on a healthy host with
|
|
347
|
+
* exotic FS." Mirrors the same shape in kg-status.ts:240.
|
|
348
|
+
*/
|
|
349
|
+
function dirSizeBytes(dir) {
|
|
350
|
+
if (!existsSync(dir))
|
|
351
|
+
return 0;
|
|
352
|
+
let total = 0;
|
|
353
|
+
const stack = [dir];
|
|
354
|
+
while (stack.length > 0) {
|
|
355
|
+
const cur = stack.pop();
|
|
356
|
+
let entries;
|
|
357
|
+
try {
|
|
358
|
+
entries = readdirSync(cur, { withFileTypes: true });
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
for (const entry of entries) {
|
|
364
|
+
const full = path.join(cur, entry.name);
|
|
365
|
+
if (entry.isSymbolicLink())
|
|
366
|
+
continue;
|
|
367
|
+
if (entry.isDirectory()) {
|
|
368
|
+
stack.push(full);
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
try {
|
|
372
|
+
total += statSync(full).size;
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
// race: file disappeared between readdir + stat
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return total;
|
|
380
|
+
}
|
|
381
|
+
function formatBytes(n) {
|
|
382
|
+
if (n < 1024)
|
|
383
|
+
return `${n} B`;
|
|
384
|
+
if (n < 1024 * 1024)
|
|
385
|
+
return `${(n / 1024).toFixed(1)} KB`;
|
|
386
|
+
if (n < 1024 * 1024 * 1024)
|
|
387
|
+
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
388
|
+
return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=health-probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-probes.js","sourceRoot":"","sources":["../../src/lib/health-probes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAe,MAAM,SAAS,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM9D,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAchC;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAe,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IAClD,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;QAClC,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC;IACH,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;QACtB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;KACvB,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,YAAY,GAAc,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAEpE,0EAA0E;AAE1E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,aAAyB,iBAAiB;IAE1C,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC3E,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IACtE,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,OAAO,EAAE,6BAA6B;QACtC,MAAM,EAAE,0DAA0D;KACnE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAA2B,EAC3B,aAAyB,iBAAiB;IAE1C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE,SAAS,GAAG,sBAAsB;gBAC3C,MAAM,EAAE,qEAAqE;aAC9E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,mBAAmB,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,YAAuB,YAAY;IAEnC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,iBAAiB,CAAC,CAAC;IACxE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,+BAA+B,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5F,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE,4BAA4B,GAAG,CAAC,MAAM,EAAE;gBACjD,MAAM,EAAE,oFAAoF;aAC7F,CAAC;QACJ,CAAC;QACD,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;QAC/D,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,8GAA8G;YACvH,MAAM,EAAE,8GAA8G;SACvH,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,GAAY,CAAC;QACvB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,iBAAiB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACxF,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,gCAAgC,MAAM,EAAE;YACjD,MAAM,EAAE,oFAAoF;SAC7F,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAAC,IAAY;IAC1C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACxD,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,OAAQ,IAAgC,CAAC,UAAU,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACnF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,gBAAyB;IAC5D,MAAM,SAAS,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,yBAAyB,SAAS,EAAE;YAC7C,MAAM,EAAE,+DAA+D;SACxE,CAAC;IACJ,CAAC;IACD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,yBAA0B,GAAa,CAAC,OAAO,EAAE;YAC1D,MAAM,EAAE,+EAA+E;SACxF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,wDAAwD;YACjE,MAAM,EAAE,4EAA4E;SACrF,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC9F,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,cAAc,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC5G,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,2CAA2C,QAAQ,CAAC,MAAM,cAAc;YACjF,MAAM,EAAE,wEAAwE;SACjF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,MAAM,8BAA8B,EAAE,CAAC;AACrF,CAAC;AAED,SAAS,mBAAmB,CAAC,gBAAyB;IACpD,sEAAsE;IACtE,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACjD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,QAAQ,GAAG,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IAC5F,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;AAC3D,CAAC;AAUD;;;;;GAKG;AACH,SAAS,cAAc,CAAC,OAAqB,EAAE,GAAW;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjF,IAAI,SAAS,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,CAAC,SAAS,IAAI,GAAG;QAAE,OAAO,SAAS,CAAC;IACxF,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,QAAQ,CAAC;IACjD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,gBAAyB;IAC5D,MAAM,QAAQ,GAAG,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAEjD,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,oBAAoB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;IAE1C,IAAI,UAAU,IAAI,cAAc,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,cAAc,WAAW,CAAC,UAAU,CAAC,wBAAwB;YACtE,MAAM,EAAE,+EAA+E;SACxF,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,IAAI,cAAc,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE,cAAc,WAAW,CAAC,UAAU,CAAC,iDAAiD;SAChG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,WAAW,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;AACpF,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY,EAAE,MAA8B;IACxE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAS;QACnC,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,MAAgB,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBAAE,SAAS;gBACnC,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,KAAK,GAAa,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACzB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,cAAc,EAAE;gBAAE,SAAS;YACrC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjB,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC;IAC9B,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1D,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IACxE,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kg-caps.ts — KG storage cap thresholds (single source of truth).
|
|
3
|
+
*
|
|
4
|
+
* Phase A1 follow-up (audit finding HIGH-1: drift): A1's `health-probes.ts`
|
|
5
|
+
* and the pre-existing `commands/kg-status.ts` were both hard-coding the
|
|
6
|
+
* 1.5 GB soft / 5 GB hard cap thresholds. With doctor + diagnose + kg-status
|
|
7
|
+
* as three consumers (A1 added consumer #2; A3 makes it #3 transitively),
|
|
8
|
+
* the plan's "third-consumer threshold" has arrived. Pin the constants here
|
|
9
|
+
* so any future cap-policy change touches one file.
|
|
10
|
+
*
|
|
11
|
+
* Drift contract: every consumer of these constants MUST import from this
|
|
12
|
+
* module, NOT redefine inline. A grep for `1_500_000_000` or `5_000_000_000`
|
|
13
|
+
* across `packages/cli/src/` should match only this file.
|
|
14
|
+
*/
|
|
15
|
+
/** Soft warn threshold — 1.5 GB. Below this: silent. Above: doctor prints a "consider pruning" note but still exits 0. */
|
|
16
|
+
export declare const SOFT_CAP_BYTES = 1500000000;
|
|
17
|
+
/** Hard fail threshold — 5 GB. At or above: doctor exits 1; `olam kg status` exits 1. */
|
|
18
|
+
export declare const HARD_CAP_BYTES = 5000000000;
|
|
19
|
+
//# sourceMappingURL=kg-caps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kg-caps.d.ts","sourceRoot":"","sources":["../../src/lib/kg-caps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,0HAA0H;AAC1H,eAAO,MAAM,cAAc,aAAgB,CAAC;AAE5C,yFAAyF;AACzF,eAAO,MAAM,cAAc,aAAgB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kg-caps.ts — KG storage cap thresholds (single source of truth).
|
|
3
|
+
*
|
|
4
|
+
* Phase A1 follow-up (audit finding HIGH-1: drift): A1's `health-probes.ts`
|
|
5
|
+
* and the pre-existing `commands/kg-status.ts` were both hard-coding the
|
|
6
|
+
* 1.5 GB soft / 5 GB hard cap thresholds. With doctor + diagnose + kg-status
|
|
7
|
+
* as three consumers (A1 added consumer #2; A3 makes it #3 transitively),
|
|
8
|
+
* the plan's "third-consumer threshold" has arrived. Pin the constants here
|
|
9
|
+
* so any future cap-policy change touches one file.
|
|
10
|
+
*
|
|
11
|
+
* Drift contract: every consumer of these constants MUST import from this
|
|
12
|
+
* module, NOT redefine inline. A grep for `1_500_000_000` or `5_000_000_000`
|
|
13
|
+
* across `packages/cli/src/` should match only this file.
|
|
14
|
+
*/
|
|
15
|
+
/** Soft warn threshold — 1.5 GB. Below this: silent. Above: doctor prints a "consider pruning" note but still exits 0. */
|
|
16
|
+
export const SOFT_CAP_BYTES = 1_500_000_000;
|
|
17
|
+
/** Hard fail threshold — 5 GB. At or above: doctor exits 1; `olam kg status` exits 1. */
|
|
18
|
+
export const HARD_CAP_BYTES = 5_000_000_000;
|
|
19
|
+
//# sourceMappingURL=kg-caps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kg-caps.js","sourceRoot":"","sources":["../../src/lib/kg-caps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,0HAA0H;AAC1H,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;AAE5C,yFAAyF;AACzF,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC"}
|