@lmzhen/dsh-evolution-core 0.30.43 → 0.31.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.
- package/lib/index.js +16 -8
- package/lib/types/instance-scope.d.ts +6 -4
- package/lib/types/instance-scope.js +6 -4
- package/lib/types/platform-services.d.ts +1 -1
- package/lib/types/platform-services.js +2 -1
- package/lib/types/run-registry.js +2 -1
- package/lib/types/serial.d.ts +4 -3
- package/lib/types/serial.js +4 -3
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -5905,9 +5905,10 @@ function buildLearnPrompt(userRequest) {
|
|
|
5905
5905
|
/**
|
|
5906
5906
|
* A process-local serial task queue: each task starts only after the previous
|
|
5907
5907
|
* one settles (success or failure), so read-modify-write sequences that share
|
|
5908
|
-
* one file never interleave inside this process.
|
|
5909
|
-
*
|
|
5910
|
-
*
|
|
5908
|
+
* one file never interleave inside this process. When the IO backend provides
|
|
5909
|
+
* a cross-process transact lock, that is the first layer; the node backend does
|
|
5910
|
+
* not, so this chain is its only serialization. (0.3.17 S2.8, T-1: the shape was
|
|
5911
|
+
* duplicated in state-json and
|
|
5911
5912
|
* memory-files — one factory now).
|
|
5912
5913
|
*/
|
|
5913
5914
|
function makeSerialQueue() {
|
|
@@ -9078,7 +9079,7 @@ function renderLongRunTable() {
|
|
|
9078
9079
|
* `client` probes run in the browser half, where the host has no view of the seats.
|
|
9079
9080
|
* @module @lmzhen/dsh-evolution-core
|
|
9080
9081
|
*/
|
|
9081
|
-
/** The
|
|
9082
|
+
/** The 30 probes, in service-name order (the guard checks this list against the tree). */
|
|
9082
9083
|
const PLATFORM_SERVICE_PROBES = Object.freeze([
|
|
9083
9084
|
{
|
|
9084
9085
|
service: "agentDefaultModel",
|
|
@@ -9224,6 +9225,11 @@ const PLATFORM_SERVICE_PROBES = Object.freeze([
|
|
|
9224
9225
|
service: "tools",
|
|
9225
9226
|
feature: "tool registration and the guard seam",
|
|
9226
9227
|
side: "host"
|
|
9228
|
+
},
|
|
9229
|
+
{
|
|
9230
|
+
service: "workingDirectory",
|
|
9231
|
+
feature: "the cwd used for skill snapshots and per-view policy files",
|
|
9232
|
+
side: "host"
|
|
9227
9233
|
}
|
|
9228
9234
|
]);
|
|
9229
9235
|
/**
|
|
@@ -9242,8 +9248,9 @@ function absentHostServices(has) {
|
|
|
9242
9248
|
* B3 / G4 (0.3.78): the family's single-instance contract, made explicit.
|
|
9243
9249
|
*
|
|
9244
9250
|
* Every persisted sidecar is written under TWO assumptions: the IO backend's
|
|
9245
|
-
*
|
|
9246
|
-
*
|
|
9251
|
+
* transact serializes different processes when the provider guarantees it (the
|
|
9252
|
+
* node backend is process-local only), and exactly ONE instance of each writer
|
|
9253
|
+
* service exists per evolution home. The second half
|
|
9247
9254
|
* was implicit — `makeSerialQueue()` and the module-scope stores are
|
|
9248
9255
|
* per-instance, so two rows writing one home interleave inside one file (the
|
|
9249
9256
|
* "two instances, one file" class). This module makes that half enforceable: a
|
|
@@ -9260,8 +9267,9 @@ function absentHostServices(has) {
|
|
|
9260
9267
|
* `claims` below is a module-scope Map: two ROWS over one home in ONE process
|
|
9261
9268
|
* contend, while the SAME home in another process gets its own Map and is
|
|
9262
9269
|
* granted the key. That is by construction, not a gap to close here — the
|
|
9263
|
-
* cross-process half of the contract is the IO backend's
|
|
9264
|
-
* (`transactIo`, core/io.ts)
|
|
9270
|
+
* cross-process half of the contract is the IO backend's transact
|
|
9271
|
+
* (`transactIo`, core/io.ts) when the provider guarantees it; the node backend
|
|
9272
|
+
* is process-local, so a shared home across processes is not protected by it alone.
|
|
9265
9273
|
* The FLOW2-1 finding was three call sites reading a GRANTED claim as "no other
|
|
9266
9274
|
* process can be doing this work", so the caller contract is stated here:
|
|
9267
9275
|
* - granted means "no other row OF THIS PROCESS owns the key";
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* B3 / G4 (0.3.78): the family's single-instance contract, made explicit.
|
|
3
3
|
*
|
|
4
4
|
* Every persisted sidecar is written under TWO assumptions: the IO backend's
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* transact serializes different processes when the provider guarantees it (the
|
|
6
|
+
* node backend is process-local only), and exactly ONE instance of each writer
|
|
7
|
+
* service exists per evolution home. The second half
|
|
7
8
|
* was implicit — `makeSerialQueue()` and the module-scope stores are
|
|
8
9
|
* per-instance, so two rows writing one home interleave inside one file (the
|
|
9
10
|
* "two instances, one file" class). This module makes that half enforceable: a
|
|
@@ -20,8 +21,9 @@
|
|
|
20
21
|
* `claims` below is a module-scope Map: two ROWS over one home in ONE process
|
|
21
22
|
* contend, while the SAME home in another process gets its own Map and is
|
|
22
23
|
* granted the key. That is by construction, not a gap to close here — the
|
|
23
|
-
* cross-process half of the contract is the IO backend's
|
|
24
|
-
* (`transactIo`, core/io.ts)
|
|
24
|
+
* cross-process half of the contract is the IO backend's transact
|
|
25
|
+
* (`transactIo`, core/io.ts) when the provider guarantees it; the node backend
|
|
26
|
+
* is process-local, so a shared home across processes is not protected by it alone.
|
|
25
27
|
* The FLOW2-1 finding was three call sites reading a GRANTED claim as "no other
|
|
26
28
|
* process can be doing this work", so the caller contract is stated here:
|
|
27
29
|
* - granted means "no other row OF THIS PROCESS owns the key";
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* B3 / G4 (0.3.78): the family's single-instance contract, made explicit.
|
|
3
3
|
*
|
|
4
4
|
* Every persisted sidecar is written under TWO assumptions: the IO backend's
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* transact serializes different processes when the provider guarantees it (the
|
|
6
|
+
* node backend is process-local only), and exactly ONE instance of each writer
|
|
7
|
+
* service exists per evolution home. The second half
|
|
7
8
|
* was implicit — `makeSerialQueue()` and the module-scope stores are
|
|
8
9
|
* per-instance, so two rows writing one home interleave inside one file (the
|
|
9
10
|
* "two instances, one file" class). This module makes that half enforceable: a
|
|
@@ -20,8 +21,9 @@
|
|
|
20
21
|
* `claims` below is a module-scope Map: two ROWS over one home in ONE process
|
|
21
22
|
* contend, while the SAME home in another process gets its own Map and is
|
|
22
23
|
* granted the key. That is by construction, not a gap to close here — the
|
|
23
|
-
* cross-process half of the contract is the IO backend's
|
|
24
|
-
* (`transactIo`, core/io.ts)
|
|
24
|
+
* cross-process half of the contract is the IO backend's transact
|
|
25
|
+
* (`transactIo`, core/io.ts) when the provider guarantees it; the node backend
|
|
26
|
+
* is process-local, so a shared home across processes is not protected by it alone.
|
|
25
27
|
* The FLOW2-1 finding was three call sites reading a GRANTED claim as "no other
|
|
26
28
|
* process can be doing this work", so the caller contract is stated here:
|
|
27
29
|
* - granted means "no other row OF THIS PROCESS owns the key";
|
|
@@ -20,7 +20,7 @@ export interface PlatformServiceProbe {
|
|
|
20
20
|
/** Where the probe runs. */
|
|
21
21
|
readonly side: 'host' | 'client';
|
|
22
22
|
}
|
|
23
|
-
/** The
|
|
23
|
+
/** The 30 probes, in service-name order (the guard checks this list against the tree). */
|
|
24
24
|
export declare const PLATFORM_SERVICE_PROBES: readonly PlatformServiceProbe[];
|
|
25
25
|
/**
|
|
26
26
|
* The HOST-side probes that do not resolve in this runtime — what `/evolution doctor` prints as
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* `client` probes run in the browser half, where the host has no view of the seats.
|
|
12
12
|
* @module @lmzhen/dsh-evolution-core
|
|
13
13
|
*/
|
|
14
|
-
/** The
|
|
14
|
+
/** The 30 probes, in service-name order (the guard checks this list against the tree). */
|
|
15
15
|
export const PLATFORM_SERVICE_PROBES = Object.freeze([
|
|
16
16
|
{ service: 'agentDefaultModel', feature: 'the model route inherited by a plugin review branch', side: 'host' },
|
|
17
17
|
{ service: 'agentPresets', feature: 'the preset mount that gives a plugin review branch its tools/system', side: 'host' },
|
|
@@ -42,6 +42,7 @@ export const PLATFORM_SERVICE_PROBES = Object.freeze([
|
|
|
42
42
|
{ service: 'storageDomain', feature: 'the storage-domain state provider', side: 'host' },
|
|
43
43
|
{ service: 'systemPrompt', feature: 'the protected-skills prompt variable', side: 'host' },
|
|
44
44
|
{ service: 'tools', feature: 'tool registration and the guard seam', side: 'host' },
|
|
45
|
+
{ service: 'workingDirectory', feature: 'the cwd used for skill snapshots and per-view policy files', side: 'host' },
|
|
45
46
|
]);
|
|
46
47
|
/**
|
|
47
48
|
* The HOST-side probes that do not resolve in this runtime — what `/evolution doctor` prints as
|
|
@@ -185,7 +185,8 @@ export function newRunRegistry(options) {
|
|
|
185
185
|
};
|
|
186
186
|
const persist = async () => {
|
|
187
187
|
try {
|
|
188
|
-
// Read-modify-write under
|
|
188
|
+
// Read-modify-write under io.transact when the backend provides it; the node
|
|
189
|
+
// backend serializes in-process only. The file is the
|
|
189
190
|
// BASE and only THIS process's rows are laid over it ("one writer per row"); the
|
|
190
191
|
// single write a non-owner may make is the orphan verdict for a row whose owner is
|
|
191
192
|
// gone. The row read inside this transaction IS the compare-and-swap: if its owner
|
package/lib/types/serial.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A process-local serial task queue: each task starts only after the previous
|
|
3
3
|
* one settles (success or failure), so read-modify-write sequences that share
|
|
4
|
-
* one file never interleave inside this process.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* one file never interleave inside this process. When the IO backend provides
|
|
5
|
+
* a cross-process transact lock, that is the first layer; the node backend does
|
|
6
|
+
* not, so this chain is its only serialization. (0.3.17 S2.8, T-1: the shape was
|
|
7
|
+
* duplicated in state-json and
|
|
7
8
|
* memory-files — one factory now).
|
|
8
9
|
*/
|
|
9
10
|
export declare function makeSerialQueue(): <T>(task: () => Promise<T>) => Promise<T>;
|
package/lib/types/serial.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A process-local serial task queue: each task starts only after the previous
|
|
3
3
|
* one settles (success or failure), so read-modify-write sequences that share
|
|
4
|
-
* one file never interleave inside this process.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* one file never interleave inside this process. When the IO backend provides
|
|
5
|
+
* a cross-process transact lock, that is the first layer; the node backend does
|
|
6
|
+
* not, so this chain is its only serialization. (0.3.17 S2.8, T-1: the shape was
|
|
7
|
+
* duplicated in state-json and
|
|
7
8
|
* memory-files — one factory now).
|
|
8
9
|
*/
|
|
9
10
|
export function makeSerialQueue() {
|
package/package.json
CHANGED