@atolis-hq/wake 0.2.96 → 0.2.97

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.
@@ -482,6 +482,38 @@ export function createTickRunner(deps) {
482
482
  }
483
483
  return { blocked: false };
484
484
  }
485
+ async function applyApprovedPrMergePolicy(input) {
486
+ if (input.approvalResolution.targetResourceUri === undefined || input.mergePolicy === null) {
487
+ return null;
488
+ }
489
+ const risk = await evaluatePrMergeRisk({
490
+ projection: input.projection,
491
+ targetResourceUri: input.approvalResolution.targetResourceUri,
492
+ policy: input.mergePolicy,
493
+ });
494
+ if (!risk.passed) {
495
+ return await publishPrMergePolicyBlock({
496
+ projection: input.projection,
497
+ approvalResolution: input.approvalResolution,
498
+ reason: risk.reason,
499
+ workflowName: input.workflowName,
500
+ });
501
+ }
502
+ const mergeActionsResult = await performApprovedPrMergeActions({
503
+ projection: input.projection,
504
+ approvalResolution: input.approvalResolution,
505
+ mergePolicy: input.mergePolicy,
506
+ });
507
+ if (mergeActionsResult.blocked) {
508
+ return await publishPrMergePolicyBlock({
509
+ projection: input.projection,
510
+ approvalResolution: input.approvalResolution,
511
+ reason: mergeActionsResult.reason,
512
+ workflowName: input.workflowName,
513
+ });
514
+ }
515
+ return null;
516
+ }
485
517
  // The one deterministic approval transition: /approved, wake:auto, and a
486
518
  // watcher child's onSuccess.approve all resolve a pending approval through
487
519
  // this same event shape, so replay folds them identically.
@@ -1333,34 +1365,14 @@ export function createTickRunner(deps) {
1333
1365
  }
1334
1366
  }
1335
1367
  else if (approvalResolution.approved) {
1336
- const mergePolicy = approvedMergePolicyForStage(workflow.stages[candidate.wake.stage]);
1337
- if (approvalResolution.targetResourceUri !== undefined && mergePolicy !== null) {
1338
- const risk = await evaluatePrMergeRisk({
1339
- projection: candidate,
1340
- targetResourceUri: approvalResolution.targetResourceUri,
1341
- policy: mergePolicy,
1342
- });
1343
- if (!risk.passed) {
1344
- return await publishPrMergePolicyBlock({
1345
- projection: candidate,
1346
- approvalResolution,
1347
- reason: risk.reason,
1348
- workflowName,
1349
- });
1350
- }
1351
- const mergeActionsResult = await performApprovedPrMergeActions({
1352
- projection: candidate,
1353
- approvalResolution,
1354
- mergePolicy,
1355
- });
1356
- if (mergeActionsResult.blocked) {
1357
- return await publishPrMergePolicyBlock({
1358
- projection: candidate,
1359
- approvalResolution,
1360
- reason: mergeActionsResult.reason,
1361
- workflowName,
1362
- });
1363
- }
1368
+ const mergePolicyBlock = await applyApprovedPrMergePolicy({
1369
+ projection: candidate,
1370
+ approvalResolution,
1371
+ workflowName,
1372
+ mergePolicy: approvedMergePolicyForStage(workflow.stages[candidate.wake.stage]),
1373
+ });
1374
+ if (mergePolicyBlock !== null) {
1375
+ return mergePolicyBlock;
1364
1376
  }
1365
1377
  const approvalId = `approval-${candidate.issue.number}-${deps.clock.now().getTime()}`;
1366
1378
  const approvedAt = deps.clock.now().toISOString();
@@ -2133,6 +2145,71 @@ export function createTickRunner(deps) {
2133
2145
  idempotencyKey: `${runId}:pr-review-verdict-comment`,
2134
2146
  },
2135
2147
  });
2148
+ const approvalId = `${runId}-parent-approval`;
2149
+ const parentWorkflow = watcherDispatch === null
2150
+ ? undefined
2151
+ : deps.config.workflows[watcherDispatch.parentWorkflowName];
2152
+ if (sentinel === 'DONE' &&
2153
+ watcherDispatch !== null &&
2154
+ isAwaitingApproval(candidate) &&
2155
+ typeof pendingApprovalAction === 'string' &&
2156
+ parentWorkflow !== undefined &&
2157
+ (await deps.stateStore.readEventEnvelope(`${approvalId}-completed`)) === null) {
2158
+ const approvedAt = eventStampNow();
2159
+ const approvalResolution = {
2160
+ approved: true,
2161
+ pendingAction: pendingApprovalAction,
2162
+ targetResourceUri: prReviewTargetResourceUri,
2163
+ triggeringCommentId: approvalId,
2164
+ triggeringCommentBody: parsedRunnerResult.body,
2165
+ };
2166
+ const mergePolicyBlock = await applyApprovedPrMergePolicy({
2167
+ projection: candidate,
2168
+ approvalResolution,
2169
+ workflowName: watcherDispatch.parentWorkflowName,
2170
+ mergePolicy: approvedMergePolicyForStage(parentWorkflow.stages[watcherDispatch.parentStage]),
2171
+ });
2172
+ if (mergePolicyBlock !== null) {
2173
+ return mergePolicyBlock;
2174
+ }
2175
+ const applied = await applyApprovalTransition({
2176
+ projection: candidate,
2177
+ pendingAction: pendingApprovalAction,
2178
+ approvalId,
2179
+ approvedAt,
2180
+ reason: 'watcher:approved',
2181
+ workflow: parentWorkflow,
2182
+ workflowName: watcherDispatch.parentWorkflowName,
2183
+ });
2184
+ if (applied !== null) {
2185
+ await appendAuditEvent({
2186
+ eventId: `${approvalId}-audit-watcher-approval`,
2187
+ decisionType: 'approval.watcher-resolved',
2188
+ workItemKey: candidate.workItemKey,
2189
+ runId,
2190
+ workflowRevision: await computeWorkflowRevision({
2191
+ config: deps.config,
2192
+ workflowName: watcherDispatch.parentWorkflowName,
2193
+ workflow: parentWorkflow,
2194
+ action: pendingApprovalAction,
2195
+ }),
2196
+ inputsConsidered: {
2197
+ watcherWorkflow: watcherDispatch.targetWorkflowName,
2198
+ pendingAction: pendingApprovalAction,
2199
+ childRunId: runId,
2200
+ childSentinel: sentinel,
2201
+ verifiedTargetResourceUri: prReviewTargetResourceUri,
2202
+ },
2203
+ outcome: { approved: true, nextStage: applied.nextStage },
2204
+ timestamp: approvedAt,
2205
+ sourceRefs: {
2206
+ repo: candidate.issue.repo,
2207
+ issueNumber: candidate.issue.number,
2208
+ resourceUri: prReviewTargetResourceUri,
2209
+ },
2210
+ });
2211
+ }
2212
+ }
2136
2213
  }
2137
2214
  else if (watcherDispatch !== null &&
2138
2215
  watcherSuccessPolicy?.approve === true &&
@@ -124,4 +124,4 @@ export function resolveWakeVersion(options = {}) {
124
124
  }
125
125
  return '0.1.0-dev';
126
126
  }
127
- export const wakeVersion = "g49465cd";
127
+ export const wakeVersion = "g17e7db1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atolis-hq/wake",
3
- "version": "0.2.96",
3
+ "version": "0.2.97",
4
4
  "description": "Local autonomous agent control plane for software development",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {