stitchkit 0.74.0 → 0.74.1
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.
|
@@ -18,6 +18,20 @@ export declare function parsePlatformUuid(dump: string): string | null;
|
|
|
18
18
|
* removed — but which executable answers can be, and that makes the branch provable off darwin.
|
|
19
19
|
*/
|
|
20
20
|
export declare function readDarwinPlatformUuid(command?: string): Promise<string | null>;
|
|
21
|
+
/**
|
|
22
|
+
* The state letter of a pid, or `null` where this platform will not say.
|
|
23
|
+
*
|
|
24
|
+
* `/proc/<pid>/stat` puts the command name in parentheses and the name may itself contain them, so
|
|
25
|
+
* the state follows the LAST `)` — reading the third whitespace-separated field instead is wrong for
|
|
26
|
+
* any process whose name has a space or a bracket in it.
|
|
27
|
+
*
|
|
28
|
+
* @internal `psCommand` is a seam for the tests: `/proc` is Linux-only, so the fallback branch is
|
|
29
|
+
* unreachable here without one, and an untested branch in a liveness probe is how this defect got in.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isZombieProcess(pid: number, seam?: {
|
|
32
|
+
procRoot?: string;
|
|
33
|
+
psCommand?: string;
|
|
34
|
+
}): Promise<boolean>;
|
|
21
35
|
/**
|
|
22
36
|
* Take the journal's exclusive lock under the configured policy.
|
|
23
37
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostic-journal-lock.d.ts","sourceRoot":"","sources":["../../src/application/diagnostic-journal-lock.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAoB,MAAM,kBAAkB,CAAC;AAI1D,OAAO,KAAK,EAEV,2BAA2B,EAC5B,MAAM,+BAA+B,CAAC;AAEvC,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;AAEnD,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AA6DD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,SAAU,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBtF;
|
|
1
|
+
{"version":3,"file":"diagnostic-journal-lock.d.ts","sourceRoot":"","sources":["../../src/application/diagnostic-journal-lock.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAoB,MAAM,kBAAkB,CAAC;AAI1D,OAAO,KAAK,EAEV,2BAA2B,EAC5B,MAAM,+BAA+B,CAAC;AAEvC,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;AAEnD,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AA6DD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,SAAU,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBtF;AAgED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnD,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAgDD;;;;;;;;;;;;GAYG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,2BAA2B,EACnC,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,6BAA6B,CAAC,CA2BxC"}
|
package/dist/application.js
CHANGED
|
@@ -604,13 +604,30 @@ function attribute(owner, identity) {
|
|
|
604
604
|
}
|
|
605
605
|
return owner.host === hostname() ? "this-machine" : "unattributable";
|
|
606
606
|
}
|
|
607
|
-
function probeLiveness(owner) {
|
|
607
|
+
async function probeLiveness(owner) {
|
|
608
608
|
try {
|
|
609
609
|
process.kill(owner.pid, 0);
|
|
610
|
-
return "alive";
|
|
611
610
|
} catch (error) {
|
|
612
611
|
return isRecord(error) && error.code === "ESRCH" ? "gone" : "alive";
|
|
613
612
|
}
|
|
613
|
+
return await isZombieProcess(owner.pid) ? "gone" : "alive";
|
|
614
|
+
}
|
|
615
|
+
async function isZombieProcess(pid, seam = {}) {
|
|
616
|
+
const { procRoot = "/proc", psCommand = "ps" } = seam;
|
|
617
|
+
try {
|
|
618
|
+
const stat = await readFile(`${procRoot}/${pid}/stat`, "utf8");
|
|
619
|
+
return stat.slice(stat.lastIndexOf(")") + 1).trimStart().startsWith("Z");
|
|
620
|
+
} catch {}
|
|
621
|
+
try {
|
|
622
|
+
const { stdout } = await run(psCommand, ["-o", "state=", "-p", String(pid)], {
|
|
623
|
+
timeout: 2000,
|
|
624
|
+
maxBuffer: 1 << 16,
|
|
625
|
+
encoding: "utf8"
|
|
626
|
+
});
|
|
627
|
+
return stdout.trim().startsWith("Z");
|
|
628
|
+
} catch {
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
614
631
|
}
|
|
615
632
|
async function diagnose(owner, declaredIdentity) {
|
|
616
633
|
if (!owner)
|
|
@@ -624,7 +641,7 @@ async function diagnose(owner, declaredIdentity) {
|
|
|
624
641
|
};
|
|
625
642
|
if (attribution !== "this-machine")
|
|
626
643
|
return { attribution, liveness: "not-probed", owner: record };
|
|
627
|
-
return { attribution, liveness: probeLiveness(owner), owner: record };
|
|
644
|
+
return { attribution, liveness: await probeLiveness(owner), owner: record };
|
|
628
645
|
}
|
|
629
646
|
async function readLockOwner(lockPath) {
|
|
630
647
|
let handle;
|
package/llms-full.txt
CHANGED
|
@@ -2137,9 +2137,11 @@ check({ when: new Date() }) // accepted: a live Date
|
|
|
2137
2137
|
// server // refused: expected date, received string
|
|
2138
2138
|
```
|
|
2139
2139
|
|
|
2140
|
-
This one fails in the safe direction — nothing valid is blocked — but
|
|
2141
|
-
|
|
2142
|
-
|
|
2140
|
+
This one fails in the safe direction — nothing valid is blocked — but "safe" is
|
|
2141
|
+
about traffic, not about diagnostics. The check stays silent exactly where it
|
|
2142
|
+
promised to speak: the refusal then arrives from the server, through a different
|
|
2143
|
+
path and without the field names the local gate would have given. A gate that
|
|
2144
|
+
lets through what it was added to catch is not a cheap gate, it is a quiet one.
|
|
2143
2145
|
|
|
2144
2146
|
One schema, one call, opposite answers — inside a single release, with no version
|
|
2145
2147
|
skew involved. Argument validation therefore stays on the server, which is the
|
package/package.json
CHANGED