@defrex/autobuild 0.10.1 → 0.12.0
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/README.md +3 -1
- package/SPEC.md +237 -23
- package/bin/ab-dispatch-kernel.ts +1 -1
- package/docs/architecture.md +66 -4
- package/docs/configuration.md +137 -19
- package/docs/hosted-dispatcher.md +17 -2
- package/docs/hosted-service.md +214 -0
- package/docs/mcp.md +8 -2
- package/docs/operator-api.md +107 -7
- package/docs/remote-store-protocol.md +189 -144
- package/docs/remote-ticket-protocol.md +111 -18
- package/docs/setup.md +173 -16
- package/docs/ticket-dependencies.md +1 -1
- package/package.json +7 -6
- package/packages/core/src/cli/attention.ts +209 -0
- package/packages/core/src/cli/binary.ts +3 -3
- package/packages/core/src/cli/configured-store.ts +17 -0
- package/packages/core/src/cli/connect.ts +261 -0
- package/packages/core/src/cli/dashboard/model.ts +8 -5
- package/packages/core/src/cli/dashboard/render.ts +37 -7
- package/packages/core/src/cli/dispatch-frontend.ts +16 -1
- package/packages/core/src/cli/dispatch-process.ts +25 -7
- package/packages/core/src/cli/dispatch.ts +247 -47
- package/packages/core/src/cli/dispatcher-liveness.ts +91 -0
- package/packages/core/src/cli/help.ts +45 -13
- package/packages/core/src/cli/init-validation.ts +27 -2
- package/packages/core/src/cli/main.ts +41 -15
- package/packages/core/src/cli/mcp.ts +7 -1
- package/packages/core/src/cli/pr-summary-publication.ts +220 -0
- package/packages/core/src/cli/pr-summary.ts +2 -0
- package/packages/core/src/cli/project-credentials.ts +132 -0
- package/packages/core/src/cli/repo-state.ts +15 -2
- package/packages/core/src/cli/repository-status.ts +45 -5
- package/packages/core/src/cli/self-update.ts +10 -0
- package/packages/core/src/cli/store-opening.ts +22 -14
- package/packages/core/src/cli/terminals.ts +0 -10
- package/packages/core/src/cli/ticket.ts +8 -1
- package/packages/core/src/cli/upgrade-compatibility.ts +80 -0
- package/packages/core/src/cli/wait.ts +84 -17
- package/packages/core/src/cli/watch.ts +350 -68
- package/packages/core/src/config/live.ts +4 -0
- package/packages/core/src/config/schema.ts +65 -11
- package/packages/core/src/connection.ts +86 -0
- package/packages/core/src/events/catalog.ts +10 -2
- package/packages/core/src/events/globs.ts +8 -3
- package/packages/core/src/events/payloads.ts +44 -0
- package/packages/core/src/events/repository.ts +64 -2
- package/packages/core/src/integration/harness.ts +2 -1
- package/packages/core/src/kernel/__snapshots__/reducer-registry.test.ts.snap +148 -83
- package/packages/core/src/kernel/dispatch-status.ts +9 -1
- package/packages/core/src/kernel/dispatcher-liveness.ts +70 -0
- package/packages/core/src/kernel/engine.ts +24 -0
- package/packages/core/src/kernel/generators/build-log.ts +10 -0
- package/packages/core/src/kernel/log-index.ts +17 -0
- package/packages/core/src/kernel/pr-summary.ts +89 -0
- package/packages/core/src/kernel/reducer-registry.ts +12 -0
- package/packages/core/src/kernel/reducer.ts +8 -0
- package/packages/core/src/kernel/ticket-source-health.ts +30 -0
- package/packages/core/src/ontology.ts +1 -0
- package/packages/core/src/operator/index.ts +7 -0
- package/packages/core/src/operator/query.ts +44 -19
- package/packages/core/src/operator/ticket-source-backend.ts +1 -0
- package/packages/core/src/operator/tickets.ts +6 -8
- package/packages/core/src/plugin-sdk/index.ts +1 -0
- package/packages/core/src/plugins/manifest.ts +5 -3
- package/packages/core/src/plugins/runtimes.ts +3 -1
- package/packages/core/src/ports/forge/fake.ts +13 -1
- package/packages/core/src/ports/forge/github-transport.ts +36 -1
- package/packages/core/src/ports/forge/github.ts +29 -5
- package/packages/core/src/ports/forge/local-git.ts +12 -4
- package/packages/core/src/ports/forge/summary-marker.ts +8 -0
- package/packages/core/src/ports/runner/session-env.ts +1 -0
- package/packages/core/src/ports/tickets/contract.ts +25 -0
- package/packages/core/src/ports/tickets/create.ts +11 -3
- package/packages/core/src/ports/tickets/fake.ts +10 -8
- package/packages/core/src/ports/tickets/file.ts +1 -0
- package/packages/core/src/ports/tickets/hosted-index.ts +0 -3
- package/packages/core/src/ports/tickets/linear.ts +241 -49
- package/packages/core/src/ports/tickets/remote-protocol.ts +3 -0
- package/packages/core/src/ports/tickets/remote.ts +1 -0
- package/packages/core/src/ports/types.ts +17 -0
- package/packages/core/src/ports/workspace/build-execution.ts +5 -1
- package/packages/core/src/ports/workspace/create.ts +11 -2
- package/packages/core/src/ports/workspace/distribution-archive.ts +3 -5
- package/packages/core/src/ports/workspace/harvest-execution.ts +3 -1
- package/packages/core/src/ports/workspace/local-build-execution.ts +8 -1
- package/packages/core/src/ports/workspace/vercel-sandbox.ts +47 -19
- package/packages/core/src/processes/build-execution-state.ts +1 -1
- package/packages/core/src/processes/build-runner.ts +87 -26
- package/packages/core/src/processes/dispatch-failure-budget.ts +83 -0
- package/packages/core/src/processes/dispatcher.ts +336 -83
- package/packages/core/src/processes/harvest-child.ts +1 -0
- package/packages/core/src/processes/harvest-execution-state.ts +19 -2
- package/packages/core/src/processes/harvest-runner.ts +142 -100
- package/packages/core/src/processes/phase-failure-budget.ts +1 -0
- package/packages/core/src/processes/publication-loss.ts +18 -1
- package/packages/core/src/processes/repo-view.ts +2 -1
- package/packages/core/src/store/adapter.ts +1 -0
- package/packages/core/src/store/contract.ts +109 -0
- package/packages/core/src/store/digest.ts +14 -2
- package/packages/core/src/store/local/store.ts +18 -5
- package/packages/core/src/store/remote/client.ts +1 -1
- package/packages/core/src/store/remote/compatibility.ts +90 -0
- package/packages/core/src/store/remote/credentials.ts +28 -0
- package/packages/core/src/store/remote/index.ts +14 -1
- package/packages/core/src/store/remote/protocol.ts +26 -0
- package/packages/core/src/store/remote/token.ts +74 -13
- package/packages/core/src/store/repo-state-events.ts +49 -59
- package/packages/core/src/store/types.ts +5 -1
- package/packages/core/src/testing/index.ts +7 -0
- package/skills/guide/SKILL.md +175 -26
- package/skills/guide/references/operator-api.md +135 -13
- package/skills/guide/references/plugin-authoring.md +10 -2
- package/skills/guide/references/remote-store-protocol.md +189 -144
- package/skills/guide/references/remote-ticket-protocol.md +111 -18
- package/skills/guide/references/setup.md +173 -16
- package/skills/guide/references/ticket-dependencies.md +1 -1
- package/skills/operate/SKILL.md +159 -34
- package/templates/hosted-service/package.json +13 -0
- package/templates/hosted-service/vercel.json +7 -0
|
@@ -138,27 +138,28 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
138
138
|
"$.lastEvent.actor.user: string",
|
|
139
139
|
"$.lastEvent.actor: object",
|
|
140
140
|
"$.lastEvent.build: string",
|
|
141
|
+
"$.lastEvent.payload.answer: string",
|
|
141
142
|
"$.lastEvent.payload.artifact.kind: string",
|
|
142
143
|
"$.lastEvent.payload.artifact.rev: number",
|
|
143
144
|
"$.lastEvent.payload.artifact: object",
|
|
144
|
-
"$.lastEvent.payload.
|
|
145
|
-
"$.lastEvent.payload.
|
|
146
|
-
"$.lastEvent.payload.
|
|
147
|
-
"$.lastEvent.payload.
|
|
148
|
-
"$.lastEvent.payload.
|
|
149
|
-
"$.lastEvent.payload.
|
|
145
|
+
"$.lastEvent.payload.assets: array",
|
|
146
|
+
"$.lastEvent.payload.assets[].dirCount: number",
|
|
147
|
+
"$.lastEvent.payload.assets[].fileCount: number",
|
|
148
|
+
"$.lastEvent.payload.assets[].kind: string",
|
|
149
|
+
"$.lastEvent.payload.assets[].layout: string",
|
|
150
|
+
"$.lastEvent.payload.assets[].name: string",
|
|
151
|
+
"$.lastEvent.payload.assets[].revision: number",
|
|
152
|
+
"$.lastEvent.payload.assets[].size: number",
|
|
153
|
+
"$.lastEvent.payload.assets[]: object",
|
|
150
154
|
"$.lastEvent.payload.attempt: number",
|
|
151
155
|
"$.lastEvent.payload.base.sha: string",
|
|
152
156
|
"$.lastEvent.payload.base.source: string",
|
|
153
157
|
"$.lastEvent.payload.base: object",
|
|
158
|
+
"$.lastEvent.payload.base: string",
|
|
159
|
+
"$.lastEvent.payload.baseSha: string",
|
|
160
|
+
"$.lastEvent.payload.boundary: number",
|
|
154
161
|
"$.lastEvent.payload.branch: string",
|
|
155
162
|
"$.lastEvent.payload.cause: string",
|
|
156
|
-
"$.lastEvent.payload.cleanupPending: boolean",
|
|
157
|
-
"$.lastEvent.payload.command: string",
|
|
158
|
-
"$.lastEvent.payload.commandSeq: number",
|
|
159
|
-
"$.lastEvent.payload.commits.base: string",
|
|
160
|
-
"$.lastEvent.payload.commits.head: string",
|
|
161
|
-
"$.lastEvent.payload.commits: object",
|
|
162
163
|
"$.lastEvent.payload.counters.claimed: number",
|
|
163
164
|
"$.lastEvent.payload.counters.closed: number",
|
|
164
165
|
"$.lastEvent.payload.counters.conflicted: number",
|
|
@@ -174,7 +175,6 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
174
175
|
"$.lastEvent.payload.decision: string",
|
|
175
176
|
"$.lastEvent.payload.defaultSeq: number",
|
|
176
177
|
"$.lastEvent.payload.dependencyDiagnostics: array",
|
|
177
|
-
"$.lastEvent.payload.designationSeq: number",
|
|
178
178
|
"$.lastEvent.payload.dispositions: array",
|
|
179
179
|
"$.lastEvent.payload.dispositions[].action: string",
|
|
180
180
|
"$.lastEvent.payload.dispositions[].occurrence.build: string",
|
|
@@ -185,15 +185,15 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
185
185
|
"$.lastEvent.payload.effectiveConfig.kind: string",
|
|
186
186
|
"$.lastEvent.payload.effectiveConfig.rev: number",
|
|
187
187
|
"$.lastEvent.payload.effectiveConfig: object",
|
|
188
|
+
"$.lastEvent.payload.eligibleAfter: string",
|
|
188
189
|
"$.lastEvent.payload.enabled: boolean",
|
|
189
190
|
"$.lastEvent.payload.environmentId: string",
|
|
190
191
|
"$.lastEvent.payload.error: string",
|
|
191
192
|
"$.lastEvent.payload.escalation: number",
|
|
192
193
|
"$.lastEvent.payload.execution: string",
|
|
193
|
-
"$.lastEvent.payload.exitStatus: number",
|
|
194
194
|
"$.lastEvent.payload.filename: string",
|
|
195
|
-
"$.lastEvent.payload.files: array",
|
|
196
195
|
"$.lastEvent.payload.findings: array",
|
|
196
|
+
"$.lastEvent.payload.generation: number",
|
|
197
197
|
"$.lastEvent.payload.globs: array",
|
|
198
198
|
"$.lastEvent.payload.globs[]: string",
|
|
199
199
|
"$.lastEvent.payload.host: string",
|
|
@@ -207,36 +207,36 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
207
207
|
"$.lastEvent.payload.kind: string",
|
|
208
208
|
"$.lastEvent.payload.level: string",
|
|
209
209
|
"$.lastEvent.payload.mediaType: string",
|
|
210
|
+
"$.lastEvent.payload.mergeCommit: string",
|
|
210
211
|
"$.lastEvent.payload.message: string",
|
|
211
212
|
"$.lastEvent.payload.observations: array",
|
|
212
213
|
"$.lastEvent.payload.observations[].build: string",
|
|
213
214
|
"$.lastEvent.payload.observations[].seq: number",
|
|
214
215
|
"$.lastEvent.payload.observations[]: object",
|
|
216
|
+
"$.lastEvent.payload.occurrence: number",
|
|
215
217
|
"$.lastEvent.payload.ok: boolean",
|
|
216
218
|
"$.lastEvent.payload.operation: string",
|
|
217
219
|
"$.lastEvent.payload.operator: string",
|
|
218
220
|
"$.lastEvent.payload.outcome: string",
|
|
219
|
-
"$.lastEvent.payload.output: string",
|
|
220
221
|
"$.lastEvent.payload.phase: string",
|
|
221
222
|
"$.lastEvent.payload.pid: number",
|
|
222
|
-
"$.lastEvent.payload.policyCause: string",
|
|
223
223
|
"$.lastEvent.payload.pr.headSha: string",
|
|
224
224
|
"$.lastEvent.payload.pr.number: number",
|
|
225
225
|
"$.lastEvent.payload.pr.url: string",
|
|
226
|
+
"$.lastEvent.payload.pr: number",
|
|
226
227
|
"$.lastEvent.payload.pr: object",
|
|
227
228
|
"$.lastEvent.payload.provider: string",
|
|
228
229
|
"$.lastEvent.payload.question: string",
|
|
229
230
|
"$.lastEvent.payload.queued: number",
|
|
230
231
|
"$.lastEvent.payload.reason: string",
|
|
231
232
|
"$.lastEvent.payload.ref: string",
|
|
232
|
-
"$.lastEvent.payload.refs: array",
|
|
233
|
-
"$.lastEvent.payload.refs[]: string",
|
|
234
233
|
"$.lastEvent.payload.remote: boolean",
|
|
235
234
|
"$.lastEvent.payload.report.kind: string",
|
|
236
235
|
"$.lastEvent.payload.report.rev: number",
|
|
237
236
|
"$.lastEvent.payload.report: object",
|
|
238
237
|
"$.lastEvent.payload.request: number",
|
|
239
|
-
"$.lastEvent.payload.
|
|
238
|
+
"$.lastEvent.payload.resetAt: string",
|
|
239
|
+
"$.lastEvent.payload.resolution: string",
|
|
240
240
|
"$.lastEvent.payload.role: string",
|
|
241
241
|
"$.lastEvent.payload.roleWarnings: array",
|
|
242
242
|
"$.lastEvent.payload.roleWarnings[]: string",
|
|
@@ -252,10 +252,8 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
252
252
|
"$.lastEvent.payload.snapshots.outcome: string",
|
|
253
253
|
"$.lastEvent.payload.snapshots: object",
|
|
254
254
|
"$.lastEvent.payload.source: string",
|
|
255
|
-
"$.lastEvent.payload.stage: string",
|
|
256
255
|
"$.lastEvent.payload.step: string",
|
|
257
256
|
"$.lastEvent.payload.stream: string",
|
|
258
|
-
"$.lastEvent.payload.summary: string",
|
|
259
257
|
"$.lastEvent.payload.text: string",
|
|
260
258
|
"$.lastEvent.payload.ticket.id: string",
|
|
261
259
|
"$.lastEvent.payload.ticket.source: string",
|
|
@@ -323,7 +321,6 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
323
321
|
"$.pending.abort[].actor.user: string",
|
|
324
322
|
"$.pending.abort[].actor: object",
|
|
325
323
|
"$.pending.abort[].command: string",
|
|
326
|
-
"$.pending.abort[].reason: string",
|
|
327
324
|
"$.pending.abort[].reason: undefined",
|
|
328
325
|
"$.pending.abort[].seq: number",
|
|
329
326
|
"$.pending.abort[]: object",
|
|
@@ -392,7 +389,6 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
392
389
|
"$.terminal: string",
|
|
393
390
|
"$.terminal: undefined",
|
|
394
391
|
"$.verify.currentStep: string",
|
|
395
|
-
"$.verify.currentStep: undefined",
|
|
396
392
|
"$.verify.cycleSince: number",
|
|
397
393
|
"$.verify.maxAttemptSeen: number",
|
|
398
394
|
"$.verify.results: array",
|
|
@@ -414,6 +410,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
414
410
|
"$.observations[].ts: string",
|
|
415
411
|
"$.observations[]: object",
|
|
416
412
|
"$.openInstance: null",
|
|
413
|
+
"$.readinessChangeSeq: number",
|
|
417
414
|
"$.reclaimed: array",
|
|
418
415
|
"$.terminal: string",
|
|
419
416
|
"$: object",
|
|
@@ -436,6 +433,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
436
433
|
"$.entries[].event: object",
|
|
437
434
|
"$.entries[].headSha: string",
|
|
438
435
|
"$.entries[].seq: number",
|
|
436
|
+
"$.entries[].seq: undefined",
|
|
439
437
|
"$.entries[].t: string",
|
|
440
438
|
"$.entries[]: object",
|
|
441
439
|
"$: object",
|
|
@@ -517,19 +515,11 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
517
515
|
"$.intervals.reconcile.open: object",
|
|
518
516
|
"$.intervals.reconcile: object",
|
|
519
517
|
"$.intervals.verify:types.closed: array",
|
|
520
|
-
"$.intervals.verify:types.closed[].end: number",
|
|
521
|
-
"$.intervals.verify:types.closed[].start: number",
|
|
522
|
-
"$.intervals.verify:types.closed[].startSeq: number",
|
|
523
|
-
"$.intervals.verify:types.closed[]: object",
|
|
524
518
|
"$.intervals.verify:types.open.start: number",
|
|
525
519
|
"$.intervals.verify:types.open.startSeq: number",
|
|
526
520
|
"$.intervals.verify:types.open: object",
|
|
527
521
|
"$.intervals.verify:types: object",
|
|
528
522
|
"$.intervals.verify:unit.closed: array",
|
|
529
|
-
"$.intervals.verify:unit.closed[].end: number",
|
|
530
|
-
"$.intervals.verify:unit.closed[].start: number",
|
|
531
|
-
"$.intervals.verify:unit.closed[].startSeq: number",
|
|
532
|
-
"$.intervals.verify:unit.closed[]: object",
|
|
533
523
|
"$.intervals.verify:unit.open.start: number",
|
|
534
524
|
"$.intervals.verify:unit.open.startSeq: number",
|
|
535
525
|
"$.intervals.verify:unit.open: object",
|
|
@@ -584,6 +574,23 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
584
574
|
"$.workspaceReleased: number",
|
|
585
575
|
"$: object",
|
|
586
576
|
],
|
|
577
|
+
"dispatchFailureBudget": [
|
|
578
|
+
"$.aborted: boolean",
|
|
579
|
+
"$.failures: array",
|
|
580
|
+
"$.failures[].actor.kind: string",
|
|
581
|
+
"$.failures[].actor: object",
|
|
582
|
+
"$.failures[].build: string",
|
|
583
|
+
"$.failures[].payload.attempt: number",
|
|
584
|
+
"$.failures[].payload.error: string",
|
|
585
|
+
"$.failures[].payload.stage: string",
|
|
586
|
+
"$.failures[].payload: object",
|
|
587
|
+
"$.failures[].seq: number",
|
|
588
|
+
"$.failures[].ts: string",
|
|
589
|
+
"$.failures[].type: string",
|
|
590
|
+
"$.failures[]: object",
|
|
591
|
+
"$.open: array",
|
|
592
|
+
"$: object",
|
|
593
|
+
],
|
|
587
594
|
"dispatchSettings": [
|
|
588
595
|
"$.autoMergeSeq: number",
|
|
589
596
|
"$.defaultAutoMerge: boolean",
|
|
@@ -611,6 +618,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
611
618
|
"$.run: string",
|
|
612
619
|
"$.warningNotice: string",
|
|
613
620
|
"$.warningNotice: undefined",
|
|
621
|
+
"$.yieldedHolder: undefined",
|
|
614
622
|
"$: object",
|
|
615
623
|
],
|
|
616
624
|
"frozenPrImageHost": [
|
|
@@ -715,20 +723,6 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
715
723
|
"$.byKind.screenshot.type: string",
|
|
716
724
|
"$.byKind.screenshot: object",
|
|
717
725
|
"$.byKind: object",
|
|
718
|
-
"$.hostedByDesignation.1.actor.kind: string",
|
|
719
|
-
"$.hostedByDesignation.1.actor: object",
|
|
720
|
-
"$.hostedByDesignation.1.build: string",
|
|
721
|
-
"$.hostedByDesignation.1.payload.asset.assetId: number",
|
|
722
|
-
"$.hostedByDesignation.1.payload.asset.provider: string",
|
|
723
|
-
"$.hostedByDesignation.1.payload.asset.releaseId: number",
|
|
724
|
-
"$.hostedByDesignation.1.payload.asset.repository: string",
|
|
725
|
-
"$.hostedByDesignation.1.payload.asset.url: string",
|
|
726
|
-
"$.hostedByDesignation.1.payload.asset: object",
|
|
727
|
-
"$.hostedByDesignation.1.payload.designationSeq: number",
|
|
728
|
-
"$.hostedByDesignation.1.payload: object",
|
|
729
|
-
"$.hostedByDesignation.1.seq: number",
|
|
730
|
-
"$.hostedByDesignation.1.ts: string",
|
|
731
|
-
"$.hostedByDesignation.1.type: string",
|
|
732
726
|
"$.hostedByDesignation.12.actor.kind: string",
|
|
733
727
|
"$.hostedByDesignation.12.actor: object",
|
|
734
728
|
"$.hostedByDesignation.12.build: string",
|
|
@@ -744,37 +738,36 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
744
738
|
"$.hostedByDesignation.12.ts: string",
|
|
745
739
|
"$.hostedByDesignation.12.type: string",
|
|
746
740
|
"$.hostedByDesignation.12: object",
|
|
747
|
-
"$.hostedByDesignation.
|
|
748
|
-
"$.hostedByDesignation.
|
|
749
|
-
"$.hostedByDesignation.
|
|
750
|
-
"$.hostedByDesignation.
|
|
751
|
-
"$.hostedByDesignation.
|
|
752
|
-
"$.hostedByDesignation.
|
|
753
|
-
"$.hostedByDesignation.
|
|
754
|
-
"$.hostedByDesignation.
|
|
755
|
-
"$.hostedByDesignation.
|
|
756
|
-
"$.hostedByDesignation.
|
|
757
|
-
"$.hostedByDesignation.
|
|
758
|
-
"$.hostedByDesignation.
|
|
759
|
-
"$.hostedByDesignation.
|
|
760
|
-
"$.hostedByDesignation.
|
|
761
|
-
"$.hostedByDesignation.
|
|
762
|
-
"$.hostedByDesignation.
|
|
763
|
-
"$.hostedByDesignation.
|
|
764
|
-
"$.hostedByDesignation.
|
|
765
|
-
"$.hostedByDesignation.
|
|
766
|
-
"$.hostedByDesignation.
|
|
767
|
-
"$.hostedByDesignation.
|
|
768
|
-
"$.hostedByDesignation.
|
|
769
|
-
"$.hostedByDesignation.
|
|
770
|
-
"$.hostedByDesignation.
|
|
771
|
-
"$.hostedByDesignation.
|
|
772
|
-
"$.hostedByDesignation.
|
|
773
|
-
"$.hostedByDesignation.
|
|
774
|
-
"$.hostedByDesignation.
|
|
775
|
-
"$.hostedByDesignation.
|
|
776
|
-
"$.hostedByDesignation.
|
|
777
|
-
"$.hostedByDesignation.2: object",
|
|
741
|
+
"$.hostedByDesignation.13.actor.kind: string",
|
|
742
|
+
"$.hostedByDesignation.13.actor: object",
|
|
743
|
+
"$.hostedByDesignation.13.build: string",
|
|
744
|
+
"$.hostedByDesignation.13.payload.asset.assetId: number",
|
|
745
|
+
"$.hostedByDesignation.13.payload.asset.provider: string",
|
|
746
|
+
"$.hostedByDesignation.13.payload.asset.releaseId: number",
|
|
747
|
+
"$.hostedByDesignation.13.payload.asset.repository: string",
|
|
748
|
+
"$.hostedByDesignation.13.payload.asset.url: string",
|
|
749
|
+
"$.hostedByDesignation.13.payload.asset: object",
|
|
750
|
+
"$.hostedByDesignation.13.payload.designationSeq: number",
|
|
751
|
+
"$.hostedByDesignation.13.payload: object",
|
|
752
|
+
"$.hostedByDesignation.13.seq: number",
|
|
753
|
+
"$.hostedByDesignation.13.ts: string",
|
|
754
|
+
"$.hostedByDesignation.13.type: string",
|
|
755
|
+
"$.hostedByDesignation.13: object",
|
|
756
|
+
"$.hostedByDesignation.19.actor.kind: string",
|
|
757
|
+
"$.hostedByDesignation.19.actor: object",
|
|
758
|
+
"$.hostedByDesignation.19.build: string",
|
|
759
|
+
"$.hostedByDesignation.19.payload.asset.assetId: number",
|
|
760
|
+
"$.hostedByDesignation.19.payload.asset.provider: string",
|
|
761
|
+
"$.hostedByDesignation.19.payload.asset.releaseId: number",
|
|
762
|
+
"$.hostedByDesignation.19.payload.asset.repository: string",
|
|
763
|
+
"$.hostedByDesignation.19.payload.asset.url: string",
|
|
764
|
+
"$.hostedByDesignation.19.payload.asset: object",
|
|
765
|
+
"$.hostedByDesignation.19.payload.designationSeq: number",
|
|
766
|
+
"$.hostedByDesignation.19.payload: object",
|
|
767
|
+
"$.hostedByDesignation.19.seq: number",
|
|
768
|
+
"$.hostedByDesignation.19.ts: string",
|
|
769
|
+
"$.hostedByDesignation.19.type: string",
|
|
770
|
+
"$.hostedByDesignation.19: object",
|
|
778
771
|
"$.hostedByDesignation.3.actor.kind: string",
|
|
779
772
|
"$.hostedByDesignation.3.actor: object",
|
|
780
773
|
"$.hostedByDesignation.3.build: string",
|
|
@@ -805,6 +798,36 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
805
798
|
"$.hostedByDesignation.4.ts: string",
|
|
806
799
|
"$.hostedByDesignation.4.type: string",
|
|
807
800
|
"$.hostedByDesignation.4: object",
|
|
801
|
+
"$.hostedByDesignation.5.actor.kind: string",
|
|
802
|
+
"$.hostedByDesignation.5.actor: object",
|
|
803
|
+
"$.hostedByDesignation.5.build: string",
|
|
804
|
+
"$.hostedByDesignation.5.payload.asset.assetId: number",
|
|
805
|
+
"$.hostedByDesignation.5.payload.asset.provider: string",
|
|
806
|
+
"$.hostedByDesignation.5.payload.asset.releaseId: number",
|
|
807
|
+
"$.hostedByDesignation.5.payload.asset.repository: string",
|
|
808
|
+
"$.hostedByDesignation.5.payload.asset.url: string",
|
|
809
|
+
"$.hostedByDesignation.5.payload.asset: object",
|
|
810
|
+
"$.hostedByDesignation.5.payload.designationSeq: number",
|
|
811
|
+
"$.hostedByDesignation.5.payload: object",
|
|
812
|
+
"$.hostedByDesignation.5.seq: number",
|
|
813
|
+
"$.hostedByDesignation.5.ts: string",
|
|
814
|
+
"$.hostedByDesignation.5.type: string",
|
|
815
|
+
"$.hostedByDesignation.5: object",
|
|
816
|
+
"$.hostedByDesignation.6.actor.kind: string",
|
|
817
|
+
"$.hostedByDesignation.6.actor: object",
|
|
818
|
+
"$.hostedByDesignation.6.build: string",
|
|
819
|
+
"$.hostedByDesignation.6.payload.asset.assetId: number",
|
|
820
|
+
"$.hostedByDesignation.6.payload.asset.provider: string",
|
|
821
|
+
"$.hostedByDesignation.6.payload.asset.releaseId: number",
|
|
822
|
+
"$.hostedByDesignation.6.payload.asset.repository: string",
|
|
823
|
+
"$.hostedByDesignation.6.payload.asset.url: string",
|
|
824
|
+
"$.hostedByDesignation.6.payload.asset: object",
|
|
825
|
+
"$.hostedByDesignation.6.payload.designationSeq: number",
|
|
826
|
+
"$.hostedByDesignation.6.payload: object",
|
|
827
|
+
"$.hostedByDesignation.6.seq: number",
|
|
828
|
+
"$.hostedByDesignation.6.ts: string",
|
|
829
|
+
"$.hostedByDesignation.6.type: string",
|
|
830
|
+
"$.hostedByDesignation.6: object",
|
|
808
831
|
"$.hostedByDesignation.8.actor.kind: string",
|
|
809
832
|
"$.hostedByDesignation.8.actor: object",
|
|
810
833
|
"$.hostedByDesignation.8.build: string",
|
|
@@ -837,6 +860,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
837
860
|
"$.retained[].actor.user: string",
|
|
838
861
|
"$.retained[].actor: object",
|
|
839
862
|
"$.retained[].payload.attempt: number",
|
|
863
|
+
"$.retained[].payload.cause: string",
|
|
840
864
|
"$.retained[].payload.counters.claimed: number",
|
|
841
865
|
"$.retained[].payload.counters.closed: number",
|
|
842
866
|
"$.retained[].payload.counters.conflicted: number",
|
|
@@ -872,6 +896,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
872
896
|
"$.retained[].payload.observations[].build: string",
|
|
873
897
|
"$.retained[].payload.observations[].seq: number",
|
|
874
898
|
"$.retained[].payload.observations[]: object",
|
|
899
|
+
"$.retained[].payload.operation: string",
|
|
875
900
|
"$.retained[].payload.operator: string",
|
|
876
901
|
"$.retained[].payload.outcome: string",
|
|
877
902
|
"$.retained[].payload.pid: number",
|
|
@@ -881,6 +906,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
881
906
|
"$.retained[].payload.report.kind: string",
|
|
882
907
|
"$.retained[].payload.report.rev: number",
|
|
883
908
|
"$.retained[].payload.report: object",
|
|
909
|
+
"$.retained[].payload.resetAt: string",
|
|
884
910
|
"$.retained[].payload.roleWarnings: array",
|
|
885
911
|
"$.retained[].payload.roleWarnings[]: string",
|
|
886
912
|
"$.retained[].payload.run: string",
|
|
@@ -1018,16 +1044,15 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1018
1044
|
"$.hosted[].type: string",
|
|
1019
1045
|
"$.hosted[]: object",
|
|
1020
1046
|
"$.reclaimedAt.10: number",
|
|
1021
|
-
"$.reclaimedAt.
|
|
1022
|
-
"$.reclaimedAt.15: number",
|
|
1047
|
+
"$.reclaimedAt.12: number",
|
|
1023
1048
|
"$.reclaimedAt.16: number",
|
|
1024
|
-
"$.reclaimedAt.
|
|
1025
|
-
"$.reclaimedAt.
|
|
1049
|
+
"$.reclaimedAt.17: number",
|
|
1050
|
+
"$.reclaimedAt.19: number",
|
|
1026
1051
|
"$.reclaimedAt.20: number",
|
|
1027
|
-
"$.reclaimedAt.
|
|
1052
|
+
"$.reclaimedAt.2: number",
|
|
1028
1053
|
"$.reclaimedAt.6: number",
|
|
1029
|
-
"$.reclaimedAt.7: number",
|
|
1030
1054
|
"$.reclaimedAt.8: number",
|
|
1055
|
+
"$.reclaimedAt.9: number",
|
|
1031
1056
|
"$.reclaimedAt: object",
|
|
1032
1057
|
"$: object",
|
|
1033
1058
|
],
|
|
@@ -1103,6 +1128,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1103
1128
|
"$.ledger[].request: number",
|
|
1104
1129
|
"$.ledger[].round: number",
|
|
1105
1130
|
"$.ledger[].seq: number",
|
|
1131
|
+
"$.ledger[].seq: undefined",
|
|
1106
1132
|
"$.ledger[].step: string",
|
|
1107
1133
|
"$.ledger[].t: string",
|
|
1108
1134
|
"$.ledger[]: object",
|
|
@@ -1156,6 +1182,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1156
1182
|
"$.retained[].payload.base: string",
|
|
1157
1183
|
"$.retained[].payload.baseBranch: string",
|
|
1158
1184
|
"$.retained[].payload.baseSha: string",
|
|
1185
|
+
"$.retained[].payload.boundary: number",
|
|
1159
1186
|
"$.retained[].payload.branch: string",
|
|
1160
1187
|
"$.retained[].payload.cause: string",
|
|
1161
1188
|
"$.retained[].payload.cleanupPending: boolean",
|
|
@@ -1180,6 +1207,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1180
1207
|
"$.retained[].payload.defaultSeq: number",
|
|
1181
1208
|
"$.retained[].payload.dependencyDiagnostics: array",
|
|
1182
1209
|
"$.retained[].payload.designationSeq: number",
|
|
1210
|
+
"$.retained[].payload.disposition: string",
|
|
1183
1211
|
"$.retained[].payload.dispositions: array",
|
|
1184
1212
|
"$.retained[].payload.dispositions[].action: string",
|
|
1185
1213
|
"$.retained[].payload.dispositions[].occurrence.build: string",
|
|
@@ -1190,6 +1218,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1190
1218
|
"$.retained[].payload.effectiveConfig.kind: string",
|
|
1191
1219
|
"$.retained[].payload.effectiveConfig.rev: number",
|
|
1192
1220
|
"$.retained[].payload.effectiveConfig: object",
|
|
1221
|
+
"$.retained[].payload.eligibleAfter: string",
|
|
1193
1222
|
"$.retained[].payload.enabled: boolean",
|
|
1194
1223
|
"$.retained[].payload.environmentId: string",
|
|
1195
1224
|
"$.retained[].payload.error: string",
|
|
@@ -1219,6 +1248,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1219
1248
|
"$.retained[].payload.observations[].build: string",
|
|
1220
1249
|
"$.retained[].payload.observations[].seq: number",
|
|
1221
1250
|
"$.retained[].payload.observations[]: object",
|
|
1251
|
+
"$.retained[].payload.occurrence: number",
|
|
1222
1252
|
"$.retained[].payload.ok: boolean",
|
|
1223
1253
|
"$.retained[].payload.operation: string",
|
|
1224
1254
|
"$.retained[].payload.operator: string",
|
|
@@ -1231,6 +1261,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1231
1261
|
"$.retained[].payload.pr.headSha: string",
|
|
1232
1262
|
"$.retained[].payload.pr.number: number",
|
|
1233
1263
|
"$.retained[].payload.pr.url: string",
|
|
1264
|
+
"$.retained[].payload.pr: number",
|
|
1234
1265
|
"$.retained[].payload.pr: object",
|
|
1235
1266
|
"$.retained[].payload.provider: string",
|
|
1236
1267
|
"$.retained[].payload.question: string",
|
|
@@ -1245,6 +1276,7 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1245
1276
|
"$.retained[].payload.report.rev: number",
|
|
1246
1277
|
"$.retained[].payload.report: object",
|
|
1247
1278
|
"$.retained[].payload.request: number",
|
|
1279
|
+
"$.retained[].payload.resetAt: string",
|
|
1248
1280
|
"$.retained[].payload.resolution: string",
|
|
1249
1281
|
"$.retained[].payload.retryable: boolean",
|
|
1250
1282
|
"$.retained[].payload.role: string",
|
|
@@ -1359,6 +1391,39 @@ exports[`reducer registry accumulator shapes 1`] = `
|
|
|
1359
1391
|
"$.failures[]: number",
|
|
1360
1392
|
"$: object",
|
|
1361
1393
|
],
|
|
1394
|
+
"summaryBoundary": [
|
|
1395
|
+
"$.boundary: number",
|
|
1396
|
+
"$.occurrence: number",
|
|
1397
|
+
"$.sessions.s_a: boolean",
|
|
1398
|
+
"$.sessions.s_b: boolean",
|
|
1399
|
+
"$.sessions: object",
|
|
1400
|
+
"$: object",
|
|
1401
|
+
],
|
|
1402
|
+
"summaryRequests": [
|
|
1403
|
+
"$.requests: array",
|
|
1404
|
+
"$.requests[].actor.kind: string",
|
|
1405
|
+
"$.requests[].actor: object",
|
|
1406
|
+
"$.requests[].build: string",
|
|
1407
|
+
"$.requests[].payload.boundary: number",
|
|
1408
|
+
"$.requests[].payload.occurrence: number",
|
|
1409
|
+
"$.requests[].payload: object",
|
|
1410
|
+
"$.requests[].seq: number",
|
|
1411
|
+
"$.requests[].ts: string",
|
|
1412
|
+
"$.requests[].type: string",
|
|
1413
|
+
"$.requests[]: object",
|
|
1414
|
+
"$.settled: array",
|
|
1415
|
+
"$.settled[]: number",
|
|
1416
|
+
"$: object",
|
|
1417
|
+
],
|
|
1418
|
+
"ticketSourceHealth": [
|
|
1419
|
+
"$.active.cause: string",
|
|
1420
|
+
"$.active.message: string",
|
|
1421
|
+
"$.active.operation: string",
|
|
1422
|
+
"$.active.resetAt: string",
|
|
1423
|
+
"$.active.source: string",
|
|
1424
|
+
"$.active: object",
|
|
1425
|
+
"$: object",
|
|
1426
|
+
],
|
|
1362
1427
|
"verifyDiffBase": [
|
|
1363
1428
|
"$.pendingReconcileBase: string",
|
|
1364
1429
|
"$.promoted: string",
|
|
@@ -12,6 +12,7 @@ export interface DispatchStatus {
|
|
|
12
12
|
queued?: number
|
|
13
13
|
/** Standing count from newer tick facts; absent for historical events. */
|
|
14
14
|
creationWithheld?: number
|
|
15
|
+
yieldedHolder?: string
|
|
15
16
|
availableUpgrade?: string
|
|
16
17
|
roleWarnings: string[]
|
|
17
18
|
diagnostics: string[]
|
|
@@ -58,6 +59,7 @@ export function reduceDispatchStatus(
|
|
|
58
59
|
state.lastSeq = event.seq
|
|
59
60
|
switch (event.type) {
|
|
60
61
|
case 'dispatcher.run-started':
|
|
62
|
+
state.yieldedHolder = undefined
|
|
61
63
|
state.health = 'running'
|
|
62
64
|
state.effectiveConfig = event.payload.effectiveConfig
|
|
63
65
|
state.roleWarnings = [...event.payload.roleWarnings]
|
|
@@ -88,6 +90,12 @@ export function reduceDispatchStatus(
|
|
|
88
90
|
)
|
|
89
91
|
state.warningNotice = state.notice
|
|
90
92
|
break
|
|
93
|
+
case 'dispatcher.tick-yielded':
|
|
94
|
+
state.yieldedHolder = event.payload.holder
|
|
95
|
+
break
|
|
96
|
+
case 'dispatcher.tick-started':
|
|
97
|
+
state.yieldedHolder = undefined
|
|
98
|
+
break
|
|
91
99
|
case 'dispatcher.tick-completed':
|
|
92
100
|
state.queued = event.payload.queued
|
|
93
101
|
state.creationWithheld = event.payload.counters.creationWithheld
|
|
@@ -143,7 +151,7 @@ export function reduceDispatchStatus(
|
|
|
143
151
|
|
|
144
152
|
/** Bump when `DispatchStatus`'s shape or fold semantics change (it is its own
|
|
145
153
|
* accumulator: `lastSeq` makes the fold skip already-seen events). */
|
|
146
|
-
export const DISPATCH_STATUS_REDUCER_VERSION =
|
|
154
|
+
export const DISPATCH_STATUS_REDUCER_VERSION = 2
|
|
147
155
|
|
|
148
156
|
/** The incremental form of `reduceDispatchStatus` for one run. The run is a
|
|
149
157
|
* parameter, so this is a factory. */
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { RepositoryEvent } from '../events/repository'
|
|
2
|
+
import type { RepositoryRecord } from '../store/types'
|
|
3
|
+
|
|
4
|
+
export function projectDispatcherLiveness(
|
|
5
|
+
record: RepositoryRecord | null,
|
|
6
|
+
events: RepositoryEvent[],
|
|
7
|
+
now: Date,
|
|
8
|
+
) {
|
|
9
|
+
const ordered = [...events].sort((a, b) => a.seq - b.seq)
|
|
10
|
+
const age = (at: string) => Math.max(0, now.getTime() - Date.parse(at))
|
|
11
|
+
const run = (id: string) => {
|
|
12
|
+
const start = ordered.find((e) => e.type === 'dispatcher.run-started' && e.payload.run === id)
|
|
13
|
+
const stop = ordered.findLast(
|
|
14
|
+
(e) => e.type === 'dispatcher.run-stopped' && e.payload.run === id,
|
|
15
|
+
)
|
|
16
|
+
const tick = ordered.findLast(
|
|
17
|
+
(e) =>
|
|
18
|
+
(e.type === 'dispatcher.tick-completed' || e.type === 'dispatcher.tick-failed') &&
|
|
19
|
+
e.payload.run === id,
|
|
20
|
+
)
|
|
21
|
+
const heartbeatAt =
|
|
22
|
+
record?.lease?.holder === id && start && record.heartbeatAt && record.heartbeatAt >= start.ts
|
|
23
|
+
? record.heartbeatAt
|
|
24
|
+
: null
|
|
25
|
+
return {
|
|
26
|
+
run: id,
|
|
27
|
+
pid: start?.type === 'dispatcher.run-started' ? start.payload.pid : null,
|
|
28
|
+
host: start?.type === 'dispatcher.run-started' ? (start.payload.host ?? null) : null,
|
|
29
|
+
startedAt: start?.ts ?? null,
|
|
30
|
+
heartbeatAt,
|
|
31
|
+
heartbeatAgeMs: heartbeatAt === null ? null : age(heartbeatAt),
|
|
32
|
+
leaseExpiresAt: record?.lease?.holder === id ? record.lease.expiresAt : null,
|
|
33
|
+
lastTickAt: tick?.ts ?? null,
|
|
34
|
+
lastTickAgeMs: tick ? age(tick.ts) : null,
|
|
35
|
+
lastTick:
|
|
36
|
+
tick?.type === 'dispatcher.tick-completed'
|
|
37
|
+
? { outcome: 'completed' as const, counters: tick.payload.counters }
|
|
38
|
+
: tick?.type === 'dispatcher.tick-failed'
|
|
39
|
+
? { outcome: 'failed' as const, error: tick.payload.error }
|
|
40
|
+
: null,
|
|
41
|
+
stoppedAt: stop?.ts ?? null,
|
|
42
|
+
stop: stop?.type === 'dispatcher.run-stopped' ? stop.payload : null,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const latest = ordered.findLast((e) => e.type === 'dispatcher.run-started')
|
|
46
|
+
const latestStop = ordered.findLast((e) => e.type === 'dispatcher.run-stopped')
|
|
47
|
+
const owner = record?.lease ? run(record.lease.holder) : null
|
|
48
|
+
const held =
|
|
49
|
+
owner !== null && owner.stop === null && Date.parse(record!.lease!.expiresAt) > now.getTime()
|
|
50
|
+
return {
|
|
51
|
+
state: held
|
|
52
|
+
? ('held' as const)
|
|
53
|
+
: owner && !owner.stop
|
|
54
|
+
? ('lost' as const)
|
|
55
|
+
: latestStop
|
|
56
|
+
? ('stopped' as const)
|
|
57
|
+
: ('absent' as const),
|
|
58
|
+
holder: held ? owner : null,
|
|
59
|
+
expiredHolder: !held && owner && !owner.stop ? owner : null,
|
|
60
|
+
latestRun: latest?.type === 'dispatcher.run-started' ? run(latest.payload.run) : null,
|
|
61
|
+
latestStoppedRun:
|
|
62
|
+
latestStop?.type === 'dispatcher.run-stopped' ? run(latestStop.payload.run) : null,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export type DispatcherLiveness = ReturnType<typeof projectDispatcherLiveness>
|
|
66
|
+
export function formatDispatcherIdentity(
|
|
67
|
+
run: NonNullable<DispatcherLiveness['latestRun']>,
|
|
68
|
+
): string {
|
|
69
|
+
return `${run.run}; pid ${run.pid ?? 'unknown'}; host ${run.host ?? 'unknown'}; started ${run.startedAt ?? 'unknown'}; ${run.heartbeatAgeMs === null ? 'heartbeat unknown (no renewal attributable to this run)' : `heartbeat ${run.heartbeatAgeMs}ms ago`}`
|
|
70
|
+
}
|
|
@@ -55,6 +55,7 @@ export type VerifyAction =
|
|
|
55
55
|
export type FinalizeAction = { kind: 'check'; command: string } | { kind: 'agent'; skill: string }
|
|
56
56
|
|
|
57
57
|
export type Decision =
|
|
58
|
+
| { kind: 'capture-reconcile-policy'; reconcileSeq: number }
|
|
58
59
|
| { kind: 'wait'; reason: WaitReason }
|
|
59
60
|
| { kind: 'acknowledge'; command: 'pause' | 'resume' | 'abort' }
|
|
60
61
|
| {
|
|
@@ -80,6 +81,7 @@ export type Decision =
|
|
|
80
81
|
step: string
|
|
81
82
|
attempt: number
|
|
82
83
|
reason: string
|
|
84
|
+
skipCause?: 'post-reconcile-policy'
|
|
83
85
|
}
|
|
84
86
|
| { kind: 'run-finalize-step'; step: string; action: FinalizeAction }
|
|
85
87
|
| {
|
|
@@ -313,6 +315,18 @@ export function decideNextFromFacts(state: BuildState, log: LogIndex, config: Co
|
|
|
313
315
|
const cycleAttempts = [...cycleResults, ...cycleStarted].map((v) => v.attempt)
|
|
314
316
|
const attempt =
|
|
315
317
|
cycleAttempts.length > 0 ? Math.max(...cycleAttempts) : log.maxVerifyAttemptEver + 1
|
|
318
|
+
// Freeze only a fresh reconcile cycle. A newer code-review approval restores
|
|
319
|
+
// ordinary verification. Already-started historical cycles have no snapshot:
|
|
320
|
+
// preserve their rerun-all policy, including after a crashed verify start.
|
|
321
|
+
const reconcileCycle =
|
|
322
|
+
log.lastReconcileCompletedSeq > Math.max(log.code.latestApproveSeq, log.restartSeq)
|
|
323
|
+
const policy =
|
|
324
|
+
reconcileCycle && log.reconcilePolicy?.reconcileSeq === cycleBoundary
|
|
325
|
+
? log.reconcilePolicy
|
|
326
|
+
: undefined
|
|
327
|
+
if (reconcileCycle && policy === undefined && cycleAttempts.length === 0) {
|
|
328
|
+
return { kind: 'capture-reconcile-policy', reconcileSeq: cycleBoundary }
|
|
329
|
+
}
|
|
316
330
|
const approvedPlan = log.plan.approvedPlan
|
|
317
331
|
const approvedSelection =
|
|
318
332
|
approvedPlan?.verifySteps === undefined
|
|
@@ -333,6 +347,16 @@ export function decideNextFromFacts(state: BuildState, log: LogIndex, config: Co
|
|
|
333
347
|
const stepConfig = config.verify.stepConfigs[step]
|
|
334
348
|
if (stepConfig === undefined) continue // unreachable: configSchema cross-validates (§16.1)
|
|
335
349
|
|
|
350
|
+
const exclusion = policy?.steps.find((s) => s.step === step && !s.enabled)
|
|
351
|
+
if (exclusion !== undefined)
|
|
352
|
+
return {
|
|
353
|
+
kind: 'skip-verify',
|
|
354
|
+
step,
|
|
355
|
+
attempt,
|
|
356
|
+
skipCause: 'post-reconcile-policy',
|
|
357
|
+
reason: `skipped by post-reconcile policy: ${exclusion.source} = false`,
|
|
358
|
+
}
|
|
359
|
+
|
|
336
360
|
// Missing selection data is the historical default-all behavior. For a
|
|
337
361
|
// current explicit selection, exclusion precedes path evaluation and any
|
|
338
362
|
// verifier construction. Mandatory gates remain selected defensively even
|
|
@@ -207,6 +207,16 @@ function randomWrite(rand: () => number): EventWrite {
|
|
|
207
207
|
},
|
|
208
208
|
}),
|
|
209
209
|
() => w('pr-attachment.reclaimed', { hostedSeq: 1 + Math.floor(rand() * 20) }),
|
|
210
|
+
() => w('pr-summary.requested', { occurrence: round, boundary: round + 1 }),
|
|
211
|
+
() => w('pr-summary.settled', { request: round, disposition: 'attempted' }),
|
|
212
|
+
() => w('pr-summary.attempted', { occurrence: round, boundary: round + 1, pr: 7 }),
|
|
213
|
+
() =>
|
|
214
|
+
w('pr-summary.result', {
|
|
215
|
+
attempt: round,
|
|
216
|
+
outcome: 'rate-limited',
|
|
217
|
+
eligibleAfter: '2026-10-15T00:01:00.000Z',
|
|
218
|
+
}),
|
|
219
|
+
() => w('finalize.step-started', { step: 'notes' }),
|
|
210
220
|
() => w('build.auto-merge-default-observed', { defaultSeq: round }),
|
|
211
221
|
() =>
|
|
212
222
|
w('observation.recorded', {
|