@atolis-hq/wake 0.2.97 → 0.3.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/dist/src/activities/agent/agent-activity-definition.js +26 -0
- package/dist/src/activities/agent/agent-activity.js +171 -0
- package/dist/src/activities/agent/agent-result.js +149 -0
- package/dist/src/activities/contracts/activity.js +10 -0
- package/dist/src/activities/contracts/config.js +2 -0
- package/dist/src/activities/contracts/event-schema.js +302 -0
- package/dist/src/activities/contracts/events.js +42 -0
- package/dist/src/activities/contracts/identifiers.js +29 -0
- package/dist/src/activities/contracts/registry.js +71 -0
- package/dist/src/activities/contracts/streams.js +17 -0
- package/dist/src/activities/contracts/vocabulary.js +58 -0
- package/dist/src/activities/index.js +21 -0
- package/dist/src/activities/pr/activity-support.js +111 -0
- package/dist/src/activities/pr/application.js +158 -0
- package/dist/src/activities/pr/approve.js +85 -0
- package/dist/src/activities/pr/capability.js +11 -0
- package/dist/src/activities/pr/decision-claim.js +76 -0
- package/dist/src/activities/pr/event-drafts.js +66 -0
- package/dist/src/activities/pr/intent.js +37 -0
- package/dist/src/activities/pr/merge-authority-gate.js +14 -0
- package/dist/src/activities/pr/merge.js +110 -0
- package/dist/src/activities/pr/policy.js +135 -0
- package/dist/src/activities/pr/projection.js +130 -0
- package/dist/src/activities/pr/vocabulary.js +30 -0
- package/dist/src/activities/review/authorization.js +22 -0
- package/dist/src/activities/review/contracts.js +22 -0
- package/dist/src/activities/review/signals.js +3 -0
- package/dist/src/bootstrap/analytics-projection.js +26 -0
- package/dist/src/bootstrap/board-projection.js +337 -0
- package/dist/src/bootstrap/composition-root.js +382 -0
- package/dist/src/bootstrap/config/load-config.js +51 -0
- package/dist/src/bootstrap/config/root-schema.js +134 -0
- package/dist/src/bootstrap/external-ref.js +12 -0
- package/dist/src/bootstrap/fake-provider-files.js +44 -0
- package/dist/src/bootstrap/fake-scenarios.js +22 -0
- package/dist/src/bootstrap/index.js +48 -0
- package/dist/src/bootstrap/initialise.js +434 -0
- package/dist/src/bootstrap/paths.js +15 -0
- package/dist/src/bootstrap/projection-runtime.js +27 -0
- package/dist/src/bootstrap/runner-quota-reporter.js +21 -0
- package/dist/src/bootstrap/runner-registry.js +30 -0
- package/dist/src/bootstrap/schedule-checkpoint-store.js +49 -0
- package/dist/src/bootstrap/self-update-application.js +195 -0
- package/dist/src/bootstrap/self-update-failure-log.js +33 -0
- package/dist/src/bootstrap/source-update-port.js +47 -0
- package/dist/src/bootstrap/status-publish-activity.js +42 -0
- package/dist/src/bootstrap/surface-api-applications.js +325 -0
- package/dist/src/bootstrap/surface-api-execution-applications.js +95 -0
- package/dist/src/bootstrap/surface-api-metadata.js +12 -0
- package/dist/src/bootstrap/surface-api-projection-pages.js +22 -0
- package/dist/src/bootstrap/surface-api-run-context.js +5 -0
- package/dist/src/bootstrap/surface-api-transcripts.js +57 -0
- package/dist/src/bootstrap/surface-api-work-applications.js +199 -0
- package/dist/src/bootstrap/surface-applications.js +7 -0
- package/dist/src/bootstrap/surface-cli-applications.js +701 -0
- package/dist/src/bootstrap/update-ledger.js +61 -0
- package/dist/src/bootstrap/update-maintenance-lease.js +176 -0
- package/dist/src/{version.js → bootstrap/version.js} +35 -51
- package/dist/src/control-plane/application/advance-once.js +184 -0
- package/dist/src/control-plane/application/control-plane-projection.js +42 -0
- package/dist/src/control-plane/application/control-plane-service.js +42 -0
- package/dist/src/control-plane/application/intake-pipeline.js +29 -0
- package/dist/src/control-plane/application/runner-control-service.js +66 -0
- package/dist/src/control-plane/application/runner-pipeline.js +57 -0
- package/dist/src/control-plane/application/schedule-service.js +47 -0
- package/dist/src/control-plane/application/work-cancellation-policy.js +31 -0
- package/dist/src/control-plane/contracts/commands.js +10 -0
- package/dist/src/control-plane/contracts/config.js +22 -0
- package/dist/src/control-plane/contracts/events.js +81 -0
- package/dist/src/control-plane/contracts/streams.js +5 -0
- package/dist/src/control-plane/domain/dispatch-policy.js +15 -0
- package/dist/src/control-plane/domain/quota-policy.js +26 -0
- package/dist/src/control-plane/domain/runner-quota.js +35 -0
- package/dist/src/control-plane/domain/schedule-policy.js +46 -0
- package/dist/src/control-plane/index.js +20 -0
- package/dist/src/control-plane/infrastructure/intake-host.js +24 -0
- package/dist/src/control-plane/infrastructure/resident-host.js +45 -0
- package/dist/src/control-plane/infrastructure/tick-host.js +35 -0
- package/dist/src/execution/application/activation-claim.js +50 -0
- package/dist/src/execution/application/active-run-cancellation.js +14 -0
- package/dist/src/execution/application/execution-activity.js +97 -0
- package/dist/src/execution/application/execution-projection.js +17 -0
- package/dist/src/execution/application/execution-service.js +372 -0
- package/dist/src/execution/application/execution-validation.js +26 -0
- package/dist/src/execution/application/recovery-service.js +212 -0
- package/dist/src/execution/application/run-lifecycle.js +115 -0
- package/dist/src/execution/application/run-liveness-service.js +80 -0
- package/dist/src/execution/application/run-repository.js +27 -0
- package/dist/src/execution/contracts/commands.js +1 -0
- package/dist/src/execution/contracts/config.js +35 -0
- package/dist/src/execution/contracts/control-plane.js +1 -0
- package/dist/src/execution/contracts/event-factory.js +53 -0
- package/dist/src/execution/contracts/events.js +274 -0
- package/dist/src/execution/contracts/identifiers.js +5 -0
- package/dist/src/execution/contracts/liveness.js +1 -0
- package/dist/src/execution/contracts/results.js +1 -0
- package/dist/src/execution/contracts/runner.js +15 -0
- package/dist/src/execution/contracts/streams.js +10 -0
- package/dist/src/execution/contracts/views.js +1 -0
- package/dist/src/execution/contracts/vocabulary.js +43 -0
- package/dist/src/execution/contracts/workspace.js +1 -0
- package/dist/src/execution/domain/run-result.js +34 -0
- package/dist/src/execution/domain/run.js +142 -0
- package/dist/src/execution/index.js +31 -0
- package/dist/src/execution/infrastructure/agent-runner-adapter.js +114 -0
- package/dist/src/execution/infrastructure/process-execution.js +29 -0
- package/dist/src/execution/infrastructure/prompt-templates.js +42 -0
- package/dist/src/execution/infrastructure/runners/claude.js +120 -0
- package/dist/src/execution/infrastructure/runners/codex.js +143 -0
- package/dist/src/execution/infrastructure/runners/command.js +4 -0
- package/dist/src/execution/infrastructure/runners/cursor.js +69 -0
- package/dist/src/execution/infrastructure/runners/fake-scenarios.js +99 -0
- package/dist/src/execution/infrastructure/runners/fake.js +65 -0
- package/dist/src/execution/infrastructure/runners/registry.js +26 -0
- package/dist/src/execution/infrastructure/transcript-store.js +223 -0
- package/dist/src/execution/infrastructure/transcripts.js +11 -0
- package/dist/src/execution/infrastructure/workspace/fake-workspace.js +19 -0
- package/dist/src/execution/infrastructure/workspace/git-workspace.js +241 -0
- package/dist/src/integrations/application/agent-run-publication-reactor.js +111 -0
- package/dist/src/integrations/application/artifact-registration-reactor.js +159 -0
- package/dist/src/integrations/application/poll-service.js +25 -0
- package/dist/src/integrations/application/terminal-agent-run-report.js +40 -0
- package/dist/src/integrations/application/work-admission.js +31 -0
- package/dist/src/integrations/application/work-conclusion.js +19 -0
- package/dist/src/integrations/contracts/artifact-events.js +60 -0
- package/dist/src/integrations/contracts/artifact-vocabulary.js +9 -0
- package/dist/src/integrations/contracts/config.js +14 -0
- package/dist/src/integrations/contracts/identifiers.js +5 -0
- package/dist/src/integrations/contracts/intake-rules.js +14 -0
- package/dist/src/integrations/contracts/intake.js +1 -0
- package/dist/src/integrations/contracts/outcome-vocabulary.js +7 -0
- package/dist/src/integrations/contracts/provider.js +37 -0
- package/dist/src/integrations/contracts/streams.js +10 -0
- package/dist/src/integrations/delivery/application/delivery-outcome-reactor.js +75 -0
- package/dist/src/integrations/delivery/application/delivery-projector.js +165 -0
- package/dist/src/integrations/delivery/application/delivery-service.js +173 -0
- package/dist/src/integrations/delivery/contracts/commands.js +1 -0
- package/dist/src/integrations/delivery/contracts/config.js +1 -0
- package/dist/src/integrations/delivery/contracts/event-factory.js +18 -0
- package/dist/src/integrations/delivery/contracts/events.js +86 -0
- package/dist/src/integrations/delivery/contracts/intents.js +89 -0
- package/dist/src/integrations/delivery/contracts/views.js +1 -0
- package/dist/src/integrations/delivery/contracts/vocabulary.js +22 -0
- package/dist/src/integrations/fake/durable-delivery-provider.js +48 -0
- package/dist/src/integrations/fake/external-sink.js +9 -0
- package/dist/src/integrations/fake/external-source.js +44 -0
- package/dist/src/integrations/fake/inbound-translator.js +130 -0
- package/dist/src/integrations/fake/provider.js +95 -0
- package/dist/src/integrations/github/application/agent-context-reader.js +54 -0
- package/dist/src/integrations/github/application/agent-run-comment.js +94 -0
- package/dist/src/integrations/github/application/comment-history-reader.js +43 -0
- package/dist/src/integrations/github/application/inbound-context.js +10 -0
- package/dist/src/integrations/github/application/inbound-review-signals.js +159 -0
- package/dist/src/integrations/github/application/inbound-translator.js +231 -0
- package/dist/src/integrations/github/application/inbound-watch-gate-signals.js +84 -0
- package/dist/src/integrations/github/application/intake-policy.js +23 -0
- package/dist/src/integrations/github/application/outbound-translator.js +47 -0
- package/dist/src/integrations/github/application/poll-service.js +29 -0
- package/dist/src/integrations/github/application/pull-request-translation.js +10 -0
- package/dist/src/integrations/github/application/resource-links.js +8 -0
- package/dist/src/integrations/github/application/review-command-translator.js +16 -0
- package/dist/src/integrations/github/application/wake-labels.js +95 -0
- package/dist/src/integrations/github/contracts/config.js +47 -0
- package/dist/src/integrations/github/contracts/events.js +127 -0
- package/dist/src/integrations/github/contracts/external-key.js +19 -0
- package/dist/src/integrations/github/contracts/payloads.js +9 -0
- package/dist/src/integrations/github/contracts/vocabulary.js +55 -0
- package/dist/src/integrations/github/index.js +31 -0
- package/dist/src/integrations/github/infrastructure/client-reads.js +214 -0
- package/dist/src/integrations/github/infrastructure/client.js +132 -0
- package/dist/src/integrations/github/infrastructure/content-fingerprint.js +10 -0
- package/dist/src/integrations/github/infrastructure/delivery.js +31 -0
- package/dist/src/integrations/github/infrastructure/etag-cache.js +56 -0
- package/dist/src/integrations/github/infrastructure/gh-auth.js +19 -0
- package/dist/src/integrations/github/infrastructure/issue-source.js +109 -0
- package/dist/src/integrations/github/infrastructure/pr-source.js +186 -0
- package/dist/src/integrations/github/infrastructure/review-source.js +70 -0
- package/dist/src/integrations/github/infrastructure/source.js +108 -0
- package/dist/src/integrations/github/provider.js +96 -0
- package/dist/src/integrations/index.js +30 -0
- package/dist/src/kernel/contracts/checkpoint-store.js +1 -0
- package/dist/src/kernel/contracts/clock.js +1 -0
- package/dist/src/kernel/contracts/commands.js +1 -0
- package/dist/src/kernel/contracts/event-journal.js +2 -0
- package/dist/src/kernel/contracts/event-schema.js +54 -0
- package/dist/src/kernel/contracts/events.js +11 -0
- package/dist/src/kernel/contracts/id-generator.js +1 -0
- package/dist/src/kernel/contracts/identifiers.js +8 -0
- package/dist/src/kernel/contracts/projection-store.js +1 -0
- package/dist/src/kernel/contracts/relations.js +1 -0
- package/dist/src/kernel/contracts/schema.js +17 -0
- package/dist/src/kernel/contracts/vocabulary.js +6 -0
- package/dist/src/kernel/domain/event-envelope.js +29 -0
- package/dist/src/kernel/domain/match-mode.js +11 -0
- package/dist/src/kernel/domain/relation.js +10 -0
- package/dist/src/kernel/index.js +17 -0
- package/dist/src/{lib/clock.js → kernel/infrastructure/system-clock.js} +3 -3
- package/dist/src/kernel/infrastructure/ulid-id-generator.js +9 -0
- package/dist/src/main.js +137 -1030
- package/dist/src/orchestration/application/accept-activity-outcome.js +25 -0
- package/dist/src/orchestration/application/accept-signal.js +35 -0
- package/dist/src/orchestration/application/advance-workflow.js +160 -0
- package/dist/src/orchestration/application/coordination-claims.js +107 -0
- package/dist/src/orchestration/application/group-budget-recorder.js +43 -0
- package/dist/src/orchestration/application/orchestration-projection.js +20 -0
- package/dist/src/orchestration/application/orchestration-repository.js +36 -0
- package/dist/src/orchestration/application/orchestration-service.js +82 -0
- package/dist/src/orchestration/application/request-child.js +118 -0
- package/dist/src/orchestration/application/signal-reactor.js +17 -0
- package/dist/src/orchestration/application/start-workflow.js +51 -0
- package/dist/src/orchestration/application/watch-reactor.js +82 -0
- package/dist/src/orchestration/contracts/activity-outcome.js +18 -0
- package/dist/src/orchestration/contracts/commands.js +1 -0
- package/dist/src/orchestration/contracts/config.js +128 -0
- package/dist/src/orchestration/contracts/event-decoder.js +263 -0
- package/dist/src/orchestration/contracts/events.js +41 -0
- package/dist/src/orchestration/contracts/identifiers.js +35 -0
- package/dist/src/orchestration/contracts/streams.js +38 -0
- package/dist/src/orchestration/contracts/views.js +1 -0
- package/dist/src/orchestration/contracts/vocabulary.js +30 -0
- package/dist/src/orchestration/domain/activation-policy.js +55 -0
- package/dist/src/orchestration/domain/approval-defaults.js +17 -0
- package/dist/src/orchestration/domain/child-policy.js +63 -0
- package/dist/src/orchestration/domain/compiler.js +162 -0
- package/dist/src/orchestration/domain/coordination-events.js +25 -0
- package/dist/src/orchestration/domain/decision-events.js +47 -0
- package/dist/src/orchestration/domain/interpreter.js +49 -0
- package/dist/src/orchestration/domain/operator-retry-policy.js +34 -0
- package/dist/src/orchestration/domain/retry-policy.js +26 -0
- package/dist/src/orchestration/domain/signal-policy.js +120 -0
- package/dist/src/orchestration/domain/supplemental-policy.js +61 -0
- package/dist/src/orchestration/domain/transition.js +55 -0
- package/dist/src/orchestration/domain/workflow-graph.js +41 -0
- package/dist/src/orchestration/domain/workflow-instance-events.js +236 -0
- package/dist/src/orchestration/domain/workflow-instance.js +41 -0
- package/dist/src/orchestration/domain/workflow-selector.js +21 -0
- package/dist/src/orchestration/index.js +19 -0
- package/dist/src/persistence/application/projection-runner.js +79 -0
- package/dist/src/persistence/filesystem/file-checkpoint-store.js +35 -0
- package/dist/src/persistence/filesystem/file-event-journal.js +143 -0
- package/dist/src/persistence/filesystem/file-lock.js +91 -0
- package/dist/src/persistence/filesystem/file-projection-store.js +64 -0
- package/dist/src/persistence/index.js +8 -0
- package/dist/src/persistence/memory/in-memory-checkpoint-store.js +14 -0
- package/dist/src/persistence/memory/in-memory-event-journal.js +88 -0
- package/dist/src/persistence/memory/in-memory-projection-store.js +17 -0
- package/dist/src/resources/application/lookup-projections.js +48 -0
- package/dist/src/resources/application/resource-lookup.js +16 -0
- package/dist/src/resources/application/resource-projections.js +81 -0
- package/dist/src/resources/application/resource-repository.js +18 -0
- package/dist/src/resources/application/resource-service.js +83 -0
- package/dist/src/resources/contracts/commands.js +1 -0
- package/dist/src/resources/contracts/config.js +2 -0
- package/dist/src/resources/contracts/events.js +83 -0
- package/dist/src/resources/contracts/identifiers.js +15 -0
- package/dist/src/resources/contracts/streams.js +6 -0
- package/dist/src/resources/contracts/views.js +1 -0
- package/dist/src/resources/contracts/vocabulary.js +67 -0
- package/dist/src/resources/domain/correlation.js +8 -0
- package/dist/src/resources/domain/resource.js +58 -0
- package/dist/src/resources/index.js +14 -0
- package/dist/src/surfaces/api/contracts/activities.js +1 -0
- package/dist/src/surfaces/api/contracts/board.js +2 -0
- package/dist/src/surfaces/api/contracts/common.js +46 -0
- package/dist/src/surfaces/api/contracts/control-plane.js +5 -0
- package/dist/src/surfaces/api/contracts/events.js +1 -0
- package/dist/src/surfaces/api/contracts/execution.js +1 -0
- package/dist/src/surfaces/api/contracts/index.js +13 -0
- package/dist/src/surfaces/api/contracts/observability.js +1 -0
- package/dist/src/surfaces/api/contracts/orchestration.js +1 -0
- package/dist/src/surfaces/api/contracts/resources.js +1 -0
- package/dist/src/surfaces/api/contracts/status.js +1 -0
- package/dist/src/surfaces/api/contracts/system.js +1 -0
- package/dist/src/surfaces/api/contracts/transport-values.js +39 -0
- package/dist/src/surfaces/api/contracts/work.js +17 -0
- package/dist/src/surfaces/api/http-server.js +121 -0
- package/dist/src/surfaces/api/presenters/activities.js +1 -0
- package/dist/src/surfaces/api/presenters/board.js +3 -0
- package/dist/src/surfaces/api/presenters/control-plane.js +1 -0
- package/dist/src/surfaces/api/presenters/events.js +1 -0
- package/dist/src/surfaces/api/presenters/execution.js +59 -0
- package/dist/src/surfaces/api/presenters/observability.js +1 -0
- package/dist/src/surfaces/api/presenters/orchestration.js +19 -0
- package/dist/src/surfaces/api/presenters/resources.js +15 -0
- package/dist/src/surfaces/api/presenters/status.js +3 -0
- package/dist/src/surfaces/api/presenters/system.js +14 -0
- package/dist/src/surfaces/api/presenters/work.js +16 -0
- package/dist/src/surfaces/api/problem-details.js +9 -0
- package/dist/src/surfaces/api/router.js +13 -0
- package/dist/src/surfaces/api/routes/activities.js +1 -0
- package/dist/src/surfaces/api/routes/applications.js +1 -0
- package/dist/src/surfaces/api/routes/commands.js +82 -0
- package/dist/src/surfaces/api/routes/control-plane.js +6 -0
- package/dist/src/surfaces/api/routes/events.js +1 -0
- package/dist/src/surfaces/api/routes/execution.js +8 -0
- package/dist/src/surfaces/api/routes/index.js +18 -0
- package/dist/src/surfaces/api/routes/observability.js +1 -0
- package/dist/src/surfaces/api/routes/orchestration.js +1 -0
- package/dist/src/surfaces/api/routes/pagination.js +78 -0
- package/dist/src/surfaces/api/routes/read.js +135 -0
- package/dist/src/surfaces/api/routes/resources.js +1 -0
- package/dist/src/surfaces/api/routes/responses.js +67 -0
- package/dist/src/surfaces/api/routes/system.js +1 -0
- package/dist/src/surfaces/api/routes/work.js +9 -0
- package/dist/src/surfaces/cli/commands/api.js +1 -0
- package/dist/src/surfaces/cli/commands/audit.js +10 -0
- package/dist/src/surfaces/cli/commands/correlate.js +2 -0
- package/dist/src/surfaces/cli/commands/doctor.js +6 -0
- package/dist/src/surfaces/cli/commands/init.js +39 -0
- package/dist/src/surfaces/cli/commands/sandbox-entrypoint.js +33 -0
- package/dist/src/surfaces/cli/commands/sandbox-setup.js +29 -0
- package/dist/src/surfaces/cli/commands/sandbox.js +105 -0
- package/dist/src/surfaces/cli/commands/self-update.js +38 -0
- package/dist/src/surfaces/cli/commands/smoke.js +16 -0
- package/dist/src/surfaces/cli/commands/start.js +1 -0
- package/dist/src/surfaces/cli/commands/stop.js +13 -0
- package/dist/src/surfaces/cli/commands/tick.js +1 -0
- package/dist/src/surfaces/cli/commands/ui.js +2 -0
- package/dist/src/surfaces/cli/commands/validate-state.js +5 -0
- package/dist/src/surfaces/cli/infrastructure/docker-cli.js +221 -0
- package/dist/src/surfaces/cli/infrastructure/process-log.js +86 -0
- package/dist/src/surfaces/cli/main.js +140 -0
- package/dist/src/surfaces/cli/usage.js +33 -0
- package/dist/src/surfaces/contracts/config.js +34 -0
- package/dist/src/surfaces/index.js +47 -0
- package/dist/src/surfaces/web-assets/assets/index-Bfn4FwZG.css +1 -0
- package/dist/src/surfaces/web-assets/assets/index-ipB6JPGU.js +1090 -0
- package/dist/src/surfaces/web-assets/index.html +13 -0
- package/dist/src/surfaces/web-host/asset-source.js +1 -0
- package/dist/src/surfaces/web-host/packaged-assets.js +44 -0
- package/dist/src/work/application/work-projection.js +59 -0
- package/dist/src/work/application/work-repository.js +18 -0
- package/dist/src/work/application/work-service.js +117 -0
- package/dist/src/work/contracts/commands.js +1 -0
- package/dist/src/work/contracts/config.js +2 -0
- package/dist/src/work/contracts/events.js +103 -0
- package/dist/src/work/contracts/identifiers.js +5 -0
- package/dist/src/work/contracts/streams.js +6 -0
- package/dist/src/work/contracts/views.js +1 -0
- package/dist/src/work/contracts/vocabulary.js +6 -0
- package/dist/src/work/domain/work-item.js +89 -0
- package/dist/src/work/index.js +11 -0
- package/docker/Dockerfile +10 -6
- package/docker/Dockerfile.packaged +3 -3
- package/package.json +29 -4
- package/prompts/implement.md +2 -2
- package/templates/SETUP.md +7 -7
- package/dist/src/adapters/claude/claude-runner.js +0 -529
- package/dist/src/adapters/codex/codex-runner.js +0 -503
- package/dist/src/adapters/cursor/cursor-runner.js +0 -418
- package/dist/src/adapters/docker/docker-cli.js +0 -150
- package/dist/src/adapters/fake/fake-artifact-verifier.js +0 -14
- package/dist/src/adapters/fake/fake-github-pull-request-activity-source.js +0 -77
- package/dist/src/adapters/fake/fake-resource-index.js +0 -21
- package/dist/src/adapters/fake/fake-runner.js +0 -77
- package/dist/src/adapters/fake/fake-ticketing-system.js +0 -185
- package/dist/src/adapters/fake/fake-workspace-manager.js +0 -81
- package/dist/src/adapters/fs/resource-index.js +0 -126
- package/dist/src/adapters/fs/self-update-ledger.js +0 -17
- package/dist/src/adapters/fs/state-store.js +0 -775
- package/dist/src/adapters/git/git-workspace-manager.js +0 -289
- package/dist/src/adapters/github/github-artifact-verifier.js +0 -38
- package/dist/src/adapters/github/github-auth.js +0 -16
- package/dist/src/adapters/github/github-client.js +0 -249
- package/dist/src/adapters/github/github-etag-cache.js +0 -57
- package/dist/src/adapters/github/github-issues-work-source.js +0 -692
- package/dist/src/adapters/github/github-pull-request-activity-source.js +0 -584
- package/dist/src/adapters/github/github-pull-request-merge-actor.js +0 -45
- package/dist/src/adapters/http/ui-assets.js +0 -1188
- package/dist/src/adapters/http/ui-data.js +0 -1107
- package/dist/src/adapters/http/ui-server.js +0 -458
- package/dist/src/adapters/runner/cli-command.js +0 -73
- package/dist/src/adapters/runner/prompt-templates.js +0 -76
- package/dist/src/adapters/runner/runner-cli-adapter.js +0 -112
- package/dist/src/adapters/runner/runner-registry.js +0 -139
- package/dist/src/adapters/runner/runtime-events.js +0 -32
- package/dist/src/adapters/runner/stage-prompt.js +0 -268
- package/dist/src/adapters/runner/transcripts.js +0 -25
- package/dist/src/cli/audit-command.js +0 -36
- package/dist/src/cli/correlate-command.js +0 -62
- package/dist/src/cli/doctor-command.js +0 -48
- package/dist/src/cli/init-command.js +0 -18
- package/dist/src/cli/sandbox-command.js +0 -258
- package/dist/src/cli/sandbox-entrypoint-command.js +0 -88
- package/dist/src/cli/sandbox-exec-logging.js +0 -7
- package/dist/src/cli/sandbox-resume.js +0 -79
- package/dist/src/cli/sandbox-setup-command.js +0 -31
- package/dist/src/cli/scaffold-assets.js +0 -100
- package/dist/src/cli/self-update-command.js +0 -198
- package/dist/src/cli/startup-preflight.js +0 -134
- package/dist/src/cli/stop-command.js +0 -46
- package/dist/src/cli/ui-command.js +0 -27
- package/dist/src/config/defaults.js +0 -10
- package/dist/src/config/discover-config-files.js +0 -11
- package/dist/src/config/load-config.js +0 -69
- package/dist/src/config/split-config.js +0 -14
- package/dist/src/core/active-run-recovery.js +0 -44
- package/dist/src/core/approval-intents.js +0 -16
- package/dist/src/core/audit-events.js +0 -82
- package/dist/src/core/control-plane.js +0 -192
- package/dist/src/core/event-builders.js +0 -153
- package/dist/src/core/event-resolver.js +0 -249
- package/dist/src/core/lifecycle-service.js +0 -8
- package/dist/src/core/live-execution.js +0 -81
- package/dist/src/core/outbox.js +0 -198
- package/dist/src/core/policy-engine.js +0 -389
- package/dist/src/core/projection-updater.js +0 -693
- package/dist/src/core/quota-backoff.js +0 -69
- package/dist/src/core/run-lease.js +0 -38
- package/dist/src/core/scheduled-workflow-source.js +0 -199
- package/dist/src/core/sink-router.js +0 -107
- package/dist/src/core/stale-run-reconciler.js +0 -352
- package/dist/src/core/tick-runner.js +0 -2442
- package/dist/src/core/workspace-cleanup.js +0 -117
- package/dist/src/domain/branch-naming.js +0 -14
- package/dist/src/domain/custom-commands.js +0 -58
- package/dist/src/domain/event-types.js +0 -158
- package/dist/src/domain/manual-labels.js +0 -1
- package/dist/src/domain/resource-uri.js +0 -38
- package/dist/src/domain/runner-routing.js +0 -127
- package/dist/src/domain/runtime-events.js +0 -36
- package/dist/src/domain/schema.js +0 -1233
- package/dist/src/domain/sources.js +0 -16
- package/dist/src/domain/stages.js +0 -36
- package/dist/src/domain/work-item-labels.js +0 -48
- package/dist/src/domain/work-item-lifecycle.js +0 -10
- package/dist/src/domain/work-item-status.js +0 -33
- package/dist/src/domain/workflows.js +0 -159
- package/dist/src/lib/deep-merge.js +0 -14
- package/dist/src/lib/detached-process-logging.js +0 -46
- package/dist/src/lib/event-log.js +0 -21
- package/dist/src/lib/format.js +0 -41
- package/dist/src/lib/json-file.js +0 -23
- package/dist/src/lib/lock.js +0 -181
- package/dist/src/lib/log-rotation.js +0 -42
- package/dist/src/lib/paths.js +0 -52
- package/dist/src/lib/process-identity.js +0 -54
- package/dist/src/lib/state-health.js +0 -30
- package/dist/src/lib/work-id.js +0 -19
- package/dist/src/lib/yaml-file.js +0 -20
- /package/dist/src/{core → activities/pr}/contracts.js +0 -0
- /package/dist/src/{domain/types.js → control-plane/contracts/views.js} +0 -0
|
@@ -1,693 +0,0 @@
|
|
|
1
|
-
import { CORRELATION_PRIMARY_CONFLICT_EVENT, CORRELATION_REGISTERED_EVENT, CORRELATION_RETRACTED_EVENT, RETRY_REQUESTED_EVENT, RUN_REQUESTED_EVENT, RUN_CLAIMED_EVENT, RUN_COMPLETED_EVENT, WORKFLOW_SELECTED_EVENT, WORK_ITEM_DELETED_EVENT, WORK_ITEM_FROZEN_EVENT, WORK_ITEM_UNFROZEN_EVENT, WORKSPACE_CLEANED_EVENT, } from '../domain/event-types.js';
|
|
2
|
-
import { UNRESOLVED_WORK_ITEM_KEY, parseIssueStateRecord } from '../domain/schema.js';
|
|
3
|
-
import { doneRunnerSentinel, rejectedRunnerSentinel, stageFromLabels } from '../domain/stages.js';
|
|
4
|
-
import { FROZEN_WORK_ITEM_LABEL } from '../domain/work-item-lifecycle.js';
|
|
5
|
-
import { workItemStatusForRunOutcome } from '../domain/work-item-status.js';
|
|
6
|
-
import { builtInDefaultWorkflowDefinition, defaultWorkflowName, selectWorkflowForEvent, workflowStageVocabulary, } from '../domain/workflows.js';
|
|
7
|
-
import { isCustomCommandAction } from '../domain/custom-commands.js';
|
|
8
|
-
import { createEventEnvelope } from '../lib/event-log.js';
|
|
9
|
-
function stringArrayFromPayload(value) {
|
|
10
|
-
return Array.isArray(value)
|
|
11
|
-
? value.filter((entry) => typeof entry === 'string')
|
|
12
|
-
: [];
|
|
13
|
-
}
|
|
14
|
-
function configuredStagesForLabels(config) {
|
|
15
|
-
if (config === undefined) {
|
|
16
|
-
return workflowStageVocabulary(builtInDefaultWorkflowDefinition);
|
|
17
|
-
}
|
|
18
|
-
const workflow = config.workflows[defaultWorkflowName(config)];
|
|
19
|
-
return workflow === undefined ? undefined : workflowStageVocabulary(workflow);
|
|
20
|
-
}
|
|
21
|
-
function createProjectionFromIssueEvent(event, config) {
|
|
22
|
-
const issue = event.sourceEventType === 'ticket.upsert' ? event.payload.ticket : event.payload.issue;
|
|
23
|
-
if (issue === undefined || typeof issue !== 'object' || issue === null) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
const labels = Array.isArray(issue.labels)
|
|
27
|
-
? issue.labels
|
|
28
|
-
: [];
|
|
29
|
-
// Only the scheduled-workflow-source's synthetic ticket carries a
|
|
30
|
-
// wake:schedule resourceUri; no other mint path sets this, so `scheduled`
|
|
31
|
-
// has a real backing context field instead of only ever living in a label.
|
|
32
|
-
const scheduled = event.sourceRefs.resourceUri?.split(':')[1] === 'schedule';
|
|
33
|
-
return parseIssueStateRecord({
|
|
34
|
-
schemaVersion: 1,
|
|
35
|
-
workItemKey: event.workItemKey,
|
|
36
|
-
origin: event.sourceSystem,
|
|
37
|
-
issue,
|
|
38
|
-
wake: {
|
|
39
|
-
stage: stageFromLabels(labels, configuredStagesForLabels(config)) ?? 'queue',
|
|
40
|
-
stageHistory: [],
|
|
41
|
-
recentEventIds: [event.eventId],
|
|
42
|
-
syncedAt: event.ingestedAt,
|
|
43
|
-
},
|
|
44
|
-
context: scheduled ? { scheduled: true } : {},
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
async function pinSelectedWorkflow(projection, event, ctx, config) {
|
|
48
|
-
const context = projection.context;
|
|
49
|
-
if (config === undefined || typeof context.workflow === 'string') {
|
|
50
|
-
return projection;
|
|
51
|
-
}
|
|
52
|
-
const workflow = selectWorkflowForEvent(event, config);
|
|
53
|
-
if (workflow === null) {
|
|
54
|
-
return projection;
|
|
55
|
-
}
|
|
56
|
-
const selectedEvent = await ctx.appendEvent(createEventEnvelope({
|
|
57
|
-
eventId: `workflow-selected-${projection.workItemKey}`,
|
|
58
|
-
workItemKey: projection.workItemKey,
|
|
59
|
-
streamScope: 'work-item',
|
|
60
|
-
direction: 'internal',
|
|
61
|
-
sourceSystem: 'wake',
|
|
62
|
-
sourceEventType: WORKFLOW_SELECTED_EVENT,
|
|
63
|
-
sourceRefs: event.sourceRefs,
|
|
64
|
-
occurredAt: event.occurredAt,
|
|
65
|
-
ingestedAt: event.ingestedAt,
|
|
66
|
-
trigger: 'context-only',
|
|
67
|
-
payload: {
|
|
68
|
-
workflow,
|
|
69
|
-
selectedFromEventId: event.eventId,
|
|
70
|
-
},
|
|
71
|
-
}));
|
|
72
|
-
return applyEvent(projection, selectedEvent, ctx, config);
|
|
73
|
-
}
|
|
74
|
-
async function applyEvent(current, event, ctx, config) {
|
|
75
|
-
// The shared sentinel for events whose resource failed mint qualification
|
|
76
|
-
// (tick-runner.ts's resolveInboundEvent, spec D1'). These are durable and
|
|
77
|
-
// inspectable via the event log but must never materialize a projection —
|
|
78
|
-
// otherwise every unqualified ticket.upsert/fake.issue.upsert would create
|
|
79
|
-
// one here on its first sighting (current === null), the same as a real
|
|
80
|
-
// mint, defeating the entire point of the gate. `current` is always null
|
|
81
|
-
// for this key (readIssueState(UNRESOLVED_WORK_ITEM_KEY) never has a file
|
|
82
|
-
// to read), so returning it unchanged is equivalent to "no projection".
|
|
83
|
-
if (event.workItemKey === UNRESOLVED_WORK_ITEM_KEY) {
|
|
84
|
-
return current;
|
|
85
|
-
}
|
|
86
|
-
if (event.sourceEventType === 'fake.issue.upsert' || event.sourceEventType === 'ticket.upsert') {
|
|
87
|
-
const next = createProjectionFromIssueEvent(event, config);
|
|
88
|
-
if (next === null) {
|
|
89
|
-
return current;
|
|
90
|
-
}
|
|
91
|
-
if (current === null) {
|
|
92
|
-
return pinSelectedWorkflow(next, event, ctx, config);
|
|
93
|
-
}
|
|
94
|
-
const nextStageFromLabels = stageFromLabels(next.issue.labels, configuredStagesForLabels(config));
|
|
95
|
-
const shouldReconcileStage = nextStageFromLabels !== undefined && nextStageFromLabels !== current.wake.stage;
|
|
96
|
-
const updated = parseIssueStateRecord({
|
|
97
|
-
...current,
|
|
98
|
-
origin: current.origin,
|
|
99
|
-
issue: next.issue,
|
|
100
|
-
wake: {
|
|
101
|
-
...current.wake,
|
|
102
|
-
...(shouldReconcileStage ? { stage: nextStageFromLabels } : {}),
|
|
103
|
-
syncedAt: event.ingestedAt,
|
|
104
|
-
stageHistory: shouldReconcileStage
|
|
105
|
-
? [
|
|
106
|
-
...current.wake.stageHistory,
|
|
107
|
-
{
|
|
108
|
-
stage: nextStageFromLabels,
|
|
109
|
-
changedAt: event.occurredAt,
|
|
110
|
-
reason: 'github-label-sync',
|
|
111
|
-
},
|
|
112
|
-
]
|
|
113
|
-
: current.wake.stageHistory,
|
|
114
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
115
|
-
},
|
|
116
|
-
});
|
|
117
|
-
return pinSelectedWorkflow(updated, event, ctx, config);
|
|
118
|
-
}
|
|
119
|
-
if (current === null) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
if (event.sourceEventType === WORKFLOW_SELECTED_EVENT) {
|
|
123
|
-
const workflow = event.payload.workflow;
|
|
124
|
-
if (typeof workflow !== 'string') {
|
|
125
|
-
return current;
|
|
126
|
-
}
|
|
127
|
-
return parseIssueStateRecord({
|
|
128
|
-
...current,
|
|
129
|
-
context: {
|
|
130
|
-
...current.context,
|
|
131
|
-
workflow,
|
|
132
|
-
},
|
|
133
|
-
wake: {
|
|
134
|
-
...current.wake,
|
|
135
|
-
syncedAt: event.ingestedAt,
|
|
136
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
if (event.sourceEventType === 'fake.issue.comment.created' ||
|
|
141
|
-
event.sourceEventType === 'ticket.comment.created' ||
|
|
142
|
-
event.sourceEventType === 'ticket.comment.updated' ||
|
|
143
|
-
event.sourceEventType === 'pr.comment.created' ||
|
|
144
|
-
event.sourceEventType === 'pr.review.created' ||
|
|
145
|
-
event.sourceEventType === 'pr.review-comment.created' ||
|
|
146
|
-
event.sourceEventType === 'pr.checks.failed') {
|
|
147
|
-
const comment = event.payload.comment;
|
|
148
|
-
if (comment === undefined || typeof comment !== 'object' || comment === null) {
|
|
149
|
-
return current;
|
|
150
|
-
}
|
|
151
|
-
const isBotAuthored = Boolean(event.derivedHints?.botAuthoredComment);
|
|
152
|
-
const nextComment = {
|
|
153
|
-
...comment,
|
|
154
|
-
isBotAuthored,
|
|
155
|
-
};
|
|
156
|
-
const existingComments = current.comments.filter((entry) => entry.id !== String(comment.id));
|
|
157
|
-
return parseIssueStateRecord({
|
|
158
|
-
...current,
|
|
159
|
-
comments: [...existingComments, nextComment],
|
|
160
|
-
latestComment: nextComment,
|
|
161
|
-
wake: {
|
|
162
|
-
...current.wake,
|
|
163
|
-
syncedAt: event.ingestedAt,
|
|
164
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
165
|
-
},
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
if (event.sourceEventType === RUN_CLAIMED_EVENT) {
|
|
169
|
-
const payload = event.payload;
|
|
170
|
-
if (payload.claimedStage === undefined) {
|
|
171
|
-
return parseIssueStateRecord({
|
|
172
|
-
...current,
|
|
173
|
-
wake: {
|
|
174
|
-
...current.wake,
|
|
175
|
-
syncedAt: event.ingestedAt,
|
|
176
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
177
|
-
},
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
return parseIssueStateRecord({
|
|
181
|
-
...current,
|
|
182
|
-
context: {
|
|
183
|
-
...current.context,
|
|
184
|
-
status: 'working',
|
|
185
|
-
},
|
|
186
|
-
wake: {
|
|
187
|
-
...current.wake,
|
|
188
|
-
stage: payload.claimedStage,
|
|
189
|
-
lastRunId: event.sourceRefs.runId ?? current.wake.lastRunId,
|
|
190
|
-
syncedAt: event.ingestedAt,
|
|
191
|
-
stageHistory: [
|
|
192
|
-
...current.wake.stageHistory,
|
|
193
|
-
{
|
|
194
|
-
stage: payload.claimedStage,
|
|
195
|
-
changedAt: event.occurredAt,
|
|
196
|
-
reason: `run:${payload.action ?? 'unknown'}:claimed`,
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
if (event.sourceEventType === RUN_COMPLETED_EVENT) {
|
|
204
|
-
const payload = event.payload;
|
|
205
|
-
// A historical event stream may still carry the retired AWAITING_APPROVAL
|
|
206
|
-
// sentinel (pre-ADR-0002). Normalize it here, once, so every branch below
|
|
207
|
-
// and the strict runnerSentinelSchema validation on new writes to
|
|
208
|
-
// context.lastRunSentinel only ever see the current four-value
|
|
209
|
-
// vocabulary — replaying an old event stream must still land on the same
|
|
210
|
-
// practical state (approval-gated) as it did before this change.
|
|
211
|
-
const isLegacyAwaitingApproval = payload.sentinel === 'AWAITING_APPROVAL';
|
|
212
|
-
const sentinel = isLegacyAwaitingApproval ? doneRunnerSentinel : payload.sentinel;
|
|
213
|
-
const approvalGated = payload.approvalGated === true || isLegacyAwaitingApproval;
|
|
214
|
-
// A rejecting plan-review/pr-review watcher sub-run (§5, trigger 1) or a
|
|
215
|
-
// human /changes reply (§5, trigger 2) folds onto the parent's context
|
|
216
|
-
// without touching wake.stage/lastRunId/session — same isolation
|
|
217
|
-
// guarantee PR #479 established for watcher runs generally. Checked
|
|
218
|
-
// before the watcherRun early-return below so a rejecting watcher run
|
|
219
|
-
// (which also carries watcherRun: true) still updates status/feedback,
|
|
220
|
-
// while every other watcher-run completion (e.g. an approving DONE
|
|
221
|
-
// verdict) still hits that early-return untouched.
|
|
222
|
-
if (payload.changesRequested === true) {
|
|
223
|
-
const currentChangesRequestedCount = typeof current.context.changesRequestedCount === 'number' &&
|
|
224
|
-
Number.isInteger(current.context.changesRequestedCount)
|
|
225
|
-
? current.context.changesRequestedCount
|
|
226
|
-
: 0;
|
|
227
|
-
const nextChangesRequestedCount = currentChangesRequestedCount + 1;
|
|
228
|
-
const maxRetries = config?.retry.maxChangesRequestedRetries ?? Infinity;
|
|
229
|
-
const escalate = nextChangesRequestedCount > maxRetries;
|
|
230
|
-
return parseIssueStateRecord({
|
|
231
|
-
...current,
|
|
232
|
-
context: {
|
|
233
|
-
...current.context,
|
|
234
|
-
status: escalate ? 'blocked' : 'changes-requested',
|
|
235
|
-
changesRequestedCount: nextChangesRequestedCount,
|
|
236
|
-
...(payload.reviewFeedbackBody === undefined
|
|
237
|
-
? {}
|
|
238
|
-
: { changesRequestedFeedback: payload.reviewFeedbackBody }),
|
|
239
|
-
...(payload.handledCommentId === undefined
|
|
240
|
-
? {}
|
|
241
|
-
: { lastHandledCommentId: payload.handledCommentId }),
|
|
242
|
-
},
|
|
243
|
-
wake: {
|
|
244
|
-
...current.wake,
|
|
245
|
-
syncedAt: event.ingestedAt,
|
|
246
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
247
|
-
},
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
if (payload.watcherRun === true) {
|
|
251
|
-
return parseIssueStateRecord({
|
|
252
|
-
...current,
|
|
253
|
-
wake: {
|
|
254
|
-
...current.wake,
|
|
255
|
-
syncedAt: event.ingestedAt,
|
|
256
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
257
|
-
},
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
// Clear the session when the stage moves forward (new action needed) or the
|
|
261
|
-
// run failed outright. Keep it for BLOCKED so the same action can resume
|
|
262
|
-
// the in-progress session after a human replies.
|
|
263
|
-
const isForwardProgression = payload.nextStage !== undefined && payload.nextStage !== current.wake.stage;
|
|
264
|
-
const stageChanged = payload.nextStage !== undefined && payload.nextStage !== current.wake.stage;
|
|
265
|
-
const isFailed = sentinel === 'FAILED';
|
|
266
|
-
const isCompletedCustomCommand = payload.action !== undefined &&
|
|
267
|
-
sentinel === doneRunnerSentinel &&
|
|
268
|
-
config !== undefined &&
|
|
269
|
-
isCustomCommandAction(payload.action, config);
|
|
270
|
-
const shouldClearSession = isForwardProgression || isFailed;
|
|
271
|
-
const hasPendingChangesRequested = (typeof current.context.changesRequestedCount === 'number' &&
|
|
272
|
-
current.context.changesRequestedCount > 0) ||
|
|
273
|
-
current.context.changesRequestedFeedback !== undefined;
|
|
274
|
-
const resolvesChangesRequested = sentinel === doneRunnerSentinel && (!hasPendingChangesRequested || !approvalGated);
|
|
275
|
-
const currentFailureCount = typeof current.context.failureCount === 'number' &&
|
|
276
|
-
Number.isInteger(current.context.failureCount)
|
|
277
|
-
? current.context.failureCount
|
|
278
|
-
: 0;
|
|
279
|
-
const nextContext = {
|
|
280
|
-
...current.context,
|
|
281
|
-
lastFailureClass: payload.failureClass,
|
|
282
|
-
failureCount: payload.failureClass !== undefined
|
|
283
|
-
? currentFailureCount + 1
|
|
284
|
-
: sentinel === doneRunnerSentinel || sentinel === rejectedRunnerSentinel
|
|
285
|
-
? 0
|
|
286
|
-
: currentFailureCount,
|
|
287
|
-
...(payload.handledCommentId === undefined
|
|
288
|
-
? {}
|
|
289
|
-
: { lastHandledCommentId: payload.handledCommentId }),
|
|
290
|
-
...(sentinel === undefined || isCompletedCustomCommand ? {} : { lastRunSentinel: sentinel }),
|
|
291
|
-
...(payload.action === undefined || isCompletedCustomCommand
|
|
292
|
-
? {}
|
|
293
|
-
: { lastRunAction: payload.action }),
|
|
294
|
-
...(sentinel === doneRunnerSentinel &&
|
|
295
|
-
payload.action !== undefined &&
|
|
296
|
-
!isCompletedCustomCommand
|
|
297
|
-
? { lastCompletedAction: payload.action }
|
|
298
|
-
: {}),
|
|
299
|
-
// Remembered so the approval path knows which action to resume or
|
|
300
|
-
// skip when a human posts /approved. Set only for an approval-gated
|
|
301
|
-
// DONE — REJECTED/BLOCKED/FAILED never gate on human sign-off this way.
|
|
302
|
-
...(sentinel === doneRunnerSentinel && approvalGated && payload.action !== undefined
|
|
303
|
-
? { pendingApprovalAction: payload.action }
|
|
304
|
-
: {}),
|
|
305
|
-
...(sentinel === doneRunnerSentinel && approvalGated
|
|
306
|
-
? { pendingApprovalAllowAutoApproval: payload.allowAutoApproval === true }
|
|
307
|
-
: {}),
|
|
308
|
-
...(payload.executionOutcome !== undefined
|
|
309
|
-
? { lastExecutionOutcome: payload.executionOutcome }
|
|
310
|
-
: {}),
|
|
311
|
-
...(payload.workflowOutcome !== undefined
|
|
312
|
-
? { lastWorkflowOutcome: payload.workflowOutcome }
|
|
313
|
-
: {}),
|
|
314
|
-
...(payload.failurePhase !== undefined ? { lastFailurePhase: payload.failurePhase } : {}),
|
|
315
|
-
...(payload.processStarted !== undefined
|
|
316
|
-
? { lastProcessStarted: payload.processStarted }
|
|
317
|
-
: {}),
|
|
318
|
-
...(payload.workspaceChanged !== undefined
|
|
319
|
-
? { lastWorkspaceChanged: payload.workspaceChanged }
|
|
320
|
-
: {}),
|
|
321
|
-
...(payload.externalSideEffects !== undefined
|
|
322
|
-
? { lastExternalSideEffects: payload.externalSideEffects }
|
|
323
|
-
: {}),
|
|
324
|
-
...(payload.retrySafety !== undefined ? { lastRetrySafety: payload.retrySafety } : {}),
|
|
325
|
-
...(sentinel === undefined || isCompletedCustomCommand
|
|
326
|
-
? {}
|
|
327
|
-
: {
|
|
328
|
-
status: workItemStatusForRunOutcome({
|
|
329
|
-
sentinel: sentinel,
|
|
330
|
-
stage: payload.nextStage ?? current.wake.stage,
|
|
331
|
-
approvalGated,
|
|
332
|
-
}),
|
|
333
|
-
}),
|
|
334
|
-
// An approval-gated DONE after changes-requested only resubmits work for
|
|
335
|
-
// review; the next reviewer verdict decides whether the request was
|
|
336
|
-
// actually resolved. Keep the retry counter through that gate so
|
|
337
|
-
// repeated rejections can hit the configured escalation cap.
|
|
338
|
-
...(resolvesChangesRequested
|
|
339
|
-
? { changesRequestedCount: 0, changesRequestedFeedback: undefined }
|
|
340
|
-
: {}),
|
|
341
|
-
};
|
|
342
|
-
if (sentinel === 'BLOCKED' || sentinel === 'FAILED') {
|
|
343
|
-
nextContext.blockedFromStage = current.wake.stage;
|
|
344
|
-
}
|
|
345
|
-
else if (sentinel !== undefined) {
|
|
346
|
-
delete nextContext.blockedFromStage;
|
|
347
|
-
}
|
|
348
|
-
if (!(sentinel === doneRunnerSentinel && approvalGated) && !isCompletedCustomCommand) {
|
|
349
|
-
delete nextContext.pendingApprovalAction;
|
|
350
|
-
delete nextContext.pendingApprovalAllowAutoApproval;
|
|
351
|
-
}
|
|
352
|
-
return parseIssueStateRecord({
|
|
353
|
-
...current,
|
|
354
|
-
context: nextContext,
|
|
355
|
-
wake: {
|
|
356
|
-
...current.wake,
|
|
357
|
-
stage: payload.nextStage ?? current.wake.stage,
|
|
358
|
-
lastRunId: payload.runId ?? current.wake.lastRunId,
|
|
359
|
-
sessionId: shouldClearSession ? undefined : (payload.sessionId ?? current.wake.sessionId),
|
|
360
|
-
sessionCli: shouldClearSession
|
|
361
|
-
? undefined
|
|
362
|
-
: (payload.sessionCli ?? current.wake.sessionCli),
|
|
363
|
-
workspacePath: payload.workspacePath ?? current.wake.workspacePath,
|
|
364
|
-
blockReason: payload.blockReason ?? current.wake.blockReason,
|
|
365
|
-
syncedAt: event.ingestedAt,
|
|
366
|
-
stageHistory: stageChanged
|
|
367
|
-
? [
|
|
368
|
-
...current.wake.stageHistory,
|
|
369
|
-
{
|
|
370
|
-
stage: payload.nextStage,
|
|
371
|
-
changedAt: event.occurredAt,
|
|
372
|
-
reason: payload.reason ?? event.sourceEventType,
|
|
373
|
-
},
|
|
374
|
-
]
|
|
375
|
-
: current.wake.stageHistory,
|
|
376
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
377
|
-
},
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
if (event.sourceEventType === 'ticket.reply.published') {
|
|
381
|
-
const commentId = event.sourceRefs.commentId;
|
|
382
|
-
if (commentId === undefined) {
|
|
383
|
-
return parseIssueStateRecord({
|
|
384
|
-
...current,
|
|
385
|
-
wake: {
|
|
386
|
-
...current.wake,
|
|
387
|
-
syncedAt: event.ingestedAt,
|
|
388
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
389
|
-
},
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
return parseIssueStateRecord({
|
|
393
|
-
...current,
|
|
394
|
-
wake: {
|
|
395
|
-
...current.wake,
|
|
396
|
-
expectedEcho: {
|
|
397
|
-
...current.wake.expectedEcho,
|
|
398
|
-
commentIds: Array.from(new Set([...current.wake.expectedEcho.commentIds, commentId])),
|
|
399
|
-
},
|
|
400
|
-
syncedAt: event.ingestedAt,
|
|
401
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
402
|
-
},
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
if (event.sourceEventType === RETRY_REQUESTED_EVENT) {
|
|
406
|
-
const nextContext = { ...current.context };
|
|
407
|
-
delete nextContext.lastRunSentinel;
|
|
408
|
-
delete nextContext.lastFailureClass;
|
|
409
|
-
delete nextContext.blockedFromStage;
|
|
410
|
-
return parseIssueStateRecord({
|
|
411
|
-
...current,
|
|
412
|
-
context: nextContext,
|
|
413
|
-
wake: {
|
|
414
|
-
...current.wake,
|
|
415
|
-
syncedAt: event.ingestedAt,
|
|
416
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
417
|
-
},
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
if (event.sourceEventType === RUN_REQUESTED_EVENT) {
|
|
421
|
-
return parseIssueStateRecord({
|
|
422
|
-
...current,
|
|
423
|
-
wake: {
|
|
424
|
-
...current.wake,
|
|
425
|
-
syncedAt: event.ingestedAt,
|
|
426
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
427
|
-
},
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
if (event.sourceEventType === WORK_ITEM_DELETED_EVENT) {
|
|
431
|
-
return parseIssueStateRecord({
|
|
432
|
-
...current,
|
|
433
|
-
context: {
|
|
434
|
-
...current.context,
|
|
435
|
-
deleted: {
|
|
436
|
-
at: event.occurredAt,
|
|
437
|
-
by: typeof event.payload.requestedBy === 'string' ? event.payload.requestedBy : 'unknown',
|
|
438
|
-
},
|
|
439
|
-
},
|
|
440
|
-
wake: {
|
|
441
|
-
...current.wake,
|
|
442
|
-
sessionId: undefined,
|
|
443
|
-
sessionCli: undefined,
|
|
444
|
-
syncedAt: event.ingestedAt,
|
|
445
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
446
|
-
},
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
if (event.sourceEventType === WORK_ITEM_FROZEN_EVENT) {
|
|
450
|
-
return parseIssueStateRecord({
|
|
451
|
-
...current,
|
|
452
|
-
issue: {
|
|
453
|
-
...current.issue,
|
|
454
|
-
labels: Array.from(new Set([...current.issue.labels, FROZEN_WORK_ITEM_LABEL])),
|
|
455
|
-
},
|
|
456
|
-
context: {
|
|
457
|
-
...current.context,
|
|
458
|
-
frozen: {
|
|
459
|
-
at: event.occurredAt,
|
|
460
|
-
by: typeof event.payload.requestedBy === 'string' ? event.payload.requestedBy : 'unknown',
|
|
461
|
-
},
|
|
462
|
-
},
|
|
463
|
-
wake: {
|
|
464
|
-
...current.wake,
|
|
465
|
-
syncedAt: event.ingestedAt,
|
|
466
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
467
|
-
},
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
if (event.sourceEventType === WORK_ITEM_UNFROZEN_EVENT) {
|
|
471
|
-
const nextContext = { ...current.context };
|
|
472
|
-
delete nextContext.frozen;
|
|
473
|
-
return parseIssueStateRecord({
|
|
474
|
-
...current,
|
|
475
|
-
issue: {
|
|
476
|
-
...current.issue,
|
|
477
|
-
labels: current.issue.labels.filter((label) => label !== FROZEN_WORK_ITEM_LABEL),
|
|
478
|
-
},
|
|
479
|
-
context: nextContext,
|
|
480
|
-
wake: {
|
|
481
|
-
...current.wake,
|
|
482
|
-
syncedAt: event.ingestedAt,
|
|
483
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
484
|
-
},
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
if (event.sourceEventType === WORKSPACE_CLEANED_EVENT) {
|
|
488
|
-
return parseIssueStateRecord({
|
|
489
|
-
...current,
|
|
490
|
-
wake: {
|
|
491
|
-
...current.wake,
|
|
492
|
-
workspacePath: undefined,
|
|
493
|
-
syncedAt: event.ingestedAt,
|
|
494
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
495
|
-
},
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
if (event.sourceEventType === 'ticket.labels.updated') {
|
|
499
|
-
const labels = stringArrayFromPayload(event.payload.labels);
|
|
500
|
-
return parseIssueStateRecord({
|
|
501
|
-
...current,
|
|
502
|
-
issue: {
|
|
503
|
-
...current.issue,
|
|
504
|
-
labels,
|
|
505
|
-
},
|
|
506
|
-
wake: {
|
|
507
|
-
...current.wake,
|
|
508
|
-
expectedEcho: {
|
|
509
|
-
...current.wake.expectedEcho,
|
|
510
|
-
labels,
|
|
511
|
-
},
|
|
512
|
-
syncedAt: event.ingestedAt,
|
|
513
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
514
|
-
},
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
// Purely an audit record; must never affect projection state, so a full
|
|
518
|
-
// event replay produces byte-identical output whether or not this
|
|
519
|
-
// synthesized event happens to be included in the batch being folded
|
|
520
|
-
// (it's created as a fold side effect, not iterated over on the original
|
|
521
|
-
// pass, but is naturally present on a later full replay).
|
|
522
|
-
if (event.sourceEventType === CORRELATION_PRIMARY_CONFLICT_EVENT) {
|
|
523
|
-
return current;
|
|
524
|
-
}
|
|
525
|
-
if (event.sourceEventType === CORRELATION_REGISTERED_EVENT) {
|
|
526
|
-
const payload = event.payload;
|
|
527
|
-
// ADR 0001 §6 is a *downgrade* rule, and only a downgrade rule: "a second
|
|
528
|
-
// `primary` registration on a claimed URI is downgraded to `secondary` and
|
|
529
|
-
// a warning event appended." It says nothing about promoting a requested
|
|
530
|
-
// `secondary`, and §5 lists `relation` as a payload input — so a requested
|
|
531
|
-
// `secondary` must stay `secondary`. Folding a requested `secondary` up to
|
|
532
|
-
// `primary` would silently rewrite the declaration the event made, and the
|
|
533
|
-
// downgrade rule is a corruption guard, not a merge rule — it exists to
|
|
534
|
-
// stop a second claim on a URI, not to promote unclaimed ones.
|
|
535
|
-
//
|
|
536
|
-
// (No shipped caller declares `secondary` yet — `wake correlate` hardcodes
|
|
537
|
-
// `primary`. The rule follows the spec's payload contract, which is the
|
|
538
|
-
// standard here; an emitter is #82's scope.)
|
|
539
|
-
//
|
|
540
|
-
// requested primary + held by ANOTHER work item -> secondary + conflict
|
|
541
|
-
// requested primary + unclaimed / held by THIS -> primary, indexed
|
|
542
|
-
// requested secondary -> secondary, unindexed
|
|
543
|
-
//
|
|
544
|
-
// A requested-secondary never touching the index is by design, not an
|
|
545
|
-
// orphan: the index is primary-only (ADR §5 — the resolver stamps the
|
|
546
|
-
// *primary* work item's canonical key), so a secondary has nothing to
|
|
547
|
-
// register. Promotion still requires the incumbent to retract first —
|
|
548
|
-
// never let a second registration silently steal a uri.
|
|
549
|
-
const incumbent = await ctx.resourceIndex.resolve(payload.resourceUri);
|
|
550
|
-
const heldByAnotherWorkItem = incumbent !== undefined && incumbent !== current.workItemKey;
|
|
551
|
-
const relation = payload.relation === 'primary' && !heldByAnotherWorkItem ? 'primary' : 'secondary';
|
|
552
|
-
if (relation === 'primary') {
|
|
553
|
-
await ctx.resourceIndex.register(payload.resourceUri, current.workItemKey);
|
|
554
|
-
}
|
|
555
|
-
else {
|
|
556
|
-
if (payload.relation === 'primary') {
|
|
557
|
-
await ctx.appendEvent(createEventEnvelope({
|
|
558
|
-
eventId: `${event.eventId}-primary-conflict`,
|
|
559
|
-
workItemKey: current.workItemKey,
|
|
560
|
-
streamScope: 'work-item',
|
|
561
|
-
direction: 'internal',
|
|
562
|
-
sourceSystem: 'wake',
|
|
563
|
-
sourceEventType: CORRELATION_PRIMARY_CONFLICT_EVENT,
|
|
564
|
-
sourceRefs: event.sourceRefs,
|
|
565
|
-
occurredAt: event.occurredAt,
|
|
566
|
-
ingestedAt: event.ingestedAt,
|
|
567
|
-
trigger: 'context-only',
|
|
568
|
-
payload: {
|
|
569
|
-
resourceUri: payload.resourceUri,
|
|
570
|
-
incumbentWorkItemKey: incumbent,
|
|
571
|
-
},
|
|
572
|
-
}));
|
|
573
|
-
}
|
|
574
|
-
// Coherent inverse of the retraction gate below: a registration that
|
|
575
|
-
// folds to non-primary must never leave the index stranded crediting
|
|
576
|
-
// this work item. This is reachable as a genuine *self-demotion* — a
|
|
577
|
-
// work item that holds a uri primary and then registers it `secondary`
|
|
578
|
-
// — where leaving the index pointing at us would contradict our own
|
|
579
|
-
// correlatedResources[] entry. Gated on actual index ownership, so the
|
|
580
|
-
// ordinary requested-secondary-on-an-unclaimed-uri case (owner
|
|
581
|
-
// undefined) correctly leaves the index untouched (finding B).
|
|
582
|
-
const owner = await ctx.resourceIndex.resolve(payload.resourceUri);
|
|
583
|
-
if (owner === current.workItemKey) {
|
|
584
|
-
await ctx.resourceIndex.retract(payload.resourceUri);
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
const entry = {
|
|
588
|
-
resourceUri: payload.resourceUri,
|
|
589
|
-
role: payload.role,
|
|
590
|
-
relation,
|
|
591
|
-
provenance: payload.provenance,
|
|
592
|
-
...(payload.registeredBy === undefined ? {} : { registeredBy: payload.registeredBy }),
|
|
593
|
-
registeredAt: event.occurredAt,
|
|
594
|
-
};
|
|
595
|
-
const currentCorrelatedResources = current.correlatedResources;
|
|
596
|
-
const existingIndex = currentCorrelatedResources.findIndex((resource) => resource.resourceUri === payload.resourceUri);
|
|
597
|
-
const correlatedResources = existingIndex === -1
|
|
598
|
-
? [...currentCorrelatedResources, entry]
|
|
599
|
-
: currentCorrelatedResources.map((resource, index) => index === existingIndex ? entry : resource);
|
|
600
|
-
return parseIssueStateRecord({
|
|
601
|
-
...current,
|
|
602
|
-
correlatedResources,
|
|
603
|
-
wake: {
|
|
604
|
-
...current.wake,
|
|
605
|
-
syncedAt: event.ingestedAt,
|
|
606
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
607
|
-
},
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
if (event.sourceEventType === CORRELATION_RETRACTED_EVENT) {
|
|
611
|
-
const payload = event.payload;
|
|
612
|
-
const currentCorrelatedResources = current.correlatedResources;
|
|
613
|
-
// Retract whenever the index currently credits this work item —
|
|
614
|
-
// regardless of the locally stored relation — so the registration and
|
|
615
|
-
// retraction gates are coherent inverses across a demotion. Gating this
|
|
616
|
-
// on `existing?.relation === 'primary'` (the locally folded relation at
|
|
617
|
-
// *registration* time) can strand the index pointing at a work item that
|
|
618
|
-
// no longer holds the resource once that relation has drifted, which is
|
|
619
|
-
// exactly the identity-critical path `resolve()` depends on (finding B).
|
|
620
|
-
const owner = await ctx.resourceIndex.resolve(payload.resourceUri);
|
|
621
|
-
if (owner === current.workItemKey) {
|
|
622
|
-
await ctx.resourceIndex.retract(payload.resourceUri);
|
|
623
|
-
}
|
|
624
|
-
return parseIssueStateRecord({
|
|
625
|
-
...current,
|
|
626
|
-
correlatedResources: currentCorrelatedResources.filter((resource) => resource.resourceUri !== payload.resourceUri),
|
|
627
|
-
wake: {
|
|
628
|
-
...current.wake,
|
|
629
|
-
syncedAt: event.ingestedAt,
|
|
630
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
631
|
-
},
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
return parseIssueStateRecord({
|
|
635
|
-
...current,
|
|
636
|
-
wake: {
|
|
637
|
-
...current.wake,
|
|
638
|
-
syncedAt: event.ingestedAt,
|
|
639
|
-
recentEventIds: [...current.wake.recentEventIds, event.eventId].slice(-10),
|
|
640
|
-
},
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
export function createProjectionUpdater(deps) {
|
|
644
|
-
const applyEventCtx = {
|
|
645
|
-
resourceIndex: deps.resourceIndex,
|
|
646
|
-
appendEvent: (event) => deps.stateStore.appendEventEnvelope(event),
|
|
647
|
-
};
|
|
648
|
-
return {
|
|
649
|
-
async rebuildFromEvents(events) {
|
|
650
|
-
// Correlation-index-affecting events (wake.correlation.registered in
|
|
651
|
-
// particular) must be folded in *globally* ordered time, not grouped by
|
|
652
|
-
// workItemKey and folded per-group. resourceIndex is shared/global
|
|
653
|
-
// across all work items, so whichever group happens to be visited first
|
|
654
|
-
// (Map insertion order — i.e. whichever work item's earliest event
|
|
655
|
-
// happens to appear first in the input array) would otherwise decide
|
|
656
|
-
// who wins a primary claim, independent of when the registration events
|
|
657
|
-
// actually occurred. That makes a full replay (this function, called
|
|
658
|
-
// with every event) diverge from the live/incremental fold (this
|
|
659
|
-
// function, called with one new event at a time as it happens) for any
|
|
660
|
-
// two work items whose creation order and registration order disagree
|
|
661
|
-
// — silently handing resumption for a resource to the wrong work item
|
|
662
|
-
// after `rm -rf state/` + replay. Sorting once, globally, by
|
|
663
|
-
// (ingestedAt, eventId) and folding in that single pass keeps replay
|
|
664
|
-
// and live agreeing by construction, for both the index and the
|
|
665
|
-
// per-work-item projection fold (a global sort is still a valid order
|
|
666
|
-
// for each individual work item's own events, since it's a stable
|
|
667
|
-
// sort over a total order that's consistent with each event's own
|
|
668
|
-
// ingestedAt).
|
|
669
|
-
// Sort is stable (ES2019+), so events sharing an ingestedAt keep their
|
|
670
|
-
// input order — which is append/arrival order, the same order the live
|
|
671
|
-
// fold saw them in. Do not add a tie-break on eventId: ids are not
|
|
672
|
-
// chronological, so that would reorder same-timestamp events within a
|
|
673
|
-
// work item against the order they actually happened.
|
|
674
|
-
const ordered = [...events].sort((left, right) => left.ingestedAt.localeCompare(right.ingestedAt));
|
|
675
|
-
const projections = new Map();
|
|
676
|
-
const touchedWorkItemKeys = [];
|
|
677
|
-
for (const event of ordered) {
|
|
678
|
-
if (!projections.has(event.workItemKey)) {
|
|
679
|
-
touchedWorkItemKeys.push(event.workItemKey);
|
|
680
|
-
projections.set(event.workItemKey, await deps.stateStore.readIssueState(event.workItemKey));
|
|
681
|
-
}
|
|
682
|
-
const current = projections.get(event.workItemKey) ?? null;
|
|
683
|
-
projections.set(event.workItemKey, await applyEvent(current, event, applyEventCtx, deps.config));
|
|
684
|
-
}
|
|
685
|
-
for (const workItemKey of touchedWorkItemKeys) {
|
|
686
|
-
const projection = projections.get(workItemKey) ?? null;
|
|
687
|
-
if (projection !== null) {
|
|
688
|
-
await deps.stateStore.writeIssueState(projection);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
},
|
|
692
|
-
};
|
|
693
|
-
}
|