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,325 @@
|
|
|
1
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename, dirname, join } from 'node:path';
|
|
3
|
+
import { git } from './git.js';
|
|
4
|
+
import { encodeRepoKey, ensureMirror, } from './repo-mirror.js';
|
|
5
|
+
import { branchAheadOfArbiter, rebaseContinuedBranchOntoMain, pushContinuedBranchWithStaleLeaseRetry, } from './continue-branch.js';
|
|
6
|
+
import { brand } from './brand.js';
|
|
7
|
+
import { workBranchRef } from './slug-namespace.js';
|
|
8
|
+
/**
|
|
9
|
+
* Encode a flat, deterministic, unique-per-claim **work-id** from the arbiter
|
|
10
|
+
* URL + slug: the hierarchical repo key with its `/` separators flattened to
|
|
11
|
+
* `__`, then `__<slug>` appended (ADR §2). Flat (not hierarchical) so listing /
|
|
12
|
+
* counting / GC of jobs is a flat `ls`. Reuses the `repo-mirror` repo→key
|
|
13
|
+
* encoding (dot→dash per segment) — it does NOT duplicate it.
|
|
14
|
+
*
|
|
15
|
+
* E.g. `git@github.com:wighawag/dorfl.git` + `feat`
|
|
16
|
+
* → `github-com__wighawag__dorfl__feat`.
|
|
17
|
+
*/
|
|
18
|
+
export function encodeWorkId(url, slug) {
|
|
19
|
+
const key = encodeRepoKey(url).split('/').join('__');
|
|
20
|
+
return `${key}__${slug}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The on-disk location of a job's worktree: `<workspacesDir>/work/<work-id>/`.
|
|
24
|
+
* Flat, OUTSIDE the hub (`<workspacesDir>/repos/...`), under `workspacesDir`
|
|
25
|
+
* (default `~/.dorfl`), never `~/.cache` (ADR §3).
|
|
26
|
+
*/
|
|
27
|
+
export function jobWorktreePath(workspacesDir, url, slug) {
|
|
28
|
+
return join(workspacesDir, 'work', encodeWorkId(url, slug));
|
|
29
|
+
}
|
|
30
|
+
/** Filename of the per-job record. Derived from the single brand identity
|
|
31
|
+
* (`.{base}-job.json`) so a rename flips it in lockstep.
|
|
32
|
+
*
|
|
33
|
+
* HISTORICAL: this used to be the name of a file written INSIDE the job worktree
|
|
34
|
+
* (`<work-id>/.dorfl-job.json`). That in-tree location was the mistake —
|
|
35
|
+
* a runtime control file inside the checked-out worktree got swept onto the work
|
|
36
|
+
* branch by the runner's broad `git add -A` commits (and once WEDGED a
|
|
37
|
+
* continue-rebase `git switch`). The record now lives at a SIBLING path OUTSIDE
|
|
38
|
+
* the worktree ({@link jobRecordPath}); this constant survives only as the
|
|
39
|
+
* legacy in-tree read-fallback name + as the no-op-build / clean-worktree
|
|
40
|
+
* classification token in `agent-stop.ts`/`gc.ts` (now inert — the record can no
|
|
41
|
+
* longer appear in `git status`). */
|
|
42
|
+
export const JOB_RECORD_FILENAME = brand.jobRecordFilename;
|
|
43
|
+
/**
|
|
44
|
+
* The on-disk location of a job's state record: a SIBLING of its worktree dir,
|
|
45
|
+
* `<workspacesDir>/work/<work-id>.json` (NEXT TO `<workspacesDir>/work/<work-id>/`,
|
|
46
|
+
* NOT inside it).
|
|
47
|
+
*
|
|
48
|
+
* This is the structural fix for the in-tree leak: the record is still under the
|
|
49
|
+
* same `workspacesDir/work/` control area (so `discoverJobs`'s single-directory
|
|
50
|
+
* walk still finds it), but it is PHYSICALLY OUTSIDE the checked-out git
|
|
51
|
+
* worktree, so the runner's broad `git add -A` commits can NEVER stage it — in
|
|
52
|
+
* ANY repo, with no `.gitignore` entry needed. A `<work-id>.json` file name can
|
|
53
|
+
* never collide with the `<work-id>/` worktree DIR (one carries a `.json`
|
|
54
|
+
* extension, the other does not).
|
|
55
|
+
*
|
|
56
|
+
* Derived purely from the worktree `dir` (sibling = `<dir>.json`) so every
|
|
57
|
+
* existing caller that holds a worktree dir keeps the same `(dir, …)` signature.
|
|
58
|
+
*/
|
|
59
|
+
export function jobRecordPath(dir) {
|
|
60
|
+
return join(dirname(dir), `${basename(dir)}.json`);
|
|
61
|
+
}
|
|
62
|
+
/** The LEGACY in-tree record path (`<dir>/.dorfl-job.json`) for the
|
|
63
|
+
* read-fallback below — a job worktree materialised by an OLD binary still has
|
|
64
|
+
* its record here. */
|
|
65
|
+
function legacyJobRecordPath(dir) {
|
|
66
|
+
return join(dir, JOB_RECORD_FILENAME);
|
|
67
|
+
}
|
|
68
|
+
const DEFAULT_HARNESS = { adapter: 'null' };
|
|
69
|
+
/**
|
|
70
|
+
* Create (or recreate) a job: ensure the hub mirror via `repo-mirror`, then
|
|
71
|
+
* `git worktree add` a per-job worktree OUTSIDE the hub at
|
|
72
|
+
* `<workspacesDir>/work/<work-id>/` on `work/<slug>`, branched off the
|
|
73
|
+
* freshly-fetched `<hub>/main`. Writes the per-job record at a SIBLING of the
|
|
74
|
+
* worktree (`<work-id>.json`, OUTSIDE the tree — {@link jobRecordPath}).
|
|
75
|
+
*
|
|
76
|
+
* Distinct slugs ⇒ distinct `work/<slug>` branches, so git's one-branch-per-
|
|
77
|
+
* worktree constraint is naturally avoided (ADR §2). If a stale worktree/branch
|
|
78
|
+
* for this work-id already exists it is cleared first (idempotent re-create).
|
|
79
|
+
*/
|
|
80
|
+
export function createJob(options) {
|
|
81
|
+
const env = options.env;
|
|
82
|
+
const mirror = ensureMirror({
|
|
83
|
+
url: options.url,
|
|
84
|
+
fromRepo: options.fromRepo,
|
|
85
|
+
arbiter: options.arbiter,
|
|
86
|
+
workspacesDir: options.workspacesDir,
|
|
87
|
+
env,
|
|
88
|
+
});
|
|
89
|
+
const slug = options.slug;
|
|
90
|
+
const branch = workBranchRef(options.type ?? 'task', slug);
|
|
91
|
+
const dir = jobWorktreePath(options.workspacesDir, mirror.url, slug);
|
|
92
|
+
// CONTINUE-detection (shared with the in-place path, ADR §14 keystone): after
|
|
93
|
+
// `ensureMirror`'s mirror-style fetch (`+refs/heads/*:refs/heads/*`), a kept
|
|
94
|
+
// arbiter `work/<slug>` lands as a LOCAL head `work/<slug>` in the bare mirror.
|
|
95
|
+
// If it is AHEAD of `main` (a requeue kept it), CONTINUE from it; otherwise cut
|
|
96
|
+
// FRESH off main (the common case — a first attempt, or `requeue --reset` deleted
|
|
97
|
+
// it).
|
|
98
|
+
// ARBITER-AUTHORITATIVE continue-detection: `ls-remote` the arbiter (the
|
|
99
|
+
// mirror's `origin`) so an orphaned local head/tracking-ref in the bare hub
|
|
100
|
+
// mirror — e.g. a `refs/remotes/origin/work/<slug>` in the namespace no
|
|
101
|
+
// `remote.origin.fetch` refspec prunes, or a `refs/heads/work/<slug>` that
|
|
102
|
+
// `ensureMirror`'s `--prune` could not reach — cannot resurrect a branch the
|
|
103
|
+
// arbiter no longer has (e.g. a cross-machine `gc --remote-branches` delete).
|
|
104
|
+
const continueFromKept = branchAheadOfArbiter({
|
|
105
|
+
cwd: mirror.path,
|
|
106
|
+
arbiterRemote: 'origin',
|
|
107
|
+
branch,
|
|
108
|
+
branchRef: branch,
|
|
109
|
+
mainRef: 'main',
|
|
110
|
+
env,
|
|
111
|
+
});
|
|
112
|
+
let continued = false;
|
|
113
|
+
let continueRebaseConflict = false;
|
|
114
|
+
let continuePushFailure;
|
|
115
|
+
if (continueFromKept) {
|
|
116
|
+
// The arbiter `work/<slug>` tip the mirror fetched, READ BEFORE the onboard
|
|
117
|
+
// rebase rewrites the local branch — the value the --force-with-lease push
|
|
118
|
+
// expects the arbiter to still hold. A requeue-continue can CHURN this ref
|
|
119
|
+
// after the mirror fetch, making the lease stale; the retry below re-leases
|
|
120
|
+
// against the freshly-fetched tip (the WORK branch is unshared, so re-observing
|
|
121
|
+
// + replaying is correct).
|
|
122
|
+
const expectedRemoteTip = git(['rev-parse', branch], mirror.path, {
|
|
123
|
+
env,
|
|
124
|
+
}).trim();
|
|
125
|
+
// Clear ONLY a stale worktree DIR (never the branch we are continuing), then
|
|
126
|
+
// cut the worktree FROM the kept branch (not fresh off main).
|
|
127
|
+
clearStaleWorktreeOnly(mirror.path, dir, env);
|
|
128
|
+
git(['worktree', 'add', dir, branch], mirror.path, { env });
|
|
129
|
+
continued = true;
|
|
130
|
+
// REBASE the continued branch onto the freshly-fetched mirror main at
|
|
131
|
+
// onboard-time (ADR §10: rebase, not merge) so the agent builds on a CURRENT
|
|
132
|
+
// base. A CLEAN rebase → update the already-pushed arbiter tip with
|
|
133
|
+
// --force-with-lease on the WORK branch ONLY (a requeued item is unshared) —
|
|
134
|
+
// NEVER --force, NEVER to main (§11). A CONFLICT → aborted (never
|
|
135
|
+
// auto-resolved) + flagged so the caller routes to needs-attention.
|
|
136
|
+
const rebase = rebaseContinuedBranchOntoMain(dir, 'main', env);
|
|
137
|
+
if (rebase.kind === 'conflict') {
|
|
138
|
+
continueRebaseConflict = true;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// Push the rebased tip with --force-with-lease, SURVIVING a stale-lease
|
|
142
|
+
// ("stale info") rejection: re-fetch the arbiter `work/<slug>` + main,
|
|
143
|
+
// re-rebase onto current main, and retry (bounded) instead of stranding the
|
|
144
|
+
// committed green work in the worktree. A rebase CONFLICT on a retry is the
|
|
145
|
+
// SAME abort → needs-attention path (never auto-resolved).
|
|
146
|
+
//
|
|
147
|
+
// The helper THROWS on a terminal failure (the stale-lease retry cap, or a
|
|
148
|
+
// non-stale-lease rejection / unreachable arbiter). BEFORE this task that
|
|
149
|
+
// throw ESCAPED `createJob` uncaught, crashing the run and leaving the
|
|
150
|
+
// already-committed kept work silently in `work/in-progress/` on the arbiter
|
|
151
|
+
// (the stale-lease-strand incident). We now CATCH it and flag
|
|
152
|
+
// `continuePushFailure` so the caller (`runRemotePipeline`) routes the item
|
|
153
|
+
// to needs-attention — the kept work stays committed + recoverable on the
|
|
154
|
+
// branch — instead of stranding it.
|
|
155
|
+
try {
|
|
156
|
+
const pushed = pushContinuedBranchWithStaleLeaseRetry({
|
|
157
|
+
cwd: dir,
|
|
158
|
+
branch,
|
|
159
|
+
arbiter: 'origin',
|
|
160
|
+
mainRef: 'main',
|
|
161
|
+
expectedRemoteTip,
|
|
162
|
+
env,
|
|
163
|
+
});
|
|
164
|
+
if (pushed.kind === 'conflict') {
|
|
165
|
+
continueRebaseConflict = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
continuePushFailure = err instanceof Error ? err.message : String(err);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Clear any stale registration for this work-id (idempotent re-create): a
|
|
175
|
+
// leftover worktree dir or branch from a prior crashed run would block the
|
|
176
|
+
// `worktree add`. We use git's own removal, never a bare rm -rf (ADR §4).
|
|
177
|
+
clearStale(mirror.path, dir, branch, env);
|
|
178
|
+
// Cut the worktree OUTSIDE the hub, on a fresh per-slug branch off the
|
|
179
|
+
// freshly-fetched mirror main. `--force` is not used: the branch is unique.
|
|
180
|
+
git(['worktree', 'add', '-b', branch, dir, 'main'], mirror.path, { env });
|
|
181
|
+
}
|
|
182
|
+
const record = {
|
|
183
|
+
slug,
|
|
184
|
+
repoKey: encodeRepoKey(mirror.url),
|
|
185
|
+
branch,
|
|
186
|
+
startedAt: new Date().toISOString(),
|
|
187
|
+
state: 'running',
|
|
188
|
+
harness: options.harness ?? DEFAULT_HARNESS,
|
|
189
|
+
};
|
|
190
|
+
const recordPath = jobRecordPath(dir);
|
|
191
|
+
writeJobRecord(dir, record);
|
|
192
|
+
return {
|
|
193
|
+
dir,
|
|
194
|
+
branch,
|
|
195
|
+
slug,
|
|
196
|
+
arbiterRemote: 'origin',
|
|
197
|
+
recordPath,
|
|
198
|
+
record,
|
|
199
|
+
mirror,
|
|
200
|
+
continued,
|
|
201
|
+
continueRebaseConflict,
|
|
202
|
+
continuePushFailure,
|
|
203
|
+
dispose() {
|
|
204
|
+
git(['worktree', 'remove', '--force', dir], mirror.path, { env });
|
|
205
|
+
removeJobRecord(dir);
|
|
206
|
+
pruneAndDropBranch(mirror.path, branch, env);
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Write (or overwrite) a job's record to its SIBLING path ({@link jobRecordPath},
|
|
212
|
+
* `<work-id>.json` next to the worktree), OUTSIDE the checked-out tree. `dir` is
|
|
213
|
+
* the worktree dir, kept as the parameter so every caller is unchanged.
|
|
214
|
+
*/
|
|
215
|
+
export function writeJobRecord(dir, record) {
|
|
216
|
+
writeFileSync(jobRecordPath(dir), JSON.stringify(record, null, 2) + '\n');
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Read a job's record given its worktree `dir`, or `undefined` if absent/invalid.
|
|
220
|
+
*
|
|
221
|
+
* Reads the NEW sibling location ({@link jobRecordPath}) first, then falls back
|
|
222
|
+
* to the LEGACY in-tree location (`<dir>/.dorfl-job.json`) so a job
|
|
223
|
+
* worktree materialised by an OLD binary (record still inside the tree) stays
|
|
224
|
+
* discoverable/reapable until it is torn down. New jobs only ever write the
|
|
225
|
+
* sibling path, so the fallback is purely for in-flight migration.
|
|
226
|
+
*/
|
|
227
|
+
export function readJobRecord(dir) {
|
|
228
|
+
for (const path of [jobRecordPath(dir), legacyJobRecordPath(dir)]) {
|
|
229
|
+
if (!existsSync(path)) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Delete a job's record on teardown — BOTH the new sibling path
|
|
243
|
+
* ({@link jobRecordPath}) and the legacy in-tree path (an old-binary worktree).
|
|
244
|
+
* Best-effort + idempotent (a missing file is fine). Called when a worktree is
|
|
245
|
+
* removed (reaped / disposed / cleared) so the relocated record does not outlive
|
|
246
|
+
* its worktree as an orphan `<work-id>.json` (when the record lived INSIDE the
|
|
247
|
+
* worktree it was deleted WITH it by `git worktree remove`; now that it is a
|
|
248
|
+
* sibling, its teardown must be explicit).
|
|
249
|
+
*/
|
|
250
|
+
export function removeJobRecord(dir) {
|
|
251
|
+
for (const path of [jobRecordPath(dir), legacyJobRecordPath(dir)]) {
|
|
252
|
+
try {
|
|
253
|
+
rmSync(path, { force: true });
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
// best-effort: an unremovable orphan record is harmless (discovery
|
|
257
|
+
// keys on the worktree DIR, which is gone).
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Update a job's record in place (e.g. flip `state` to `needs-attention` after a
|
|
263
|
+
* rebase conflict), merging the patch over the on-disk record. A no-op if no
|
|
264
|
+
* record exists.
|
|
265
|
+
*/
|
|
266
|
+
export function updateJobRecord(dir, patch) {
|
|
267
|
+
const current = readJobRecord(dir);
|
|
268
|
+
if (!current) {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
const next = { ...current, ...patch };
|
|
272
|
+
writeJobRecord(dir, next);
|
|
273
|
+
return next;
|
|
274
|
+
}
|
|
275
|
+
/** Remove a stale worktree dir / branch registration before re-creating. */
|
|
276
|
+
function clearStale(mirrorPath, dir, branch, env) {
|
|
277
|
+
if (existsSync(dir)) {
|
|
278
|
+
// Soft-remove: ignore errors (e.g. the dir is not a registered worktree).
|
|
279
|
+
try {
|
|
280
|
+
git(['worktree', 'remove', '--force', dir], mirrorPath, { env });
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// fall through to prune below
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
pruneAndDropBranch(mirrorPath, branch, env);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Clear ONLY a stale worktree DIR (and prune dangling registrations) — WITHOUT
|
|
290
|
+
* dropping the branch. Used on the CONTINUE path so the kept `work/<slug>`
|
|
291
|
+
* branch (the durable requeue artifact) is NEVER nuked while a leftover worktree
|
|
292
|
+
* dir from a prior crashed attempt is still cleared so `worktree add` succeeds.
|
|
293
|
+
*/
|
|
294
|
+
function clearStaleWorktreeOnly(mirrorPath, dir, env) {
|
|
295
|
+
if (existsSync(dir)) {
|
|
296
|
+
try {
|
|
297
|
+
git(['worktree', 'remove', '--force', dir], mirrorPath, { env });
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// fall through to prune below
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
git(['worktree', 'prune'], mirrorPath, { env });
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// best-effort
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** Prune dangling worktree registrations + delete the work branch if present. */
|
|
311
|
+
function pruneAndDropBranch(mirrorPath, branch, env) {
|
|
312
|
+
try {
|
|
313
|
+
git(['worktree', 'prune'], mirrorPath, { env });
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
// best-effort
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
git(['branch', '-D', branch], mirrorPath, { env });
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
// branch may not exist
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,SAAS,CAAC;AACxE,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAC,MAAM,WAAW,CAAC;AAClD,OAAO,EAAC,GAAG,EAAC,MAAM,UAAU,CAAC;AAC7B,OAAO,EACN,aAAa,EACb,YAAY,GAEZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,oBAAoB,EACpB,6BAA6B,EAC7B,sCAAsC,GACtC,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AACjC,OAAO,EAAC,aAAa,EAAqB,MAAM,qBAAqB,CAAC;AA4DtE;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,IAAY;IACrD,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,OAAO,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC9B,aAAqB,EACrB,GAAW,EACX,IAAY;IAEZ,OAAO,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;qCAWqC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC,iBAAiB,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACxC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACpD,CAAC;AAED;;sBAEsB;AACtB,SAAS,mBAAmB,CAAC,GAAW;IACvC,OAAO,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;AACvC,CAAC;AAiFD,MAAM,eAAe,GAAkB,EAAC,OAAO,EAAE,MAAM,EAAC,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CAAC,OAAyB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,MAAM,MAAM,GAAG,YAAY,CAAC;QAC3B,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,GAAG;KACH,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAErE,8EAA8E;IAC9E,6EAA6E;IAC7E,gFAAgF;IAChF,gFAAgF;IAChF,kFAAkF;IAClF,OAAO;IACP,yEAAyE;IACzE,4EAA4E;IAC5E,wEAAwE;IACxE,2EAA2E;IAC3E,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;QAC7C,GAAG,EAAE,MAAM,CAAC,IAAI;QAChB,aAAa,EAAE,QAAQ;QACvB,MAAM;QACN,SAAS,EAAE,MAAM;QACjB,OAAO,EAAE,MAAM;QACf,GAAG;KACH,CAAC,CAAC;IACH,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,sBAAsB,GAAG,KAAK,CAAC;IACnC,IAAI,mBAAuC,CAAC;IAE5C,IAAI,gBAAgB,EAAE,CAAC;QACtB,4EAA4E;QAC5E,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,gFAAgF;QAChF,2BAA2B;QAC3B,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE;YACjE,GAAG;SACH,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,6EAA6E;QAC7E,8DAA8D;QAC9D,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC9C,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;QAC1D,SAAS,GAAG,IAAI,CAAC;QAEjB,sEAAsE;QACtE,6EAA6E;QAC7E,oEAAoE;QACpE,6EAA6E;QAC7E,kEAAkE;QAClE,oEAAoE;QACpE,MAAM,MAAM,GAAG,6BAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/D,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAChC,sBAAsB,GAAG,IAAI,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,wEAAwE;YACxE,uEAAuE;YACvE,4EAA4E;YAC5E,4EAA4E;YAC5E,2DAA2D;YAC3D,EAAE;YACF,2EAA2E;YAC3E,0EAA0E;YAC1E,uEAAuE;YACvE,6EAA6E;YAC7E,8DAA8D;YAC9D,4EAA4E;YAC5E,0EAA0E;YAC1E,oCAAoC;YACpC,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,sCAAsC,CAAC;oBACrD,GAAG,EAAE,GAAG;oBACR,MAAM;oBACN,OAAO,EAAE,QAAQ;oBACjB,OAAO,EAAE,MAAM;oBACf,iBAAiB;oBACjB,GAAG;iBACH,CAAC,CAAC;gBACH,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAChC,sBAAsB,GAAG,IAAI,CAAC;gBAC/B,CAAC;YACF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,mBAAmB,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxE,CAAC;QACF,CAAC;IACF,CAAC;SAAM,CAAC;QACP,0EAA0E;QAC1E,2EAA2E;QAC3E,0EAA0E;QAC1E,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAE1C,uEAAuE;QACvE,4EAA4E;QAC5E,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,MAAM,GAAc;QACzB,IAAI;QACJ,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC;QAClC,MAAM;QACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,eAAe;KAC3C,CAAC;IACF,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAE5B,OAAO;QACN,GAAG;QACH,MAAM;QACN,IAAI;QACJ,aAAa,EAAE,QAAQ;QACvB,UAAU;QACV,MAAM;QACN,MAAM;QACN,SAAS;QACT,sBAAsB;QACtB,mBAAmB;QACnB,OAAO;YACN,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;YAChE,eAAe,CAAC,GAAG,CAAC,CAAC;YACrB,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,MAAiB;IAC5D,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACxC,KAAK,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,SAAS;QACV,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAc,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,KAAK,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC;YACJ,MAAM,CAAC,IAAI,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACR,mEAAmE;YACnE,4CAA4C;QAC7C,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC9B,GAAW,EACX,KAAyB;IAEzB,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,EAAC,GAAG,OAAO,EAAE,GAAG,KAAK,EAAC,CAAC;IACpC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,SAAS,UAAU,CAClB,UAAkB,EAClB,GAAW,EACX,MAAc,EACd,GAAkC;IAElC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,0EAA0E;QAC1E,IAAI,CAAC;YACJ,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACR,8BAA8B;QAC/B,CAAC;IACF,CAAC;IACD,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAC9B,UAAkB,EAClB,GAAW,EACX,GAAkC;IAElC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACR,8BAA8B;QAC/B,CAAC;IACF,CAAC;IACD,IAAI,CAAC;QACJ,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACR,cAAc;IACf,CAAC;AACF,CAAC;AAED,iFAAiF;AACjF,SAAS,kBAAkB,CAC1B,UAAkB,EAClB,MAAc,EACd,GAAkC;IAElC,IAAI,CAAC;QACJ,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACR,cAAc;IACf,CAAC;IACD,IAAI,CAAC;QACJ,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,EAAC,GAAG,EAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACR,uBAAuB;IACxB,CAAC;AACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dorfl",
|
|
3
|
-
"version": "0.
|
|
4
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/wighawag/dorfl.git",
|
|
7
|
+
"directory": "packages/dorfl"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/wighawag/dorfl#readme",
|
|
10
|
+
"bugs": "https://github.com/wighawag/dorfl/issues",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"bin": {
|
|
16
|
+
"dorfl": "dist/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"src"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"commander": "^14.0.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^25.2.0",
|
|
36
|
+
"as-soon": "^0.1.5",
|
|
37
|
+
"tsx": "^4.21.0",
|
|
38
|
+
"typescript": "^5.3.3",
|
|
39
|
+
"vitest": "^4.0.18"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc && node scripts/vendor-protocol.mjs",
|
|
43
|
+
"dev": "as-soon -w src pnpm build",
|
|
44
|
+
"cli": "tsx src/cli.ts",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import {existsSync, readFileSync} from 'node:fs';
|
|
2
|
+
import {dirname, resolve} from 'node:path';
|
|
3
|
+
import {fileURLToPath} from 'node:url';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The CI-integration deliverable for the `advance` loop (prd `advance-loop`,
|
|
7
|
+
* task `advance-install-ci`, US #27/28): the advance-loop CAPABILITY as a
|
|
8
|
+
* DOCUMENTED workflow TEMPLATE (not a CLI subcommand; see the task's `##
|
|
9
|
+
* Decisions`). The template at `docs/ci/advance-loop.yml.template` wires "on cron
|
|
10
|
+
* / on-answer-committed, run the RIGHT shape" and only INVOKES the existing
|
|
11
|
+
* `advance` driver; it is NOT entangled with the tick.
|
|
12
|
+
*
|
|
13
|
+
* The unified, per-capability `install-ci` CLI (auth/secrets wizard + GitHub
|
|
14
|
+
* adapter) is owned by the separate `runner-in-ci` prd
|
|
15
|
+
* (`work/prds/tasked/runner-in-ci.md`); when built it EMITS this template as its
|
|
16
|
+
* advance-loop capability. This module's job is unchanged either way: locate +
|
|
17
|
+
* STRUCTURALLY VALIDATE the template, so its shape is a contract the CLI can
|
|
18
|
+
* safely emit (see `docs/ci/README.md` "Relationship to the `install-ci` CLI").
|
|
19
|
+
*
|
|
20
|
+
* This module locates + reads that template and STRUCTURALLY VALIDATES it. The
|
|
21
|
+
* package depends on NO YAML library (see `frontmatter.ts` for the same
|
|
22
|
+
* constraint), so {@link validateAdvanceCiTemplate} checks the small set of
|
|
23
|
+
* invariants the task's acceptance criteria require directly:
|
|
24
|
+
*
|
|
25
|
+
* - triggers on a CRON schedule AND on-answer-committed (a push touching
|
|
26
|
+
* `work/questions/**`);
|
|
27
|
+
* - `propose` mode → a MATRIX of independent jobs enumerated via the
|
|
28
|
+
* mirror-side pool scan (`dorfl scan --json`), one `advance … --propose`
|
|
29
|
+
* per item (the `--propose` flag TIES the integration mode to the matrix shape,
|
|
30
|
+
* so a leg can never merge to main);
|
|
31
|
+
* - `merge` mode → a MATRIX of independent jobs (one per item), each leg
|
|
32
|
+
* running `dorfl advance <item> --merge` so build/gate/review run
|
|
33
|
+
* concurrently across siblings; the LAND TAIL is serialised by the engine's
|
|
34
|
+
* `mergeRetries` CAS-retry loop (the git-alone floor), NOT by this
|
|
35
|
+
* workflow's job shape — a host-specific `concurrency:` group would be
|
|
36
|
+
* load-bearing for safety, which the floor framing forbids;
|
|
37
|
+
* - the dispatch input is `integrationMode` (ONE word, ONE meaning): it drives
|
|
38
|
+
* BOTH the integration flag the legs pass AND the job shape, so they cannot
|
|
39
|
+
* desync;
|
|
40
|
+
* - it references the EXISTING `advance` driver only (no new execution model);
|
|
41
|
+
* - it is a `.template` (so it never self-triggers in THIS repo).
|
|
42
|
+
*
|
|
43
|
+
* The check is deliberately a set of presence/shape assertions over the raw text
|
|
44
|
+
* rather than a full YAML parse — it is the dependency-free counterpart of "the
|
|
45
|
+
* template parses + references the right driver invocations" the task asks for.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/** A single structural problem found in the template. */
|
|
49
|
+
export interface AdvanceCiTemplateProblem {
|
|
50
|
+
/** A short, stable id for the violated invariant (for tests/assertions). */
|
|
51
|
+
id: string;
|
|
52
|
+
/** Human-readable description of what is missing or wrong. */
|
|
53
|
+
message: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The result of {@link validateAdvanceCiTemplate}. */
|
|
57
|
+
export interface AdvanceCiTemplateValidation {
|
|
58
|
+
/** True iff the template satisfies EVERY structural invariant. */
|
|
59
|
+
ok: boolean;
|
|
60
|
+
/** Each violated invariant (empty when `ok`). */
|
|
61
|
+
problems: AdvanceCiTemplateProblem[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Locate the workflow template `docs/ci/advance-loop.yml.template`. It is a
|
|
66
|
+
* REPO doc (the maintainer copies it into a consumer's `.github/workflows/`), so
|
|
67
|
+
* it is resolved relative to this source file's monorepo position — the same
|
|
68
|
+
* dev-monorepo walk `resolveProtocolDoc`'s last candidates use. `override`
|
|
69
|
+
* short-circuits for tests / unusual layouts.
|
|
70
|
+
*/
|
|
71
|
+
export function resolveAdvanceCiTemplatePath(override?: string): string {
|
|
72
|
+
if (override) {
|
|
73
|
+
return override;
|
|
74
|
+
}
|
|
75
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
76
|
+
// here = .../packages/dorfl/{src,dist}; the doc lives at the monorepo
|
|
77
|
+
// root under docs/ci/. Walk up to the root from either src/ or dist/.
|
|
78
|
+
const candidates = [
|
|
79
|
+
resolve(here, '..', '..', '..', 'docs', 'ci', 'advance-loop.yml.template'),
|
|
80
|
+
resolve(
|
|
81
|
+
here,
|
|
82
|
+
'..',
|
|
83
|
+
'..',
|
|
84
|
+
'..',
|
|
85
|
+
'..',
|
|
86
|
+
'docs',
|
|
87
|
+
'ci',
|
|
88
|
+
'advance-loop.yml.template',
|
|
89
|
+
),
|
|
90
|
+
];
|
|
91
|
+
for (const candidate of candidates) {
|
|
92
|
+
if (existsSync(candidate)) {
|
|
93
|
+
return candidate;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Fall back to the first candidate so the error names the expected path.
|
|
97
|
+
return candidates[0];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Read the raw template text. Throws (ENOENT) if it cannot be located. */
|
|
101
|
+
export function loadAdvanceCiTemplate(override?: string): string {
|
|
102
|
+
return readFileSync(resolveAdvanceCiTemplatePath(override), 'utf8');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Structurally validate the advance-loop CI workflow template against the task's
|
|
107
|
+
* acceptance criteria. Dependency-free (no YAML lib): a set of presence/shape
|
|
108
|
+
* assertions over the raw text.
|
|
109
|
+
*/
|
|
110
|
+
export function validateAdvanceCiTemplate(
|
|
111
|
+
text: string,
|
|
112
|
+
): AdvanceCiTemplateValidation {
|
|
113
|
+
const problems: AdvanceCiTemplateProblem[] = [];
|
|
114
|
+
const require = (id: string, present: boolean, message: string): void => {
|
|
115
|
+
if (!present) {
|
|
116
|
+
problems.push({id, message});
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// --- Triggers: cron AND on-answer-committed ---------------------------------
|
|
121
|
+
require('trigger-cron', /\bschedule:\s*[\s\S]*?-\s*cron:/.test(
|
|
122
|
+
text,
|
|
123
|
+
), 'must trigger on a cron schedule (`on.schedule[].cron`).');
|
|
124
|
+
require('trigger-on-answer-committed', /\bpush:\s*[\s\S]*?paths:[\s\S]*?work\/questions\//.test(
|
|
125
|
+
text,
|
|
126
|
+
), 'must trigger on-answer-committed (a push touching `work/questions/**`).');
|
|
127
|
+
|
|
128
|
+
// --- propose ⇒ a MATRIX enumerated via the mirror-side pool scan -------------
|
|
129
|
+
require('propose-matrix', /strategy:\s*[\s\S]*?matrix:/.test(
|
|
130
|
+
text,
|
|
131
|
+
), '`propose` mode must emit a MATRIX of jobs (`strategy.matrix`).');
|
|
132
|
+
require('propose-enumerates-via-scan', /dorfl scan --json/.test(
|
|
133
|
+
text,
|
|
134
|
+
), 'the matrix items must be ENUMERATED via the mirror-side pool scan ' +
|
|
135
|
+
'(`dorfl scan --json`).');
|
|
136
|
+
// The `enumerate` `jq` must UNION taskable prds into the matrix
|
|
137
|
+
// (`ci-propose-matrix-must-enumerate-sliceable-prds-not-only-slices`): a
|
|
138
|
+
// task-only `jq` would render `DORFL_AUTO_TASK` dead on the hourly
|
|
139
|
+
// cron — a ready ungated PRD would never become a matrix leg. The `jq` must
|
|
140
|
+
// read `scan --json`'s taskable-SPEC pool (`repos[].specs[]` + `cwd.repo.specs[]`)
|
|
141
|
+
// and emit `spec:<slug>` legs alongside the `task:<slug>` legs.
|
|
142
|
+
require('propose-enumerates-taskable-specs', /"spec:" \+ \.slug/.test(text) &&
|
|
143
|
+
/\.specs\[\]/.test(
|
|
144
|
+
text,
|
|
145
|
+
), 'the propose-mode `enumerate` `jq` must union taskable specs into the ' +
|
|
146
|
+
"matrix as `spec:<slug>` legs (read from `scan --json`'s `repos[].specs[]` " +
|
|
147
|
+
'+ `cwd.repo.specs[]` pools), so a ready ungated SPEC becomes one auto-task ' +
|
|
148
|
+
'matrix leg alongside the eligible-task legs ' +
|
|
149
|
+
'(`ci-propose-matrix-must-enumerate-sliceable-prds-not-only-slices`).');
|
|
150
|
+
require('propose-one-advance-per-item', /dorfl advance "?\$\{\{\s*matrix\./.test(
|
|
151
|
+
text,
|
|
152
|
+
), 'each matrix leg must run one `dorfl advance <matrix item>` ' +
|
|
153
|
+
'(one PR per item).');
|
|
154
|
+
// The matrix leg must carry `--propose` so the integration mode is TIED to the
|
|
155
|
+
// matrix shape (it cannot desync from the dispatch `integrationMode` input nor
|
|
156
|
+
// fall back to a repo config default of `merge`). Scoped to the `advance-propose`
|
|
157
|
+
// job so it is the LEG that carries it, not merely the file somewhere.
|
|
158
|
+
require('propose-leg-carries-propose-flag', /advance-propose:[\s\S]*?dorfl advance "?\$\{\{\s*matrix\.[\s\S]*?--propose\b/.test(
|
|
159
|
+
text,
|
|
160
|
+
), 'each `propose` matrix leg must pass `--propose` so the integration mode is ' +
|
|
161
|
+
'TIED to the matrix shape (a leg can never merge to main / desync from the ' +
|
|
162
|
+
'dispatch mode).');
|
|
163
|
+
|
|
164
|
+
// --- merge ⇒ a MATRIX per item (parallel build/gate/review, serialised land) -
|
|
165
|
+
// The engine's `integrateLock` + `mergeRetries` CAS-retry loop is what makes
|
|
166
|
+
// concurrent merge jobs LAND-SAFE (`land-time-reverify-and-parallel-merge-ceiling`):
|
|
167
|
+
// build/gate/review fan out across siblings, and a non-fast-forward push
|
|
168
|
+
// triggers re-rebase + re-gate + retry up to the resolved `mergeRetries` cap.
|
|
169
|
+
// The cross-job serialiser is the CAS-retry loop itself — the git-alone floor.
|
|
170
|
+
require('merge-matrix', /advance-merge:[\s\S]*?strategy:\s*[\s\S]*?matrix:/.test(
|
|
171
|
+
text,
|
|
172
|
+
), 'the `merge` job must use a MATRIX (parallel build/gate/review per item; ' +
|
|
173
|
+
"the land tail is serialised by the engine's `mergeRetries` CAS-retry " +
|
|
174
|
+
"loop, not by the workflow's job shape).");
|
|
175
|
+
// Each merge matrix leg must run one `dorfl advance <matrix.item> --merge`,
|
|
176
|
+
// scoped to the `advance-merge:` job so the `--merge` flag is TIED to its leg
|
|
177
|
+
// (cannot desync from the dispatch `integrationMode` input nor fall back to a
|
|
178
|
+
// repo config default of `propose`).
|
|
179
|
+
require('merge-leg-carries-merge-flag', /advance-merge:[\s\S]*?dorfl advance "?\$\{\{\s*matrix\.[\s\S]*?--merge\b/.test(
|
|
180
|
+
text,
|
|
181
|
+
), 'each `merge` matrix leg must pass `--merge` so the integration mode is ' +
|
|
182
|
+
'TIED to the matrix shape (a leg can never propose-only / desync from the ' +
|
|
183
|
+
'dispatch mode).');
|
|
184
|
+
// The merge fan-out is the SAFETY-FLOOR shape: no `concurrency:` group on the
|
|
185
|
+
// `advance-merge:` job, because a GitHub Actions `concurrency:` serialiser
|
|
186
|
+
// would be load-bearing for cross-job land safety, and the floor must work on
|
|
187
|
+
// a bare arbiter with no host (Applied Answer q1: scaled CAS-retry is the
|
|
188
|
+
// floor; the portable cross-job ref-lock is the planned accelerator; GitHub
|
|
189
|
+
// `concurrency:` is OPTIONAL host sugar only, deliberately not used here).
|
|
190
|
+
require('merge-no-host-concurrency-serialiser', !/advance-merge:[\s\S]*?\n\s{4}concurrency:/.test(
|
|
191
|
+
text,
|
|
192
|
+
), 'the `merge` job must NOT carry a `concurrency:` group: a host-specific ' +
|
|
193
|
+
'serialiser would make the cross-job land safety depend on a GitHub Actions ' +
|
|
194
|
+
"feature; the engine's `mergeRetries` CAS-retry loop is the git-alone " +
|
|
195
|
+
'floor.');
|
|
196
|
+
|
|
197
|
+
// --- It only INVOKES the existing `advance` driver (no new execution model) --
|
|
198
|
+
require('invokes-advance-driver', /dorfl advance\b/.test(
|
|
199
|
+
text,
|
|
200
|
+
), 'the workflow must INVOKE the existing `advance` driver.');
|
|
201
|
+
|
|
202
|
+
return {ok: problems.length === 0, problems};
|
|
203
|
+
}
|