@lmzhen/dsh-evolution-approval 0.3.79 → 0.3.81
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 +36 -0
- package/lib/types/index.d.ts +20 -0
- package/package.json +5 -5
package/lib/index.js
CHANGED
|
@@ -134,6 +134,42 @@ var EvolutionApproval = class extends Service {
|
|
|
134
134
|
async approve(id) {
|
|
135
135
|
return await this.dedupe(`approve:${id}`, () => this.doApprove(id));
|
|
136
136
|
}
|
|
137
|
+
/** S2-P2-22 (0.3.80): return an ORPHANED executing record to the pending
|
|
138
|
+
* window. "Orphaned" = status `executing` with no approve running in THIS
|
|
139
|
+
* process (the family single-instance claim rules out any other live
|
|
140
|
+
* process, so a claim that is not in this service's in-flight dedupe map
|
|
141
|
+
* belongs to a dead one). The stored `claimedBy` rides along as the seam's
|
|
142
|
+
* release credential, so no state-seam expansion is needed. The operator is
|
|
143
|
+
* expected to verify the effect first: re-approving replays the write
|
|
144
|
+
* deliberately (duplicates possible if the effect already landed);
|
|
145
|
+
* rejecting closes the record. */
|
|
146
|
+
async release(id) {
|
|
147
|
+
const executing = (await this.state().listPending("executing")).find((item) => item.id === id);
|
|
148
|
+
if (!executing) {
|
|
149
|
+
if ((await this.state().listPending("pending")).find((item) => item.id === id)) return {
|
|
150
|
+
ok: false,
|
|
151
|
+
message: `Pending write "${id}" is already in the pending window — approve or reject it.`
|
|
152
|
+
};
|
|
153
|
+
return {
|
|
154
|
+
ok: false,
|
|
155
|
+
message: `Pending write "${id}" is not in the executing window — nothing to release.`
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (this.inFlight.has(`approve:${id}`) || this.inFlight.has(`reject:${id}`)) return {
|
|
159
|
+
ok: false,
|
|
160
|
+
message: `Pending write "${id}" has an approve/reject RUNNING in this process — do not release it. Verify the effect instead; a completed approve resolves its own record.`
|
|
161
|
+
};
|
|
162
|
+
const claimId = typeof executing.claimedBy === "string" ? executing.claimedBy : "";
|
|
163
|
+
if (claimId === "") return {
|
|
164
|
+
ok: false,
|
|
165
|
+
message: `Pending write "${id}" carries no claim to release (unexpected record shape) — reject it instead.`
|
|
166
|
+
};
|
|
167
|
+
await this.state().releasePendingClaim(id, claimId);
|
|
168
|
+
return {
|
|
169
|
+
ok: true,
|
|
170
|
+
message: `Released "${id}" back to the pending window. VERIFY the effect first: approve re-runs the write deliberately (duplicates possible if the effect already landed); reject closes the record.`
|
|
171
|
+
};
|
|
172
|
+
}
|
|
137
173
|
async reject(id) {
|
|
138
174
|
return await this.dedupe(`reject:${id}`, async () => {
|
|
139
175
|
const claimId = randomUUID();
|
package/lib/types/index.d.ts
CHANGED
|
@@ -95,6 +95,13 @@ export type ApprovalLike = {
|
|
|
95
95
|
ok: boolean;
|
|
96
96
|
message: string;
|
|
97
97
|
}>;
|
|
98
|
+
/** S2-P2-22 (0.3.80): return an ORPHANED executing record (an approve that
|
|
99
|
+
* crashed mid-run) to the pending window, so it can be deliberately
|
|
100
|
+
* re-approved or rejected. Optional: only the real service implements it. */
|
|
101
|
+
release?(id: string): Promise<{
|
|
102
|
+
ok: boolean;
|
|
103
|
+
message: string;
|
|
104
|
+
}>;
|
|
98
105
|
};
|
|
99
106
|
/** The requesting session's effective policy (override ?? configured default);
|
|
100
107
|
* undefined when the approval service is not mounted or no session is
|
|
@@ -156,6 +163,19 @@ export declare class EvolutionApproval extends Service {
|
|
|
156
163
|
ok: boolean;
|
|
157
164
|
message: string;
|
|
158
165
|
}>;
|
|
166
|
+
/** S2-P2-22 (0.3.80): return an ORPHANED executing record to the pending
|
|
167
|
+
* window. "Orphaned" = status `executing` with no approve running in THIS
|
|
168
|
+
* process (the family single-instance claim rules out any other live
|
|
169
|
+
* process, so a claim that is not in this service's in-flight dedupe map
|
|
170
|
+
* belongs to a dead one). The stored `claimedBy` rides along as the seam's
|
|
171
|
+
* release credential, so no state-seam expansion is needed. The operator is
|
|
172
|
+
* expected to verify the effect first: re-approving replays the write
|
|
173
|
+
* deliberately (duplicates possible if the effect already landed);
|
|
174
|
+
* rejecting closes the record. */
|
|
175
|
+
release(id: string): Promise<{
|
|
176
|
+
ok: boolean;
|
|
177
|
+
message: string;
|
|
178
|
+
}>;
|
|
159
179
|
reject(id: string): Promise<{
|
|
160
180
|
ok: boolean;
|
|
161
181
|
message: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-approval",
|
|
3
3
|
"description": "Stage/pending approval service for Hermes-style self-evolution writes (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.81",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
33
|
-
"@lmzhen/dsh-evolution-state-storage": "^0.3.
|
|
34
|
-
"@lmzhen/dsh-evolution-state": "^0.3.
|
|
33
|
+
"@lmzhen/dsh-evolution-state-storage": "^0.3.81",
|
|
34
|
+
"@lmzhen/dsh-evolution-state": "^0.3.81"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@lmzhen/dsh-evolution-state-storage": "^0.3.
|
|
38
|
-
"@lmzhen/dsh-evolution-state": "^0.3.
|
|
37
|
+
"@lmzhen/dsh-evolution-state-storage": "^0.3.81",
|
|
38
|
+
"@lmzhen/dsh-evolution-state": "^0.3.81"
|
|
39
39
|
}
|
|
40
40
|
}
|