@dsh-enhanced/assistant-automations 0.1.3
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/LICENSE +21 -0
- package/README.md +135 -0
- package/cordis.patch.yml +36 -0
- package/lib/artifacts.d.ts +15 -0
- package/lib/artifacts.d.ts.map +1 -0
- package/lib/artifacts.js +68 -0
- package/lib/artifacts.js.map +1 -0
- package/lib/coordinator.d.ts +126 -0
- package/lib/coordinator.d.ts.map +1 -0
- package/lib/coordinator.js +374 -0
- package/lib/coordinator.js.map +1 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/operator.d.ts +4 -0
- package/lib/operator.d.ts.map +1 -0
- package/lib/operator.js +12 -0
- package/lib/operator.js.map +1 -0
- package/lib/proposals.d.ts +89 -0
- package/lib/proposals.d.ts.map +1 -0
- package/lib/proposals.js +499 -0
- package/lib/proposals.js.map +1 -0
- package/lib/runner.d.ts +34 -0
- package/lib/runner.d.ts.map +1 -0
- package/lib/runner.js +272 -0
- package/lib/runner.js.map +1 -0
- package/lib/schedule.d.ts +32 -0
- package/lib/schedule.d.ts.map +1 -0
- package/lib/schedule.js +245 -0
- package/lib/schedule.js.map +1 -0
- package/lib/service.d.ts +159 -0
- package/lib/service.d.ts.map +1 -0
- package/lib/service.js +445 -0
- package/lib/service.js.map +1 -0
- package/lib/sqlite.d.ts +8 -0
- package/lib/sqlite.d.ts.map +1 -0
- package/lib/sqlite.js +281 -0
- package/lib/sqlite.js.map +1 -0
- package/lib/store.d.ts +169 -0
- package/lib/store.d.ts.map +1 -0
- package/lib/store.js +1002 -0
- package/lib/store.js.map +1 -0
- package/lib/tools.d.ts +4 -0
- package/lib/tools.d.ts.map +1 -0
- package/lib/tools.js +226 -0
- package/lib/tools.js.map +1 -0
- package/lib/types.d.ts +182 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +2 -0
- package/lib/version.js.map +1 -0
- package/package.json +106 -0
package/lib/proposals.js
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { isAbsolute } from 'node:path';
|
|
3
|
+
import { ApprovalSettlementConflict, validateApprovalSettlement, } from '@dsh-enhanced/assistant-policy';
|
|
4
|
+
import { AutomationDatabaseError, openAutomationDatabase } from './sqlite.js';
|
|
5
|
+
import { AutomationStoreError, normalizeAutomationDefinition, } from './store.js';
|
|
6
|
+
export class AutomationProposalStoreError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = 'AutomationProposalStoreError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function hash(value) {
|
|
15
|
+
return createHash('sha256').update(JSON.stringify(value)).digest('hex');
|
|
16
|
+
}
|
|
17
|
+
function id(idempotencyKey) {
|
|
18
|
+
return `automation-${createHash('sha256').update(idempotencyKey).digest('hex').slice(0, 32)}`;
|
|
19
|
+
}
|
|
20
|
+
function approvalDispatch(value) {
|
|
21
|
+
if (value === null)
|
|
22
|
+
return undefined;
|
|
23
|
+
let parsed;
|
|
24
|
+
try {
|
|
25
|
+
parsed = JSON.parse(value);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation proposal dispatch is not valid JSON');
|
|
29
|
+
}
|
|
30
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
31
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation proposal dispatch is invalid');
|
|
32
|
+
}
|
|
33
|
+
const route = parsed;
|
|
34
|
+
if (Object.keys(route).sort().join(',') !== 'bindingId,principal,sourceId,workspace'
|
|
35
|
+
|| typeof route['sourceId'] !== 'string'
|
|
36
|
+
|| !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u.test(route['sourceId'])
|
|
37
|
+
|| typeof route['bindingId'] !== 'string' || route['bindingId'].trim() === ''
|
|
38
|
+
|| typeof route['workspace'] !== 'string' || !isAbsolute(route['workspace'])
|
|
39
|
+
|| typeof route['principal'] !== 'string' || route['principal'].trim() === '') {
|
|
40
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation proposal dispatch is invalid');
|
|
41
|
+
}
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
sourceId: route['sourceId'],
|
|
44
|
+
bindingId: route['bindingId'],
|
|
45
|
+
workspace: route['workspace'],
|
|
46
|
+
principal: route['principal'],
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function stored(row) {
|
|
50
|
+
if (!Number.isSafeInteger(row.ttl_ms) || row.ttl_ms <= 0) {
|
|
51
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation proposal TTL is invalid');
|
|
52
|
+
}
|
|
53
|
+
return Object.freeze({
|
|
54
|
+
proposalId: row.id,
|
|
55
|
+
...(row.policy_proposal_id === null ? {} : { policyProposalId: row.policy_proposal_id }),
|
|
56
|
+
idempotencyKey: row.idempotency_key,
|
|
57
|
+
requester: row.requester,
|
|
58
|
+
principal: row.principal,
|
|
59
|
+
...(row.dispatch_json === null ? {} : { dispatch: approvalDispatch(row.dispatch_json) }),
|
|
60
|
+
requestHash: row.change_hash,
|
|
61
|
+
changeHash: hash(JSON.parse(row.change_json)),
|
|
62
|
+
mutation: Object.freeze(JSON.parse(row.change_json)),
|
|
63
|
+
status: row.status,
|
|
64
|
+
expiresAt: row.expires_at,
|
|
65
|
+
ttlMs: row.ttl_ms,
|
|
66
|
+
createdAt: row.created_at,
|
|
67
|
+
version: row.version,
|
|
68
|
+
...(row.result_automation_id === null ? {} : { resultAutomationId: row.result_automation_id }),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export class AutomationProposalStore {
|
|
72
|
+
database;
|
|
73
|
+
now;
|
|
74
|
+
closed = false;
|
|
75
|
+
constructor(options) {
|
|
76
|
+
this.now = options.now ?? Date.now;
|
|
77
|
+
try {
|
|
78
|
+
this.database = openAutomationDatabase(options.path);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (error instanceof AutomationDatabaseError) {
|
|
82
|
+
throw new AutomationProposalStoreError(error.code, error.message);
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
close() {
|
|
88
|
+
if (this.closed)
|
|
89
|
+
return;
|
|
90
|
+
this.closed = true;
|
|
91
|
+
this.database.close();
|
|
92
|
+
}
|
|
93
|
+
get(proposalId) {
|
|
94
|
+
const row = this.database.prepare('SELECT * FROM automation_proposals WHERE id = ?').get(proposalId);
|
|
95
|
+
return row === undefined ? undefined : stored(row);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* List proposals still pending locally, oldest first, so a reconciler can pair
|
|
99
|
+
* them with their policy decision.
|
|
100
|
+
*/
|
|
101
|
+
listPending(limit) {
|
|
102
|
+
if (!Number.isSafeInteger(limit) || limit <= 0 || limit > 1_000) {
|
|
103
|
+
throw new AutomationProposalStoreError('invalid-input', 'pending proposal limit must be between 1 and 1000');
|
|
104
|
+
}
|
|
105
|
+
const rows = this.database.prepare(`
|
|
106
|
+
SELECT * FROM automation_proposals WHERE status = 'pending'
|
|
107
|
+
ORDER BY updated_at, id LIMIT ?
|
|
108
|
+
`).all(limit);
|
|
109
|
+
return rows.map(row => stored(row));
|
|
110
|
+
}
|
|
111
|
+
prepare(input) {
|
|
112
|
+
const existingRow = this.database.prepare('SELECT * FROM automation_proposals WHERE id = ?').get(input.proposalId);
|
|
113
|
+
if (existingRow !== undefined) {
|
|
114
|
+
const existing = stored(existingRow);
|
|
115
|
+
if (existing.idempotencyKey !== input.idempotencyKey || existing.requester !== input.requester
|
|
116
|
+
|| existing.principal !== input.principal || existing.requestHash !== input.requestHash
|
|
117
|
+
|| existing.ttlMs !== input.ttlMs) {
|
|
118
|
+
throw new AutomationProposalStoreError('idempotency-conflict', 'automation proposal key was reused with different input');
|
|
119
|
+
}
|
|
120
|
+
return { proposal: existing, replayed: true };
|
|
121
|
+
}
|
|
122
|
+
const now = this.now();
|
|
123
|
+
this.database.prepare(`
|
|
124
|
+
INSERT INTO automation_proposals(
|
|
125
|
+
id, policy_proposal_id, idempotency_key, requester, principal, dispatch_json, change_hash, change_json,
|
|
126
|
+
status, expires_at, ttl_ms, result_automation_id, created_at, updated_at, version
|
|
127
|
+
) VALUES (?, NULL, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, NULL, ?, ?, 1)
|
|
128
|
+
`).run(input.proposalId, input.idempotencyKey, input.requester, input.principal, input.dispatch === undefined ? null : JSON.stringify(input.dispatch), input.requestHash, JSON.stringify(input.mutation), input.expiresAt, input.ttlMs, now, now);
|
|
129
|
+
return { proposal: this.get(input.proposalId), replayed: false };
|
|
130
|
+
}
|
|
131
|
+
/** Move an inspected, still-pending row behind older peers using a durable monotonic timestamp. */
|
|
132
|
+
deferPending(proposalId) {
|
|
133
|
+
const now = this.now();
|
|
134
|
+
this.database.prepare(`
|
|
135
|
+
UPDATE automation_proposals
|
|
136
|
+
SET updated_at = CASE WHEN updated_at >= ? THEN updated_at + 1 ELSE ? END
|
|
137
|
+
WHERE id = ? AND status = 'pending'
|
|
138
|
+
`).run(now, now, proposalId);
|
|
139
|
+
}
|
|
140
|
+
attachPolicy(proposalId, policyProposalId, expiresAt) {
|
|
141
|
+
const proposal = this.get(proposalId);
|
|
142
|
+
if (proposal === undefined)
|
|
143
|
+
throw new AutomationProposalStoreError('not-found', 'automation proposal was not found');
|
|
144
|
+
if (proposal.policyProposalId !== undefined && proposal.policyProposalId !== policyProposalId) {
|
|
145
|
+
throw new AutomationProposalStoreError('idempotency-conflict', 'automation proposal is attached to another policy proposal');
|
|
146
|
+
}
|
|
147
|
+
if (proposal.policyProposalId !== undefined && proposal.expiresAt !== expiresAt) {
|
|
148
|
+
throw new AutomationProposalStoreError('idempotency-conflict', 'automation proposal expiry differs from policy');
|
|
149
|
+
}
|
|
150
|
+
this.database.prepare(`
|
|
151
|
+
UPDATE automation_proposals SET policy_proposal_id = ?, expires_at = ?, updated_at = ? WHERE id = ?
|
|
152
|
+
`).run(policyProposalId, expiresAt, this.now(), proposalId);
|
|
153
|
+
return this.get(proposalId);
|
|
154
|
+
}
|
|
155
|
+
settle(input) {
|
|
156
|
+
const current = this.get(input.proposalId);
|
|
157
|
+
if (current === undefined)
|
|
158
|
+
throw new AutomationProposalStoreError('not-found', 'automation proposal was not found');
|
|
159
|
+
if (current.status !== 'pending') {
|
|
160
|
+
if (current.status !== input.status || current.version !== input.version
|
|
161
|
+
|| current.resultAutomationId !== input.resultAutomationId) {
|
|
162
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation proposal is already settled differently');
|
|
163
|
+
}
|
|
164
|
+
return { proposal: current, replayed: true };
|
|
165
|
+
}
|
|
166
|
+
this.database.prepare(`
|
|
167
|
+
UPDATE automation_proposals
|
|
168
|
+
SET status = ?, result_automation_id = ?, updated_at = ?, version = ?
|
|
169
|
+
WHERE id = ? AND status = 'pending'
|
|
170
|
+
`).run(input.status, input.resultAutomationId ?? null, this.now(), input.version, input.proposalId);
|
|
171
|
+
return { proposal: this.get(input.proposalId), replayed: false };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function validateIdentity(value, field) {
|
|
175
|
+
if (typeof value !== 'string' || value.trim() === '' || Buffer.byteLength(value, 'utf8') > 500) {
|
|
176
|
+
throw new AutomationProposalStoreError('invalid-input', `${field} is invalid`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function diff(mutation) {
|
|
180
|
+
return JSON.stringify(mutation, null, 2);
|
|
181
|
+
}
|
|
182
|
+
function summary(mutation) {
|
|
183
|
+
return `${mutation.op} automation ${mutation.automationId}`;
|
|
184
|
+
}
|
|
185
|
+
function result(proposal, replayed, automations) {
|
|
186
|
+
const automation = proposal.resultAutomationId === undefined ? undefined : automations.get(proposal.resultAutomationId);
|
|
187
|
+
return Object.freeze({
|
|
188
|
+
proposalId: proposal.proposalId,
|
|
189
|
+
...(proposal.policyProposalId === undefined ? {} : { policyProposalId: proposal.policyProposalId }),
|
|
190
|
+
status: proposal.status,
|
|
191
|
+
version: proposal.version,
|
|
192
|
+
expiresAt: proposal.expiresAt,
|
|
193
|
+
mutation: proposal.mutation,
|
|
194
|
+
diff: diff(proposal.mutation),
|
|
195
|
+
summary: summary(proposal.mutation),
|
|
196
|
+
replayed,
|
|
197
|
+
...(automation === undefined ? {} : { automation }),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
export class AutomationProposalManager {
|
|
201
|
+
automations;
|
|
202
|
+
proposals;
|
|
203
|
+
policy;
|
|
204
|
+
now;
|
|
205
|
+
constructor(automations, proposals, policy, now = Date.now) {
|
|
206
|
+
this.automations = automations;
|
|
207
|
+
this.proposals = proposals;
|
|
208
|
+
this.policy = policy;
|
|
209
|
+
this.now = now;
|
|
210
|
+
}
|
|
211
|
+
propose(input) {
|
|
212
|
+
validateIdentity(input.idempotencyKey, 'idempotencyKey');
|
|
213
|
+
validateIdentity(input.requester, 'requester');
|
|
214
|
+
validateIdentity(input.principal, 'principal');
|
|
215
|
+
if (!Number.isSafeInteger(input.ttlMs) || input.ttlMs <= 0) {
|
|
216
|
+
throw new AutomationProposalStoreError('invalid-input', 'proposal ttlMs must be positive');
|
|
217
|
+
}
|
|
218
|
+
const dispatch = input.dispatch === undefined
|
|
219
|
+
? undefined
|
|
220
|
+
: approvalDispatch(JSON.stringify({
|
|
221
|
+
sourceId: input.dispatch.sourceId,
|
|
222
|
+
bindingId: input.dispatch.bindingId,
|
|
223
|
+
workspace: input.dispatch.workspace,
|
|
224
|
+
principal: input.dispatch.principal,
|
|
225
|
+
}));
|
|
226
|
+
if (dispatch !== undefined && dispatch.principal !== input.principal) {
|
|
227
|
+
throw new AutomationProposalStoreError('invalid-input', 'approval dispatch belongs to another principal');
|
|
228
|
+
}
|
|
229
|
+
let mutation;
|
|
230
|
+
if (input.mutation.op === 'create') {
|
|
231
|
+
validateIdentity(input.mutation.automationId, 'automationId');
|
|
232
|
+
mutation = Object.freeze({
|
|
233
|
+
op: 'create',
|
|
234
|
+
automationId: input.mutation.automationId,
|
|
235
|
+
definition: normalizeAutomationDefinition(input.mutation.definition),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
validateIdentity(input.mutation.automationId, 'automationId');
|
|
240
|
+
if (!Number.isSafeInteger(input.mutation.expectedVersion) || input.mutation.expectedVersion <= 0) {
|
|
241
|
+
throw new AutomationProposalStoreError('invalid-input', 'expectedVersion must be positive');
|
|
242
|
+
}
|
|
243
|
+
mutation = Object.freeze({
|
|
244
|
+
op: input.mutation.op,
|
|
245
|
+
automationId: input.mutation.automationId,
|
|
246
|
+
expectedVersion: input.mutation.expectedVersion,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
const requestHash = hash({
|
|
250
|
+
idempotencyKey: input.idempotencyKey,
|
|
251
|
+
requester: input.requester,
|
|
252
|
+
principal: input.principal,
|
|
253
|
+
dispatch,
|
|
254
|
+
ttlMs: input.ttlMs,
|
|
255
|
+
mutation,
|
|
256
|
+
});
|
|
257
|
+
const proposalId = id(input.idempotencyKey);
|
|
258
|
+
const existing = this.proposals.get(proposalId);
|
|
259
|
+
let saved;
|
|
260
|
+
if (existing !== undefined) {
|
|
261
|
+
if (existing.requestHash !== requestHash) {
|
|
262
|
+
throw new AutomationProposalStoreError('idempotency-conflict', 'automation proposal key was reused');
|
|
263
|
+
}
|
|
264
|
+
saved = { proposal: existing, replayed: true };
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const current = this.automations.get(mutation.automationId);
|
|
268
|
+
if (mutation.op === 'create') {
|
|
269
|
+
if (current !== undefined) {
|
|
270
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation id already exists');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
if (current === undefined)
|
|
275
|
+
throw new AutomationProposalStoreError('not-found', 'automation was not found');
|
|
276
|
+
if (current.version !== mutation.expectedVersion) {
|
|
277
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation version changed before proposal');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
saved = this.proposals.prepare({
|
|
281
|
+
proposalId,
|
|
282
|
+
idempotencyKey: input.idempotencyKey,
|
|
283
|
+
requester: input.requester,
|
|
284
|
+
principal: input.principal,
|
|
285
|
+
...(dispatch === undefined ? {} : { dispatch }),
|
|
286
|
+
requestHash,
|
|
287
|
+
mutation,
|
|
288
|
+
expiresAt: this.now() + input.ttlMs,
|
|
289
|
+
ttlMs: input.ttlMs,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (saved.proposal.status !== 'pending' || saved.proposal.policyProposalId !== undefined) {
|
|
293
|
+
return result(saved.proposal, true, this.automations);
|
|
294
|
+
}
|
|
295
|
+
const recovered = this.recoverOrCreatePolicyProposal(saved.proposal);
|
|
296
|
+
if (recovered === undefined)
|
|
297
|
+
return this.settleSecurityConflict(saved.proposal, saved.replayed);
|
|
298
|
+
if (recovered.status !== 'pending') {
|
|
299
|
+
return this.settleValidated(recovered.proposal, recovered.snapshot, saved.replayed || recovered.replayed);
|
|
300
|
+
}
|
|
301
|
+
return result(recovered.proposal, saved.replayed || recovered.replayed, this.automations);
|
|
302
|
+
}
|
|
303
|
+
decide(input) {
|
|
304
|
+
let proposal = this.proposals.get(input.proposalId);
|
|
305
|
+
if (proposal === undefined)
|
|
306
|
+
throw new AutomationProposalStoreError('not-found', 'automation proposal was not found');
|
|
307
|
+
if (proposal.principal !== input.principal) {
|
|
308
|
+
throw new AutomationProposalStoreError('unauthorized', 'automation proposal belongs to another principal');
|
|
309
|
+
}
|
|
310
|
+
if (proposal.status !== 'pending')
|
|
311
|
+
return result(proposal, true, this.automations);
|
|
312
|
+
if (proposal.policyProposalId === undefined) {
|
|
313
|
+
const recovered = this.recoverOrCreatePolicyProposal(proposal);
|
|
314
|
+
if (recovered === undefined)
|
|
315
|
+
return this.settleSecurityConflict(proposal, false);
|
|
316
|
+
proposal = recovered.proposal;
|
|
317
|
+
if (recovered.status !== 'pending') {
|
|
318
|
+
return this.settleValidated(proposal, recovered.snapshot, recovered.replayed);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
const decision = this.policy.decideProposal({
|
|
322
|
+
proposalId: proposal.policyProposalId,
|
|
323
|
+
principal: input.principal,
|
|
324
|
+
expectedVersion: input.expectedVersion,
|
|
325
|
+
decision: input.decision,
|
|
326
|
+
reason: input.reason,
|
|
327
|
+
});
|
|
328
|
+
if (decision.status === 'pending')
|
|
329
|
+
throw new AutomationProposalStoreError('invalid-state', 'policy returned pending');
|
|
330
|
+
const snapshot = this.policy.getProposal(proposal.policyProposalId);
|
|
331
|
+
return this.settleValidated(proposal, snapshot, decision.replayed);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Commit locally pending proposals whose policy decision already settled
|
|
335
|
+
* elsewhere, for example on an approval card minutes after the turn ended.
|
|
336
|
+
*
|
|
337
|
+
* Approval is never inferred: the terminal status is read back from the policy
|
|
338
|
+
* ledger and applied through the same settle path `decide()` uses, so repeated
|
|
339
|
+
* reconciles are idempotent.
|
|
340
|
+
*/
|
|
341
|
+
reconcile(limit) {
|
|
342
|
+
const settled = [];
|
|
343
|
+
for (const candidate of this.proposals.listPending(limit)) {
|
|
344
|
+
let pending = candidate;
|
|
345
|
+
let decision;
|
|
346
|
+
if (pending.policyProposalId === undefined) {
|
|
347
|
+
try {
|
|
348
|
+
const recovered = this.recoverOrCreatePolicyProposal(pending);
|
|
349
|
+
if (recovered === undefined) {
|
|
350
|
+
settled.push(this.settleSecurityConflict(pending, false));
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
pending = recovered.proposal;
|
|
354
|
+
decision = recovered.snapshot;
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
this.proposals.deferPending(pending.proposalId);
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (decision === undefined) {
|
|
362
|
+
try {
|
|
363
|
+
decision = this.policy.getProposal(pending.policyProposalId);
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
this.proposals.deferPending(pending.proposalId);
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (decision?.status === 'pending') {
|
|
371
|
+
this.proposals.deferPending(pending.proposalId);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
settled.push(this.settleValidated(pending, decision, false));
|
|
375
|
+
}
|
|
376
|
+
return settled;
|
|
377
|
+
}
|
|
378
|
+
policyIdentity(proposal) {
|
|
379
|
+
return {
|
|
380
|
+
idempotencyKey: `assistant-automations:${proposal.idempotencyKey}`,
|
|
381
|
+
requester: proposal.requester,
|
|
382
|
+
principal: proposal.principal,
|
|
383
|
+
action: `automation.${proposal.mutation.op}`,
|
|
384
|
+
resource: { kind: 'automation', id: proposal.mutation.automationId },
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Atomically recover or create the Policy half under the locally frozen
|
|
389
|
+
* deadline. An abandoned result is terminal and must never be resurrected.
|
|
390
|
+
*/
|
|
391
|
+
recoverOrCreatePolicyProposal(proposal) {
|
|
392
|
+
const recovered = this.policy.recoverOrCreateProposal({
|
|
393
|
+
...this.policyIdentity(proposal),
|
|
394
|
+
diff: diff(proposal.mutation),
|
|
395
|
+
summary: summary(proposal.mutation),
|
|
396
|
+
notAfter: proposal.expiresAt,
|
|
397
|
+
...(proposal.dispatch === undefined ? {} : { dispatch: proposal.dispatch }),
|
|
398
|
+
});
|
|
399
|
+
if (recovered.kind === 'abandoned')
|
|
400
|
+
return undefined;
|
|
401
|
+
const policyProposal = recovered.proposal;
|
|
402
|
+
const attached = this.proposals.attachPolicy(proposal.proposalId, policyProposal.proposalId, policyProposal.expiresAt);
|
|
403
|
+
return {
|
|
404
|
+
proposal: attached,
|
|
405
|
+
status: policyProposal.status,
|
|
406
|
+
snapshot: policyProposal.status === 'pending'
|
|
407
|
+
? undefined
|
|
408
|
+
: this.policy.getProposal(policyProposal.proposalId),
|
|
409
|
+
replayed: policyProposal.replayed,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
settleValidated(proposal, snapshot, replayed) {
|
|
413
|
+
if (proposal.policyProposalId === undefined) {
|
|
414
|
+
throw new AutomationProposalStoreError('invalid-state', 'automation proposal is not attached to policy');
|
|
415
|
+
}
|
|
416
|
+
if (snapshot === undefined)
|
|
417
|
+
return this.settleSecurityConflict(proposal, replayed);
|
|
418
|
+
try {
|
|
419
|
+
const terminal = validateApprovalSettlement(snapshot, {
|
|
420
|
+
proposalId: proposal.policyProposalId,
|
|
421
|
+
requester: proposal.requester,
|
|
422
|
+
principal: proposal.principal,
|
|
423
|
+
action: `automation.${proposal.mutation.op}`,
|
|
424
|
+
resource: { kind: 'automation', id: proposal.mutation.automationId },
|
|
425
|
+
summary: summary(proposal.mutation),
|
|
426
|
+
diff: diff(proposal.mutation),
|
|
427
|
+
expiresAt: proposal.expiresAt,
|
|
428
|
+
expectedVersion: proposal.version,
|
|
429
|
+
});
|
|
430
|
+
return this.settleDecided(proposal, terminal.status, terminal.version, replayed);
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
if (!(error instanceof ApprovalSettlementConflict))
|
|
434
|
+
throw error;
|
|
435
|
+
return this.settleSecurityConflict(proposal, replayed);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
settleSecurityConflict(proposal, replayed) {
|
|
439
|
+
if (proposal.status !== 'pending' || proposal.version >= Number.MAX_SAFE_INTEGER) {
|
|
440
|
+
throw new AutomationProposalStoreError('invalid-state', 'settled automation proposal failed immutable policy validation');
|
|
441
|
+
}
|
|
442
|
+
const settled = this.proposals.settle({
|
|
443
|
+
proposalId: proposal.proposalId,
|
|
444
|
+
status: 'conflicted',
|
|
445
|
+
version: proposal.version + 1,
|
|
446
|
+
});
|
|
447
|
+
return result(settled.proposal, replayed || settled.replayed, this.automations);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Apply one already-terminal policy status to a pending automation proposal. A
|
|
451
|
+
* store conflict downgrades the proposal to `conflicted` instead of losing the
|
|
452
|
+
* decision, matching the rule that a decision is never re-asked.
|
|
453
|
+
*/
|
|
454
|
+
settleDecided(proposal, policyStatus, policyVersion, replayed) {
|
|
455
|
+
let status = policyStatus;
|
|
456
|
+
let automationId;
|
|
457
|
+
if (policyStatus === 'approved') {
|
|
458
|
+
try {
|
|
459
|
+
if (proposal.mutation.op === 'create') {
|
|
460
|
+
this.automations.createApproved({
|
|
461
|
+
automationId: proposal.mutation.automationId,
|
|
462
|
+
idempotencyKey: `proposal:${proposal.proposalId}`,
|
|
463
|
+
definition: proposal.mutation.definition,
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
this.automations.changeApproved({
|
|
468
|
+
automationId: proposal.mutation.automationId,
|
|
469
|
+
operation: proposal.mutation.op,
|
|
470
|
+
expectedVersion: proposal.mutation.expectedVersion,
|
|
471
|
+
idempotencyKey: `proposal:${proposal.proposalId}`,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
automationId = proposal.mutation.automationId;
|
|
475
|
+
}
|
|
476
|
+
catch (error) {
|
|
477
|
+
if (error instanceof AutomationStoreError
|
|
478
|
+
&& ['idempotency-conflict', 'invalid-state', 'not-found', 'version-conflict'].includes(error.code)) {
|
|
479
|
+
status = 'conflicted';
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
throw error;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
const settled = this.proposals.settle({
|
|
487
|
+
proposalId: proposal.proposalId,
|
|
488
|
+
status,
|
|
489
|
+
version: policyVersion,
|
|
490
|
+
...(automationId === undefined ? {} : { resultAutomationId: automationId }),
|
|
491
|
+
});
|
|
492
|
+
return result(settled.proposal, replayed || settled.replayed, this.automations);
|
|
493
|
+
}
|
|
494
|
+
get(proposalId) {
|
|
495
|
+
const proposal = this.proposals.get(proposalId);
|
|
496
|
+
return proposal === undefined ? undefined : result(proposal, true, this.automations);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
//# sourceMappingURL=proposals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposals.js","sourceRoot":"","sources":["../src/proposals.ts"],"names":[],"mappings":"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"}
|
package/lib/runner.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { AssistantPolicyService, PolicyBudgetConfig } from '@dsh-enhanced/assistant-policy';
|
|
3
|
+
import { type AutomationRunner, type AutomationRunnerInput, type AutomationRunnerResult } from './coordinator.js';
|
|
4
|
+
export declare class AutomationBudgetReplayError extends Error {
|
|
5
|
+
readonly reservationStatus: 'finalized' | 'released' | 'reserved';
|
|
6
|
+
readonly code: "automation-budget-reservation-replayed";
|
|
7
|
+
constructor(reservationStatus: 'finalized' | 'released' | 'reserved');
|
|
8
|
+
}
|
|
9
|
+
export declare const AUTOMATION_RUN_BUDGET_METRIC = "automation-runs";
|
|
10
|
+
/** Prove the configured Policy budget uses the fixed per-run unit before reservation. */
|
|
11
|
+
export declare function assertAutomationRunBudget(policy: Pick<AssistantPolicyService, 'getBudgetConfig'>, budgetId: string): Readonly<PolicyBudgetConfig>;
|
|
12
|
+
export interface DshAutomationRunnerOptions {
|
|
13
|
+
/** Explicit escape hatch for deployments whose unattended routes have no configured Policy budget. */
|
|
14
|
+
readonly allowUnbudgetedExecution?: boolean;
|
|
15
|
+
/** Audited native-tool routes whose upstream adapters do not publish registry metadata yet. */
|
|
16
|
+
readonly toolCapableProviders?: readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* How to admit a route that publishes no tool-call capability at all. The DSH
|
|
19
|
+
* `generate` contract accepts `tools` for every adapter, so `allow` matches
|
|
20
|
+
* that baseline; `deny` opts a deployment into strict allowlisting. A
|
|
21
|
+
* provider-owned `none` declaration always fails closed either way.
|
|
22
|
+
*/
|
|
23
|
+
readonly unknownRouteToolCalls?: 'allow' | 'deny';
|
|
24
|
+
}
|
|
25
|
+
export declare class DshAutomationRunner implements AutomationRunner {
|
|
26
|
+
private readonly ctx;
|
|
27
|
+
private readonly policy;
|
|
28
|
+
private readonly allowUnbudgetedExecution;
|
|
29
|
+
private readonly toolCapableProviders;
|
|
30
|
+
private readonly unknownRouteToolCalls;
|
|
31
|
+
constructor(ctx: Context, policy: AssistantPolicyService, options?: DshAutomationRunnerOptions);
|
|
32
|
+
run(input: AutomationRunnerInput): Promise<AutomationRunnerResult>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AASlD,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AAEhG,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAA;AA2CzB,qBAAa,2BAA4B,SAAQ,KAAK;IAGxC,QAAQ,CAAC,iBAAiB,EAAE,WAAW,GAAG,UAAU,GAAG,UAAU;IAF7E,QAAQ,CAAC,IAAI,EAAG,wCAAwC,CAAS;gBAE5C,iBAAiB,EAAE,WAAW,GAAG,UAAU,GAAG,UAAU;CAI9E;AAED,eAAO,MAAM,4BAA4B,oBAAoB,CAAA;AAE7D,yFAAyF;AACzF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,EACvD,QAAQ,EAAE,MAAM,GACf,QAAQ,CAAC,kBAAkB,CAAC,CAW9B;AAED,MAAM,WAAW,0BAA0B;IACzC,sGAAsG;IACtG,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAC3C,+FAA+F;IAC/F,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAClD;AA4BD,qBAAa,mBAAoB,YAAW,gBAAgB;IAMxD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqB;IAC1D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAkB;gBAGrC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,sBAAsB,EAC/C,OAAO,GAAE,0BAA+B;IAOpC,GAAG,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;CAiLzE"}
|