@ttsc/unplugin 0.31.2 → 0.31.4
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/lib/core/transform/session/claimSharedCompile.js +6 -4
- package/lib/core/transform/session/claimSharedCompile.js.map +1 -1
- package/lib/core/transform/session/claimSharedCompile.mjs +6 -4
- package/lib/core/transform/session/claimSharedCompile.mjs.map +1 -1
- package/lib/core/transform/session/openTtscTransformSession.d.cts +1 -1
- package/lib/core/transform/session/openTtscTransformSession.d.mts +1 -1
- package/lib/core/transform/session/openTtscTransformSession.d.ts +1 -1
- package/lib/core/transform/session/openTtscTransformSession.js +7 -3
- package/lib/core/transform/session/openTtscTransformSession.js.map +1 -1
- package/lib/core/transform/session/openTtscTransformSession.mjs +7 -3
- package/lib/core/transform/session/openTtscTransformSession.mjs.map +1 -1
- package/lib/core/transform/tracker/broker/sweepAbandonedWatchProbes.d.cts +6 -6
- package/lib/core/transform/tracker/broker/sweepAbandonedWatchProbes.d.mts +6 -6
- package/lib/core/transform/tracker/broker/sweepAbandonedWatchProbes.d.ts +6 -6
- package/lib/core/transform/tracker/broker/sweepAbandonedWatchProbes.js +9 -7
- package/lib/core/transform/tracker/broker/sweepAbandonedWatchProbes.js.map +1 -1
- package/lib/core/transform/tracker/broker/sweepAbandonedWatchProbes.mjs +9 -7
- package/lib/core/transform/tracker/broker/sweepAbandonedWatchProbes.mjs.map +1 -1
- package/lib/core/transform/tracker/settleProjectMutationEvents.d.cts +23 -29
- package/lib/core/transform/tracker/settleProjectMutationEvents.d.mts +23 -29
- package/lib/core/transform/tracker/settleProjectMutationEvents.d.ts +23 -29
- package/lib/core/transform/tracker/settleProjectMutationEvents.js +25 -37
- package/lib/core/transform/tracker/settleProjectMutationEvents.js.map +1 -1
- package/lib/core/transform/tracker/settleProjectMutationEvents.mjs +25 -37
- package/lib/core/transform/tracker/settleProjectMutationEvents.mjs.map +1 -1
- package/lib/core/transform/tracker/verifyGenerationLocations.d.cts +41 -0
- package/lib/core/transform/tracker/verifyGenerationLocations.d.mts +41 -0
- package/lib/core/transform/tracker/verifyGenerationLocations.d.ts +41 -0
- package/lib/core/transform/tracker/verifyGenerationLocations.js +54 -0
- package/lib/core/transform/tracker/verifyGenerationLocations.js.map +1 -0
- package/lib/core/transform/tracker/verifyGenerationLocations.mjs +52 -0
- package/lib/core/transform/tracker/verifyGenerationLocations.mjs.map +1 -0
- package/lib/core/transform/utils/isZombieProcess.d.cts +26 -0
- package/lib/core/transform/utils/isZombieProcess.d.mts +26 -0
- package/lib/core/transform/utils/isZombieProcess.d.ts +26 -0
- package/lib/core/transform/utils/isZombieProcess.js +46 -0
- package/lib/core/transform/utils/isZombieProcess.js.map +1 -0
- package/lib/core/transform/utils/isZombieProcess.mjs +44 -0
- package/lib/core/transform/utils/isZombieProcess.mjs.map +1 -0
- package/lib/core/transform/validation/TtscGenerationProof.d.cts +12 -4
- package/lib/core/transform/validation/TtscGenerationProof.d.mts +12 -4
- package/lib/core/transform/validation/TtscGenerationProof.d.ts +12 -4
- package/lib/core/transform/validation/TtscGenerationProof.js +13 -4
- package/lib/core/transform/validation/TtscGenerationProof.js.map +1 -1
- package/lib/core/transform/validation/TtscGenerationProof.mjs +13 -4
- package/lib/core/transform/validation/TtscGenerationProof.mjs.map +1 -1
- package/lib/core/transform/validation/matchesCachedExternalInputs.d.cts +2 -2
- package/lib/core/transform/validation/matchesCachedExternalInputs.d.mts +2 -2
- package/lib/core/transform/validation/matchesCachedExternalInputs.d.ts +2 -2
- package/lib/core/transform/validation/matchesCachedExternalInputs.js +26 -5
- package/lib/core/transform/validation/matchesCachedExternalInputs.js.map +1 -1
- package/lib/core/transform/validation/matchesCachedExternalInputs.mjs +26 -5
- package/lib/core/transform/validation/matchesCachedExternalInputs.mjs.map +1 -1
- package/lib/core/transform/validation/matchesCompleteInputSnapshot.js +1 -1
- package/lib/core/transform/validation/matchesCompleteInputSnapshot.js.map +1 -1
- package/lib/core/transform/validation/matchesCompleteInputSnapshot.mjs +1 -1
- package/lib/core/transform/validation/matchesCompleteInputSnapshot.mjs.map +1 -1
- package/lib/core/transform/validation/matchesUniversalHostInputProbes.d.cts +15 -8
- package/lib/core/transform/validation/matchesUniversalHostInputProbes.d.mts +15 -8
- package/lib/core/transform/validation/matchesUniversalHostInputProbes.d.ts +15 -8
- package/lib/core/transform/validation/matchesUniversalHostInputProbes.js +29 -20
- package/lib/core/transform/validation/matchesUniversalHostInputProbes.js.map +1 -1
- package/lib/core/transform/validation/matchesUniversalHostInputProbes.mjs +29 -20
- package/lib/core/transform/validation/matchesUniversalHostInputProbes.mjs.map +1 -1
- package/lib/core/transform/validation/matchesUniversalHostInputs.js +1 -1
- package/lib/core/transform/validation/matchesUniversalHostInputs.js.map +1 -1
- package/lib/core/transform/validation/matchesUniversalHostInputs.mjs +1 -1
- package/lib/core/transform/validation/matchesUniversalHostInputs.mjs.map +1 -1
- package/package.json +3 -3
- package/src/core/transform/session/claimSharedCompile.ts +6 -4
- package/src/core/transform/session/openTtscTransformSession.ts +7 -3
- package/src/core/transform/tracker/broker/sweepAbandonedWatchProbes.ts +8 -7
- package/src/core/transform/tracker/settleProjectMutationEvents.ts +25 -36
- package/src/core/transform/tracker/verifyGenerationLocations.ts +53 -0
- package/src/core/transform/utils/isZombieProcess.ts +39 -0
- package/src/core/transform/validation/TtscGenerationProof.ts +20 -4
- package/src/core/transform/validation/matchesCachedExternalInputs.ts +28 -5
- package/src/core/transform/validation/matchesCompleteInputSnapshot.ts +1 -1
- package/src/core/transform/validation/matchesUniversalHostInputProbes.ts +27 -16
- package/src/core/transform/validation/matchesUniversalHostInputs.ts +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether process `pid` has exited and only waits for its parent to collect its
|
|
3
|
+
* status.
|
|
4
|
+
*
|
|
5
|
+
* Signal zero still reaches such a zombie, so a liveness probe built on it
|
|
6
|
+
* alone counts the process alive. A parent that never collects, such as a
|
|
7
|
+
* container's PID 1 that is not an init or a subreaper that collects only when
|
|
8
|
+
* its own command ends, keeps the zombie indefinitely, and the locks and
|
|
9
|
+
* directories it owned would never be reclaimed. Only Linux exposes the state,
|
|
10
|
+
* through `/proc`; elsewhere, and whenever it cannot be read, this answers
|
|
11
|
+
* `false` so the caller's existing probe decides. A leader whose own thread
|
|
12
|
+
* exited also reads as a zombie while its other threads run, so the zombie must
|
|
13
|
+
* be the process's last thread. A zombie keeps its id until collected, so this
|
|
14
|
+
* never names a live process.
|
|
15
|
+
*
|
|
16
|
+
* @param pid A positive process id that signal zero just found.
|
|
17
|
+
* @evidence contracts/common.md#principled-implementation The kernel's own process status, zombie or dead with no other thread, establishes the exit; any unreadable or other status leaves the caller's signal-zero answer standing.
|
|
18
|
+
* @evidence contracts/common.md#clear-and-simple-design One predicate serves the shared-compile lock, session-owner and watch-probe owners alike.
|
|
19
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No PID list, timeout or error-to-exited fallback substitutes for the kernel status.
|
|
20
|
+
* @evidence contracts/common.md#meaningful-documentation The paragraph explains why signal zero misses a zombie, which parents leave one behind, why a zombie leader with running threads is not one and why its id cannot name a live process.
|
|
21
|
+
* @evidence contracts/portability.md#os-neutral-implementation Only Linux exposes zombies through /proc; other platforms keep their probe's answer.
|
|
22
|
+
* @evidence contracts/performance.md#efficient-algorithms One small /proc read on Linux, nothing elsewhere.
|
|
23
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work Process state is a current observation and is never cached.
|
|
24
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The read retains no handle; the status text becomes reclaimable on return.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isZombieProcess(pid: number): boolean;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether process `pid` has exited and only waits for its parent to collect its
|
|
3
|
+
* status.
|
|
4
|
+
*
|
|
5
|
+
* Signal zero still reaches such a zombie, so a liveness probe built on it
|
|
6
|
+
* alone counts the process alive. A parent that never collects, such as a
|
|
7
|
+
* container's PID 1 that is not an init or a subreaper that collects only when
|
|
8
|
+
* its own command ends, keeps the zombie indefinitely, and the locks and
|
|
9
|
+
* directories it owned would never be reclaimed. Only Linux exposes the state,
|
|
10
|
+
* through `/proc`; elsewhere, and whenever it cannot be read, this answers
|
|
11
|
+
* `false` so the caller's existing probe decides. A leader whose own thread
|
|
12
|
+
* exited also reads as a zombie while its other threads run, so the zombie must
|
|
13
|
+
* be the process's last thread. A zombie keeps its id until collected, so this
|
|
14
|
+
* never names a live process.
|
|
15
|
+
*
|
|
16
|
+
* @param pid A positive process id that signal zero just found.
|
|
17
|
+
* @evidence contracts/common.md#principled-implementation The kernel's own process status, zombie or dead with no other thread, establishes the exit; any unreadable or other status leaves the caller's signal-zero answer standing.
|
|
18
|
+
* @evidence contracts/common.md#clear-and-simple-design One predicate serves the shared-compile lock, session-owner and watch-probe owners alike.
|
|
19
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No PID list, timeout or error-to-exited fallback substitutes for the kernel status.
|
|
20
|
+
* @evidence contracts/common.md#meaningful-documentation The paragraph explains why signal zero misses a zombie, which parents leave one behind, why a zombie leader with running threads is not one and why its id cannot name a live process.
|
|
21
|
+
* @evidence contracts/portability.md#os-neutral-implementation Only Linux exposes zombies through /proc; other platforms keep their probe's answer.
|
|
22
|
+
* @evidence contracts/performance.md#efficient-algorithms One small /proc read on Linux, nothing elsewhere.
|
|
23
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work Process state is a current observation and is never cached.
|
|
24
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The read retains no handle; the status text becomes reclaimable on return.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isZombieProcess(pid: number): boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('node:fs');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether process `pid` has exited and only waits for its parent to collect its
|
|
7
|
+
* status.
|
|
8
|
+
*
|
|
9
|
+
* Signal zero still reaches such a zombie, so a liveness probe built on it
|
|
10
|
+
* alone counts the process alive. A parent that never collects, such as a
|
|
11
|
+
* container's PID 1 that is not an init or a subreaper that collects only when
|
|
12
|
+
* its own command ends, keeps the zombie indefinitely, and the locks and
|
|
13
|
+
* directories it owned would never be reclaimed. Only Linux exposes the state,
|
|
14
|
+
* through `/proc`; elsewhere, and whenever it cannot be read, this answers
|
|
15
|
+
* `false` so the caller's existing probe decides. A leader whose own thread
|
|
16
|
+
* exited also reads as a zombie while its other threads run, so the zombie must
|
|
17
|
+
* be the process's last thread. A zombie keeps its id until collected, so this
|
|
18
|
+
* never names a live process.
|
|
19
|
+
*
|
|
20
|
+
* @param pid A positive process id that signal zero just found.
|
|
21
|
+
* @evidence contracts/common.md#principled-implementation The kernel's own process status, zombie or dead with no other thread, establishes the exit; any unreadable or other status leaves the caller's signal-zero answer standing.
|
|
22
|
+
* @evidence contracts/common.md#clear-and-simple-design One predicate serves the shared-compile lock, session-owner and watch-probe owners alike.
|
|
23
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No PID list, timeout or error-to-exited fallback substitutes for the kernel status.
|
|
24
|
+
* @evidence contracts/common.md#meaningful-documentation The paragraph explains why signal zero misses a zombie, which parents leave one behind, why a zombie leader with running threads is not one and why its id cannot name a live process.
|
|
25
|
+
* @evidence contracts/portability.md#os-neutral-implementation Only Linux exposes zombies through /proc; other platforms keep their probe's answer.
|
|
26
|
+
* @evidence contracts/performance.md#efficient-algorithms One small /proc read on Linux, nothing elsewhere.
|
|
27
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work Process state is a current observation and is never cached.
|
|
28
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The read retains no handle; the status text becomes reclaimable on return.
|
|
29
|
+
*/
|
|
30
|
+
function isZombieProcess(pid) {
|
|
31
|
+
if (process.platform !== "linux")
|
|
32
|
+
return false;
|
|
33
|
+
let status;
|
|
34
|
+
try {
|
|
35
|
+
status = fs.readFileSync(`/proc/${pid}/status`, "utf8");
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const state = /^State:\s*(\S)/m.exec(status)?.[1];
|
|
41
|
+
const threads = /^Threads:\s*(\d+)/m.exec(status)?.[1];
|
|
42
|
+
return (state === "Z" || state === "X") && threads === "1";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
exports.isZombieProcess = isZombieProcess;
|
|
46
|
+
//# sourceMappingURL=isZombieProcess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isZombieProcess.js","sources":["../../../../src/core/transform/utils/isZombieProcess.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AACG,SAAU,eAAe,CAAC,GAAW,EAAA;AACzC,IAAA,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;AAAE,QAAA,OAAO,KAAK;AAC9C,IAAA,IAAI,MAAc;AAClB,IAAA,IAAI;QACF,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,CAAA,MAAA,EAAS,GAAG,CAAA,OAAA,CAAS,EAAE,MAAM,CAAC;IACzD;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACA,IAAA,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACjD,IAAA,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACtD,IAAA,OAAO,CAAC,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,KAAK,OAAO,KAAK,GAAG;AAC5D;;;;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Whether process `pid` has exited and only waits for its parent to collect its
|
|
5
|
+
* status.
|
|
6
|
+
*
|
|
7
|
+
* Signal zero still reaches such a zombie, so a liveness probe built on it
|
|
8
|
+
* alone counts the process alive. A parent that never collects, such as a
|
|
9
|
+
* container's PID 1 that is not an init or a subreaper that collects only when
|
|
10
|
+
* its own command ends, keeps the zombie indefinitely, and the locks and
|
|
11
|
+
* directories it owned would never be reclaimed. Only Linux exposes the state,
|
|
12
|
+
* through `/proc`; elsewhere, and whenever it cannot be read, this answers
|
|
13
|
+
* `false` so the caller's existing probe decides. A leader whose own thread
|
|
14
|
+
* exited also reads as a zombie while its other threads run, so the zombie must
|
|
15
|
+
* be the process's last thread. A zombie keeps its id until collected, so this
|
|
16
|
+
* never names a live process.
|
|
17
|
+
*
|
|
18
|
+
* @param pid A positive process id that signal zero just found.
|
|
19
|
+
* @evidence contracts/common.md#principled-implementation The kernel's own process status, zombie or dead with no other thread, establishes the exit; any unreadable or other status leaves the caller's signal-zero answer standing.
|
|
20
|
+
* @evidence contracts/common.md#clear-and-simple-design One predicate serves the shared-compile lock, session-owner and watch-probe owners alike.
|
|
21
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No PID list, timeout or error-to-exited fallback substitutes for the kernel status.
|
|
22
|
+
* @evidence contracts/common.md#meaningful-documentation The paragraph explains why signal zero misses a zombie, which parents leave one behind, why a zombie leader with running threads is not one and why its id cannot name a live process.
|
|
23
|
+
* @evidence contracts/portability.md#os-neutral-implementation Only Linux exposes zombies through /proc; other platforms keep their probe's answer.
|
|
24
|
+
* @evidence contracts/performance.md#efficient-algorithms One small /proc read on Linux, nothing elsewhere.
|
|
25
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work Process state is a current observation and is never cached.
|
|
26
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The read retains no handle; the status text becomes reclaimable on return.
|
|
27
|
+
*/
|
|
28
|
+
function isZombieProcess(pid) {
|
|
29
|
+
if (process.platform !== "linux")
|
|
30
|
+
return false;
|
|
31
|
+
let status;
|
|
32
|
+
try {
|
|
33
|
+
status = fs.readFileSync(`/proc/${pid}/status`, "utf8");
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const state = /^State:\s*(\S)/m.exec(status)?.[1];
|
|
39
|
+
const threads = /^Threads:\s*(\d+)/m.exec(status)?.[1];
|
|
40
|
+
return (state === "Z" || state === "X") && threads === "1";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { isZombieProcess };
|
|
44
|
+
//# sourceMappingURL=isZombieProcess.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isZombieProcess.mjs","sources":["../../../../src/core/transform/utils/isZombieProcess.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AACG,SAAU,eAAe,CAAC,GAAW,EAAA;AACzC,IAAA,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;AAAE,QAAA,OAAO,KAAK;AAC9C,IAAA,IAAI,MAAc;AAClB,IAAA,IAAI;QACF,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,CAAA,MAAA,EAAS,GAAG,CAAA,OAAA,CAAS,EAAE,MAAM,CAAC;IACzD;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACA,IAAA,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACjD,IAAA,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACtD,IAAA,OAAO,CAAC,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,KAAK,OAAO,KAAK,GAAG;AAC5D;;;;"}
|
|
@@ -43,6 +43,12 @@ export declare namespace TtscGenerationProof {
|
|
|
43
43
|
readonly environments?: ReadonlyMap<string, string | undefined>;
|
|
44
44
|
/** Current native predicate verdict, unbuilt until its first gate. */
|
|
45
45
|
nativePredicates?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Identities this admission's location verification read, by watched
|
|
48
|
+
* directory, absent when it ran none. An identity proves its directory is
|
|
49
|
+
* one now; an absent or undefined entry proves nothing.
|
|
50
|
+
*/
|
|
51
|
+
readonly locations?: ReadonlyMap<string, string | undefined>;
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
48
54
|
* Prepare native authority only when this delivery needs a new input proof.
|
|
@@ -60,15 +66,17 @@ export declare namespace TtscGenerationProof {
|
|
|
60
66
|
function prepare(cached: TtscCachedProjectTransform, file: string, epoch: number | undefined): Promise<void>;
|
|
61
67
|
/**
|
|
62
68
|
* Start fresh synchronous observation after notification and preparation
|
|
63
|
-
* awaits, sharing actual SDK queries and native predicate replay locally.
|
|
69
|
+
* awaits, sharing actual SDK queries and native predicate replay locally. A
|
|
70
|
+
* persistent delivery also rechecks its trackers' watched directories here
|
|
71
|
+
* and keeps what that read for the validators that follow.
|
|
64
72
|
*
|
|
65
|
-
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work; a qualified pass needs no redundant native environment observation.
|
|
73
|
+
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work, and a persistent delivery's watched directories are rechecked after it; a qualified pass needs no redundant native environment observation.
|
|
66
74
|
* @evidence contracts/common.md#clear-and-simple-design One constructor binds observations to their exact generation.
|
|
67
75
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts No current verdict is retained across deliveries or asynchronous boundaries.
|
|
68
76
|
* @evidence contracts/common.md#meaningful-documentation Native prose identifies the mandatory ordering and synchronous lifetime.
|
|
69
77
|
* @evidence contracts/portability.md#os-neutral-implementation Native observation remains with the environment witness owner and actual generation path identity.
|
|
70
|
-
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries.
|
|
71
|
-
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch; pass sharing uses its independent first-delivery contract.
|
|
78
|
+
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries, and location verification reads each watched directory once.
|
|
79
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch and the location identities; pass sharing uses its independent first-delivery contract.
|
|
72
80
|
* @evidence contracts/performance.md#bound-retention-and-release-resources The caller releases the transaction at the end of synchronous admission; no registry or native handle is acquired.
|
|
73
81
|
*/
|
|
74
82
|
function create(cached: TtscCachedProjectTransform, file: string, epoch: number | undefined): Transaction;
|
|
@@ -43,6 +43,12 @@ export declare namespace TtscGenerationProof {
|
|
|
43
43
|
readonly environments?: ReadonlyMap<string, string | undefined>;
|
|
44
44
|
/** Current native predicate verdict, unbuilt until its first gate. */
|
|
45
45
|
nativePredicates?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Identities this admission's location verification read, by watched
|
|
48
|
+
* directory, absent when it ran none. An identity proves its directory is
|
|
49
|
+
* one now; an absent or undefined entry proves nothing.
|
|
50
|
+
*/
|
|
51
|
+
readonly locations?: ReadonlyMap<string, string | undefined>;
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
48
54
|
* Prepare native authority only when this delivery needs a new input proof.
|
|
@@ -60,15 +66,17 @@ export declare namespace TtscGenerationProof {
|
|
|
60
66
|
function prepare(cached: TtscCachedProjectTransform, file: string, epoch: number | undefined): Promise<void>;
|
|
61
67
|
/**
|
|
62
68
|
* Start fresh synchronous observation after notification and preparation
|
|
63
|
-
* awaits, sharing actual SDK queries and native predicate replay locally.
|
|
69
|
+
* awaits, sharing actual SDK queries and native predicate replay locally. A
|
|
70
|
+
* persistent delivery also rechecks its trackers' watched directories here
|
|
71
|
+
* and keeps what that read for the validators that follow.
|
|
64
72
|
*
|
|
65
|
-
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work; a qualified pass needs no redundant native environment observation.
|
|
73
|
+
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work, and a persistent delivery's watched directories are rechecked after it; a qualified pass needs no redundant native environment observation.
|
|
66
74
|
* @evidence contracts/common.md#clear-and-simple-design One constructor binds observations to their exact generation.
|
|
67
75
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts No current verdict is retained across deliveries or asynchronous boundaries.
|
|
68
76
|
* @evidence contracts/common.md#meaningful-documentation Native prose identifies the mandatory ordering and synchronous lifetime.
|
|
69
77
|
* @evidence contracts/portability.md#os-neutral-implementation Native observation remains with the environment witness owner and actual generation path identity.
|
|
70
|
-
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries.
|
|
71
|
-
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch; pass sharing uses its independent first-delivery contract.
|
|
78
|
+
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries, and location verification reads each watched directory once.
|
|
79
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch and the location identities; pass sharing uses its independent first-delivery contract.
|
|
72
80
|
* @evidence contracts/performance.md#bound-retention-and-release-resources The caller releases the transaction at the end of synchronous admission; no registry or native handle is acquired.
|
|
73
81
|
*/
|
|
74
82
|
function create(cached: TtscCachedProjectTransform, file: string, epoch: number | undefined): Transaction;
|
|
@@ -43,6 +43,12 @@ export declare namespace TtscGenerationProof {
|
|
|
43
43
|
readonly environments?: ReadonlyMap<string, string | undefined>;
|
|
44
44
|
/** Current native predicate verdict, unbuilt until its first gate. */
|
|
45
45
|
nativePredicates?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Identities this admission's location verification read, by watched
|
|
48
|
+
* directory, absent when it ran none. An identity proves its directory is
|
|
49
|
+
* one now; an absent or undefined entry proves nothing.
|
|
50
|
+
*/
|
|
51
|
+
readonly locations?: ReadonlyMap<string, string | undefined>;
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
48
54
|
* Prepare native authority only when this delivery needs a new input proof.
|
|
@@ -60,15 +66,17 @@ export declare namespace TtscGenerationProof {
|
|
|
60
66
|
function prepare(cached: TtscCachedProjectTransform, file: string, epoch: number | undefined): Promise<void>;
|
|
61
67
|
/**
|
|
62
68
|
* Start fresh synchronous observation after notification and preparation
|
|
63
|
-
* awaits, sharing actual SDK queries and native predicate replay locally.
|
|
69
|
+
* awaits, sharing actual SDK queries and native predicate replay locally. A
|
|
70
|
+
* persistent delivery also rechecks its trackers' watched directories here
|
|
71
|
+
* and keeps what that read for the validators that follow.
|
|
64
72
|
*
|
|
65
|
-
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work; a qualified pass needs no redundant native environment observation.
|
|
73
|
+
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work, and a persistent delivery's watched directories are rechecked after it; a qualified pass needs no redundant native environment observation.
|
|
66
74
|
* @evidence contracts/common.md#clear-and-simple-design One constructor binds observations to their exact generation.
|
|
67
75
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts No current verdict is retained across deliveries or asynchronous boundaries.
|
|
68
76
|
* @evidence contracts/common.md#meaningful-documentation Native prose identifies the mandatory ordering and synchronous lifetime.
|
|
69
77
|
* @evidence contracts/portability.md#os-neutral-implementation Native observation remains with the environment witness owner and actual generation path identity.
|
|
70
|
-
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries.
|
|
71
|
-
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch; pass sharing uses its independent first-delivery contract.
|
|
78
|
+
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries, and location verification reads each watched directory once.
|
|
79
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch and the location identities; pass sharing uses its independent first-delivery contract.
|
|
72
80
|
* @evidence contracts/performance.md#bound-retention-and-release-resources The caller releases the transaction at the end of synchronous admission; no registry or native handle is acquired.
|
|
73
81
|
*/
|
|
74
82
|
function create(cached: TtscCachedProjectTransform, file: string, epoch: number | undefined): Transaction;
|
|
@@ -9,6 +9,7 @@ var selectPluginSourceInputs = require('../envelope/selectPluginSourceInputs.js'
|
|
|
9
9
|
var pathIdentityKey = require('../filesystem/pathIdentityKey.js');
|
|
10
10
|
var preparePluginBuildEnvironments = require('../inputs/preparePluginBuildEnvironments.js');
|
|
11
11
|
var toProjectKey = require('../project/toProjectKey.js');
|
|
12
|
+
var verifyGenerationLocations = require('../tracker/verifyGenerationLocations.js');
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* The shared ownership boundary for generation reuse in every adapter.
|
|
@@ -53,20 +54,28 @@ exports.TtscGenerationProof = void 0;
|
|
|
53
54
|
TtscGenerationProof.prepare = prepare;
|
|
54
55
|
/**
|
|
55
56
|
* Start fresh synchronous observation after notification and preparation
|
|
56
|
-
* awaits, sharing actual SDK queries and native predicate replay locally.
|
|
57
|
+
* awaits, sharing actual SDK queries and native predicate replay locally. A
|
|
58
|
+
* persistent delivery also rechecks its trackers' watched directories here
|
|
59
|
+
* and keeps what that read for the validators that follow.
|
|
57
60
|
*
|
|
58
|
-
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work; a qualified pass needs no redundant native environment observation.
|
|
61
|
+
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work, and a persistent delivery's watched directories are rechecked after it; a qualified pass needs no redundant native environment observation.
|
|
59
62
|
* @evidence contracts/common.md#clear-and-simple-design One constructor binds observations to their exact generation.
|
|
60
63
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts No current verdict is retained across deliveries or asynchronous boundaries.
|
|
61
64
|
* @evidence contracts/common.md#meaningful-documentation Native prose identifies the mandatory ordering and synchronous lifetime.
|
|
62
65
|
* @evidence contracts/portability.md#os-neutral-implementation Native observation remains with the environment witness owner and actual generation path identity.
|
|
63
|
-
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries.
|
|
64
|
-
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch; pass sharing uses its independent first-delivery contract.
|
|
66
|
+
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries, and location verification reads each watched directory once.
|
|
67
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch and the location identities; pass sharing uses its independent first-delivery contract.
|
|
65
68
|
* @evidence contracts/performance.md#bound-retention-and-release-resources The caller releases the transaction at the end of synchronous admission; no registry or native handle is acquired.
|
|
66
69
|
*/
|
|
67
70
|
function create(cached, file, epoch) {
|
|
68
71
|
return {
|
|
69
72
|
cached,
|
|
73
|
+
// A persistent delivery rechecks its watched directories here, after
|
|
74
|
+
// its last await, so a directory replaced while it prepared withdraws
|
|
75
|
+
// its tracker before admission reads it.
|
|
76
|
+
...(epoch === undefined
|
|
77
|
+
? { locations: verifyGenerationLocations.verifyGenerationLocations(cached) }
|
|
78
|
+
: {}),
|
|
70
79
|
...(sharesPass(cached, file, epoch)
|
|
71
80
|
? {}
|
|
72
81
|
: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtscGenerationProof.js","sources":["../../../../src/core/transform/validation/TtscGenerationProof.ts"],"sourcesContent":[null],"names":["TtscGenerationProof","preparePluginBuildEnvironments","resultFilesystem","PluginBuildEnvironmentReadings","selectPluginSourceInputs","envelopeDerivation","pathIdentityKey","toProjectKey","disposeCachedTransform","evictGeneration"],"mappings":"
|
|
1
|
+
{"version":3,"file":"TtscGenerationProof.js","sources":["../../../../src/core/transform/validation/TtscGenerationProof.ts"],"sourcesContent":[null],"names":["TtscGenerationProof","preparePluginBuildEnvironments","resultFilesystem","verifyGenerationLocations","PluginBuildEnvironmentReadings","selectPluginSourceInputs","envelopeDerivation","pathIdentityKey","toProjectKey","disposeCachedTransform","evictGeneration"],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ import { selectPluginSourceInputs } from '../envelope/selectPluginSourceInputs.m
|
|
|
7
7
|
import { pathIdentityKey } from '../filesystem/pathIdentityKey.mjs';
|
|
8
8
|
import { preparePluginBuildEnvironments } from '../inputs/preparePluginBuildEnvironments.mjs';
|
|
9
9
|
import { toProjectKey } from '../project/toProjectKey.mjs';
|
|
10
|
+
import { verifyGenerationLocations } from '../tracker/verifyGenerationLocations.mjs';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* The shared ownership boundary for generation reuse in every adapter.
|
|
@@ -51,20 +52,28 @@ var TtscGenerationProof;
|
|
|
51
52
|
TtscGenerationProof.prepare = prepare;
|
|
52
53
|
/**
|
|
53
54
|
* Start fresh synchronous observation after notification and preparation
|
|
54
|
-
* awaits, sharing actual SDK queries and native predicate replay locally.
|
|
55
|
+
* awaits, sharing actual SDK queries and native predicate replay locally. A
|
|
56
|
+
* persistent delivery also rechecks its trackers' watched directories here
|
|
57
|
+
* and keeps what that read for the validators that follow.
|
|
55
58
|
*
|
|
56
|
-
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work; a qualified pass needs no redundant native environment observation.
|
|
59
|
+
* @evidence contracts/common.md#principled-implementation Current environments are batch-qualified after asynchronous work, and a persistent delivery's watched directories are rechecked after it; a qualified pass needs no redundant native environment observation.
|
|
57
60
|
* @evidence contracts/common.md#clear-and-simple-design One constructor binds observations to their exact generation.
|
|
58
61
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts No current verdict is retained across deliveries or asynchronous boundaries.
|
|
59
62
|
* @evidence contracts/common.md#meaningful-documentation Native prose identifies the mandatory ordering and synchronous lifetime.
|
|
60
63
|
* @evidence contracts/portability.md#os-neutral-implementation Native observation remains with the environment witness owner and actual generation path identity.
|
|
61
|
-
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries.
|
|
62
|
-
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch; pass sharing uses its independent first-delivery contract.
|
|
64
|
+
* @evidence contracts/performance.md#efficient-algorithms Plugin selection is generation-indexed; one batch shares variable hashing and distinct SDK metadata queries, and location verification reads each watched directory once.
|
|
65
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Only the following synchronous validators borrow this batch and the location identities; pass sharing uses its independent first-delivery contract.
|
|
63
66
|
* @evidence contracts/performance.md#bound-retention-and-release-resources The caller releases the transaction at the end of synchronous admission; no registry or native handle is acquired.
|
|
64
67
|
*/
|
|
65
68
|
function create(cached, file, epoch) {
|
|
66
69
|
return {
|
|
67
70
|
cached,
|
|
71
|
+
// A persistent delivery rechecks its watched directories here, after
|
|
72
|
+
// its last await, so a directory replaced while it prepared withdraws
|
|
73
|
+
// its tracker before admission reads it.
|
|
74
|
+
...(epoch === undefined
|
|
75
|
+
? { locations: verifyGenerationLocations(cached) }
|
|
76
|
+
: {}),
|
|
68
77
|
...(sharesPass(cached, file, epoch)
|
|
69
78
|
? {}
|
|
70
79
|
: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtscGenerationProof.mjs","sources":["../../../../src/core/transform/validation/TtscGenerationProof.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TtscGenerationProof.mjs","sources":["../../../../src/core/transform/validation/TtscGenerationProof.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import type { TtscCachedProjectTransform } from "../cache/TtscCachedProjectTrans
|
|
|
8
8
|
* The caller adopts those signatures only once every input is proven unchanged,
|
|
9
9
|
* so a signature never outlives the content comparison that justified it.
|
|
10
10
|
*
|
|
11
|
-
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec; only stable separable metadata can replace that comparison, so aliases cannot answer for one another.
|
|
11
|
+
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec and resolves its own physical file; only stable separable metadata can replace that comparison, so aliases cannot answer for one another. Spellings resolving to one physical file now share that file's content read, which the codecs hash by content alone.
|
|
12
12
|
* @evidence contracts/common.md#clear-and-simple-design One pass returns the aggregate verdict and earned signatures, leaving all-or-nothing adoption to its caller.
|
|
13
13
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Recorded missing states and absent hash keys remain distinct from successful content proof; newer reads do not rewrite the authoritative recorded hashes.
|
|
14
14
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs distinguish mixed codecs, clock-qualified reuse and caller-owned signature adoption before tags.
|
|
@@ -22,7 +22,7 @@ import type { TtscCachedProjectTransform } from "../cache/TtscCachedProjectTrans
|
|
|
22
22
|
* failures/listings, then recaptures metadata for earned signatures.
|
|
23
23
|
* Earned signature storage grows with successful observed spellings; legacy
|
|
24
24
|
* fallback also materializes the recorded hash key array.
|
|
25
|
-
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, and adopted signatures come only from a completely successful caller verdict.
|
|
25
|
+
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, read once per codec and physical file in this pass, and adopted signatures come only from a completely successful caller verdict.
|
|
26
26
|
*/
|
|
27
27
|
export declare function matchesCachedExternalInputs(
|
|
28
28
|
/** Generation recording lexical inputs, distinct codecs and earned signatures. */
|
|
@@ -8,7 +8,7 @@ import type { TtscCachedProjectTransform } from "../cache/TtscCachedProjectTrans
|
|
|
8
8
|
* The caller adopts those signatures only once every input is proven unchanged,
|
|
9
9
|
* so a signature never outlives the content comparison that justified it.
|
|
10
10
|
*
|
|
11
|
-
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec; only stable separable metadata can replace that comparison, so aliases cannot answer for one another.
|
|
11
|
+
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec and resolves its own physical file; only stable separable metadata can replace that comparison, so aliases cannot answer for one another. Spellings resolving to one physical file now share that file's content read, which the codecs hash by content alone.
|
|
12
12
|
* @evidence contracts/common.md#clear-and-simple-design One pass returns the aggregate verdict and earned signatures, leaving all-or-nothing adoption to its caller.
|
|
13
13
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Recorded missing states and absent hash keys remain distinct from successful content proof; newer reads do not rewrite the authoritative recorded hashes.
|
|
14
14
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs distinguish mixed codecs, clock-qualified reuse and caller-owned signature adoption before tags.
|
|
@@ -22,7 +22,7 @@ import type { TtscCachedProjectTransform } from "../cache/TtscCachedProjectTrans
|
|
|
22
22
|
* failures/listings, then recaptures metadata for earned signatures.
|
|
23
23
|
* Earned signature storage grows with successful observed spellings; legacy
|
|
24
24
|
* fallback also materializes the recorded hash key array.
|
|
25
|
-
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, and adopted signatures come only from a completely successful caller verdict.
|
|
25
|
+
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, read once per codec and physical file in this pass, and adopted signatures come only from a completely successful caller verdict.
|
|
26
26
|
*/
|
|
27
27
|
export declare function matchesCachedExternalInputs(
|
|
28
28
|
/** Generation recording lexical inputs, distinct codecs and earned signatures. */
|
|
@@ -8,7 +8,7 @@ import type { TtscCachedProjectTransform } from "../cache/TtscCachedProjectTrans
|
|
|
8
8
|
* The caller adopts those signatures only once every input is proven unchanged,
|
|
9
9
|
* so a signature never outlives the content comparison that justified it.
|
|
10
10
|
*
|
|
11
|
-
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec; only stable separable metadata can replace that comparison, so aliases cannot answer for one another.
|
|
11
|
+
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec and resolves its own physical file; only stable separable metadata can replace that comparison, so aliases cannot answer for one another. Spellings resolving to one physical file now share that file's content read, which the codecs hash by content alone.
|
|
12
12
|
* @evidence contracts/common.md#clear-and-simple-design One pass returns the aggregate verdict and earned signatures, leaving all-or-nothing adoption to its caller.
|
|
13
13
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Recorded missing states and absent hash keys remain distinct from successful content proof; newer reads do not rewrite the authoritative recorded hashes.
|
|
14
14
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs distinguish mixed codecs, clock-qualified reuse and caller-owned signature adoption before tags.
|
|
@@ -22,7 +22,7 @@ import type { TtscCachedProjectTransform } from "../cache/TtscCachedProjectTrans
|
|
|
22
22
|
* failures/listings, then recaptures metadata for earned signatures.
|
|
23
23
|
* Earned signature storage grows with successful observed spellings; legacy
|
|
24
24
|
* fallback also materializes the recorded hash key array.
|
|
25
|
-
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, and adopted signatures come only from a completely successful caller verdict.
|
|
25
|
+
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, read once per codec and physical file in this pass, and adopted signatures come only from a completely successful caller verdict.
|
|
26
26
|
*/
|
|
27
27
|
export declare function matchesCachedExternalInputs(
|
|
28
28
|
/** Generation recording lexical inputs, distinct codecs and earned signatures. */
|
|
@@ -5,6 +5,7 @@ var resultFilesystem = require('../cache/resultFilesystem.js');
|
|
|
5
5
|
var derivationIdentity = require('../envelope/derivationIdentity.js');
|
|
6
6
|
var envelopeDerivation = require('../envelope/envelopeDerivation.js');
|
|
7
7
|
var graphInputStateHash = require('../inputs/graphInputStateHash.js');
|
|
8
|
+
var hostInputRealpath = require('../inputs/hostInputRealpath.js');
|
|
8
9
|
var hostInputStateHash = require('../inputs/hostInputStateHash.js');
|
|
9
10
|
var inputMetadataEvidence = require('../inputs/inputMetadataEvidence.js');
|
|
10
11
|
var inputMetadataSignature = require('../inputs/inputMetadataSignature.js');
|
|
@@ -20,7 +21,7 @@ var MISSING_INPUT_STATE = require('./MISSING_INPUT_STATE.js');
|
|
|
20
21
|
* The caller adopts those signatures only once every input is proven unchanged,
|
|
21
22
|
* so a signature never outlives the content comparison that justified it.
|
|
22
23
|
*
|
|
23
|
-
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec; only stable separable metadata can replace that comparison, so aliases cannot answer for one another.
|
|
24
|
+
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec and resolves its own physical file; only stable separable metadata can replace that comparison, so aliases cannot answer for one another. Spellings resolving to one physical file now share that file's content read, which the codecs hash by content alone.
|
|
24
25
|
* @evidence contracts/common.md#clear-and-simple-design One pass returns the aggregate verdict and earned signatures, leaving all-or-nothing adoption to its caller.
|
|
25
26
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Recorded missing states and absent hash keys remain distinct from successful content proof; newer reads do not rewrite the authoritative recorded hashes.
|
|
26
27
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs distinguish mixed codecs, clock-qualified reuse and caller-owned signature adoption before tags.
|
|
@@ -34,7 +35,7 @@ var MISSING_INPUT_STATE = require('./MISSING_INPUT_STATE.js');
|
|
|
34
35
|
* failures/listings, then recaptures metadata for earned signatures.
|
|
35
36
|
* Earned signature storage grows with successful observed spellings; legacy
|
|
36
37
|
* fallback also materializes the recorded hash key array.
|
|
37
|
-
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, and adopted signatures come only from a completely successful caller verdict.
|
|
38
|
+
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, read once per codec and physical file in this pass, and adopted signatures come only from a completely successful caller verdict.
|
|
38
39
|
*/
|
|
39
40
|
function matchesCachedExternalInputs(
|
|
40
41
|
/** Generation recording lexical inputs, distinct codecs and earned signatures. */
|
|
@@ -46,6 +47,8 @@ cached) {
|
|
|
46
47
|
const filesystem = resultFilesystem.resultFilesystem(cached.result);
|
|
47
48
|
const recordedHashes = cached.externalInputHashes ?? {};
|
|
48
49
|
const recordedSignatures = cached.externalInputSignatures ?? {};
|
|
50
|
+
// Content hashes this pass read, by codec and current physical file.
|
|
51
|
+
const sharedReads = new Map();
|
|
49
52
|
// Compare each spelling against the recorded state under its own name. Two
|
|
50
53
|
// spellings share one identity exactly when they selected one physical file
|
|
51
54
|
// at generation time, which is the state a retarget ends, so neither may
|
|
@@ -87,9 +90,27 @@ cached) {
|
|
|
87
90
|
before.signature === recordedSignatures[spelling]) {
|
|
88
91
|
continue;
|
|
89
92
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
// Each spelling resolves on its own and the first one resolving to a
|
|
94
|
+
// physical file reads it through its own spelling, as the filesystem view
|
|
95
|
+
// answers; a later spelling resolving to that file now reuses the read,
|
|
96
|
+
// since the codecs hash content alone. A metadata-only change otherwise
|
|
97
|
+
// read an alias and its target twice in one delivery.
|
|
98
|
+
const graph = Object.prototype.hasOwnProperty.call(graphRealpaths, identity);
|
|
99
|
+
const physical = hostInputRealpath.hostInputRealpath(file, filesystem);
|
|
100
|
+
const shared = physical === null
|
|
101
|
+
? undefined
|
|
102
|
+
: `${graph ? "graph" : "host"}\0${physical}`;
|
|
103
|
+
let hash;
|
|
104
|
+
if (shared !== undefined && sharedReads.has(shared)) {
|
|
105
|
+
hash = sharedReads.get(shared);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
hash = graph
|
|
109
|
+
? graphInputStateHash.graphInputStateHash(file, filesystem)
|
|
110
|
+
: hostInputStateHash.hostInputStateHash(file, filesystem);
|
|
111
|
+
if (shared !== undefined)
|
|
112
|
+
sharedReads.set(shared, hash);
|
|
113
|
+
}
|
|
93
114
|
const after = inputMetadataSignature.inputMetadataSignature(file, filesystem);
|
|
94
115
|
if (!Object.prototype.hasOwnProperty.call(recordedHashes, identity) ||
|
|
95
116
|
recordedHashes[identity] !== (hash ?? MISSING_INPUT_STATE.MISSING_INPUT_STATE)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchesCachedExternalInputs.js","sources":["../../../../src/core/transform/validation/matchesCachedExternalInputs.ts"],"sourcesContent":[null],"names":["envelopeDerivation","resultFilesystem","derivationIdentity","inputMetadataEvidence","matchesGraphInputObservation","inputMetadataSignature","graphInputStateHash","hostInputStateHash","MISSING_INPUT_STATE"],"mappings":"
|
|
1
|
+
{"version":3,"file":"matchesCachedExternalInputs.js","sources":["../../../../src/core/transform/validation/matchesCachedExternalInputs.ts"],"sourcesContent":[null],"names":["envelopeDerivation","resultFilesystem","derivationIdentity","inputMetadataEvidence","matchesGraphInputObservation","inputMetadataSignature","hostInputRealpath","graphInputStateHash","hostInputStateHash","MISSING_INPUT_STATE"],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { resultFilesystem } from '../cache/resultFilesystem.mjs';
|
|
|
3
3
|
import { derivationIdentity } from '../envelope/derivationIdentity.mjs';
|
|
4
4
|
import { envelopeDerivation } from '../envelope/envelopeDerivation.mjs';
|
|
5
5
|
import { graphInputStateHash } from '../inputs/graphInputStateHash.mjs';
|
|
6
|
+
import { hostInputRealpath } from '../inputs/hostInputRealpath.mjs';
|
|
6
7
|
import { hostInputStateHash } from '../inputs/hostInputStateHash.mjs';
|
|
7
8
|
import { inputMetadataEvidence } from '../inputs/inputMetadataEvidence.mjs';
|
|
8
9
|
import { inputMetadataSignature } from '../inputs/inputMetadataSignature.mjs';
|
|
@@ -18,7 +19,7 @@ import { MISSING_INPUT_STATE } from './MISSING_INPUT_STATE.mjs';
|
|
|
18
19
|
* The caller adopts those signatures only once every input is proven unchanged,
|
|
19
20
|
* so a signature never outlives the content comparison that justified it.
|
|
20
21
|
*
|
|
21
|
-
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec; only stable separable metadata can replace that comparison, so aliases cannot answer for one another.
|
|
22
|
+
* @evidence contracts/common.md#principled-implementation Each lexical spelling replays its predicates or owning content codec and resolves its own physical file; only stable separable metadata can replace that comparison, so aliases cannot answer for one another. Spellings resolving to one physical file now share that file's content read, which the codecs hash by content alone.
|
|
22
23
|
* @evidence contracts/common.md#clear-and-simple-design One pass returns the aggregate verdict and earned signatures, leaving all-or-nothing adoption to its caller.
|
|
23
24
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Recorded missing states and absent hash keys remain distinct from successful content proof; newer reads do not rewrite the authoritative recorded hashes.
|
|
24
25
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs distinguish mixed codecs, clock-qualified reuse and caller-owned signature adoption before tags.
|
|
@@ -32,7 +33,7 @@ import { MISSING_INPUT_STATE } from './MISSING_INPUT_STATE.mjs';
|
|
|
32
33
|
* failures/listings, then recaptures metadata for earned signatures.
|
|
33
34
|
* Earned signature storage grows with successful observed spellings; legacy
|
|
34
35
|
* fallback also materializes the recorded hash key array.
|
|
35
|
-
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, and adopted signatures come only from a completely successful caller verdict.
|
|
36
|
+
* @evidence contracts/performance.md#reuse-equivalent-work The generation's unchanged separable signatures share prior content validation; changed metadata or clock ordering requires replay, read once per codec and physical file in this pass, and adopted signatures come only from a completely successful caller verdict.
|
|
36
37
|
*/
|
|
37
38
|
function matchesCachedExternalInputs(
|
|
38
39
|
/** Generation recording lexical inputs, distinct codecs and earned signatures. */
|
|
@@ -44,6 +45,8 @@ cached) {
|
|
|
44
45
|
const filesystem = resultFilesystem(cached.result);
|
|
45
46
|
const recordedHashes = cached.externalInputHashes ?? {};
|
|
46
47
|
const recordedSignatures = cached.externalInputSignatures ?? {};
|
|
48
|
+
// Content hashes this pass read, by codec and current physical file.
|
|
49
|
+
const sharedReads = new Map();
|
|
47
50
|
// Compare each spelling against the recorded state under its own name. Two
|
|
48
51
|
// spellings share one identity exactly when they selected one physical file
|
|
49
52
|
// at generation time, which is the state a retarget ends, so neither may
|
|
@@ -85,9 +88,27 @@ cached) {
|
|
|
85
88
|
before.signature === recordedSignatures[spelling]) {
|
|
86
89
|
continue;
|
|
87
90
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
// Each spelling resolves on its own and the first one resolving to a
|
|
92
|
+
// physical file reads it through its own spelling, as the filesystem view
|
|
93
|
+
// answers; a later spelling resolving to that file now reuses the read,
|
|
94
|
+
// since the codecs hash content alone. A metadata-only change otherwise
|
|
95
|
+
// read an alias and its target twice in one delivery.
|
|
96
|
+
const graph = Object.prototype.hasOwnProperty.call(graphRealpaths, identity);
|
|
97
|
+
const physical = hostInputRealpath(file, filesystem);
|
|
98
|
+
const shared = physical === null
|
|
99
|
+
? undefined
|
|
100
|
+
: `${graph ? "graph" : "host"}\0${physical}`;
|
|
101
|
+
let hash;
|
|
102
|
+
if (shared !== undefined && sharedReads.has(shared)) {
|
|
103
|
+
hash = sharedReads.get(shared);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
hash = graph
|
|
107
|
+
? graphInputStateHash(file, filesystem)
|
|
108
|
+
: hostInputStateHash(file, filesystem);
|
|
109
|
+
if (shared !== undefined)
|
|
110
|
+
sharedReads.set(shared, hash);
|
|
111
|
+
}
|
|
91
112
|
const after = inputMetadataSignature(file, filesystem);
|
|
92
113
|
if (!Object.prototype.hasOwnProperty.call(recordedHashes, identity) ||
|
|
93
114
|
recordedHashes[identity] !== (hash ?? MISSING_INPUT_STATE)) {
|