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,542 @@
|
|
|
1
|
+
import {run, type RunResult} from './git.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The **continue-detection** shared by BOTH onboarding paths (the keystone of
|
|
5
|
+
* the `requeue-continue-and-reset` task). `requeue` keeps the `work/<slug>`
|
|
6
|
+
* branch so the NEXT claim CONTINUES from its tip instead of force-cutting a
|
|
7
|
+
* fresh branch off main. This module factors the one question both onboarding
|
|
8
|
+
* paths must ask — **"does the arbiter have a `work/<slug>` ref AHEAD of
|
|
9
|
+
* main?"** — into ONE helper, plus the rebase-onto-fresh-main step the continued
|
|
10
|
+
* branch needs at onboard-time (ADR §10: rebase-or-abort, never auto-resolve →
|
|
11
|
+
* conflict routes to needs-attention; the agent builds on a CURRENT base).
|
|
12
|
+
*
|
|
13
|
+
* The two onboarding paths reference the same two refs differently:
|
|
14
|
+
* - **in-place** (`src/start.ts` `switchToWorkBranch`, used by
|
|
15
|
+
* `do`/`start`/`work-on`): a normal clone. After `git fetch <arbiter>` the
|
|
16
|
+
* branch is the remote-tracking ref `<arbiter>/work/<slug>` and main is
|
|
17
|
+
* `<arbiter>/main`.
|
|
18
|
+
* - **job-worktree** (`src/workspace.ts` `createJob`, used by
|
|
19
|
+
* `do --remote`/`run`): a BARE hub mirror. `ensureMirror` fetches
|
|
20
|
+
* `+refs/heads/*:refs/heads/*`, so the arbiter's `work/<slug>` lands as a
|
|
21
|
+
* LOCAL head `work/<slug>` and main is the local head `main`.
|
|
22
|
+
*
|
|
23
|
+
* Both call {@link branchAheadOf} with the appropriate ref names; the predicate
|
|
24
|
+
* is identical (ref exists AND is not an ancestor of main, i.e. it carries
|
|
25
|
+
* commits beyond main — the prior attempt's work to continue from). When the
|
|
26
|
+
* branch is ABSENT (the common case: a fresh task, or a `requeue --reset` that
|
|
27
|
+
* deleted it) the predicate is false and the caller falls through to the normal
|
|
28
|
+
* fresh-cut-off-main path with NO special logic.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/** Run git, returning the raw result (no throw) — for soft checks. */
|
|
32
|
+
function gitSoft(
|
|
33
|
+
args: string[],
|
|
34
|
+
cwd: string,
|
|
35
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
36
|
+
): RunResult {
|
|
37
|
+
return run('git', args, cwd, {env});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* True iff the git ref `branchRef` exists in `cwd` AND its tip is NOT an
|
|
42
|
+
* ancestor of `mainRef` — i.e. it carries commits beyond main (the prior
|
|
43
|
+
* attempt's work a `requeue` kept, to be continued). False when the ref is
|
|
44
|
+
* absent (nothing to continue → fresh cut) or already merged into main (no work
|
|
45
|
+
* beyond main → nothing to continue). Read-only; never throws.
|
|
46
|
+
*
|
|
47
|
+
* Both onboarding paths feed this ONE predicate with their own ref names:
|
|
48
|
+
* - in-place clone: branchRef=`<arbiter>/work/<slug>`, mainRef=`<arbiter>/main`
|
|
49
|
+
* - bare hub mirror: branchRef=`work/<slug>`, mainRef=`main`
|
|
50
|
+
*/
|
|
51
|
+
export function branchAheadOf(
|
|
52
|
+
cwd: string,
|
|
53
|
+
branchRef: string,
|
|
54
|
+
mainRef: string,
|
|
55
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
56
|
+
): boolean {
|
|
57
|
+
const tip = gitSoft(
|
|
58
|
+
['rev-parse', '--verify', '--quiet', `${branchRef}^{commit}`],
|
|
59
|
+
cwd,
|
|
60
|
+
env,
|
|
61
|
+
).stdout.trim();
|
|
62
|
+
if (tip === '') {
|
|
63
|
+
return false; // the branch is not on the arbiter → fresh cut, no continue
|
|
64
|
+
}
|
|
65
|
+
const mainTip = gitSoft(
|
|
66
|
+
['rev-parse', '--verify', '--quiet', `${mainRef}^{commit}`],
|
|
67
|
+
cwd,
|
|
68
|
+
env,
|
|
69
|
+
).stdout.trim();
|
|
70
|
+
if (mainTip === '') {
|
|
71
|
+
// No main to compare against (shouldn't happen): treat as ahead so the kept
|
|
72
|
+
// branch is continued rather than silently dropped.
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
// Ahead ⇔ the branch tip is NOT an ancestor of main (it has commits main lacks).
|
|
76
|
+
const isAncestor =
|
|
77
|
+
gitSoft(['merge-base', '--is-ancestor', tip, mainTip], cwd, env).status ===
|
|
78
|
+
0;
|
|
79
|
+
return !isAncestor;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Arbiter-authoritative continue-detection: like {@link branchAheadOf}, but
|
|
84
|
+
* first asks the arbiter (`git ls-remote <arbiterRemote> refs/heads/<branch>`)
|
|
85
|
+
* whether the kept branch EXISTS — so a STALE local remote-tracking ref
|
|
86
|
+
* (`refs/remotes/<arbiter>/<branch>` or a bare mirror's `refs/heads/<branch>`)
|
|
87
|
+
* pointing at a branch already DELETED on the arbiter (by `requeue --reset`, by
|
|
88
|
+
* the merge-reap, or cross-machine by `gc --remote-branches`) can no longer
|
|
89
|
+
* fool the onboard into "continue". This is the READ-side backstop that pairs
|
|
90
|
+
* with the WRITE-side write-through ordering at every delete site
|
|
91
|
+
* (local-ref-first, then `git push <arbiter> --delete`): write-through keeps
|
|
92
|
+
* SAME-MACHINE state in sync at the source; this catches the CROSS-MACHINE
|
|
93
|
+
* residue at the read (the other machine cannot touch this machine's local
|
|
94
|
+
* tracking refs). A plain `git remote prune` does NOT cover this — verified a
|
|
95
|
+
* no-op on the bare hub mirror, which has no `remote.origin.fetch` refspec for
|
|
96
|
+
* the orphaned `refs/remotes/origin/*` namespace.
|
|
97
|
+
*
|
|
98
|
+
* The decision rules, in order:
|
|
99
|
+
* - `git ls-remote <arbiterRemote> refs/heads/<branch>` exits 0 with EMPTY
|
|
100
|
+
* stdout (branch absent on the arbiter) ⇒ NOT ahead (fresh cut). This is
|
|
101
|
+
* the bug-fix case: a stale local ref CANNOT override the arbiter's truth.
|
|
102
|
+
* - `ls-remote` exits 0 with a sha ⇒ delegate to {@link branchAheadOf} on
|
|
103
|
+
* the local refs (the existing predicate: ref exists AND not an ancestor
|
|
104
|
+
* of main). The arbiter-present case is the normal continue path.
|
|
105
|
+
* - `ls-remote` exits non-zero (unreachable arbiter / offline) ⇒ fall back
|
|
106
|
+
* to {@link branchAheadOf} on the local refs — the best the read can do
|
|
107
|
+
* when the arbiter cannot answer (same direction as today).
|
|
108
|
+
*
|
|
109
|
+
* `branch` is the unqualified branch name on the arbiter (e.g.
|
|
110
|
+
* `work/task-<slug>`); `branchRef` + `mainRef` are the local refs the
|
|
111
|
+
* arbiter-present delegate uses (in-place clone: `<arbiter>/<branch>` /
|
|
112
|
+
* `<arbiter>/main`; bare hub mirror: `<branch>` / `main`). `arbiterRemote` is
|
|
113
|
+
* the remote NAME to ls-remote (e.g. `origin` for the mirror, `arbiter` for an
|
|
114
|
+
* in-place clone with the conventional remote name).
|
|
115
|
+
*/
|
|
116
|
+
export function branchAheadOfArbiter(options: {
|
|
117
|
+
cwd: string;
|
|
118
|
+
/** The remote NAME to `ls-remote` (the arbiter as known to this repo). */
|
|
119
|
+
arbiterRemote: string;
|
|
120
|
+
/** Unqualified branch name on the arbiter (e.g. `work/task-<slug>`). */
|
|
121
|
+
branch: string;
|
|
122
|
+
/** The local ref to read for the ahead-of-main check (when arbiter says present). */
|
|
123
|
+
branchRef: string;
|
|
124
|
+
/** The local main ref to compare against. */
|
|
125
|
+
mainRef: string;
|
|
126
|
+
env: NodeJS.ProcessEnv | undefined;
|
|
127
|
+
}): boolean {
|
|
128
|
+
const {cwd, arbiterRemote, branch, branchRef, mainRef, env} = options;
|
|
129
|
+
const ls = gitSoft(['ls-remote', '--heads', arbiterRemote, branch], cwd, env);
|
|
130
|
+
if (ls.status === 0) {
|
|
131
|
+
// Reachable arbiter: its answer is AUTHORITATIVE. Empty ⇒ branch absent
|
|
132
|
+
// ⇒ no continue (a stale local ref cannot resurrect a deleted branch).
|
|
133
|
+
if (ls.stdout.trim() === '') {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
// Present on the arbiter ⇒ use the existing local-ref predicate to decide
|
|
137
|
+
// ahead-of-main (which is how "there is work to continue" is defined).
|
|
138
|
+
return branchAheadOf(cwd, branchRef, mainRef, env);
|
|
139
|
+
}
|
|
140
|
+
// Unreachable arbiter / offline — fall back to the local-ref answer (the
|
|
141
|
+
// best the read can do when the arbiter cannot answer; same direction as
|
|
142
|
+
// before this backstop existed).
|
|
143
|
+
return branchAheadOf(cwd, branchRef, mainRef, env);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** The result of rebasing a continued branch onto the freshly-fetched main. */
|
|
147
|
+
export interface ContinueRebaseResult {
|
|
148
|
+
/** `clean` — the rebase replayed onto main with no conflict. */
|
|
149
|
+
/** `conflict` — the rebase conflicted; it was `--abort`ed (never auto-resolved). */
|
|
150
|
+
kind: 'clean' | 'conflict';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Rebase the CURRENTLY-CHECKED-OUT continued `work/<slug>` branch onto
|
|
155
|
+
* `mainRef` (the freshly-fetched main), so the agent builds on a CURRENT base
|
|
156
|
+
* (ADR §10: rebase, NOT merge — linear history; the prior attempt's commits were
|
|
157
|
+
* based on an OLD main that moved while the item sat in backlog).
|
|
158
|
+
*
|
|
159
|
+
* This is a PLAIN rebase. After the per-item-lock cut-over (prd
|
|
160
|
+
* `ledger-status-per-item-lock-refs`, tasks 9a–9d) NO transient status lands on
|
|
161
|
+
* a work branch: claim does not move the body (it rests in `backlog/`),
|
|
162
|
+
* needs-attention is the lock `state: stuck` (not a `git mv`), and the
|
|
163
|
+
* tasking/advancing markers are gone. So a branch cut from `main` inherits no
|
|
164
|
+
* runner-authored move-only bookkeeping commit, there is nothing to drop, and
|
|
165
|
+
* the old `drop-bookkeeping-rebase` machinery (which papered over the
|
|
166
|
+
* rename/rename ledger conflict that inheritance caused) is deleted. The ONLY
|
|
167
|
+
* commits replayed are the agent's own wip / `→done` commits.
|
|
168
|
+
*
|
|
169
|
+
* A CLEAN rebase returns `{kind: 'clean'}`; a CONFLICTING rebase (a GENUINE code
|
|
170
|
+
* conflict) is `--abort`ed (NEVER auto-resolved) and returns `{kind: 'conflict'}`
|
|
171
|
+
* so the caller can route the item to needs-attention via the §10 path. Must be
|
|
172
|
+
* called while HEAD is the continued branch.
|
|
173
|
+
*
|
|
174
|
+
* RENAME-DETECTION-OFF (task `disable-rename-detection-on-continue-rebase`): the
|
|
175
|
+
* rebase is invoked with `-c merge.directoryRenames=false` SCOPED to the
|
|
176
|
+
* invocation (never a persistent `git config` write), so a single durable
|
|
177
|
+
* folder-transition `git mv` out of a SPARSE source folder is NOT misread by
|
|
178
|
+
* git's directory-rename heuristic as a whole-DIRECTORY rename — which would
|
|
179
|
+
* spuriously flag every sibling file main added into that same folder as
|
|
180
|
+
* `CONFLICT (file location)` and force a FALSE needs-attention. Content-rename
|
|
181
|
+
* detection (`-Xno-renames` / `merge.renames` / `diff.renames`) is NOT what
|
|
182
|
+
* controls this conflict and was empirically verified ineffective; only
|
|
183
|
+
* `merge.directoryRenames=false` suppresses it. A GENUINE same-path content
|
|
184
|
+
* conflict still conflicts unchanged.
|
|
185
|
+
*/
|
|
186
|
+
export function rebaseContinuedBranchOntoMain(
|
|
187
|
+
cwd: string,
|
|
188
|
+
mainRef: string,
|
|
189
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
190
|
+
): ContinueRebaseResult {
|
|
191
|
+
const rebase = gitSoft(
|
|
192
|
+
['-c', 'merge.directoryRenames=false', 'rebase', mainRef],
|
|
193
|
+
cwd,
|
|
194
|
+
env,
|
|
195
|
+
);
|
|
196
|
+
if (rebase.status === 0) {
|
|
197
|
+
return {kind: 'clean'};
|
|
198
|
+
}
|
|
199
|
+
// NEVER auto-resolve: abort back to a clean continued-branch tip.
|
|
200
|
+
gitSoft(['rebase', '--abort'], cwd, env);
|
|
201
|
+
return {kind: 'conflict'};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The default cap on stale-lease push retries — mirrors the claim / tasking-lock
|
|
206
|
+
* INSTANT-contention loop's `retries: 3` default (`claim-cas.ts` `DEFAULT_RETRIES`).
|
|
207
|
+
* After this many re-fetch + re-rebase + re-push attempts the green work is left
|
|
208
|
+
* RECOVERABLE and the caller surfaces a clear terminal failure.
|
|
209
|
+
*/
|
|
210
|
+
export const DEFAULT_STALE_LEASE_RETRIES = 3;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Lexical signal of a `--force-with-lease` STALE-LEASE rejection (git prints
|
|
214
|
+
* `! [rejected] <ref> (stale info)`), as distinct from any OTHER push failure
|
|
215
|
+
* (connectivity, auth, a protected ref). ONLY this case is safe to re-lease +
|
|
216
|
+
* retry on the UNSHARED work branch — every other failure must surface, never
|
|
217
|
+
* silently overwrite. This is the SAME family of contention markers the
|
|
218
|
+
* ledger-write CAS recognises (`ledger-write.ts`), narrowed here to the lease's
|
|
219
|
+
* own `stale info`.
|
|
220
|
+
*/
|
|
221
|
+
export function isStaleLeaseRejection(stderr: string): boolean {
|
|
222
|
+
return /stale info/i.test(stderr);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Outcome of {@link pushProposeBranchWithStaleLeaseRetry} — the sibling of
|
|
227
|
+
* {@link ContinuedPushResult} on the PROPOSE-mode work-branch push.
|
|
228
|
+
*/
|
|
229
|
+
export type ProposePushResult =
|
|
230
|
+
/** The work branch landed on the arbiter (first try or after a stale-lease retry). */
|
|
231
|
+
| {kind: 'pushed'}
|
|
232
|
+
/**
|
|
233
|
+
* BENIGN already-landed race tail: the remote `work/<slug>` ref is GONE on
|
|
234
|
+
* the arbiter AND our HEAD is provably reachable from `<arbiter>/main` — i.e.
|
|
235
|
+
* the work already landed via a sibling's merge and its head was reaped
|
|
236
|
+
* (`integrator.ts` `deleteMergedHeadBranch`'s ancestor-guarded reap, or `gc`).
|
|
237
|
+
* This is the propose-push analogue of the leased-delete `already-reaped`
|
|
238
|
+
* outcome (`item-lock.ts`): a vanished ref whose work is provably landed is
|
|
239
|
+
* the DESIRED end state, not a failure.
|
|
240
|
+
*/
|
|
241
|
+
| {kind: 'already-landed'};
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Push the propose-mode work branch with the SAME stale-lease retry semantics
|
|
245
|
+
* as {@link pushContinuedBranchWithStaleLeaseRetry} (explicit
|
|
246
|
+
* `--force-with-lease=<branch>:<expectedTip>`, `stale info` detection, bounded
|
|
247
|
+
* re-observation + retry, terminal throw on cap exhaustion / non-stale
|
|
248
|
+
* failure), plus the one race the continue path does not have: a `work/<slug>`
|
|
249
|
+
* ref that is GONE on the arbiter because the work already LANDED on `main` is
|
|
250
|
+
* a BENIGN already-landed success, not a failure. The predicate mirrors the
|
|
251
|
+
* leased-delete `already-reaped` + merged-head-reap ancestor guards: gone ref
|
|
252
|
+
* AND `HEAD` is an ancestor of `<arbiter>/main`.
|
|
253
|
+
*
|
|
254
|
+
* WHY a propose-specific helper instead of the continue helper verbatim: the
|
|
255
|
+
* continue helper's stale-lease retry RE-REBASES the kept branch onto the
|
|
256
|
+
* freshly-fetched main (a kept-branch onboard's job — main may have moved
|
|
257
|
+
* while the prior attempt sat in backlog). In the propose path the caller has
|
|
258
|
+
* ALREADY rebased the branch onto `<arbiter>/main` (`integrateWithRebase`, or
|
|
259
|
+
* `integration-core.ts` `recoverAlreadyCommitted`'s recovery rebase), so the
|
|
260
|
+
* only race the lease needs to survive here is the remote work ref MOVING /
|
|
261
|
+
* REAPING under us — re-leasing against the freshly-observed tip is enough,
|
|
262
|
+
* AND a re-rebase mid-integrate would smuggle a NEW rebase past
|
|
263
|
+
* `integrateWithRebase`'s explicit conflict-aborts-to-needs-attention contract.
|
|
264
|
+
* So this helper shares the stale-info detection + bounded retry shape (the
|
|
265
|
+
* `--force-with-lease`-only / never-bare-force / never-`:main` guardrails are
|
|
266
|
+
* identical) but does NOT layer the rebase step.
|
|
267
|
+
*
|
|
268
|
+
* Guardrails (ADR §11): `--force-with-lease` ONLY (re-computed each attempt),
|
|
269
|
+
* NEVER bare `--force`, NEVER `:main`, the WORK branch ONLY. The lease is
|
|
270
|
+
* threaded as `<branch>:<expectedTip>` — using EMPTY (`<branch>:`) when the
|
|
271
|
+
* arbiter has no ref yet (the first-time propose / post-reap shape — the same
|
|
272
|
+
* create-only lease form `item-lock.ts` uses for the lock CAS), so a bare-hub-
|
|
273
|
+
* mirror worktree (no `refs/remotes/<arbiter>/*` upstream) leases correctly.
|
|
274
|
+
*
|
|
275
|
+
* Bounded by `retries` (default {@link DEFAULT_STALE_LEASE_RETRIES}, mirroring
|
|
276
|
+
* the claim / continue retry cap). Must be called while HEAD is the propose
|
|
277
|
+
* `<branch>`.
|
|
278
|
+
*/
|
|
279
|
+
export function pushProposeBranchWithStaleLeaseRetry(options: {
|
|
280
|
+
cwd: string;
|
|
281
|
+
branch: string;
|
|
282
|
+
/** The arbiter remote name to push to / observe (e.g. `arbiter`, `origin`). */
|
|
283
|
+
arbiter: string;
|
|
284
|
+
retries?: number;
|
|
285
|
+
env: NodeJS.ProcessEnv | undefined;
|
|
286
|
+
/** Optional progress note sink (mirrors the continue helper's `note`). */
|
|
287
|
+
note?: (message: string) => void;
|
|
288
|
+
}): ProposePushResult {
|
|
289
|
+
const {cwd, branch, arbiter, env} = options;
|
|
290
|
+
const note = options.note ?? (() => {});
|
|
291
|
+
const retries = options.retries ?? DEFAULT_STALE_LEASE_RETRIES;
|
|
292
|
+
const mainRef = `refs/remotes/${arbiter}/main`;
|
|
293
|
+
|
|
294
|
+
const refreshMain = (): void => {
|
|
295
|
+
gitSoft(
|
|
296
|
+
['fetch', '--quiet', arbiter, `+refs/heads/main:${mainRef}`],
|
|
297
|
+
cwd,
|
|
298
|
+
env,
|
|
299
|
+
);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/** The arbiter's CURRENT `<branch>` sha (via `ls-remote`), or `''` when absent / unreachable. */
|
|
303
|
+
const observeArbiterTip = (): string => {
|
|
304
|
+
const ls = gitSoft(['ls-remote', '--heads', arbiter, branch], cwd, env);
|
|
305
|
+
if (ls.status !== 0) return '';
|
|
306
|
+
const m = /^([0-9a-f]{40})/m.exec(ls.stdout.trim());
|
|
307
|
+
return m ? m[1] : '';
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
/** True iff HEAD is provably reachable from `<arbiter>/main` (the work landed). */
|
|
311
|
+
const headOnArbiterMain = (): boolean => {
|
|
312
|
+
const head = gitSoft(
|
|
313
|
+
['rev-parse', '--verify', '--quiet', 'HEAD'],
|
|
314
|
+
cwd,
|
|
315
|
+
env,
|
|
316
|
+
).stdout.trim();
|
|
317
|
+
if (head === '') return false;
|
|
318
|
+
return (
|
|
319
|
+
gitSoft(['merge-base', '--is-ancestor', head, mainRef], cwd, env)
|
|
320
|
+
.status === 0
|
|
321
|
+
);
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* The BENIGN already-landed predicate: the remote work ref is GONE on the
|
|
326
|
+
* arbiter AND our HEAD is provably reachable from `<arbiter>/main`. Mirrors
|
|
327
|
+
* `integrator.ts` `deleteMergedHeadBranch`'s ancestor-guarded reap + the
|
|
328
|
+
* `item-lock.ts` leased-delete `already-reaped` precedent: a vanished ref
|
|
329
|
+
* whose work is provably landed is the desired end state. Re-fetches main
|
|
330
|
+
* first so the answer reflects the current arbiter, not a stale local view.
|
|
331
|
+
*/
|
|
332
|
+
const benignAlreadyLanded = (): boolean => {
|
|
333
|
+
refreshMain();
|
|
334
|
+
return observeArbiterTip() === '' && headOnArbiterMain();
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
// Short-circuit BEFORE any push: the dominant recovery race shape (a sibling
|
|
338
|
+
// already merged this work and reaped the head before we even attempted our
|
|
339
|
+
// push). Avoids burning a stale-lease retry budget on a no-op.
|
|
340
|
+
if (benignAlreadyLanded()) {
|
|
341
|
+
note(
|
|
342
|
+
`${branch}: already landed on ${arbiter}/main + remote head reaped — ` +
|
|
343
|
+
'clean no-op (no push, no review request).',
|
|
344
|
+
);
|
|
345
|
+
return {kind: 'already-landed'};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
let attempt = 0;
|
|
349
|
+
// eslint-disable-next-line no-constant-condition
|
|
350
|
+
while (true) {
|
|
351
|
+
const observed = observeArbiterTip();
|
|
352
|
+
// Explicit `<branch>:<expected>` — EMPTY when the ref is absent (first-time
|
|
353
|
+
// propose, or a post-reap retry), MATCHING when present. The empty-expected
|
|
354
|
+
// shape is the same create-only `--force-with-lease=<ref>:` form
|
|
355
|
+
// `item-lock.ts` uses for the CAS create.
|
|
356
|
+
const lease = observed === '' ? `${branch}:` : `${branch}:${observed}`;
|
|
357
|
+
const push = gitSoft(
|
|
358
|
+
['push', arbiter, `${branch}:${branch}`, `--force-with-lease=${lease}`],
|
|
359
|
+
cwd,
|
|
360
|
+
env,
|
|
361
|
+
);
|
|
362
|
+
if (push.status === 0) {
|
|
363
|
+
return {kind: 'pushed'};
|
|
364
|
+
}
|
|
365
|
+
// Only `stale info` is re-leasable on this unshared work branch; every
|
|
366
|
+
// other failure (connectivity, protected ref, auth) SURFACES at once.
|
|
367
|
+
if (!isStaleLeaseRejection(push.stderr)) {
|
|
368
|
+
throw new Error(
|
|
369
|
+
`pushing ${branch} to ${arbiter} failed (not a stale lease): ` +
|
|
370
|
+
(push.stderr.trim() || `exit ${push.status}`),
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
// A stale lease: re-check the BENIGN already-landed predicate first (the
|
|
374
|
+
// race tail this task carries), else retry with a freshly-observed lease.
|
|
375
|
+
if (benignAlreadyLanded()) {
|
|
376
|
+
note(
|
|
377
|
+
`${branch}: stale lease + work already on ${arbiter}/main + remote ` +
|
|
378
|
+
'head reaped — clean no-op.',
|
|
379
|
+
);
|
|
380
|
+
return {kind: 'already-landed'};
|
|
381
|
+
}
|
|
382
|
+
attempt += 1;
|
|
383
|
+
if (attempt > retries) {
|
|
384
|
+
throw new Error(
|
|
385
|
+
`pushing ${branch} to ${arbiter} kept failing with a stale ` +
|
|
386
|
+
`--force-with-lease after ${retries} retr${retries === 1 ? 'y' : 'ies'} ` +
|
|
387
|
+
'(the arbiter work ref keeps moving under us, and the work is not ' +
|
|
388
|
+
`provably on main). The green work is still committed on ${branch} — ` +
|
|
389
|
+
'route to needs-attention and retry when the churn settles.',
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
note(
|
|
393
|
+
`${branch} propose push rejected (stale lease) — re-observe + retry ` +
|
|
394
|
+
`(${attempt}/${retries})...`,
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/** The outcome of {@link pushContinuedBranchWithStaleLeaseRetry}. */
|
|
400
|
+
export type ContinuedPushResult =
|
|
401
|
+
/** The work branch landed on the arbiter (first try or after a clean re-rebase). */
|
|
402
|
+
| {kind: 'pushed'}
|
|
403
|
+
/**
|
|
404
|
+
* A re-rebase onto the freshly-fetched main CONFLICTED on a retry; it was
|
|
405
|
+
* `--abort`ed (NEVER auto-resolved). The caller routes the item to
|
|
406
|
+
* needs-attention via the §10 path — the green work stays intact on the branch.
|
|
407
|
+
*/
|
|
408
|
+
| {kind: 'conflict'};
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Push the CONTINUED `work/<slug>` branch to the arbiter with
|
|
412
|
+
* `--force-with-lease`, surviving a STALE-LEASE ("stale info") rejection by
|
|
413
|
+
* re-observing the arbiter's tip and replaying our green work onto it — instead
|
|
414
|
+
* of stranding a committed, gate-green build in the job worktree (the observed
|
|
415
|
+
* `advance-verb-resolver` incident).
|
|
416
|
+
*
|
|
417
|
+
* WHY a retry is SAFE here: the `work/<slug>` branch is UNSHARED — the arbiter
|
|
418
|
+
* CAS serialises the claim per slug, so no rival writer legitimately advances it
|
|
419
|
+
* concurrently. The lease's job is to catch a STALE LOCAL view, not a rival; so
|
|
420
|
+
* on a stale-lease rejection the correct response is to re-fetch the actual
|
|
421
|
+
* remote tip, rebase our work onto current main, and push again, re-leased
|
|
422
|
+
* against the JUST-fetched ref. This stays within the existing guardrails:
|
|
423
|
+
* `--force-with-lease` ONLY (re-computed each attempt), NEVER bare `--force`,
|
|
424
|
+
* NEVER targeting `main`, the WORK branch ONLY (ADR §11).
|
|
425
|
+
*
|
|
426
|
+
* The flow, bounded by `retries` (default {@link DEFAULT_STALE_LEASE_RETRIES},
|
|
427
|
+
* mirroring the claim/tasking-lock instant-contention cap):
|
|
428
|
+
* 1. Push `<branch>:<branch> --force-with-lease=<branch>:<expectedRemoteTip>`.
|
|
429
|
+
* 2. On success → `{kind: 'pushed'}`.
|
|
430
|
+
* 3. On a STALE-LEASE rejection → re-fetch `main` + `<branch>` from the arbiter
|
|
431
|
+
* (into a remote-tracking ref, since the branch is CHECKED OUT here), re-run
|
|
432
|
+
* the onboard-time rebase onto the freshly-fetched main, and retry with the
|
|
433
|
+
* lease re-leased against the freshly-fetched remote tip. A rebase CONFLICT
|
|
434
|
+
* on a retry → `{kind: 'conflict'}` (the existing abort → needs-attention
|
|
435
|
+
* path; the retry covers ONLY the clean-rebase stale-lease case).
|
|
436
|
+
* 4. After the cap → THROW a clear terminal error (the green work is still
|
|
437
|
+
* committed on the branch, so the caller's needs-attention route keeps it
|
|
438
|
+
* recoverable).
|
|
439
|
+
* 5. Any NON-stale push failure (connectivity, protected ref) → THROW at once
|
|
440
|
+
* (never re-leased, never silently swallowed).
|
|
441
|
+
*
|
|
442
|
+
* `expectedRemoteTip` is the arbiter `work/<slug>` sha the caller already
|
|
443
|
+
* observed (the pre-rebase mirror head). The explicit `<branch>:<sha>` lease is
|
|
444
|
+
* REQUIRED in the bare-hub-mirror worktree, which has no `refs/remotes/origin/*`
|
|
445
|
+
* upstream for git to imply the lease from. Must be called while HEAD is the
|
|
446
|
+
* continued `<branch>`.
|
|
447
|
+
*/
|
|
448
|
+
export function pushContinuedBranchWithStaleLeaseRetry(options: {
|
|
449
|
+
cwd: string;
|
|
450
|
+
branch: string;
|
|
451
|
+
/** The arbiter remote name to push to / re-fetch from (e.g. `origin`). */
|
|
452
|
+
arbiter: string;
|
|
453
|
+
/** The local main ref to rebase onto across retries (e.g. `main`). */
|
|
454
|
+
mainRef: string;
|
|
455
|
+
/** The arbiter `<branch>` sha the caller already observed (pre-rebase tip). */
|
|
456
|
+
expectedRemoteTip: string;
|
|
457
|
+
retries?: number;
|
|
458
|
+
env: NodeJS.ProcessEnv | undefined;
|
|
459
|
+
/** Optional progress note sink (mirrors the claim loop's `note`). */
|
|
460
|
+
note?: (message: string) => void;
|
|
461
|
+
}): ContinuedPushResult {
|
|
462
|
+
const {cwd, branch, arbiter, mainRef, env} = options;
|
|
463
|
+
const note = options.note ?? (() => {});
|
|
464
|
+
const retries = options.retries ?? DEFAULT_STALE_LEASE_RETRIES;
|
|
465
|
+
// The remote-tracking ref we re-fetch the arbiter `<branch>` into so the lease
|
|
466
|
+
// can be re-computed WITHOUT touching the checked-out local `<branch>` head
|
|
467
|
+
// (git refuses to fetch into a checked-out branch).
|
|
468
|
+
const trackingRef = `refs/remotes/${arbiter}/${branch}`;
|
|
469
|
+
let expectedTip = options.expectedRemoteTip;
|
|
470
|
+
|
|
471
|
+
let attempt = 0;
|
|
472
|
+
// eslint-disable-next-line no-constant-condition
|
|
473
|
+
while (true) {
|
|
474
|
+
const push = gitSoft(
|
|
475
|
+
[
|
|
476
|
+
'push',
|
|
477
|
+
arbiter,
|
|
478
|
+
`${branch}:${branch}`,
|
|
479
|
+
`--force-with-lease=${branch}:${expectedTip}`,
|
|
480
|
+
],
|
|
481
|
+
cwd,
|
|
482
|
+
env,
|
|
483
|
+
);
|
|
484
|
+
if (push.status === 0) {
|
|
485
|
+
return {kind: 'pushed'};
|
|
486
|
+
}
|
|
487
|
+
// Only a STALE-LEASE rejection is re-leasable on this unshared branch; any
|
|
488
|
+
// other failure (connectivity, protected ref) surfaces immediately.
|
|
489
|
+
if (!isStaleLeaseRejection(push.stderr)) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
`pushing ${branch} to ${arbiter} failed (not a stale lease): ` +
|
|
492
|
+
(push.stderr.trim() || `exit ${push.status}`),
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
attempt += 1;
|
|
497
|
+
if (attempt > retries) {
|
|
498
|
+
throw new Error(
|
|
499
|
+
`pushing ${branch} to ${arbiter} kept failing with a stale ` +
|
|
500
|
+
`--force-with-lease after ${retries} retr${retries === 1 ? 'y' : 'ies'} ` +
|
|
501
|
+
'(the arbiter work ref keeps moving under us). The green work is ' +
|
|
502
|
+
`still committed on ${branch} — route to needs-attention and retry ` +
|
|
503
|
+
'when the churn settles.',
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
note(
|
|
507
|
+
`${branch} push rejected (stale lease) — re-fetch + re-rebase + retry ` +
|
|
508
|
+
`(${attempt}/${retries})...`,
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
// Re-observe the arbiter: refresh local `main` (NOT checked out → fetch into
|
|
512
|
+
// its head) and the arbiter `<branch>` (CHECKED OUT → fetch into a
|
|
513
|
+
// remote-tracking ref so the lease can re-compute against it).
|
|
514
|
+
gitSoft(
|
|
515
|
+
[
|
|
516
|
+
'fetch',
|
|
517
|
+
arbiter,
|
|
518
|
+
`+refs/heads/main:${mainRef}`,
|
|
519
|
+
`+refs/heads/${branch}:${trackingRef}`,
|
|
520
|
+
],
|
|
521
|
+
cwd,
|
|
522
|
+
env,
|
|
523
|
+
);
|
|
524
|
+
const fresh = gitSoft(
|
|
525
|
+
['rev-parse', '--verify', '--quiet', trackingRef],
|
|
526
|
+
cwd,
|
|
527
|
+
env,
|
|
528
|
+
).stdout.trim();
|
|
529
|
+
if (fresh !== '') {
|
|
530
|
+
expectedTip = fresh;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Replay our green work onto the freshly-fetched main (ADR §10: rebase, not
|
|
534
|
+
// merge). A CONFLICT is the EXISTING abort → needs-attention path — the retry
|
|
535
|
+
// handles ONLY the clean-rebase stale-lease case (never auto-resolves).
|
|
536
|
+
const rebase = rebaseContinuedBranchOntoMain(cwd, mainRef, env);
|
|
537
|
+
if (rebase.kind === 'conflict') {
|
|
538
|
+
return {kind: 'conflict'};
|
|
539
|
+
}
|
|
540
|
+
// Loop: retry the push, now re-leased against the freshly-fetched remote tip.
|
|
541
|
+
}
|
|
542
|
+
}
|