dorfl 0.0.0 → 0.1.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/advance-ci-template.d.ts +73 -0
- package/dist/advance-ci-template.d.ts.map +1 -0
- package/dist/advance-ci-template.js +104 -0
- package/dist/advance-ci-template.js.map +1 -0
- package/dist/advance-classify.d.ts +132 -0
- package/dist/advance-classify.d.ts.map +1 -0
- package/dist/advance-classify.js +120 -0
- package/dist/advance-classify.js.map +1 -0
- package/dist/advance-drivers.d.ts +182 -0
- package/dist/advance-drivers.d.ts.map +1 -0
- package/dist/advance-drivers.js +231 -0
- package/dist/advance-drivers.js.map +1 -0
- package/dist/advance-isolated.d.ts +156 -0
- package/dist/advance-isolated.d.ts.map +1 -0
- package/dist/advance-isolated.js +256 -0
- package/dist/advance-isolated.js.map +1 -0
- package/dist/advance-lifecycle-template.d.ts +107 -0
- package/dist/advance-lifecycle-template.d.ts.map +1 -0
- package/dist/advance-lifecycle-template.js +668 -0
- package/dist/advance-lifecycle-template.js.map +1 -0
- package/dist/advance-loop-driver.d.ts +325 -0
- package/dist/advance-loop-driver.d.ts.map +1 -0
- package/dist/advance-loop-driver.js +437 -0
- package/dist/advance-loop-driver.js.map +1 -0
- package/dist/advance-treeless-publish.d.ts +108 -0
- package/dist/advance-treeless-publish.d.ts.map +1 -0
- package/dist/advance-treeless-publish.js +71 -0
- package/dist/advance-treeless-publish.js.map +1 -0
- package/dist/advance.d.ts +340 -0
- package/dist/advance.d.ts.map +1 -0
- package/dist/advance.js +1122 -0
- package/dist/advance.js.map +1 -0
- package/dist/advancing-lock.d.ts +294 -0
- package/dist/advancing-lock.d.ts.map +1 -0
- package/dist/advancing-lock.js +594 -0
- package/dist/advancing-lock.js.map +1 -0
- package/dist/agent-launch.d.ts +79 -0
- package/dist/agent-launch.d.ts.map +1 -0
- package/dist/agent-launch.js +61 -0
- package/dist/agent-launch.js.map +1 -0
- package/dist/agent-stop.d.ts +149 -0
- package/dist/agent-stop.d.ts.map +1 -0
- package/dist/agent-stop.js +307 -0
- package/dist/agent-stop.js.map +1 -0
- package/dist/apply-decide.d.ts +127 -0
- package/dist/apply-decide.d.ts.map +1 -0
- package/dist/apply-decide.js +176 -0
- package/dist/apply-decide.js.map +1 -0
- package/dist/apply-merge-action.d.ts +206 -0
- package/dist/apply-merge-action.d.ts.map +1 -0
- package/dist/apply-merge-action.js +307 -0
- package/dist/apply-merge-action.js.map +1 -0
- package/dist/apply-persist.d.ts +174 -0
- package/dist/apply-persist.d.ts.map +1 -0
- package/dist/apply-persist.js +359 -0
- package/dist/apply-persist.js.map +1 -0
- package/dist/arbiter.d.ts +120 -0
- package/dist/arbiter.d.ts.map +1 -0
- package/dist/arbiter.js +255 -0
- package/dist/arbiter.js.map +1 -0
- package/dist/brand.d.ts +70 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +84 -0
- package/dist/brand.js.map +1 -0
- package/dist/buildable-body.d.ts +132 -0
- package/dist/buildable-body.d.ts.map +1 -0
- package/dist/buildable-body.js +131 -0
- package/dist/buildable-body.js.map +1 -0
- package/dist/categorise.d.ts +66 -0
- package/dist/categorise.d.ts.map +1 -0
- package/dist/categorise.js +106 -0
- package/dist/categorise.js.map +1 -0
- package/dist/claim-cas.d.ts +117 -0
- package/dist/claim-cas.d.ts.map +1 -0
- package/dist/claim-cas.js +312 -0
- package/dist/claim-cas.js.map +1 -0
- package/dist/cli-spinner.d.ts +112 -0
- package/dist/cli-spinner.d.ts.map +1 -0
- package/dist/cli-spinner.js +157 -0
- package/dist/cli-spinner.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3094 -0
- package/dist/cli.js.map +1 -0
- package/dist/close-job-template.d.ts +70 -0
- package/dist/close-job-template.d.ts.map +1 -0
- package/dist/close-job-template.js +180 -0
- package/dist/close-job-template.js.map +1 -0
- package/dist/close-job.d.ts +95 -0
- package/dist/close-job.d.ts.map +1 -0
- package/dist/close-job.js +226 -0
- package/dist/close-job.js.map +1 -0
- package/dist/complete.d.ts +361 -0
- package/dist/complete.d.ts.map +1 -0
- package/dist/complete.js +885 -0
- package/dist/complete.js.map +1 -0
- package/dist/concurrency.d.ts +68 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +112 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/config-override.d.ts +76 -0
- package/dist/config-override.d.ts.map +1 -0
- package/dist/config-override.js +50 -0
- package/dist/config-override.js.map +1 -0
- package/dist/config.d.ts +668 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +241 -0
- package/dist/config.js.map +1 -0
- package/dist/continue-branch.d.ts +249 -0
- package/dist/continue-branch.d.ts.map +1 -0
- package/dist/continue-branch.js +389 -0
- package/dist/continue-branch.js.map +1 -0
- package/dist/cwd-section.d.ts +186 -0
- package/dist/cwd-section.d.ts.map +1 -0
- package/dist/cwd-section.js +209 -0
- package/dist/cwd-section.js.map +1 -0
- package/dist/decision-engine.d.ts +170 -0
- package/dist/decision-engine.d.ts.map +1 -0
- package/dist/decision-engine.js +136 -0
- package/dist/decision-engine.js.map +1 -0
- package/dist/detect.d.ts +17 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +118 -0
- package/dist/detect.js.map +1 -0
- package/dist/do-autopick.d.ts +85 -0
- package/dist/do-autopick.d.ts.map +1 -0
- package/dist/do-autopick.js +112 -0
- package/dist/do-autopick.js.map +1 -0
- package/dist/do-config.d.ts +312 -0
- package/dist/do-config.d.ts.map +1 -0
- package/dist/do-config.js +358 -0
- package/dist/do-config.js.map +1 -0
- package/dist/do-remote-auto.d.ts +75 -0
- package/dist/do-remote-auto.d.ts.map +1 -0
- package/dist/do-remote-auto.js +111 -0
- package/dist/do-remote-auto.js.map +1 -0
- package/dist/do.d.ts +621 -0
- package/dist/do.d.ts.map +1 -0
- package/dist/do.js +1882 -0
- package/dist/do.js.map +1 -0
- package/dist/drop-source.d.ts +96 -0
- package/dist/drop-source.d.ts.map +1 -0
- package/dist/drop-source.js +91 -0
- package/dist/drop-source.js.map +1 -0
- package/dist/eligibility.d.ts +46 -0
- package/dist/eligibility.d.ts.map +1 -0
- package/dist/eligibility.js +34 -0
- package/dist/eligibility.js.map +1 -0
- package/dist/env-config.d.ts +51 -0
- package/dist/env-config.d.ts.map +1 -0
- package/dist/env-config.js +272 -0
- package/dist/env-config.js.map +1 -0
- package/dist/failure-cause.d.ts +70 -0
- package/dist/failure-cause.d.ts.map +1 -0
- package/dist/failure-cause.js +126 -0
- package/dist/failure-cause.js.map +1 -0
- package/dist/format.d.ts +43 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +256 -0
- package/dist/format.js.map +1 -0
- package/dist/frontmatter.d.ts +215 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +345 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/gate-readiness.d.ts +84 -0
- package/dist/gate-readiness.d.ts.map +1 -0
- package/dist/gate-readiness.js +103 -0
- package/dist/gate-readiness.js.map +1 -0
- package/dist/gc.d.ts +165 -0
- package/dist/gc.d.ts.map +1 -0
- package/dist/gc.js +313 -0
- package/dist/gc.js.map +1 -0
- package/dist/gh-failure.d.ts +42 -0
- package/dist/gh-failure.d.ts.map +1 -0
- package/dist/gh-failure.js +49 -0
- package/dist/gh-failure.js.map +1 -0
- package/dist/git.d.ts +75 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +130 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +187 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +343 -0
- package/dist/github.js.map +1 -0
- package/dist/harness.d.ts +242 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +157 -0
- package/dist/harness.js.map +1 -0
- package/dist/identity.d.ts +167 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +231 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +147 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/install-ci-branch-protection.d.ts +147 -0
- package/dist/install-ci-branch-protection.d.ts.map +1 -0
- package/dist/install-ci-branch-protection.js +166 -0
- package/dist/install-ci-branch-protection.js.map +1 -0
- package/dist/install-ci-capabilities/advance-lifecycle.d.ts +15 -0
- package/dist/install-ci-capabilities/advance-lifecycle.d.ts.map +1 -0
- package/dist/install-ci-capabilities/advance-lifecycle.js +28 -0
- package/dist/install-ci-capabilities/advance-lifecycle.js.map +1 -0
- package/dist/install-ci-capabilities/close-job.d.ts +13 -0
- package/dist/install-ci-capabilities/close-job.d.ts.map +1 -0
- package/dist/install-ci-capabilities/close-job.js +26 -0
- package/dist/install-ci-capabilities/close-job.js.map +1 -0
- package/dist/install-ci-capabilities/example-noop.d.ts +16 -0
- package/dist/install-ci-capabilities/example-noop.d.ts.map +1 -0
- package/dist/install-ci-capabilities/example-noop.js +23 -0
- package/dist/install-ci-capabilities/example-noop.js.map +1 -0
- package/dist/install-ci-capabilities/intake.d.ts +15 -0
- package/dist/install-ci-capabilities/intake.d.ts.map +1 -0
- package/dist/install-ci-capabilities/intake.js +28 -0
- package/dist/install-ci-capabilities/intake.js.map +1 -0
- package/dist/install-ci-capabilities/verify.d.ts +14 -0
- package/dist/install-ci-capabilities/verify.d.ts.map +1 -0
- package/dist/install-ci-capabilities/verify.js +27 -0
- package/dist/install-ci-capabilities/verify.js.map +1 -0
- package/dist/install-ci-core.d.ts +446 -0
- package/dist/install-ci-core.d.ts.map +1 -0
- package/dist/install-ci-core.js +760 -0
- package/dist/install-ci-core.js.map +1 -0
- package/dist/install-ci-github.d.ts +167 -0
- package/dist/install-ci-github.d.ts.map +1 -0
- package/dist/install-ci-github.js +315 -0
- package/dist/install-ci-github.js.map +1 -0
- package/dist/install-ci.d.ts +105 -0
- package/dist/install-ci.d.ts.map +1 -0
- package/dist/install-ci.js +363 -0
- package/dist/install-ci.js.map +1 -0
- package/dist/intake-event.d.ts +88 -0
- package/dist/intake-event.d.ts.map +1 -0
- package/dist/intake-event.js +66 -0
- package/dist/intake-event.js.map +1 -0
- package/dist/intake-marker.d.ts +95 -0
- package/dist/intake-marker.d.ts.map +1 -0
- package/dist/intake-marker.js +127 -0
- package/dist/intake-marker.js.map +1 -0
- package/dist/intake-triage.d.ts +48 -0
- package/dist/intake-triage.d.ts.map +1 -0
- package/dist/intake-triage.js +95 -0
- package/dist/intake-triage.js.map +1 -0
- package/dist/intake-trigger-template.d.ts +185 -0
- package/dist/intake-trigger-template.d.ts.map +1 -0
- package/dist/intake-trigger-template.js +449 -0
- package/dist/intake-trigger-template.js.map +1 -0
- package/dist/intake.d.ts +569 -0
- package/dist/intake.d.ts.map +1 -0
- package/dist/intake.js +1628 -0
- package/dist/intake.js.map +1 -0
- package/dist/integration-core.d.ts +539 -0
- package/dist/integration-core.d.ts.map +1 -0
- package/dist/integration-core.js +2195 -0
- package/dist/integration-core.js.map +1 -0
- package/dist/integrator.d.ts +343 -0
- package/dist/integrator.d.ts.map +1 -0
- package/dist/integrator.js +400 -0
- package/dist/integrator.js.map +1 -0
- package/dist/isolation.d.ts +219 -0
- package/dist/isolation.d.ts.map +1 -0
- package/dist/isolation.js +261 -0
- package/dist/isolation.js.map +1 -0
- package/dist/issue-provider.d.ts +349 -0
- package/dist/issue-provider.d.ts.map +1 -0
- package/dist/issue-provider.js +360 -0
- package/dist/issue-provider.js.map +1 -0
- package/dist/item-lock.d.ts +626 -0
- package/dist/item-lock.d.ts.map +1 -0
- package/dist/item-lock.js +1381 -0
- package/dist/item-lock.js.map +1 -0
- package/dist/item-path.d.ts +49 -0
- package/dist/item-path.d.ts.map +1 -0
- package/dist/item-path.js +66 -0
- package/dist/item-path.js.map +1 -0
- package/dist/ledger-lint.d.ts +129 -0
- package/dist/ledger-lint.d.ts.map +1 -0
- package/dist/ledger-lint.js +249 -0
- package/dist/ledger-lint.js.map +1 -0
- package/dist/ledger-read.d.ts +357 -0
- package/dist/ledger-read.d.ts.map +1 -0
- package/dist/ledger-read.js +442 -0
- package/dist/ledger-read.js.map +1 -0
- package/dist/ledger-write.d.ts +330 -0
- package/dist/ledger-write.d.ts.map +1 -0
- package/dist/ledger-write.js +411 -0
- package/dist/ledger-write.js.map +1 -0
- package/dist/lifecycle-gather.d.ts +30 -0
- package/dist/lifecycle-gather.d.ts.map +1 -0
- package/dist/lifecycle-gather.js +205 -0
- package/dist/lifecycle-gather.js.map +1 -0
- package/dist/lifecycle-pools.d.ts +180 -0
- package/dist/lifecycle-pools.d.ts.map +1 -0
- package/dist/lifecycle-pools.js +78 -0
- package/dist/lifecycle-pools.js.map +1 -0
- package/dist/merge-question-surfacer.d.ts +166 -0
- package/dist/merge-question-surfacer.d.ts.map +1 -0
- package/dist/merge-question-surfacer.js +297 -0
- package/dist/merge-question-surfacer.js.map +1 -0
- package/dist/mint-adr.d.ts +126 -0
- package/dist/mint-adr.d.ts.map +1 -0
- package/dist/mint-adr.js +257 -0
- package/dist/mint-adr.js.map +1 -0
- package/dist/mirror-pool-scan.d.ts +125 -0
- package/dist/mirror-pool-scan.d.ts.map +1 -0
- package/dist/mirror-pool-scan.js +104 -0
- package/dist/mirror-pool-scan.js.map +1 -0
- package/dist/needs-attention.d.ts +341 -0
- package/dist/needs-attention.d.ts.map +1 -0
- package/dist/needs-attention.js +900 -0
- package/dist/needs-attention.js.map +1 -0
- package/dist/orphan-sidecar.d.ts +79 -0
- package/dist/orphan-sidecar.d.ts.map +1 -0
- package/dist/orphan-sidecar.js +71 -0
- package/dist/orphan-sidecar.js.map +1 -0
- package/dist/output.d.ts +48 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +66 -0
- package/dist/output.js.map +1 -0
- package/dist/pi-harness.d.ts +179 -0
- package/dist/pi-harness.d.ts.map +1 -0
- package/dist/pi-harness.js +342 -0
- package/dist/pi-harness.js.map +1 -0
- package/dist/placement.d.ts +99 -0
- package/dist/placement.d.ts.map +1 -0
- package/dist/placement.js +67 -0
- package/dist/placement.js.map +1 -0
- package/dist/prd-to-spec.d.ts +315 -0
- package/dist/prd-to-spec.d.ts.map +1 -0
- package/dist/prd-to-spec.js +684 -0
- package/dist/prd-to-spec.js.map +1 -0
- package/dist/prepare.d.ts +121 -0
- package/dist/prepare.d.ts.map +1 -0
- package/dist/prepare.js +140 -0
- package/dist/prepare.js.map +1 -0
- package/dist/prompt.d.ts +360 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +499 -0
- package/dist/prompt.js.map +1 -0
- package/dist/protocol/ADR-FORMAT.md +47 -0
- package/dist/protocol/CLAIM-PROTOCOL.md +217 -0
- package/dist/protocol/REVIEW-PROTOCOL.md +119 -0
- package/dist/protocol/SURFACE-PROTOCOL.md +121 -0
- package/dist/protocol/TASKING-PROTOCOL.md +122 -0
- package/dist/protocol/WORK-CONTRACT.md +276 -0
- package/dist/protocol/spec-template.md +71 -0
- package/dist/protocol/task-template.md +65 -0
- package/dist/readiness.d.ts +66 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +36 -0
- package/dist/readiness.js.map +1 -0
- package/dist/reap-branches.d.ts +102 -0
- package/dist/reap-branches.d.ts.map +1 -0
- package/dist/reap-branches.js +149 -0
- package/dist/reap-branches.js.map +1 -0
- package/dist/recover-isolated.d.ts +72 -0
- package/dist/recover-isolated.d.ts.map +1 -0
- package/dist/recover-isolated.js +188 -0
- package/dist/recover-isolated.js.map +1 -0
- package/dist/registry.d.ts +172 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +296 -0
- package/dist/registry.js.map +1 -0
- package/dist/repo-config.d.ts +201 -0
- package/dist/repo-config.d.ts.map +1 -0
- package/dist/repo-config.js +414 -0
- package/dist/repo-config.js.map +1 -0
- package/dist/repo-key.d.ts +20 -0
- package/dist/repo-key.d.ts.map +1 -0
- package/dist/repo-key.js +68 -0
- package/dist/repo-key.js.map +1 -0
- package/dist/repo-mirror.d.ts +177 -0
- package/dist/repo-mirror.d.ts.map +1 -0
- package/dist/repo-mirror.js +271 -0
- package/dist/repo-mirror.js.map +1 -0
- package/dist/retry-backoff.d.ts +90 -0
- package/dist/retry-backoff.d.ts.map +1 -0
- package/dist/retry-backoff.js +98 -0
- package/dist/retry-backoff.js.map +1 -0
- package/dist/review-gate.d.ts +173 -0
- package/dist/review-gate.d.ts.map +1 -0
- package/dist/review-gate.js +261 -0
- package/dist/review-gate.js.map +1 -0
- package/dist/review-verdict.d.ts +149 -0
- package/dist/review-verdict.d.ts.map +1 -0
- package/dist/review-verdict.js +332 -0
- package/dist/review-verdict.js.map +1 -0
- package/dist/run.d.ts +221 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +963 -0
- package/dist/run.js.map +1 -0
- package/dist/scan.d.ts +308 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +374 -0
- package/dist/scan.js.map +1 -0
- package/dist/select-order.d.ts +75 -0
- package/dist/select-order.d.ts.map +1 -0
- package/dist/select-order.js +108 -0
- package/dist/select-order.js.map +1 -0
- package/dist/select-priority.d.ts +188 -0
- package/dist/select-priority.d.ts.map +1 -0
- package/dist/select-priority.js +80 -0
- package/dist/select-priority.js.map +1 -0
- package/dist/select.d.ts +25 -0
- package/dist/select.d.ts.map +1 -0
- package/dist/select.js +43 -0
- package/dist/select.js.map +1 -0
- package/dist/session-path.d.ts +36 -0
- package/dist/session-path.d.ts.map +1 -0
- package/dist/session-path.js +129 -0
- package/dist/session-path.js.map +1 -0
- package/dist/sidecar-apply.d.ts +83 -0
- package/dist/sidecar-apply.d.ts.map +1 -0
- package/dist/sidecar-apply.js +111 -0
- package/dist/sidecar-apply.js.map +1 -0
- package/dist/sidecar.d.ts +245 -0
- package/dist/sidecar.d.ts.map +1 -0
- package/dist/sidecar.js +481 -0
- package/dist/sidecar.js.map +1 -0
- package/dist/slug-namespace.d.ts +204 -0
- package/dist/slug-namespace.d.ts.map +1 -0
- package/dist/slug-namespace.js +229 -0
- package/dist/slug-namespace.js.map +1 -0
- package/dist/spec-complete.d.ts +44 -0
- package/dist/spec-complete.d.ts.map +1 -0
- package/dist/spec-complete.js +69 -0
- package/dist/spec-complete.js.map +1 -0
- package/dist/start.d.ts +97 -0
- package/dist/start.d.ts.map +1 -0
- package/dist/start.js +633 -0
- package/dist/start.js.map +1 -0
- package/dist/status.d.ts +199 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +228 -0
- package/dist/status.js.map +1 -0
- package/dist/surface-gate.d.ts +162 -0
- package/dist/surface-gate.d.ts.map +1 -0
- package/dist/surface-gate.js +206 -0
- package/dist/surface-gate.js.map +1 -0
- package/dist/surface-persist.d.ts +86 -0
- package/dist/surface-persist.d.ts.map +1 -0
- package/dist/surface-persist.js +129 -0
- package/dist/surface-persist.js.map +1 -0
- package/dist/tasker-review-loop.d.ts +249 -0
- package/dist/tasker-review-loop.d.ts.map +1 -0
- package/dist/tasker-review-loop.js +369 -0
- package/dist/tasker-review-loop.js.map +1 -0
- package/dist/tasking-eligibility.d.ts +74 -0
- package/dist/tasking-eligibility.d.ts.map +1 -0
- package/dist/tasking-eligibility.js +52 -0
- package/dist/tasking-eligibility.js.map +1 -0
- package/dist/tasking-lock.d.ts +111 -0
- package/dist/tasking-lock.d.ts.map +1 -0
- package/dist/tasking-lock.js +256 -0
- package/dist/tasking-lock.js.map +1 -0
- package/dist/tasking.d.ts +275 -0
- package/dist/tasking.d.ts.map +1 -0
- package/dist/tasking.js +952 -0
- package/dist/tasking.js.map +1 -0
- package/dist/triage-gate.d.ts +127 -0
- package/dist/triage-gate.d.ts.map +1 -0
- package/dist/triage-gate.js +139 -0
- package/dist/triage-gate.js.map +1 -0
- package/dist/triage-persist.d.ts +163 -0
- package/dist/triage-persist.d.ts.map +1 -0
- package/dist/triage-persist.js +387 -0
- package/dist/triage-persist.js.map +1 -0
- package/dist/verdict-json.d.ts +32 -0
- package/dist/verdict-json.d.ts.map +1 -0
- package/dist/verdict-json.js +74 -0
- package/dist/verdict-json.js.map +1 -0
- package/dist/verify-workflow-template.d.ts +60 -0
- package/dist/verify-workflow-template.d.ts.map +1 -0
- package/dist/verify-workflow-template.js +126 -0
- package/dist/verify-workflow-template.js.map +1 -0
- package/dist/verify.d.ts +60 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +62 -0
- package/dist/verify.js.map +1 -0
- package/dist/watch-session.d.ts +112 -0
- package/dist/watch-session.d.ts.map +1 -0
- package/dist/watch-session.js +347 -0
- package/dist/watch-session.js.map +1 -0
- package/dist/work-layout.d.ts +198 -0
- package/dist/work-layout.d.ts.map +1 -0
- package/dist/work-layout.js +217 -0
- package/dist/work-layout.js.map +1 -0
- package/dist/work-on.d.ts +154 -0
- package/dist/work-on.d.ts.map +1 -0
- package/dist/work-on.js +387 -0
- package/dist/work-on.js.map +1 -0
- package/dist/workspace.d.ts +224 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +325 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +46 -2
- package/src/advance-ci-template.ts +203 -0
- package/src/advance-classify.ts +197 -0
- package/src/advance-drivers.ts +414 -0
- package/src/advance-isolated.ts +432 -0
- package/src/advance-lifecycle-template.ts +791 -0
- package/src/advance-loop-driver.ts +745 -0
- package/src/advance-treeless-publish.ts +177 -0
- package/src/advance.ts +1564 -0
- package/src/advancing-lock.ts +988 -0
- package/src/agent-launch.ts +137 -0
- package/src/agent-stop.ts +361 -0
- package/src/apply-decide.ts +242 -0
- package/src/apply-merge-action.ts +502 -0
- package/src/apply-persist.ts +518 -0
- package/src/arbiter.ts +372 -0
- package/src/brand.ts +111 -0
- package/src/buildable-body.ts +196 -0
- package/src/categorise.ts +158 -0
- package/src/claim-cas.ts +513 -0
- package/src/cli-spinner.ts +225 -0
- package/src/cli.ts +4369 -0
- package/src/close-job-template.ts +236 -0
- package/src/close-job.ts +319 -0
- package/src/complete.ts +1379 -0
- package/src/concurrency.ts +151 -0
- package/src/config-override.ts +116 -0
- package/src/config.ts +883 -0
- package/src/continue-branch.ts +542 -0
- package/src/cwd-section.ts +392 -0
- package/src/decision-engine.ts +272 -0
- package/src/detect.ts +124 -0
- package/src/do-autopick.ts +223 -0
- package/src/do-config.ts +589 -0
- package/src/do-remote-auto.ts +197 -0
- package/src/do.ts +2623 -0
- package/src/drop-source.ts +194 -0
- package/src/eligibility.ts +79 -0
- package/src/env-config.ts +305 -0
- package/src/failure-cause.ts +142 -0
- package/src/format.ts +313 -0
- package/src/frontmatter.ts +485 -0
- package/src/gate-readiness.ts +147 -0
- package/src/gc.ts +510 -0
- package/src/gh-failure.ts +53 -0
- package/src/git.ts +186 -0
- package/src/github.ts +468 -0
- package/src/harness.ts +355 -0
- package/src/identity.ts +322 -0
- package/src/index.ts +785 -0
- package/src/install-ci-branch-protection.ts +255 -0
- package/src/install-ci-capabilities/advance-lifecycle.ts +34 -0
- package/src/install-ci-capabilities/close-job.ts +32 -0
- package/src/install-ci-capabilities/example-noop.ts +24 -0
- package/src/install-ci-capabilities/intake.ts +34 -0
- package/src/install-ci-capabilities/verify.ts +33 -0
- package/src/install-ci-core.ts +1088 -0
- package/src/install-ci-github.ts +376 -0
- package/src/install-ci.ts +552 -0
- package/src/intake-event.ts +102 -0
- package/src/intake-marker.ts +195 -0
- package/src/intake-triage.ts +138 -0
- package/src/intake-trigger-template.ts +591 -0
- package/src/intake.ts +2445 -0
- package/src/integration-core.ts +3065 -0
- package/src/integrator.ts +771 -0
- package/src/isolation.ts +484 -0
- package/src/issue-provider.ts +733 -0
- package/src/item-lock.ts +1858 -0
- package/src/item-path.ts +75 -0
- package/src/ledger-lint.ts +332 -0
- package/src/ledger-read.ts +924 -0
- package/src/ledger-write.ts +865 -0
- package/src/lifecycle-gather.ts +298 -0
- package/src/lifecycle-pools.ts +250 -0
- package/src/merge-question-surfacer.ts +496 -0
- package/src/mint-adr.ts +362 -0
- package/src/mirror-pool-scan.ts +240 -0
- package/src/needs-attention.ts +1506 -0
- package/src/orphan-sidecar.ts +150 -0
- package/src/output.ts +89 -0
- package/src/pi-harness.ts +403 -0
- package/src/placement.ts +131 -0
- package/src/prd-to-spec.ts +1023 -0
- package/src/prepare.ts +230 -0
- package/src/prompt.ts +760 -0
- package/src/readiness.ts +98 -0
- package/src/reap-branches.ts +278 -0
- package/src/recover-isolated.ts +276 -0
- package/src/registry.ts +475 -0
- package/src/repo-config.ts +550 -0
- package/src/repo-key.ts +74 -0
- package/src/repo-mirror.ts +367 -0
- package/src/retry-backoff.ts +130 -0
- package/src/review-gate.ts +389 -0
- package/src/review-verdict.ts +422 -0
- package/src/run.ts +1430 -0
- package/src/scan.ts +611 -0
- package/src/select-order.ts +143 -0
- package/src/select-priority.ts +266 -0
- package/src/select.ts +62 -0
- package/src/session-path.ts +153 -0
- package/src/sidecar-apply.ts +216 -0
- package/src/sidecar.ts +700 -0
- package/src/slug-namespace.ts +367 -0
- package/src/spec-complete.ts +118 -0
- package/src/start.ts +974 -0
- package/src/status.ts +441 -0
- package/src/surface-gate.ts +337 -0
- package/src/surface-persist.ts +241 -0
- package/src/tasker-review-loop.ts +671 -0
- package/src/tasking-eligibility.ts +114 -0
- package/src/tasking-lock.ts +416 -0
- package/src/tasking.ts +1438 -0
- package/src/triage-gate.ts +248 -0
- package/src/triage-persist.ts +570 -0
- package/src/verdict-json.ts +73 -0
- package/src/verify-workflow-template.ts +159 -0
- package/src/verify.ts +123 -0
- package/src/watch-session.ts +397 -0
- package/src/work-layout.ts +262 -0
- package/src/work-on.ts +660 -0
- package/src/workspace.ts +502 -0
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
import {
|
|
2
|
+
performAdvance,
|
|
3
|
+
type AdvanceResult,
|
|
4
|
+
type AdvanceContext,
|
|
5
|
+
} from './advance.js';
|
|
6
|
+
import type {AdvanceTickRunner, AdvanceTickOptions} from './advance-drivers.js';
|
|
7
|
+
import {scanMirrorPool} from './mirror-pool-scan.js';
|
|
8
|
+
import {ledgerRead, type LedgerReadStrategy} from './ledger-read.js';
|
|
9
|
+
import {selectPrioritised, type SelectedItem} from './select-priority.js';
|
|
10
|
+
import type {LifecyclePoolGates} from './lifecycle-pools.js';
|
|
11
|
+
import {runConcurrent} from './concurrency.js';
|
|
12
|
+
import {scan, type ScanReport} from './scan.js';
|
|
13
|
+
import {run as runProcess} from './git.js';
|
|
14
|
+
import {jobWorktreeDoDriver} from './do.js';
|
|
15
|
+
import {
|
|
16
|
+
pushTreelessResult,
|
|
17
|
+
TREELESS_RUNGS,
|
|
18
|
+
} from './advance-treeless-publish.js';
|
|
19
|
+
import type {Config} from './config.js';
|
|
20
|
+
import type {
|
|
21
|
+
RunTick,
|
|
22
|
+
RunOnceOptions,
|
|
23
|
+
RunOnceResult,
|
|
24
|
+
ItemResult,
|
|
25
|
+
ItemStatus,
|
|
26
|
+
} from './run.js';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The **`advance` LOOP DRIVER** (prd `advance-loop`, task
|
|
30
|
+
* `advance-drivers-and-gates`, US #7/22/26/31) — the second of the two drivers
|
|
31
|
+
* over the substrate-agnostic advance TICK. Where the one-shot driver
|
|
32
|
+
* (`advance-drivers.ts`) runs the tick over named item(s) SEQUENTIALLY, this
|
|
33
|
+
* driver loops the tick over the ELIGIBLE SET with genuine PARALLELISM, each item
|
|
34
|
+
* independently lock-guarded by the `advancing` borrow.
|
|
35
|
+
*
|
|
36
|
+
* It WRAPS the EXISTING substrate, building NO new machinery:
|
|
37
|
+
*
|
|
38
|
+
* - the eligible set comes from the SHARED `mirror-side-eligible-pool-scan`
|
|
39
|
+
* ({@link scanMirrorPool}) — the SAME enumeration the one-shot/CI `advance`
|
|
40
|
+
* driver + `do --remote -n` consume (NOT invented twice), gated per-action
|
|
41
|
+
* (build→`autoBuild`, task→`autoTask`) by the SELECTION layer;
|
|
42
|
+
* - parallelism is the SAME bounded scheduler `run`'s build tick uses
|
|
43
|
+
* ({@link runConcurrent}) — `maxParallel` global / `perRepoMax` per repo;
|
|
44
|
+
* - the per-item `advancing` borrow is held INSIDE {@link performAdvance}
|
|
45
|
+
* (classify → lock → execute, winner-only), so a CAS loser among the parallel
|
|
46
|
+
* ticks backs off having spent only the free classification — the lock is the
|
|
47
|
+
* ONLY shared state across the in-flight ticks.
|
|
48
|
+
*
|
|
49
|
+
* `run` ≡ CI (US #7): the loop is just repeated batches of THIS tick (same
|
|
50
|
+
* contract, different substrate / cadence — a `run` daemon, a CI cron, the CI
|
|
51
|
+
* matrix). The tick is the contract; this driver owns ONLY the
|
|
52
|
+
* select-pool + run-batch-concurrently part, exactly mirroring how
|
|
53
|
+
* `runOnce`/`runLoop` separate the tick from the scheduling loop (so the
|
|
54
|
+
* advance-loop forward-pointer's "swap the tick without re-architecting the loop"
|
|
55
|
+
* holds — the loop machinery is `run.ts`'s `runLoop`, this is its advance tick).
|
|
56
|
+
*
|
|
57
|
+
* **Convergence / drain (US #31).** Each batch advances every eligible item one
|
|
58
|
+
* rung, surfaces+idles, or no-ops on a pending sidecar; the candidate pool shrinks
|
|
59
|
+
* MONOTONICALLY as answers arrive (an answered item flips from a no-op to an
|
|
60
|
+
* `apply` that resolves it) and is STABLE when there are none (a pending-sidecar
|
|
61
|
+
* pool is all no-ops — calm at rest, no thrash). {@link advanceBatchSummary}
|
|
62
|
+
* exposes the counts the convergence tests assert on.
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/** What {@link advanceOnce} needs: which bare mirror + the gate config + the tick seam. */
|
|
66
|
+
export interface AdvanceOnceOptions {
|
|
67
|
+
/** The bare hub mirror whose committed `main` the eligible pool is scanned from. */
|
|
68
|
+
mirrorPath: string;
|
|
69
|
+
/**
|
|
70
|
+
* The resolved (remote) repo config — `autoBuild`/`autoTask` gate the pool
|
|
71
|
+
* scan, `selectionOrder` the cross-pool order. The per-action gate family is
|
|
72
|
+
* applied at the SELECTION layer, exactly as the one-shot driver applies it.
|
|
73
|
+
*/
|
|
74
|
+
config: Config;
|
|
75
|
+
/**
|
|
76
|
+
* The mirror-LOCAL ref whose `work/` to scan (default `main`). A bare hub
|
|
77
|
+
* mirror's `main` is a LOCAL branch.
|
|
78
|
+
*/
|
|
79
|
+
ref?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Global cap on advance ticks IN FLIGHT at once (the daemon's `maxParallel`).
|
|
82
|
+
* Defaults to `config.maxParallel`.
|
|
83
|
+
*/
|
|
84
|
+
maxParallel?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Per-repo cap on ticks in flight (the daemon's `perRepoMax`). The mirror is one
|
|
87
|
+
* repo, so this also bounds the whole batch. Defaults to `config.perRepoMax`.
|
|
88
|
+
*/
|
|
89
|
+
perRepoMax?: number;
|
|
90
|
+
/**
|
|
91
|
+
* The per-item advance tick context (everything BUT `arg`): the run context the
|
|
92
|
+
* tick threads to each item (cwd, arbiter, doOptions, the surface/triage gate
|
|
93
|
+
* seams, …). Each selected item's `arg` is filled in by this driver.
|
|
94
|
+
*/
|
|
95
|
+
context: Omit<AdvanceTickOptions, 'arg'>;
|
|
96
|
+
/** Override the single-tick runner (tests inject a stub). Defaults to {@link performAdvance}. */
|
|
97
|
+
run?: AdvanceTickRunner;
|
|
98
|
+
/** Override the read seam (mirror pool); defaults to the active {@link ledgerRead}. */
|
|
99
|
+
read?: LedgerReadStrategy;
|
|
100
|
+
/** Sink for a non-fatal mirror-config-read warning, forwarded to the scan. */
|
|
101
|
+
warn?: (message: string) => void;
|
|
102
|
+
/** The git env the mirror scan's read ops run under (identity/non-interactive). */
|
|
103
|
+
env?: NodeJS.ProcessEnv;
|
|
104
|
+
/**
|
|
105
|
+
* The LIFECYCLE-POOL create-gates (task `advance-autopick-lifecycle-pools`),
|
|
106
|
+
* forwarded to {@link scanMirrorPool}. INTERIM, born OFF: omitted ⇒ BOTH
|
|
107
|
+
* create-gates off, so the loop/CI advance auto-triages / auto-surfaces nothing
|
|
108
|
+
* (the apply sub-pool is always-on). The gate tasks wire this to
|
|
109
|
+
* `observationTriage` / `surfaceBlockers`.
|
|
110
|
+
*/
|
|
111
|
+
lifecycleGates?: LifecyclePoolGates;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** One advanced item's result + the identity it was for (input order preserved). */
|
|
115
|
+
export interface AdvanceBatchItem {
|
|
116
|
+
/** The namespaced arg the tick was run on (`prd:<slug>` / bare slug). */
|
|
117
|
+
arg: string;
|
|
118
|
+
/** The tick's result, or a captured throw mapped to a usage-error result. */
|
|
119
|
+
result: AdvanceResult;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** The aggregate outcome of ONE loop-driver batch (the convergence signal). */
|
|
123
|
+
export interface AdvanceBatchResult {
|
|
124
|
+
/** Every selected item's result, in selection (priority) order. */
|
|
125
|
+
items: AdvanceBatchItem[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Run ONE batch of the loop driver: scan the mirror's eligible pool, select +
|
|
130
|
+
* order it (gated per-action), and run the advance TICK per item CONCURRENTLY,
|
|
131
|
+
* each independently `advancing`-lock-guarded inside {@link performAdvance}.
|
|
132
|
+
* Returns every item's result (input order preserved). A `run` daemon / CI cron
|
|
133
|
+
* loops THIS — the loop owns cadence, the batch owns one round's work.
|
|
134
|
+
*/
|
|
135
|
+
export async function advanceOnce(
|
|
136
|
+
options: AdvanceOnceOptions,
|
|
137
|
+
): Promise<AdvanceBatchResult> {
|
|
138
|
+
const run = options.run ?? performAdvance;
|
|
139
|
+
const read = options.read ?? ledgerRead;
|
|
140
|
+
const maxParallel = options.maxParallel ?? options.config.maxParallel;
|
|
141
|
+
const perRepoMax = options.perRepoMax ?? options.config.perRepoMax;
|
|
142
|
+
|
|
143
|
+
// Enumerate the eligible pool from the bare mirror's committed `main` — the
|
|
144
|
+
// SHARED `mirror-side-eligible-pool-scan` (gated on `autoBuild`/`autoTask`).
|
|
145
|
+
const scan = await scanMirrorPool({
|
|
146
|
+
mirrorPath: options.mirrorPath,
|
|
147
|
+
config: options.config,
|
|
148
|
+
ref: options.ref,
|
|
149
|
+
read,
|
|
150
|
+
warn: options.warn,
|
|
151
|
+
env: options.env,
|
|
152
|
+
lifecycleGates: options.lifecycleGates,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Order across the (up to) FIVE pools per the resolved `selectionOrder` (apply
|
|
156
|
+
// pinned first) — ALL eligible items (the loop drains the whole pool each batch;
|
|
157
|
+
// `count` is the one-shot/`-n` concern). The lifecycle pools come from the SHARED
|
|
158
|
+
// mirror enumeration, so the loop/CI selection agrees with the in-place one-shot.
|
|
159
|
+
const selected = selectPrioritised({
|
|
160
|
+
report: scan.report,
|
|
161
|
+
caps: {
|
|
162
|
+
maxParallel: Number.MAX_SAFE_INTEGER,
|
|
163
|
+
perRepoMax: Number.MAX_SAFE_INTEGER,
|
|
164
|
+
},
|
|
165
|
+
specs: scan.specs,
|
|
166
|
+
selectionOrder: options.config.selectionOrder,
|
|
167
|
+
lifecycle: scan.lifecycle,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (selected.length === 0) {
|
|
171
|
+
return {items: []};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Run the tick per item CONCURRENTLY (the SAME bounded scheduler `run`'s build
|
|
175
|
+
// tick uses), each independently `advancing`-lock-guarded inside the tick. The
|
|
176
|
+
// scheduler never rejects — a thrown tick is captured, so one item can never
|
|
177
|
+
// abort the batch (mirrors `runOnce`'s settled-slot contract).
|
|
178
|
+
const settled = await runConcurrent({
|
|
179
|
+
items: selected,
|
|
180
|
+
maxInFlight: Math.max(1, maxParallel),
|
|
181
|
+
// The mirror is ONE repo, so every item shares the repo key — `perRepoMax`
|
|
182
|
+
// bounds the whole batch (matching `run`'s per-repo cap semantics).
|
|
183
|
+
keyFor: () => options.mirrorPath,
|
|
184
|
+
perKeyMax: Math.max(1, perRepoMax),
|
|
185
|
+
worker: async (item) => {
|
|
186
|
+
const result = await run({
|
|
187
|
+
...options.context,
|
|
188
|
+
arg: argForSelected(item),
|
|
189
|
+
read,
|
|
190
|
+
});
|
|
191
|
+
// A TREE-LESS rung (surface/apply/triage) committed its sidecar / marker
|
|
192
|
+
// LOCALLY in the shared per-mirror `treelessCwd` (`context.cwd`); ff-push
|
|
193
|
+
// it to the mirror's arbiter so the result LANDS on `main` (the CLI wipes +
|
|
194
|
+
// re-clones that cwd EACH TICK, so an un-pushed local commit is lost). The
|
|
195
|
+
// build/task rungs already pushed via the job-worktree `doDriver`.
|
|
196
|
+
//
|
|
197
|
+
// The bounded re-fetch+rebase retry inside `pushTreelessResult` is
|
|
198
|
+
// LOAD-BEARING here: the `treelessCwd` is cloned ONCE per mirror at tick
|
|
199
|
+
// start and SHARED across the mirror's SERIAL batch, so a `build`/`task`
|
|
200
|
+
// rung EARLIER in the batch can integrate to the mirror's `main` mid-tick
|
|
201
|
+
// and a LATER tree-less push is non-fast-forward BY CONSTRUCTION — the
|
|
202
|
+
// retry rebases the slug-only commit onto the advanced `main` and lands it.
|
|
203
|
+
if (
|
|
204
|
+
result.exitCode === 0 &&
|
|
205
|
+
result.rung !== undefined &&
|
|
206
|
+
TREELESS_RUNGS.has(result.rung) &&
|
|
207
|
+
options.context.cwd !== undefined
|
|
208
|
+
) {
|
|
209
|
+
await pushTreelessResult({
|
|
210
|
+
cwd: options.context.cwd,
|
|
211
|
+
arbiter: options.context.arbiter ?? 'origin',
|
|
212
|
+
// Large liveness ceiling (C2, task `c2-rebase-until-real-on-durable-main-
|
|
213
|
+
// promotions`): a clean re-rebase no longer counts against a small
|
|
214
|
+
// budget; a genuine same-path conflict still stops definitively.
|
|
215
|
+
retries: 1000,
|
|
216
|
+
env: options.env,
|
|
217
|
+
note: options.context.note ?? (() => {}),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const items: AdvanceBatchItem[] = settled.map((slot, i) => {
|
|
225
|
+
const arg = argForSelected(selected[i]);
|
|
226
|
+
if ('ok' in slot) {
|
|
227
|
+
return {arg, result: slot.ok};
|
|
228
|
+
}
|
|
229
|
+
// A captured throw → a usage-error result (never crashes the batch).
|
|
230
|
+
const detail =
|
|
231
|
+
slot.error instanceof Error ? slot.error.message : String(slot.error);
|
|
232
|
+
return {
|
|
233
|
+
arg,
|
|
234
|
+
result: {exitCode: 1, outcome: 'usage-error', message: detail},
|
|
235
|
+
};
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
return {items};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* The advance arg for a selected item (the SELECTION->ARG dispatch): `obs:<slug>`
|
|
243
|
+
* for an observation (the triage rung), `spec:<slug>` for a spec, bare slug for a
|
|
244
|
+
* task. The tick re-classifies each arg into the right rung (surface/apply for a
|
|
245
|
+
* `needsAnswers`-blocked task/spec; triage for an observation).
|
|
246
|
+
*/
|
|
247
|
+
function argForSelected(item: SelectedItem): string {
|
|
248
|
+
if (item.namespace === 'observation') {
|
|
249
|
+
return `obs:${item.slug}`;
|
|
250
|
+
}
|
|
251
|
+
return item.namespace === 'spec' ? `spec:${item.slug}` : item.slug;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Read a bare hub mirror's `origin` URL (`git -C <mirror> remote get-url
|
|
256
|
+
* origin`) — the arbiter URL the per-mirror job-worktree `do` driver
|
|
257
|
+
* ({@link jobWorktreeDoDriver}) materialises its worktree off (the SAME URL
|
|
258
|
+
* `run`'s `claimAgainstRepo` resolves; `registry.ts readOriginUrl` reads it for
|
|
259
|
+
* the registry view). Falls back to a `file://<path>` URL when the remote is
|
|
260
|
+
* unreadable, so a malformed/origin-less mirror still resolves to SOMETHING
|
|
261
|
+
* addressable rather than throwing mid-batch.
|
|
262
|
+
*/
|
|
263
|
+
function mirrorOriginUrl(
|
|
264
|
+
mirrorPath: string,
|
|
265
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
266
|
+
): string {
|
|
267
|
+
const result = runProcess(
|
|
268
|
+
'git',
|
|
269
|
+
['remote', 'get-url', 'origin'],
|
|
270
|
+
mirrorPath,
|
|
271
|
+
{env},
|
|
272
|
+
);
|
|
273
|
+
const url = result.status === 0 ? result.stdout.trim() : '';
|
|
274
|
+
return url !== '' ? url : `file://${mirrorPath}`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* One mirror's slot in a {@link advanceRegistrySet} batch: which mirror drained,
|
|
279
|
+
* and that mirror's batch result (or a captured throw mapped to a usage-error
|
|
280
|
+
* batch — one mirror can never abort the whole registry sweep).
|
|
281
|
+
*/
|
|
282
|
+
export interface AdvanceRegistryMirrorResult {
|
|
283
|
+
/** The bare hub mirror that was drained this batch. */
|
|
284
|
+
mirrorPath: string;
|
|
285
|
+
/** That mirror's {@link advanceOnce} batch result. */
|
|
286
|
+
batch: AdvanceBatchResult;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** The aggregate outcome of ONE registry-set advance batch (every mirror's batch). */
|
|
290
|
+
export interface AdvanceRegistrySetResult {
|
|
291
|
+
/** Each drained mirror's batch, in registry-discovery order. */
|
|
292
|
+
mirrors: AdvanceRegistryMirrorResult[];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* What {@link advanceRegistrySet} needs: the global config (the registry +
|
|
297
|
+
* caps), the per-mirror advance CONTEXT factory, and the execution workspace.
|
|
298
|
+
*/
|
|
299
|
+
export interface AdvanceRegistrySetOptions {
|
|
300
|
+
/**
|
|
301
|
+
* The global config. Its `workspacesDir` IS the registry (the hub-mirror set
|
|
302
|
+
* {@link scan} enumerates); `maxParallel`/`perRepoMax` are the SAME caps the
|
|
303
|
+
* build tick's scheduler uses.
|
|
304
|
+
*/
|
|
305
|
+
config: Config;
|
|
306
|
+
/**
|
|
307
|
+
* Build the per-mirror advance CONTEXT (everything BUT `arg` and the build/task
|
|
308
|
+
* `doDriver`). The driver INJECTS the per-mirror job-worktree `doDriver`
|
|
309
|
+
* ({@link jobWorktreeDoDriver}) on top of what this returns, so the build/task
|
|
310
|
+
* rungs run isolated off THAT mirror's arbiter — the caller supplies the gate
|
|
311
|
+
* seams + `doOptions` base (harness, verify, review, …), exactly as the CLI
|
|
312
|
+
* wires them for the single-mirror path. `cwd` here is irrelevant to the
|
|
313
|
+
* build/task rungs (the worktree driver replaces it); the tree-less
|
|
314
|
+
* surface/triage/apply rungs use it as their ledger-write cwd.
|
|
315
|
+
*/
|
|
316
|
+
contextFor: (input: {
|
|
317
|
+
mirrorPath: string;
|
|
318
|
+
originUrl: string;
|
|
319
|
+
}) => Omit<AdvanceTickOptions, 'arg' | 'doDriver'>;
|
|
320
|
+
/**
|
|
321
|
+
* The execution working area (bare hub mirrors + per-job worktrees). Defaults
|
|
322
|
+
* to `config.workspacesDir`. The per-mirror worktree `doDriver` materialises its
|
|
323
|
+
* worktree under here — the agents' area, the SAME isolation `run` uses.
|
|
324
|
+
*/
|
|
325
|
+
workspace?: string;
|
|
326
|
+
/** Pre-computed registry scan (tests); omitted ⇒ the live `scan(config)`. */
|
|
327
|
+
report?: ScanReport;
|
|
328
|
+
/** Override the single-tick runner (tests). Defaults to {@link performAdvance}. */
|
|
329
|
+
run?: AdvanceTickRunner;
|
|
330
|
+
/** Override the read seam (mirror pool); defaults to the active {@link ledgerRead}. */
|
|
331
|
+
read?: LedgerReadStrategy;
|
|
332
|
+
/** Sink for non-fatal warnings (mirror-config read; forwarded to scan + pool scan). */
|
|
333
|
+
warn?: (message: string) => void;
|
|
334
|
+
/** The git env the registry scan + per-mirror pool scans run under. */
|
|
335
|
+
env?: NodeJS.ProcessEnv;
|
|
336
|
+
/**
|
|
337
|
+
* The LIFECYCLE-POOL create-gates, forwarded to each mirror's
|
|
338
|
+
* {@link advanceOnce}. INTERIM, born OFF (omitted ⇒ both off). The CLI wires
|
|
339
|
+
* this to `observationTriage`/`surfaceBlockers`, exactly as the single-mirror
|
|
340
|
+
* path does.
|
|
341
|
+
*/
|
|
342
|
+
lifecycleGates?: LifecyclePoolGates;
|
|
343
|
+
/**
|
|
344
|
+
* The per-machine config-override map (ADR
|
|
345
|
+
* `per-machine-config-override-layer`), forwarded to the registry {@link scan}
|
|
346
|
+
* so per-mirror `autoTask`/`observationTriage`/`surfaceBlockers` resolutions
|
|
347
|
+
* honour the override. Default: empty (no override).
|
|
348
|
+
*/
|
|
349
|
+
override?: import('./config-override.js').ConfigOverrideMap;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* The **registry-set advance DRIVER** with **per-mirror job-worktree isolation**
|
|
354
|
+
* (task `advance-loop-driver-registry-set-job-worktrees`) — the advance-tick TWIN
|
|
355
|
+
* of `runOnce`/`runOneItem`'s build substrate, the substrate `run-uses-advance-tick`
|
|
356
|
+
* needs to become a clean tick swap. Where {@link advanceOnce} drains ONE named
|
|
357
|
+
* mirror's pool IN-PLACE (the single-mirror path), this driver:
|
|
358
|
+
*
|
|
359
|
+
* 1. **discovers the REGISTRY SET** the SAME way `runOnce` does — via
|
|
360
|
+
* {@link scan} over `config.workspacesDir`'s hub mirrors (NOT a single
|
|
361
|
+
* `--advance <mirror>` arg); and
|
|
362
|
+
* 2. loops {@link advanceOnce}'s batch over that set, GENUINELY CONCURRENT
|
|
363
|
+
* ACROSS REPOS under {@link runConcurrent} (`maxParallel` global /
|
|
364
|
+
* `perRepoMax` per repo — the SAME scheduler `run`'s build tick uses), each
|
|
365
|
+
* mirror's pool itself drained concurrently by `advanceOnce` (reusing the
|
|
366
|
+
* per-item `advancing` borrow INSIDE {@link performAdvance} — no new lock,
|
|
367
|
+
* no new scheduler); and
|
|
368
|
+
* 3. threads a **per-mirror job-worktree `doDriver`** ({@link jobWorktreeDoDriver})
|
|
369
|
+
* into each mirror's advance context, so the build/task rungs run isolated
|
|
370
|
+
* in their OWN worktree off THAT mirror's arbiter (the SAME isolation
|
|
371
|
+
* `runOneItem` gives the build tick) instead of in `process.cwd()`. The
|
|
372
|
+
* surface/triage/apply rungs stay on their tree-less ledger-write moves
|
|
373
|
+
* (no build worktree needed) — the worktree driver governs ONLY the
|
|
374
|
+
* build/task orchestration target.
|
|
375
|
+
*
|
|
376
|
+
* Under calm gates (both lifecycle create-gates off) this is the OBSERVABLE-
|
|
377
|
+
* OUTCOME equivalent of plain `run`'s build tick over the same registry: build
|
|
378
|
+
* ready tasks / task ready prds, each per-job-worktree-isolated off the
|
|
379
|
+
* mirror's arbiter, same integration result — two callers of one
|
|
380
|
+
* `performIntegration` band (the advance build rung reaches it via `performDo`
|
|
381
|
+
* → `performDoRemote`; `runOneItem` reaches it directly), NOT a shared code path.
|
|
382
|
+
*/
|
|
383
|
+
export async function advanceRegistrySet(
|
|
384
|
+
options: AdvanceRegistrySetOptions,
|
|
385
|
+
): Promise<AdvanceRegistrySetResult> {
|
|
386
|
+
const config = options.config;
|
|
387
|
+
const workspace = options.workspace ?? config.workspacesDir;
|
|
388
|
+
// DISCOVERY = the registry (the hub-mirror set, ADR §1) — the SAME `scan(config)`
|
|
389
|
+
// `runOnce` uses. Each row's `path` is a bare hub mirror to drain.
|
|
390
|
+
const report =
|
|
391
|
+
options.report ??
|
|
392
|
+
(await scan(config, {
|
|
393
|
+
warn: options.warn,
|
|
394
|
+
env: options.env,
|
|
395
|
+
override: options.override,
|
|
396
|
+
}));
|
|
397
|
+
const mirrors = report.repos.map((repo) => repo.path);
|
|
398
|
+
|
|
399
|
+
// GENUINELY CONCURRENT ACROSS REPOS (the registry-set point) under the SAME
|
|
400
|
+
// bounded scheduler `run`'s build tick uses: `maxParallel` bounds the whole
|
|
401
|
+
// registry sweep, one `advanceOnce` per mirror in flight.
|
|
402
|
+
//
|
|
403
|
+
// WITHIN one mirror the batch is SERIALISED (`perRepoMax: 1` into `advanceOnce`).
|
|
404
|
+
// WHY: the per-item `advancing` borrow + the tree-less surface/triage/apply rungs
|
|
405
|
+
// commit in the per-mirror `context.cwd` working tree, and the borrow's CAS is
|
|
406
|
+
// race-correct ONLY when each contender holds its OWN clone (the distinct-clone
|
|
407
|
+
// model `advancing-lock.ts` is built + tested against — two contenders sharing
|
|
408
|
+
// one checkout corrupt each other's HEAD/index, the SAME reason `run` serialises
|
|
409
|
+
// the per-repo CLAIM via `createKeyedLock`). A bare mirror has no per-item cwd, so
|
|
410
|
+
// the build/task rungs already get their OWN job worktree (via `jobWorktreeDoDriver`
|
|
411
|
+
// → `performDoRemote`) but the lock + tree-less rungs share the one cwd — so within
|
|
412
|
+
// ONE mirror they must run one-at-a-time. Cross-mirror concurrency (distinct
|
|
413
|
+
// arbiters → distinct cwds, no contention) stays GENUINE, which is the
|
|
414
|
+
// registry-set point. Per-item-cwd isolation (to also parallelise WITHIN a
|
|
415
|
+
// mirror) is a follow-up; this task keeps the borrow reused unchanged + correct.
|
|
416
|
+
const settled = await runConcurrent({
|
|
417
|
+
items: mirrors,
|
|
418
|
+
maxInFlight: Math.max(1, config.maxParallel),
|
|
419
|
+
keyFor: (mirrorPath) => mirrorPath,
|
|
420
|
+
perKeyMax: 1,
|
|
421
|
+
worker: (mirrorPath) => {
|
|
422
|
+
const originUrl = mirrorOriginUrl(mirrorPath, options.env);
|
|
423
|
+
// The per-mirror context the CLI shaped (gates + doOptions base) PLUS the
|
|
424
|
+
// per-mirror job-worktree `doDriver` injected here, so the build/task rungs
|
|
425
|
+
// build isolated off THIS mirror's arbiter (cwd untouched).
|
|
426
|
+
const baseContext = options.contextFor({mirrorPath, originUrl});
|
|
427
|
+
const context: Omit<AdvanceTickOptions, 'arg'> = {
|
|
428
|
+
...baseContext,
|
|
429
|
+
doDriver: jobWorktreeDoDriver({
|
|
430
|
+
remote: originUrl,
|
|
431
|
+
workspacesDir: workspace,
|
|
432
|
+
}),
|
|
433
|
+
};
|
|
434
|
+
return advanceOnce({
|
|
435
|
+
mirrorPath,
|
|
436
|
+
config,
|
|
437
|
+
context,
|
|
438
|
+
run: options.run,
|
|
439
|
+
read: options.read,
|
|
440
|
+
warn: options.warn,
|
|
441
|
+
env: options.env,
|
|
442
|
+
lifecycleGates: options.lifecycleGates,
|
|
443
|
+
// SERIALISE within the mirror (one tick at a time over the shared cwd) —
|
|
444
|
+
// the borrow + tree-less rungs commit in `context.cwd` and are race-correct
|
|
445
|
+
// only per distinct clone (see the block above). Cross-mirror concurrency
|
|
446
|
+
// is genuine (the outer `runConcurrent`).
|
|
447
|
+
maxParallel: 1,
|
|
448
|
+
perRepoMax: 1,
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
// One mirror can never abort the registry sweep: a captured throw becomes an
|
|
454
|
+
// empty batch (mirrors `advanceOnce`'s per-item settled-slot contract one layer up).
|
|
455
|
+
const mirrorResults: AdvanceRegistryMirrorResult[] = settled.map(
|
|
456
|
+
(slot, i) => ({
|
|
457
|
+
mirrorPath: mirrors[i],
|
|
458
|
+
batch: 'ok' in slot ? slot.ok : {items: []},
|
|
459
|
+
}),
|
|
460
|
+
);
|
|
461
|
+
return {mirrors: mirrorResults};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/** Project a whole registry-set batch onto the convergence counts (a pure sum). */
|
|
465
|
+
export function advanceRegistrySetSummary(
|
|
466
|
+
result: AdvanceRegistrySetResult,
|
|
467
|
+
): AdvanceBatchSummary {
|
|
468
|
+
let advanced = 0;
|
|
469
|
+
let idle = 0;
|
|
470
|
+
let stuck = 0;
|
|
471
|
+
let total = 0;
|
|
472
|
+
for (const {batch} of result.mirrors) {
|
|
473
|
+
const s = advanceBatchSummary(batch);
|
|
474
|
+
advanced += s.advanced;
|
|
475
|
+
idle += s.idle;
|
|
476
|
+
stuck += s.stuck;
|
|
477
|
+
total += s.total;
|
|
478
|
+
}
|
|
479
|
+
return {advanced, idle, stuck, total};
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/** The convergence counts of one batch (the drain/idle signal US #31 asserts on). */
|
|
483
|
+
export interface AdvanceBatchSummary {
|
|
484
|
+
/** Items the batch ADVANCED a rung (build/task/surface/apply/triage). */
|
|
485
|
+
advanced: number;
|
|
486
|
+
/** Items that NO-OPed (a pending sidecar idling — the calm-at-rest population). */
|
|
487
|
+
idle: number;
|
|
488
|
+
/** Items that FAILED / contended (non-zero, non-no-op). */
|
|
489
|
+
stuck: number;
|
|
490
|
+
/** Total selected this batch (= the candidate pool size). */
|
|
491
|
+
total: number;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/** Summarise a batch into the convergence counts (a pure projection). */
|
|
495
|
+
export function advanceBatchSummary(
|
|
496
|
+
result: AdvanceBatchResult,
|
|
497
|
+
): AdvanceBatchSummary {
|
|
498
|
+
let advanced = 0;
|
|
499
|
+
let idle = 0;
|
|
500
|
+
let stuck = 0;
|
|
501
|
+
for (const {result: r} of result.items) {
|
|
502
|
+
if (r.outcome === 'no-op') {
|
|
503
|
+
idle++;
|
|
504
|
+
} else if (r.exitCode === 0) {
|
|
505
|
+
advanced++;
|
|
506
|
+
} else {
|
|
507
|
+
stuck++;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return {advanced, idle, stuck, total: result.items.length};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Is this batch CALM-AT-REST (US #31) — every selected item idled (a pending
|
|
515
|
+
* sidecar awaiting a human) and nothing failed? A pending-sidecar pool is STABLE:
|
|
516
|
+
* the loop re-ticks it, finds all no-ops, and idles without thrash. As answers
|
|
517
|
+
* arrive the idle count shrinks MONOTONICALLY (an answered item flips to an
|
|
518
|
+
* advance), so the loop converges.
|
|
519
|
+
*/
|
|
520
|
+
export function isBatchCalmAtRest(result: AdvanceBatchResult): boolean {
|
|
521
|
+
const s = advanceBatchSummary(result);
|
|
522
|
+
return s.total > 0 && s.advanced === 0 && s.stuck === 0;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* The advance-specific dependencies the {@link RunTick} adapter closes over —
|
|
527
|
+
* everything the {@link advanceOnce} batch needs that is NOT carried by the
|
|
528
|
+
* generic per-tick {@link RunOnceOptions} (which describe the BUILD tick's
|
|
529
|
+
* checkout-scan world). The CLI builds these ONCE (the mirror to drain, the
|
|
530
|
+
* resolved remote config, the per-item advance context) and hands them to
|
|
531
|
+
* {@link advanceRunTick}; the loop ({@link runLoop}) then drives the resulting
|
|
532
|
+
* tick exactly as it drives the build tick.
|
|
533
|
+
*/
|
|
534
|
+
export interface AdvanceRunTickDeps extends Omit<
|
|
535
|
+
AdvanceOnceOptions,
|
|
536
|
+
'maxParallel' | 'perRepoMax' | 'warn' | 'env'
|
|
537
|
+
> {
|
|
538
|
+
/* `lifecycleGates` is inherited from {@link AdvanceOnceOptions} (born OFF). */
|
|
539
|
+
/**
|
|
540
|
+
* Override the per-batch caps. Defaults to `config.maxParallel` /
|
|
541
|
+
* `config.perRepoMax` (the SAME knobs the build tick's scheduler uses), so a
|
|
542
|
+
* `run` daemon caps advance ticks identically.
|
|
543
|
+
*/
|
|
544
|
+
maxParallel?: number;
|
|
545
|
+
perRepoMax?: number;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Adapt the {@link advanceOnce} LOOP DRIVER to the {@link RunTick} swap SEAM so
|
|
550
|
+
* `run` (≡ CI, US #7) drives the ADVANCE tick over the mirror-side eligible pool
|
|
551
|
+
* instead of the build tick. `run.ts` deliberately writes {@link runLoop} against
|
|
552
|
+
* {@link RunTick} (NOT against `runOnce`) precisely so the advance-loop prd can
|
|
553
|
+
* swap the tick WITHOUT re-architecting the loop — this is that swap.
|
|
554
|
+
*
|
|
555
|
+
* The seam is `(RunOnceOptions) => Promise<RunOnceResult>`; one advance batch is
|
|
556
|
+
* `(AdvanceOnceOptions) => Promise<AdvanceBatchResult>`. The deps the advance
|
|
557
|
+
* batch needs that the generic per-tick options do NOT carry (the mirror to
|
|
558
|
+
* drain, the remote config, the per-item advance context) are CLOSED OVER here;
|
|
559
|
+
* the per-tick `RunOnceOptions` contribute only the cross-cutting seams that DO
|
|
560
|
+
* generalise — `onWarn` (the warning sink) and `env` (the git env). The batch's
|
|
561
|
+
* own item-level pool scan supersedes `RunOnceOptions.report` (the build tick's
|
|
562
|
+
* checkout scan), so that field is ignored for the advance tick.
|
|
563
|
+
*
|
|
564
|
+
* The {@link AdvanceBatchResult} is projected onto {@link RunOnceResult} so the
|
|
565
|
+
* loop's aggregation/reporting (`claimedAndDone` / `skipped` / `failed` /
|
|
566
|
+
* `needsAttention`) works UNCHANGED — an `advanced` item is `claimed-done`, an
|
|
567
|
+
* idling pending-sidecar `no-op` is `lost-race` (skipped, calm-at-rest), a CAS
|
|
568
|
+
* loser is `claim-contended` (skipped), and any error is `needs-attention`. So
|
|
569
|
+
* the loop's existing convergence signal (`claimedAndDone` falls to 0 once the
|
|
570
|
+
* pool is all idle) doubles as the advance loop's drain/idle signal (US #31).
|
|
571
|
+
*/
|
|
572
|
+
export function advanceRunTick(deps: AdvanceRunTickDeps): RunTick {
|
|
573
|
+
return async (options: RunOnceOptions): Promise<RunOnceResult> => {
|
|
574
|
+
const batch = await advanceOnce({
|
|
575
|
+
mirrorPath: deps.mirrorPath,
|
|
576
|
+
config: deps.config,
|
|
577
|
+
ref: deps.ref,
|
|
578
|
+
context: deps.context,
|
|
579
|
+
run: deps.run,
|
|
580
|
+
read: deps.read,
|
|
581
|
+
lifecycleGates: deps.lifecycleGates,
|
|
582
|
+
maxParallel: deps.maxParallel,
|
|
583
|
+
perRepoMax: deps.perRepoMax,
|
|
584
|
+
// Cross-cutting seams that DO generalise come from the per-tick options
|
|
585
|
+
// (the SAME ones the build tick receives) — so a `run` daemon threads its
|
|
586
|
+
// warning sink + git env to the advance tick identically.
|
|
587
|
+
warn: options.onWarn,
|
|
588
|
+
env: options.env,
|
|
589
|
+
});
|
|
590
|
+
return batchToRunOnceResult(batch, deps.mirrorPath);
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* The deps the {@link advanceRegistrySetRunTick} adapter closes over — everything
|
|
596
|
+
* the {@link advanceRegistrySet} batch needs that the generic per-tick
|
|
597
|
+
* {@link RunOnceOptions} does NOT carry. This is the REGISTRY-SET twin of
|
|
598
|
+
* {@link AdvanceRunTickDeps}: where that adapter drives ONE named mirror in-place
|
|
599
|
+
* ({@link advanceRunTick}), this one discovers the WHOLE registry via
|
|
600
|
+
* `scan(config)` and runs each mirror's pool in a per-mirror job worktree — the
|
|
601
|
+
* substrate `run` needs so plain `run` (no flag) ≡ advance with calm-default gates.
|
|
602
|
+
* The CLI builds these ONCE (the resolved config, the per-mirror advance-context
|
|
603
|
+
* factory, the execution workspace) and hands them to {@link advanceRegistrySetRunTick};
|
|
604
|
+
* the loop ({@link runLoop}) then drives the resulting tick exactly as it drove the
|
|
605
|
+
* build tick.
|
|
606
|
+
*/
|
|
607
|
+
export interface AdvanceRegistrySetRunTickDeps extends Omit<
|
|
608
|
+
AdvanceRegistrySetOptions,
|
|
609
|
+
'warn' | 'env' | 'report'
|
|
610
|
+
> {
|
|
611
|
+
/* `contextFor`/`config`/`workspace`/`run`/`read`/`lifecycleGates` are inherited
|
|
612
|
+
* from {@link AdvanceRegistrySetOptions} (lifecycle gates born OFF). */
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Adapt the REGISTRY-SET advance DRIVER ({@link advanceRegistrySet}) onto the
|
|
617
|
+
* {@link RunTick} swap SEAM so plain `run` (no flag) drives the ADVANCE tick over
|
|
618
|
+
* the WHOLE registry instead of the build tick (`runOnce`) — the task
|
|
619
|
+
* `run-uses-advance-tick`. `run.ts` deliberately writes {@link runLoop} against
|
|
620
|
+
* {@link RunTick} (NOT against `runOnce`) precisely so the advance-loop design can
|
|
621
|
+
* swap the tick WITHOUT re-architecting the loop; this is that swap, now pointing
|
|
622
|
+
* the seam at the REGISTRY-SET advance driver the precursor built (registry-set
|
|
623
|
+
* discovery + per-mirror job-worktree isolation — the SAME substrate plain `run`'s
|
|
624
|
+
* build tick uses).
|
|
625
|
+
*
|
|
626
|
+
* Under calm gates (both lifecycle create-gates off) this is the OBSERVABLE-
|
|
627
|
+
* OUTCOME equivalent of plain `run`'s build tick over the same registry: build
|
|
628
|
+
* ready tasks / task ready prds, each per-job-worktree-isolated off the
|
|
629
|
+
* mirror's arbiter, same integration result; touch no observations, surface no
|
|
630
|
+
* questions. Flip a gate and the SAME tick performs the lifecycle
|
|
631
|
+
* (triage / surface / apply) for free — no separate `--advance` mode to discover.
|
|
632
|
+
*
|
|
633
|
+
* The seam is `(RunOnceOptions) => Promise<RunOnceResult>`; one registry-set
|
|
634
|
+
* batch is `(AdvanceRegistrySetOptions) => Promise<AdvanceRegistrySetResult>`. The
|
|
635
|
+
* deps the batch needs that the generic per-tick options do NOT carry (the config,
|
|
636
|
+
* the per-mirror context factory, the workspace) are CLOSED OVER here; the
|
|
637
|
+
* per-tick `RunOnceOptions` contribute only the cross-cutting seams that DO
|
|
638
|
+
* generalise — `onWarn` (the warning sink) and `env` (the git env). The batch's
|
|
639
|
+
* own registry discovery supersedes `RunOnceOptions.report` (the build tick's
|
|
640
|
+
* checkout scan), so that field is ignored for the advance tick.
|
|
641
|
+
*/
|
|
642
|
+
export function advanceRegistrySetRunTick(
|
|
643
|
+
deps: AdvanceRegistrySetRunTickDeps,
|
|
644
|
+
): RunTick {
|
|
645
|
+
return async (options: RunOnceOptions): Promise<RunOnceResult> => {
|
|
646
|
+
const result = await advanceRegistrySet({
|
|
647
|
+
config: deps.config,
|
|
648
|
+
override: deps.override,
|
|
649
|
+
contextFor: deps.contextFor,
|
|
650
|
+
workspace: deps.workspace,
|
|
651
|
+
run: deps.run,
|
|
652
|
+
read: deps.read,
|
|
653
|
+
lifecycleGates: deps.lifecycleGates,
|
|
654
|
+
// Cross-cutting seams that DO generalise come from the per-tick options
|
|
655
|
+
// (the SAME ones the build tick receives) — so the `run` daemon threads its
|
|
656
|
+
// warning sink + git env to the advance tick identically.
|
|
657
|
+
warn: options.onWarn,
|
|
658
|
+
env: options.env,
|
|
659
|
+
});
|
|
660
|
+
return registrySetToRunOnceResult(result);
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Project a whole REGISTRY-SET advance batch onto a {@link RunOnceResult} so the
|
|
666
|
+
* existing run loop aggregates + reports it with NO advance-specific code. Each
|
|
667
|
+
* mirror's per-item results are flattened (the `repoPath` is that mirror; the
|
|
668
|
+
* `slug` is the advanced arg), reusing the SAME per-item status mapping the
|
|
669
|
+
* single-mirror {@link batchToRunOnceResult} uses — so the loop's convergence
|
|
670
|
+
* signal (`claimedAndDone` falls to 0 once every pool idles) holds across the
|
|
671
|
+
* registry exactly as it does for one mirror.
|
|
672
|
+
*/
|
|
673
|
+
function registrySetToRunOnceResult(
|
|
674
|
+
result: AdvanceRegistrySetResult,
|
|
675
|
+
): RunOnceResult {
|
|
676
|
+
const items: ItemResult[] = result.mirrors.flatMap(({mirrorPath, batch}) =>
|
|
677
|
+
batch.items.map(({arg, result: r}) => ({
|
|
678
|
+
repoPath: mirrorPath,
|
|
679
|
+
slug: arg,
|
|
680
|
+
status: advanceOutcomeToItemStatus(r),
|
|
681
|
+
detail: r.message,
|
|
682
|
+
})),
|
|
683
|
+
);
|
|
684
|
+
const claimedAndDone = items.filter(
|
|
685
|
+
(i) => i.status === 'claimed-done',
|
|
686
|
+
).length;
|
|
687
|
+
const skipped = items.filter(
|
|
688
|
+
(i) => i.status === 'lost-race' || i.status === 'claim-contended',
|
|
689
|
+
).length;
|
|
690
|
+
const needsAttention = items.filter(
|
|
691
|
+
(i) => i.status === 'needs-attention',
|
|
692
|
+
).length;
|
|
693
|
+
const failed = needsAttention;
|
|
694
|
+
return {claimedAndDone, skipped, failed, needsAttention, items};
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Project one advance batch onto a {@link RunOnceResult} so the existing run loop
|
|
699
|
+
* aggregates + reports it with NO advance-specific code. The `repoPath` is the
|
|
700
|
+
* mirror (the one repo this batch drains); the `slug` is the advanced arg.
|
|
701
|
+
*/
|
|
702
|
+
function batchToRunOnceResult(
|
|
703
|
+
batch: AdvanceBatchResult,
|
|
704
|
+
mirrorPath: string,
|
|
705
|
+
): RunOnceResult {
|
|
706
|
+
const items: ItemResult[] = batch.items.map(({arg, result}) => ({
|
|
707
|
+
repoPath: mirrorPath,
|
|
708
|
+
slug: arg,
|
|
709
|
+
status: advanceOutcomeToItemStatus(result),
|
|
710
|
+
detail: result.message,
|
|
711
|
+
}));
|
|
712
|
+
const claimedAndDone = items.filter(
|
|
713
|
+
(i) => i.status === 'claimed-done',
|
|
714
|
+
).length;
|
|
715
|
+
const skipped = items.filter(
|
|
716
|
+
(i) => i.status === 'lost-race' || i.status === 'claim-contended',
|
|
717
|
+
).length;
|
|
718
|
+
const needsAttention = items.filter(
|
|
719
|
+
(i) => i.status === 'needs-attention',
|
|
720
|
+
).length;
|
|
721
|
+
const failed = needsAttention;
|
|
722
|
+
return {claimedAndDone, skipped, failed, needsAttention, items};
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Map one advance tick's outcome onto the run loop's {@link ItemStatus} so the
|
|
727
|
+
* loop's counters carry the convergence semantics: an item that ADVANCED a rung
|
|
728
|
+
* is `claimed-done`; a `no-op` (an idling pending sidecar — the calm-at-rest
|
|
729
|
+
* population) is `lost-race` (skipped, NOT a failure — the loop does no work on
|
|
730
|
+
* it and does not retry); a CAS `lost`/`contended` is `lost-race`/
|
|
731
|
+
* `claim-contended` (a parallel sibling won; back off); anything else (a
|
|
732
|
+
* usage/invariant error or a captured throw) is `needs-attention`.
|
|
733
|
+
*/
|
|
734
|
+
function advanceOutcomeToItemStatus(result: AdvanceResult): ItemStatus {
|
|
735
|
+
if (result.exitCode === 0) {
|
|
736
|
+
return result.outcome === 'no-op' ? 'lost-race' : 'claimed-done';
|
|
737
|
+
}
|
|
738
|
+
if (result.exitCode === 2 || result.outcome === 'lost') {
|
|
739
|
+
return 'lost-race';
|
|
740
|
+
}
|
|
741
|
+
if (result.exitCode === 3 || result.outcome === 'contended') {
|
|
742
|
+
return 'claim-contended';
|
|
743
|
+
}
|
|
744
|
+
return 'needs-attention';
|
|
745
|
+
}
|