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,668 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `install-ci` ADVANCE-LIFECYCLE capability (prd `runner-in-ci`, task
|
|
3
|
+
* `install-ci-advance-lifecycle-workflow`; capability C: auto-triage observations
|
|
4
|
+
* + surface declared blockers + apply committed answers). This module GENERATES
|
|
5
|
+
* the advance-lifecycle workflow by ABSORBING and PARAMETERISING the existing seed
|
|
6
|
+
* `docs/ci/advance-loop.yml.template` (the advance-loop capability's output) — it
|
|
7
|
+
* does NOT hand-roll a competing advance workflow. It also STRUCTURALLY VALIDATES
|
|
8
|
+
* the emitted YAML, mirroring the snapshot-assertion style of
|
|
9
|
+
* `advance-ci-template.ts` (the package depends on
|
|
10
|
+
* NO YAML lib, so the checks are presence/shape assertions over the raw text).
|
|
11
|
+
*
|
|
12
|
+
* This is the "human is the clock" loop: CI drains the populated `work/` tree
|
|
13
|
+
* toward done while the human only answers committed question sidecars on their own
|
|
14
|
+
* time. Over the build/task tick (its sibling capability), the advance-lifecycle
|
|
15
|
+
* tick adds exactly three things — and they are the whole reason `advance` (not
|
|
16
|
+
* `do`) is the verb here:
|
|
17
|
+
*
|
|
18
|
+
* - the LIFECYCLE rungs (triage observations / surface declared blockers / apply
|
|
19
|
+
* a committed answer), gated by the two calm-default lifecycle gates below;
|
|
20
|
+
* - the on-answer-committed trigger `on: push work/questions/**`, which re-runs
|
|
21
|
+
* the loop promptly when a question sidecar is answered;
|
|
22
|
+
* - (already in the absorbed seed) capability F — the `reap-merged-branches` job
|
|
23
|
+
* (`gc --remote-branches`) on the same `schedule:` cron, opt-out via the
|
|
24
|
+
* `sweepMergedBranches` dispatch input.
|
|
25
|
+
*
|
|
26
|
+
* The discipline is VERBATIM from the seed:
|
|
27
|
+
*
|
|
28
|
+
* - CI ALWAYS invokes `advance` (ADR `ci-config-policy-and-gate-family` §1):
|
|
29
|
+
* `advance` is a strict superset of `do`, and with the lifecycle gates at their
|
|
30
|
+
* calm defaults it degrades to exactly `do`'s build/task behaviour. The verb
|
|
31
|
+
* is NEVER a user decision; the workflow tunes behaviour via the
|
|
32
|
+
* `DORFL_*` env block, not by swapping the verb. There is NO
|
|
33
|
+
* `autoAdvance` gate.
|
|
34
|
+
* - The two LIFECYCLE gates are ORTHOGONAL peers, both calm by default:
|
|
35
|
+
* `DORFL_OBSERVATION_TRIAGE` (`off`/`ask`/`auto`, calm `off`) governs the
|
|
36
|
+
* raw observation INBOX; `DORFL_SURFACE_BLOCKERS` (`true`/`false`, calm
|
|
37
|
+
* `false`) governs DECLARED `needsAnswers` work. "Groom my observations but
|
|
38
|
+
* leave my blocked work alone" = `OBSERVATION_TRIAGE: ask` + `SURFACE_BLOCKERS:
|
|
39
|
+
* false`. Applying a committed answer has NO gate.
|
|
40
|
+
* - ONE word `integrationMode` drives BOTH the job SHAPE AND the
|
|
41
|
+
* `--propose`/`--merge` flag (they can never desync): `propose` ⇒ a DYNAMIC
|
|
42
|
+
* matrix (`dorfl scan --json | jq` enumerates one leg per eligible id,
|
|
43
|
+
* each leg carries `--propose` so it can NEVER merge to `main`); `merge` ⇒ ALSO
|
|
44
|
+
* a MATRIX (one leg per item; build/gate/review fan out, the LAND tail is
|
|
45
|
+
* serialised by the engine's `mergeRetries` CAS-retry loop — the git-alone
|
|
46
|
+
* floor — NOT by the workflow shape; PRD
|
|
47
|
+
* `land-time-reverify-and-parallel-merge-ceiling`). This is integration-mode
|
|
48
|
+
* behaviour, IDENTICAL to the build tick (integration mode is
|
|
49
|
+
* verb-independent).
|
|
50
|
+
* - CI runs IN-PLACE (the CI container IS the isolation): no
|
|
51
|
+
* `--isolated`/`--remote`/registry. A CI concurrency group (per-ref) prevents
|
|
52
|
+
* overlapping ticks; the claim CAS is the real cross-run serialiser.
|
|
53
|
+
* - All invocations use explicit slug prefixes (`task:`/`spec:`), never bare
|
|
54
|
+
* (ADR `command-surface-and-journeys` §3a).
|
|
55
|
+
* - The running CI job NEVER edits `.github/workflows/**` (US #9): it requests
|
|
56
|
+
* NO `workflows` permission and cannot rewrite its own triggers.
|
|
57
|
+
*
|
|
58
|
+
* The structural validator is the dependency-free counterpart of "the workflow
|
|
59
|
+
* parses + carries the right discipline" the task's acceptance criteria require;
|
|
60
|
+
* the test generates this artifact under `--fake` and asserts every invariant.
|
|
61
|
+
*/
|
|
62
|
+
import { providerSecretsWithBlock } from './install-ci-core.js';
|
|
63
|
+
/** The capability id (the registry key + the emitted workflow file stem). */
|
|
64
|
+
export const ADVANCE_LIFECYCLE_CAPABILITY_ID = 'advance-lifecycle';
|
|
65
|
+
/** The wizard-facing label for the advance-lifecycle capability. */
|
|
66
|
+
export const ADVANCE_LIFECYCLE_CAPABILITY_LABEL = 'Auto-triage observations + surface declared blockers + apply committed answers (the advance lifecycle loop: cron + dispatch + on-answer-committed)';
|
|
67
|
+
/** The repo-relative path (under the output base) of the emitted workflow. */
|
|
68
|
+
export const ADVANCE_LIFECYCLE_WORKFLOW_PATH = 'workflows/advance-lifecycle.yml';
|
|
69
|
+
/**
|
|
70
|
+
* Generate the advance-lifecycle workflow YAML by PARAMETERISING the seed
|
|
71
|
+
* `docs/ci/advance-loop.yml.template`. Deterministic: the same config produces
|
|
72
|
+
* byte-identical output. The workflow is a FIXED shell (ADR §6: all policy is
|
|
73
|
+
* env/config, so the artifact carries no config-derived policy beyond the env-block
|
|
74
|
+
* scaffolding) — `config` is accepted for parity with the `CapabilityEmitter` seam
|
|
75
|
+
* and future per-config wiring, but the advance-lifecycle shape itself is
|
|
76
|
+
* config-independent.
|
|
77
|
+
*
|
|
78
|
+
* This is the absorbed seed, with two parameterisations: (1) it wires the SHARED
|
|
79
|
+
* composite setup action (`./.github/actions/dorfl-setup`, emitted by the
|
|
80
|
+
* core task) into every job; (2) it surfaces the engine gate family — including
|
|
81
|
+
* the two calm-default LIFECYCLE gates — as the `DORFL_*` env block, so the
|
|
82
|
+
* out-of-the-box tick asks nothing until the user opts in. The seed's capability-F
|
|
83
|
+
* reap job + `sweepMergedBranches` input are PRESERVED verbatim (NOT stripped); no
|
|
84
|
+
* separate gc-sweep workflow is emitted.
|
|
85
|
+
*/
|
|
86
|
+
export function generateAdvanceLifecycleWorkflow(config) {
|
|
87
|
+
// The agent-running jobs (propose / merge) pass the configured provider
|
|
88
|
+
// secret(s) to the setup action ONCE via `with:`; the action forwards them to
|
|
89
|
+
// `$GITHUB_ENV` so `pi` can authenticate (models-json mode). auth-json mode has
|
|
90
|
+
// no provider keys here (it uses auth.json), so the block is empty.
|
|
91
|
+
const setupWith = providerSecretsWithBlock(config);
|
|
92
|
+
return `\
|
|
93
|
+
# dorfl — the ADVANCE LIFECYCLE loop in CI (capability C: auto-triage
|
|
94
|
+
# observations + surface declared blockers + apply committed answers, prd
|
|
95
|
+
# runner-in-ci). EMITTED by \`dorfl install-ci\` by PARAMETERISING the seed
|
|
96
|
+
# \`docs/ci/advance-loop.yml.template\` (the advance-loop capability's output) — the
|
|
97
|
+
# human commits it. DO NOT hand-edit a copy — re-run install-ci to upgrade the
|
|
98
|
+
# shell, and edit the workflow SHAPE in the seed template, not here.
|
|
99
|
+
#
|
|
100
|
+
# THIS is the "human is the clock" loop: CI drains the populated work/ tree toward
|
|
101
|
+
# done while the human only answers committed question sidecars (work/questions/**)
|
|
102
|
+
# on their own time.
|
|
103
|
+
#
|
|
104
|
+
# CI ALWAYS invokes \`advance\` (NEVER a user-chosen verb): \`advance\` is a strict
|
|
105
|
+
# superset of \`do\`, and with the lifecycle gates at their calm defaults (below) it
|
|
106
|
+
# degrades to exactly \`do\`'s build/task behaviour (ADR
|
|
107
|
+
# ci-config-policy-and-gate-family §1). The triage/surface/apply rungs + the
|
|
108
|
+
# on-answer-committed trigger are EXACTLY what \`advance\` adds over the build/task
|
|
109
|
+
# tick. There is NO \`autoAdvance\` gate — the lifecycle decomposes into the gate
|
|
110
|
+
# family in the env block.
|
|
111
|
+
#
|
|
112
|
+
# ONE WORD, ONE MEANING — \`integrationMode\` drives BOTH the job SHAPE AND the
|
|
113
|
+
# \`--propose\`/\`--merge\` flag the legs pass, so they can NEVER desync:
|
|
114
|
+
# * propose ⇒ a DYNAMIC matrix (one leg per eligible id, enumerated via
|
|
115
|
+
# \`dorfl scan --json | jq\`), each leg \`advance --propose\`
|
|
116
|
+
# opening its OWN PR — a leg can NEVER merge to main.
|
|
117
|
+
# * merge ⇒ ALSO a MATRIX (one leg per item; build/gate/review fan out, the
|
|
118
|
+
# LAND tail — rebase + CAS push to \`main\` — is serialised by the
|
|
119
|
+
# engine's \`mergeRetries\` CAS-retry loop, NOT by the workflow shape.
|
|
120
|
+
# PRD \`land-time-reverify-and-parallel-merge-ceiling\`: a
|
|
121
|
+
# non-fast-forward push triggers re-rebase + re-gate + retry, never
|
|
122
|
+
# a \`--force\`. The cross-job serialiser is the CAS-retry FLOOR;
|
|
123
|
+
# there is NO host-specific \`concurrency:\` group on the merge job).
|
|
124
|
+
# This is integration-mode behaviour, IDENTICAL to the build/task tick
|
|
125
|
+
# (integration mode is verb-independent). The CLAIM CAS, not the matrix, is the
|
|
126
|
+
# real cross-run serialiser: a leg that loses the claim race exits clean.
|
|
127
|
+
#
|
|
128
|
+
# CI runs IN-PLACE (the CI container IS the isolation): NO --isolated/--remote/
|
|
129
|
+
# registry (laptop-only affordances). The concurrency group below stops
|
|
130
|
+
# overlapping ticks of the same ref from colliding.
|
|
131
|
+
#
|
|
132
|
+
# SAFETY (US #9): the running job is FORBIDDEN from editing the workflows tree
|
|
133
|
+
# under .github. It requests NO \`workflows\` permission, so it can never rewrite
|
|
134
|
+
# its own triggers.
|
|
135
|
+
|
|
136
|
+
name: advance-lifecycle
|
|
137
|
+
|
|
138
|
+
on:
|
|
139
|
+
schedule:
|
|
140
|
+
# Cron tick: drain whatever the human has answered/produced since the last run
|
|
141
|
+
# (triage / surface / apply + build / task). Adjust the cadence to taste
|
|
142
|
+
# (here: hourly).
|
|
143
|
+
- cron: '0 * * * *'
|
|
144
|
+
push:
|
|
145
|
+
# On-answer-committed: a push that touches an answered question sidecar
|
|
146
|
+
# (\`work/questions/**\`) re-runs the loop so the human's answer is applied
|
|
147
|
+
# promptly. This is the lifecycle-specific trigger \`do\` cannot provide.
|
|
148
|
+
paths:
|
|
149
|
+
- 'work/questions/**'
|
|
150
|
+
workflow_dispatch:
|
|
151
|
+
inputs:
|
|
152
|
+
integrationMode:
|
|
153
|
+
description: "Integration mode (drives BOTH the integration flag passed to \`advance\` AND the job shape): propose ⇒ a matrix, each leg \`advance --propose\` (one PR per item); merge ⇒ a matrix, each leg \`advance --merge\` (one item — build/gate/review fan out in parallel; the LAND tail is serialised by the engine's \`mergeRetries\` CAS-retry loop, not by the workflow shape)."
|
|
154
|
+
required: false
|
|
155
|
+
default: 'propose'
|
|
156
|
+
type: choice
|
|
157
|
+
options:
|
|
158
|
+
- propose
|
|
159
|
+
- merge
|
|
160
|
+
sweepMergedBranches:
|
|
161
|
+
description: 'Reap merged remote work/* branches on the scheduled tick (gc --remote-branches): delete only branches PROVABLY MERGED into <arbiter>/main, so out-of-band human/UI PR merges stop leaving their work/<slug> branches lingering on the arbiter. ON by default; set false to opt out. An in-flight (un-merged) branch is NEVER touched.'
|
|
162
|
+
required: false
|
|
163
|
+
default: true
|
|
164
|
+
type: boolean
|
|
165
|
+
# ── GATE-FAMILY one-shot overrides (dispatch only) ──────────────────────
|
|
166
|
+
# Override an engine gate for THIS manual run only, riding the env layer of
|
|
167
|
+
# flag > env > per-repo > global > default. Modelled as \`type: choice\` with a
|
|
168
|
+
# BLANK first option (not \`type: boolean\`, which cannot represent "unset"):
|
|
169
|
+
# blank ⇒ emit NOTHING (the committed .dorfl.json wins, today's
|
|
170
|
+
# behaviour); a non-blank choice ⇒ export the matching DORFL_* for this
|
|
171
|
+
# run. The blank is load-bearing: env-config coercion THROWS on an empty
|
|
172
|
+
# string, so the per-job step below only writes when the input is non-blank.
|
|
173
|
+
autoBuild:
|
|
174
|
+
description: 'One-shot override of the autoBuild gate (DORFL_AUTO_BUILD) for THIS dispatch run only. Blank ⇒ no override (config wins).'
|
|
175
|
+
required: false
|
|
176
|
+
default: ''
|
|
177
|
+
type: choice
|
|
178
|
+
options:
|
|
179
|
+
- ''
|
|
180
|
+
- 'true'
|
|
181
|
+
- 'false'
|
|
182
|
+
autoTask:
|
|
183
|
+
description: 'One-shot override of the autoTask gate (DORFL_AUTO_TASK) for THIS dispatch run only. Blank ⇒ no override (config wins).'
|
|
184
|
+
required: false
|
|
185
|
+
default: ''
|
|
186
|
+
type: choice
|
|
187
|
+
options:
|
|
188
|
+
- ''
|
|
189
|
+
- 'true'
|
|
190
|
+
- 'false'
|
|
191
|
+
observationTriage:
|
|
192
|
+
description: 'One-shot override of the observationTriage gate (DORFL_OBSERVATION_TRIAGE) for THIS dispatch run only. Blank ⇒ no override (config wins).'
|
|
193
|
+
required: false
|
|
194
|
+
default: ''
|
|
195
|
+
type: choice
|
|
196
|
+
options:
|
|
197
|
+
- ''
|
|
198
|
+
- 'off'
|
|
199
|
+
- 'ask'
|
|
200
|
+
- 'auto'
|
|
201
|
+
surfaceBlockers:
|
|
202
|
+
description: 'One-shot override of the surfaceBlockers gate (DORFL_SURFACE_BLOCKERS) for THIS dispatch run only. Blank ⇒ no override (config wins).'
|
|
203
|
+
required: false
|
|
204
|
+
default: ''
|
|
205
|
+
type: choice
|
|
206
|
+
options:
|
|
207
|
+
- ''
|
|
208
|
+
- 'true'
|
|
209
|
+
- 'false'
|
|
210
|
+
|
|
211
|
+
# Serialise overlapping ticks of the same ref; the claim CAS is the real
|
|
212
|
+
# cross-run serialiser, this just avoids redundant concurrent ticks.
|
|
213
|
+
concurrency:
|
|
214
|
+
group: advance-lifecycle-\${{ github.ref }}
|
|
215
|
+
cancel-in-progress: false
|
|
216
|
+
|
|
217
|
+
# NO \`workflows\` permission: the running job can NEVER edit the workflows tree
|
|
218
|
+
# under .github (US #9). \`contents: write\` + \`pull-requests: write\` are all this
|
|
219
|
+
# tick needs (commit work, open PRs); it never rewrites its triggers.
|
|
220
|
+
permissions:
|
|
221
|
+
contents: write
|
|
222
|
+
pull-requests: write
|
|
223
|
+
|
|
224
|
+
env:
|
|
225
|
+
# The resolved integration mode: the dispatch input when present, else \`propose\`
|
|
226
|
+
# (the conservative default — one PR per item, a human merges). This single value
|
|
227
|
+
# selects BOTH the job shape (via the \`if:\` guards below) AND the integration flag
|
|
228
|
+
# the \`advance\` legs pass (\`--propose\`/\`--merge\`), so they can never desync.
|
|
229
|
+
INTEGRATION_MODE: \${{ github.event.inputs.integrationMode || 'propose' }}
|
|
230
|
+
# Reap merged remote work/* branches on the scheduled tick (capability F). ON by
|
|
231
|
+
# default (the empty dispatch input on a \`schedule\`/\`push\` trigger reads as the
|
|
232
|
+
# default); set the \`sweepMergedBranches\` dispatch input to \`false\` to opt out.
|
|
233
|
+
# This is the provider-agnostic hygiene sweep (\`gc --remote-branches\`) for
|
|
234
|
+
# out-of-band human/UI PR merges, whose work/<slug> branch nothing else deletes.
|
|
235
|
+
SWEEP_MERGED_BRANCHES: \${{ github.event.inputs.sweepMergedBranches || 'true' }}
|
|
236
|
+
|
|
237
|
+
# ── The engine GATE FAMILY is resolved FROM CONFIG, not carried here ─────────
|
|
238
|
+
# CI is NOT a special policy surface (ADR ci-config-policy-and-gate-family §5):
|
|
239
|
+
# it runs the SAME engine gates, resolved through flag > env > per-repo > global
|
|
240
|
+
# > default. The SAME .dorfl.json the laptop uses applies here. This
|
|
241
|
+
# workflow emits NO DORFL_AUTO_BUILD / DORFL_AUTO_TASK /
|
|
242
|
+
# DORFL_OBSERVATION_TRIAGE / DORFL_SURFACE_BLOCKERS line on a
|
|
243
|
+
# SCHEDULE/PUSH tick, so the env layer carries NO defaults there — your committed
|
|
244
|
+
# .dorfl.json wins (then the global config, then the strict built-in
|
|
245
|
+
# defaults autoBuild:false / autoTask:false / observationTriage:'off' /
|
|
246
|
+
# surfaceBlockers:false). The ONE exception is a manual \`workflow_dispatch\` where
|
|
247
|
+
# you fill a gate override input (above): the per-job step then exports that ONE
|
|
248
|
+
# DORFL_* for that run only (blank input ⇒ still nothing). The override
|
|
249
|
+
# MUST be wired into every job that resolves the gate family — including the
|
|
250
|
+
# \`enumerate\` scan (it gates the matrix pools via observationTriage/surfaceBlockers
|
|
251
|
+
# /autoTask/autoBuild), not just the agent-running jobs — or the override is inert
|
|
252
|
+
# for the very pools it targets. To enable CI autonomy durably, set the gate(s) in
|
|
253
|
+
# .dorfl.json (applies everywhere) — NOT by re-running install-ci (ADR §6:
|
|
254
|
+
# install-ci is one-time).
|
|
255
|
+
|
|
256
|
+
jobs:
|
|
257
|
+
# ── ENUMERATE (propose only) ────────────────────────────────────────────────
|
|
258
|
+
# Build the DYNAMIC matrix from the eligible-pool scan. \`scan --json\` reports
|
|
259
|
+
# BOTH the registry/hub-mirror pool (\`repos[].items[]\`, \`repos[].specs[]\`,
|
|
260
|
+
# \`repos[].lifecycle\`) AND the in-place working checkout (\`cwd.repo.items[]\`,
|
|
261
|
+
# \`cwd.repo.specs[]\`, \`cwd.repo.lifecycle\`); CI runs IN-PLACE so the items live
|
|
262
|
+
# in the latter (a fresh runner has no registered mirror). \`jq\` unions + dedups
|
|
263
|
+
# the build/task pools AND the LIFECYCLE pools into a deduplicated GitHub
|
|
264
|
+
# Actions matrix list of explicit \`task:<slug>\` / \`spec:<slug>\` / \`obs:<slug>\`
|
|
265
|
+
# ids (CI MUST use explicit prefixes). The lifecycle legs run the WHOLE
|
|
266
|
+
# answer-loop in propose mode (not only merge): \`obs:\` (triage untriaged
|
|
267
|
+
# observations), surface \`task:\`/\`spec:\` (\`needsAnswers\`, no answered sidecar)
|
|
268
|
+
# AND apply \`task:\`/\`spec:\` (\`needsAnswers\`, answered sidecar — consume the
|
|
269
|
+
# committed answer, closing the on-answer \`push: work/questions/**\` loop). Each
|
|
270
|
+
# becomes one matrix leg → one independent \`advance --propose\`. Skipped in merge
|
|
271
|
+
# mode. Inert with calm-default gates (empty triage/surface pools).
|
|
272
|
+
enumerate:
|
|
273
|
+
runs-on: ubuntu-latest
|
|
274
|
+
outputs:
|
|
275
|
+
items: \${{ steps.scan.outputs.items }}
|
|
276
|
+
any: \${{ steps.scan.outputs.any }}
|
|
277
|
+
steps:
|
|
278
|
+
- uses: actions/checkout@v4
|
|
279
|
+
with:
|
|
280
|
+
fetch-depth: 0
|
|
281
|
+
- uses: ./.github/actions/dorfl-setup
|
|
282
|
+
- name: apply dispatch gate overrides (one-shot, this run only)
|
|
283
|
+
# MUST run BEFORE \`scan\`: scan's matrix pools are gated by the SAME engine
|
|
284
|
+
# gate family (autoTask/autoBuild + lifecycle observationTriage/
|
|
285
|
+
# surfaceBlockers), so an override that does not reach this job produces an
|
|
286
|
+
# empty matrix and is silently inert. \`if:\` + the inner \`[ -n ... ]\` guard
|
|
287
|
+
# keep schedule/push (and a blank dispatch field) exporting NOTHING — an
|
|
288
|
+
# empty DORFL_* would make env-config coercion throw.
|
|
289
|
+
if: \${{ github.event_name == 'workflow_dispatch' }}
|
|
290
|
+
run: |
|
|
291
|
+
[ -n "\${{ github.event.inputs.autoBuild }}" ] && echo "DORFL_AUTO_BUILD=\${{ github.event.inputs.autoBuild }}" >> "$GITHUB_ENV"
|
|
292
|
+
[ -n "\${{ github.event.inputs.autoTask }}" ] && echo "DORFL_AUTO_TASK=\${{ github.event.inputs.autoTask }}" >> "$GITHUB_ENV"
|
|
293
|
+
[ -n "\${{ github.event.inputs.observationTriage }}" ] && echo "DORFL_OBSERVATION_TRIAGE=\${{ github.event.inputs.observationTriage }}" >> "$GITHUB_ENV"
|
|
294
|
+
[ -n "\${{ github.event.inputs.surfaceBlockers }}" ] && echo "DORFL_SURFACE_BLOCKERS=\${{ github.event.inputs.surfaceBlockers }}" >> "$GITHUB_ENV"
|
|
295
|
+
true
|
|
296
|
+
- id: scan
|
|
297
|
+
# Enumerate eligible items as namespaced ids, one matrix leg per id. CI
|
|
298
|
+
# uses explicit \`task:\` / \`spec:\` / \`obs:\` prefixes, never bare (ADR
|
|
299
|
+
# command-surface §3a). Eligible TASKS ⇒ \`task:<slug>\` legs (\`advance\`
|
|
300
|
+
# builds them); TASKABLE SPECS ⇒ \`spec:<slug>\` legs (\`advance\` auto-tasks
|
|
301
|
+
# them, capability B — \`DORFL_AUTO_TASK\` above). LIFECYCLE pools:
|
|
302
|
+
# \`lifecycle.triage[]\` ⇒ \`obs:<slug>\` (the \`obs:\` prefix is fixed here),
|
|
303
|
+
# \`lifecycle.surface[]\` + \`lifecycle.apply[]\` ⇒ \`.namespace + ":" + .slug\`
|
|
304
|
+
# (surface: \`task:\`/\`spec:\` blocker-question legs; apply: \`task:\`/\`spec:\`
|
|
305
|
+
# AND \`observation:\` legs — an answered observation sidecar is consumed by
|
|
306
|
+
# the apply rung too, so it MUST carry through here). CI runs IN-PLACE, so we use
|
|
307
|
+
# \`scan --here\`: it reports ONLY the cwd checkout (\`cwd.repo.*\`) and SKIPS
|
|
308
|
+
# the cross-repo registry loop (no N-mirror fetches; a fresh runner has no
|
|
309
|
+
# registered mirror anyway). The \`cwd\` arbiter is the checkout's own clone,
|
|
310
|
+
# so the fetch-first is a near-noop. \`jq\` still reads the (now-empty)
|
|
311
|
+
# \`repos[]\` branches harmlessly; we union + dedup so the matrix has one
|
|
312
|
+
# leg per item.
|
|
313
|
+
run: |
|
|
314
|
+
items="$(dorfl scan --json --here \\
|
|
315
|
+
| jq -c '[(.repos[].items[]?, .cwd.repo.items[]?) | select(.eligibility.eligible == true) | "task:" + .slug] + [(.repos[].specs[]?, .cwd.repo.specs[]?) | select(.eligibility.eligible == true) | "spec:" + .slug] + [(.repos[].lifecycle.triage[]?, .cwd.repo.lifecycle.triage[]?) | "obs:" + .slug] + [(.repos[].lifecycle.surface[]?, .cwd.repo.lifecycle.surface[]?, .repos[].lifecycle.apply[]?, .cwd.repo.lifecycle.apply[]?) | .namespace + ":" + .slug] | unique')"
|
|
316
|
+
echo "items=\${items}" >> "$GITHUB_OUTPUT"
|
|
317
|
+
if [ "$(echo "\${items}" | jq 'length')" -gt 0 ]; then
|
|
318
|
+
echo "any=true" >> "$GITHUB_OUTPUT"
|
|
319
|
+
else
|
|
320
|
+
echo "any=false" >> "$GITHUB_OUTPUT"
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
# ── PROPOSE: a MATRIX of independent jobs (one PR per item) ──────────────────
|
|
324
|
+
# True parallelism — each item is an independent PR, so a matrix is the right
|
|
325
|
+
# parallel shape and \`-n\` is NOT needed. Each leg passes \`--propose\`, tying the
|
|
326
|
+
# integration mode to THIS shape: it sits at the top of the precedence chain, so
|
|
327
|
+
# the workflow mode always wins over the repo config default and a leg can NEVER
|
|
328
|
+
# merge to main. Explicit \`task:\`/\`spec:\` prefixes only, never bare.
|
|
329
|
+
advance-propose:
|
|
330
|
+
needs: enumerate
|
|
331
|
+
if: \${{ (github.event.inputs.integrationMode || 'propose') == 'propose' && needs.enumerate.outputs.any == 'true' }}
|
|
332
|
+
runs-on: ubuntu-latest
|
|
333
|
+
strategy:
|
|
334
|
+
# Independent PRs: one failing item must NOT cancel the others.
|
|
335
|
+
fail-fast: false
|
|
336
|
+
# Cap concurrent legs (config \`maxParallel\`, install-ci --max-parallel):
|
|
337
|
+
# each leg spawns a FULL agent session (build + Gate-2 review), so an
|
|
338
|
+
# unbounded fan-out over a large item set exhausts the model-provider API
|
|
339
|
+
# rate limit (429s that strand legs as transient-infra stuck) AND thrashes
|
|
340
|
+
# the arbiter-main CAS. A bounded fan-out drains steadily instead.
|
|
341
|
+
max-parallel: ${config.maxParallel}
|
|
342
|
+
matrix:
|
|
343
|
+
item: \${{ fromJson(needs.enumerate.outputs.items) }}
|
|
344
|
+
steps:
|
|
345
|
+
- uses: actions/checkout@v4
|
|
346
|
+
with:
|
|
347
|
+
fetch-depth: 0
|
|
348
|
+
- uses: ./.github/actions/dorfl-setup${setupWith}
|
|
349
|
+
- name: apply dispatch gate overrides (one-shot, this run only)
|
|
350
|
+
# Mirror of the enumerate-job override (see there): export each gate's
|
|
351
|
+
# DORFL_* ONLY on a workflow_dispatch with a non-blank input, so the
|
|
352
|
+
# one-shot override also reaches the \`advance\` leg that builds the item.
|
|
353
|
+
if: \${{ github.event_name == 'workflow_dispatch' }}
|
|
354
|
+
run: |
|
|
355
|
+
[ -n "\${{ github.event.inputs.autoBuild }}" ] && echo "DORFL_AUTO_BUILD=\${{ github.event.inputs.autoBuild }}" >> "$GITHUB_ENV"
|
|
356
|
+
[ -n "\${{ github.event.inputs.autoTask }}" ] && echo "DORFL_AUTO_TASK=\${{ github.event.inputs.autoTask }}" >> "$GITHUB_ENV"
|
|
357
|
+
[ -n "\${{ github.event.inputs.observationTriage }}" ] && echo "DORFL_OBSERVATION_TRIAGE=\${{ github.event.inputs.observationTriage }}" >> "$GITHUB_ENV"
|
|
358
|
+
[ -n "\${{ github.event.inputs.surfaceBlockers }}" ] && echo "DORFL_SURFACE_BLOCKERS=\${{ github.event.inputs.surfaceBlockers }}" >> "$GITHUB_ENV"
|
|
359
|
+
true
|
|
360
|
+
- name: advance one item in-place (propose ⇒ opens a PR)
|
|
361
|
+
# In-place in this checkout (no --isolated/--remote): the CI container IS
|
|
362
|
+
# the isolation. \`--propose\` can ONLY ride a matrix leg, never the merge
|
|
363
|
+
# job, so a parallel merge-to-main is structurally impossible.
|
|
364
|
+
# \`--propose\` shells \`gh\` to open the PR, which reads \`GH_TOKEN\` from the
|
|
365
|
+
# env (a workflow PERMISSION is not a credential). Prefer a dedicated
|
|
366
|
+
# \`DORFL_GH_TOKEN\` secret (a PAT / App token) so PRs carry YOUR
|
|
367
|
+
# identity AND trigger downstream workflows (PRs opened with the built-in
|
|
368
|
+
# \`GITHUB_TOKEN\` are \`github-actions[bot]\` and do NOT trigger further
|
|
369
|
+
# \`on: pull_request\` runs). Falls back to the auto \`GITHUB_TOKEN\` so it
|
|
370
|
+
# works zero-config; the job's \`pull-requests: write\` scopes that token.
|
|
371
|
+
env:
|
|
372
|
+
GH_TOKEN: \${{ secrets.DORFL_GH_TOKEN || secrets.GITHUB_TOKEN }}
|
|
373
|
+
# \`--watch\` streams the build agent's high-signal turns (assistant text,
|
|
374
|
+
# tool calls, finish) into THIS job log live, so the run shows the agent
|
|
375
|
+
# working instead of freezing after "Start work". A read-only observer (no
|
|
376
|
+
# outcome/gate/git effect). It fits because each matrix leg names ONE item
|
|
377
|
+
# (one pi session to tail) — the merge job is now a per-item matrix too
|
|
378
|
+
# (see below) and streams the same way.
|
|
379
|
+
run: dorfl advance "\${{ matrix.item }}" --propose --watch --arbiter origin
|
|
380
|
+
|
|
381
|
+
# ── MERGE: a MATRIX of independent jobs (parallel build/gate/review, serialised land) ──
|
|
382
|
+
# PRD \`land-time-reverify-and-parallel-merge-ceiling\` (stories 4 + 6): each item
|
|
383
|
+
# gets its own leg; build/gate/review run concurrently across siblings; the LAND
|
|
384
|
+
# TAIL is serialised by the engine's \`mergeRetries\` CAS-retry loop — the
|
|
385
|
+
# git-alone floor — NOT by the workflow shape. A non-fast-forward push triggers
|
|
386
|
+
# re-rebase + re-gate + retry up to the resolved \`mergeRetries\` cap; never a
|
|
387
|
+
# \`--force\`. NO host-specific \`concurrency:\` group on this job (it would be
|
|
388
|
+
# load-bearing for cross-job safety, breaking the floor framing).
|
|
389
|
+
# The fully-autonomous-to-main path (this job + all gates on) is still a LOUD,
|
|
390
|
+
# NON-DEFAULT opt-in: the default integrationMode is \`propose\`, so reaching
|
|
391
|
+
# merge-to-main requires deliberately dispatching/pinning \`merge\`.
|
|
392
|
+
advance-merge:
|
|
393
|
+
needs: enumerate
|
|
394
|
+
if: \${{ (github.event.inputs.integrationMode || 'propose') == 'merge' && needs.enumerate.outputs.any == 'true' }}
|
|
395
|
+
runs-on: ubuntu-latest
|
|
396
|
+
strategy:
|
|
397
|
+
# Independent landings: one failing item must NOT cancel the others; a
|
|
398
|
+
# loser of the CAS race re-rebases + re-gates + retries.
|
|
399
|
+
fail-fast: false
|
|
400
|
+
# Cap concurrent legs (config \`maxParallel\`, see advance-propose): a FULL
|
|
401
|
+
# agent session per leg, so bound the fan-out to avoid API-429s + CAS thrash.
|
|
402
|
+
max-parallel: ${config.maxParallel}
|
|
403
|
+
matrix:
|
|
404
|
+
item: \${{ fromJson(needs.enumerate.outputs.items) }}
|
|
405
|
+
steps:
|
|
406
|
+
- uses: actions/checkout@v4
|
|
407
|
+
with:
|
|
408
|
+
fetch-depth: 0
|
|
409
|
+
- uses: ./.github/actions/dorfl-setup${setupWith}
|
|
410
|
+
- name: apply dispatch gate overrides (one-shot, this run only)
|
|
411
|
+
# Mirror of the enumerate-job override (see there): export each gate's
|
|
412
|
+
# DORFL_* ONLY on a workflow_dispatch with a non-blank input. The
|
|
413
|
+
# merge job re-scans the pool inside \`advance -n\`, so it needs the override
|
|
414
|
+
# too for the lifecycle/task pools to reflect it.
|
|
415
|
+
if: \${{ github.event_name == 'workflow_dispatch' }}
|
|
416
|
+
run: |
|
|
417
|
+
[ -n "\${{ github.event.inputs.autoBuild }}" ] && echo "DORFL_AUTO_BUILD=\${{ github.event.inputs.autoBuild }}" >> "$GITHUB_ENV"
|
|
418
|
+
[ -n "\${{ github.event.inputs.autoTask }}" ] && echo "DORFL_AUTO_TASK=\${{ github.event.inputs.autoTask }}" >> "$GITHUB_ENV"
|
|
419
|
+
[ -n "\${{ github.event.inputs.observationTriage }}" ] && echo "DORFL_OBSERVATION_TRIAGE=\${{ github.event.inputs.observationTriage }}" >> "$GITHUB_ENV"
|
|
420
|
+
[ -n "\${{ github.event.inputs.surfaceBlockers }}" ] && echo "DORFL_SURFACE_BLOCKERS=\${{ github.event.inputs.surfaceBlockers }}" >> "$GITHUB_ENV"
|
|
421
|
+
true
|
|
422
|
+
- name: advance one item in-place (merge ⇒ rebase + CAS land on main)
|
|
423
|
+
# In-place (no --isolated/--remote). \`--merge\` ties the integration mode
|
|
424
|
+
# to THIS (matrix) shape: it sits at the top of the precedence chain, so
|
|
425
|
+
# the workflow mode always wins over the repo's \`.dorfl.json\` default.
|
|
426
|
+
# Cross-job land safety comes from the engine's CAS-retry loop, not from
|
|
427
|
+
# this workflow's job shape. \`gh\` (merge / PR housekeeping) reads
|
|
428
|
+
# \`GH_TOKEN\` from the env.
|
|
429
|
+
env:
|
|
430
|
+
GH_TOKEN: \${{ secrets.DORFL_GH_TOKEN || secrets.GITHUB_TOKEN }}
|
|
431
|
+
# \`--watch\` streams the build agent's high-signal turns into THIS job
|
|
432
|
+
# log live; each leg names ONE item, so it fits the same way it does on
|
|
433
|
+
# the propose legs.
|
|
434
|
+
run: dorfl advance "\${{ matrix.item }}" --merge --watch --arbiter origin
|
|
435
|
+
|
|
436
|
+
# ── REAP merged remote work/* branches (capability F, the hygiene sweep) ─────
|
|
437
|
+
# PRESERVED from the seed (NOT a separate gc-sweep workflow): the provider-
|
|
438
|
+
# agnostic counterpart of the worktree reaper. Deletes remote \`work/<slug>\`
|
|
439
|
+
# branches that are PROVABLY MERGED into \`origin/main\`, so an out-of-band
|
|
440
|
+
# human/UI PR merge stops leaving its branch lingering on the arbiter.
|
|
441
|
+
# Independent of the integration mode (both propose- and merge-mode repos
|
|
442
|
+
# accumulate out-of-band-merged branches), so it runs on EVERY tick regardless
|
|
443
|
+
# of \`integrationMode\` — gated ONLY by the \`sweepMergedBranches\` opt-out (ON by
|
|
444
|
+
# default). It NEVER touches an un-merged/in-flight branch and NEVER \`--force\`s.
|
|
445
|
+
# Plain git, so it works against any provider (incl. a \`--bare\` arbiter).
|
|
446
|
+
#
|
|
447
|
+
# OPTIONAL belt-and-suspenders for a GitHub arbiter: enable the repo-level
|
|
448
|
+
# "Automatically delete head branches" setting (\`delete_branch_on_merge\`), owned
|
|
449
|
+
# by the install-ci wizard — an ADDITIVE GitHub-only convenience, NOT a
|
|
450
|
+
# replacement for this sweep (the only thing that reaps on a \`--bare\`/non-GitHub
|
|
451
|
+
# arbiter).
|
|
452
|
+
reap-merged-branches:
|
|
453
|
+
if: \${{ (github.event.inputs.sweepMergedBranches || 'true') == 'true' }}
|
|
454
|
+
runs-on: ubuntu-latest
|
|
455
|
+
steps:
|
|
456
|
+
- uses: actions/checkout@v4
|
|
457
|
+
with:
|
|
458
|
+
fetch-depth: 0
|
|
459
|
+
- uses: ./.github/actions/dorfl-setup
|
|
460
|
+
- name: reap merged remote work/* branches + orphan sidecars (gc --remote-branches)
|
|
461
|
+
# Deletes ONLY branches provably merged into origin/main; reports
|
|
462
|
+
# deleted-vs-retained-with-reason. Safe to run every tick (idempotent).
|
|
463
|
+
# This invocation ALSO reaps ORPHAN question sidecars: a
|
|
464
|
+
# sidecar under the questions queue (<type>-<slug>.md) whose source item
|
|
465
|
+
# was deleted out-of-band (git rm; the sidecar's working-tree source no
|
|
466
|
+
# longer exists). The orphan sweep rides THIS scheduled invocation
|
|
467
|
+
# precisely so it is never "in the code but never invoked in CI".
|
|
468
|
+
run: dorfl gc --remote-branches --arbiter origin
|
|
469
|
+
`;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Structurally validate the advance-lifecycle workflow against the task's
|
|
473
|
+
* acceptance criteria. Dependency-free (no YAML lib): presence/shape assertions
|
|
474
|
+
* over the raw text, mirroring {@link validateAdvanceCiTemplate}.
|
|
475
|
+
*/
|
|
476
|
+
export function validateAdvanceLifecycleWorkflow(text) {
|
|
477
|
+
const problems = [];
|
|
478
|
+
const require = (id, present, message) => {
|
|
479
|
+
if (!present) {
|
|
480
|
+
problems.push({ id, message });
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
// The OPERATIVE (non-comment) lines: the prohibitions below (no `--isolated`/
|
|
484
|
+
// `--remote`/`do`/`autoAdvance`/`.github/workflows` self-edit) are about what
|
|
485
|
+
// the job DOES, not what the explanatory comments MENTION. A YAML `#` comment
|
|
486
|
+
// line is documentation, so strip full-line comments before the negative checks.
|
|
487
|
+
// The positive presence checks run over the full text (comments are harmless).
|
|
488
|
+
const operative = text
|
|
489
|
+
.split('\n')
|
|
490
|
+
.filter((line) => !/^\s*#/.test(line))
|
|
491
|
+
.join('\n');
|
|
492
|
+
// --- Always invokes `advance`, NEVER `do` ----------------------------------
|
|
493
|
+
require('invokes-advance', /dorfl advance\b/.test(text), 'the workflow must invoke the `advance` driver (CI always runs `advance`).');
|
|
494
|
+
require('never-invokes-do', !/dorfl do\b/.test(operative), 'the workflow must NEVER invoke `do` directly (CI always invokes `advance`, ' +
|
|
495
|
+
'ADR ci-config-policy-and-gate-family §1).');
|
|
496
|
+
// --- Triggers: cron + workflow_dispatch + the on-answer-committed push -------
|
|
497
|
+
require('trigger-cron', /\bschedule:\s*[\s\S]*?-\s*cron:/.test(text), 'must trigger on a cron schedule (`on.schedule[].cron`).');
|
|
498
|
+
require('trigger-workflow-dispatch', /\bworkflow_dispatch:/.test(text), 'must trigger on `workflow_dispatch` (manual catch-up/debug).');
|
|
499
|
+
require('dispatch-integration-mode-input', /workflow_dispatch:[\s\S]*?inputs:[\s\S]*?integrationMode:/.test(text), 'the `workflow_dispatch` must carry an `integrationMode` input.');
|
|
500
|
+
// The DEFINING lifecycle trigger: an on-answer-committed push (a push touching
|
|
501
|
+
// `work/questions/**`) re-runs the loop so a freshly-answered sidecar applies
|
|
502
|
+
// promptly. This is what `advance` adds over the build/task tick.
|
|
503
|
+
require('trigger-on-answer-committed', /\bpush:\s*[\s\S]*?paths:[\s\S]*?work\/questions\//.test(text), 'must trigger on-answer-committed (a push touching `work/questions/**`) — ' +
|
|
504
|
+
'the lifecycle answer loop.');
|
|
505
|
+
// --- integrationMode drives BOTH shape and flag (one word, one meaning) -----
|
|
506
|
+
require('integration-mode-one-word', /integrationMode:/.test(text) &&
|
|
507
|
+
/github\.event\.inputs\.integrationMode/.test(text), 'the dispatch input must be `integrationMode` (one word driving BOTH the ' +
|
|
508
|
+
'flag and the derived job shape).');
|
|
509
|
+
// --- propose ⇒ a DYNAMIC matrix enumerated via `scan --json` ----------------
|
|
510
|
+
require('propose-matrix', /strategy:\s*[\s\S]*?matrix:/.test(text), '`propose` mode must emit a MATRIX of jobs (`strategy.matrix`).');
|
|
511
|
+
require('propose-enumerates-via-scan', /dorfl scan --json/.test(text), 'the matrix items must be ENUMERATED via the eligible-pool scan ' +
|
|
512
|
+
'(`dorfl scan --json`).');
|
|
513
|
+
require('propose-one-advance-per-item', /dorfl advance "?\$\{\{\s*matrix\./.test(text), 'each matrix leg must run one `dorfl advance <matrix item>` ' +
|
|
514
|
+
'(one PR per item).');
|
|
515
|
+
require('propose-leg-carries-propose-flag', /advance-propose:[\s\S]*?dorfl advance "?\$\{\{\s*matrix\.[\s\S]*?--propose\b/.test(text), 'each `propose` matrix leg must pass `--propose` so the integration mode is ' +
|
|
516
|
+
'TIED to the matrix shape (a leg can never merge to main / desync from the ' +
|
|
517
|
+
'dispatch mode).');
|
|
518
|
+
// --- merge ⇒ a MATRIX per item (parallel build/gate/review, serialised land) -
|
|
519
|
+
// PRD `land-time-reverify-and-parallel-merge-ceiling` stories 4 + 6: build/
|
|
520
|
+
// gate/review fan out; the LAND tail is serialised by the engine's
|
|
521
|
+
// `mergeRetries` CAS-retry loop (the git-alone floor), NOT the workflow.
|
|
522
|
+
require('merge-matrix', /advance-merge:[\s\S]*?strategy:\s*[\s\S]*?matrix:/.test(text), 'the `merge` job must use a MATRIX (parallel build/gate/review per item; ' +
|
|
523
|
+
"the land tail is serialised by the engine's `mergeRetries` CAS-retry " +
|
|
524
|
+
"loop, not by the workflow's job shape).");
|
|
525
|
+
require('merge-leg-carries-merge-flag', /advance-merge:[\s\S]*?dorfl advance "?\$\{\{\s*matrix\.[\s\S]*?--merge\b/.test(text), 'each `merge` matrix leg must pass `--merge` so the integration mode is ' +
|
|
526
|
+
'TIED to the matrix shape (a leg can never propose-only / desync from the ' +
|
|
527
|
+
'dispatch mode).');
|
|
528
|
+
// No host-specific cross-job serialiser on the merge job: a GitHub Actions
|
|
529
|
+
// `concurrency:` block there would make cross-job land safety depend on a host
|
|
530
|
+
// feature, breaking the git-alone-floor framing (Applied Answer q1).
|
|
531
|
+
require('merge-no-host-concurrency-serialiser', !/advance-merge:[\s\S]*?\n\s{4}concurrency:/.test(text), 'the `merge` job must NOT carry a `concurrency:` group: a host-specific ' +
|
|
532
|
+
'serialiser would make the cross-job land safety depend on a GitHub Actions ' +
|
|
533
|
+
"feature; the engine's `mergeRetries` CAS-retry loop is the git-alone floor.");
|
|
534
|
+
// --- The DORFL_* gate family must NOT be carried as workflow env -----
|
|
535
|
+
// The workflow emits NO active gate env line for any of AUTO_BUILD / AUTO_TASK
|
|
536
|
+
// / OBSERVATION_TRIAGE / SURFACE_BLOCKERS: the env layer is the OPTIONAL CI-only
|
|
537
|
+
// override layer, NOT the carrier of defaults. Emitting any of them would FORCE
|
|
538
|
+
// env to win over the repo's own .dorfl.json (the precedence is
|
|
539
|
+
// flag > env > per-repo > global > default), silently shadowing per-repo gate
|
|
540
|
+
// config in CI — exactly the bug this task closes. A user who genuinely wants a
|
|
541
|
+
// CI-SPECIFIC override adds the env var themselves (the opt-in CI override the
|
|
542
|
+
// env layer is FOR). Check the OPERATIVE (non-comment) lines so the explanatory
|
|
543
|
+
// header comment that NAMES these keys is not a false positive.
|
|
544
|
+
require('no-gate-env-auto-build', !/DORFL_AUTO_BUILD\s*:/.test(operative), 'the workflow must NOT emit an `DORFL_AUTO_BUILD:` env assignment ' +
|
|
545
|
+
'(env carries no defaults; the gate is resolved from per-repo config / built-in default).');
|
|
546
|
+
require('no-gate-env-auto-task', !/DORFL_AUTO_TASK\s*:/.test(operative), 'the workflow must NOT emit an `DORFL_AUTO_TASK:` env assignment ' +
|
|
547
|
+
'(env carries no defaults; the gate is resolved from per-repo config / built-in default).');
|
|
548
|
+
require('no-gate-env-observation-triage', !/DORFL_OBSERVATION_TRIAGE\s*:/.test(operative), 'the workflow must NOT emit an `DORFL_OBSERVATION_TRIAGE:` env ' +
|
|
549
|
+
'assignment (env carries no defaults; resolved from per-repo config / built-in default).');
|
|
550
|
+
require('no-gate-env-surface-blockers', !/DORFL_SURFACE_BLOCKERS\s*:/.test(operative), 'the workflow must NOT emit an `DORFL_SURFACE_BLOCKERS:` env ' +
|
|
551
|
+
'assignment (env carries no defaults; resolved from per-repo config / built-in default).');
|
|
552
|
+
// --- Gate-family DISPATCH OVERRIDES (one-shot, dispatch only) ---------------
|
|
553
|
+
// Each gate is exposed as a `workflow_dispatch` input AND its override is wired
|
|
554
|
+
// (as a guarded `$GITHUB_ENV` write, NOT a YAML `env:` key — so the
|
|
555
|
+
// `no-gate-env-*` invariants above still hold) into EVERY job that resolves the
|
|
556
|
+
// gate family: `enumerate` (it gates the matrix pools via `scan`), plus the two
|
|
557
|
+
// agent-running jobs. The enumerate wiring is the load-bearing one: without it a
|
|
558
|
+
// dispatch override of `observationTriage`/`surfaceBlockers`/`autoTask` produces
|
|
559
|
+
// an empty matrix and is silently inert (the bug this task's review caught).
|
|
560
|
+
for (const input of [
|
|
561
|
+
'autoBuild',
|
|
562
|
+
'autoTask',
|
|
563
|
+
'observationTriage',
|
|
564
|
+
'surfaceBlockers',
|
|
565
|
+
]) {
|
|
566
|
+
require(`dispatch-${input}-input`, new RegExp(`workflow_dispatch:[\\s\\S]*?inputs:[\\s\\S]*?\\b${input}:`).test(text), `the \`workflow_dispatch\` must carry a \`${input}\` gate-override input.`);
|
|
567
|
+
}
|
|
568
|
+
for (const [input, envVar] of [
|
|
569
|
+
['autoBuild', 'DORFL_AUTO_BUILD'],
|
|
570
|
+
['autoTask', 'DORFL_AUTO_TASK'],
|
|
571
|
+
['observationTriage', 'DORFL_OBSERVATION_TRIAGE'],
|
|
572
|
+
['surfaceBlockers', 'DORFL_SURFACE_BLOCKERS'],
|
|
573
|
+
]) {
|
|
574
|
+
// The override is a guarded shell write: `[ -n <input> ] && echo <ENV>=<input> >> $GITHUB_ENV`.
|
|
575
|
+
const guardedWrite = new RegExp(`\\[ -n "\\$\\{\\{ github\\.event\\.inputs\\.${input} \\}\\}" \\][\\s\\S]*?${envVar}=`);
|
|
576
|
+
require(`dispatch-${input}-guarded-write`, guardedWrite.test(text), `the \`${input}\` override must be a blank-guarded write of \`${envVar}\` ` +
|
|
577
|
+
'to `$GITHUB_ENV` (blank dispatch input / schedule / push emit nothing).');
|
|
578
|
+
}
|
|
579
|
+
// The ENUMERATE job MUST carry the override before its `scan` step — else the
|
|
580
|
+
// matrix pools are built from the un-overridden gates and the override is inert.
|
|
581
|
+
require('enumerate-carries-gate-override', /enumerate:[\s\S]*?DORFL_OBSERVATION_TRIAGE=[\s\S]*?id: scan/.test(text), 'the `enumerate` job must apply the dispatch gate override BEFORE its `scan` ' +
|
|
582
|
+
'step (scan gates the matrix pools by the gate family; otherwise the ' +
|
|
583
|
+
'override is silently inert for the lifecycle/task pools).');
|
|
584
|
+
// The override must be GUARDED by the workflow_dispatch event so schedule/push
|
|
585
|
+
// runs never even enter the write step.
|
|
586
|
+
require('gate-override-dispatch-guarded', /if:\s*\$\{\{\s*github\.event_name == 'workflow_dispatch'\s*\}\}/.test(text), 'the gate-override step must be guarded by `if: github.event_name == ' +
|
|
587
|
+
"'workflow_dispatch'` so schedule/push ticks export nothing.");
|
|
588
|
+
// There is NO autoAdvance gate (the lifecycle decomposes into the gate family).
|
|
589
|
+
require('no-auto-advance-gate', !/DORFL_AUTO_ADVANCE\b/.test(operative) &&
|
|
590
|
+
!/autoAdvance/.test(operative), 'there must be NO `autoAdvance` gate (the lifecycle decomposes into the ' +
|
|
591
|
+
'existing gate family; ADR ci-config-policy-and-gate-family §2).');
|
|
592
|
+
// --- Capability F: the reap job + sweep input PRESERVED (not stripped) ------
|
|
593
|
+
require('reap-merged-branches-job', /reap-merged-branches:/.test(text), "the absorbed seed's `reap-merged-branches` job (capability F) must be " +
|
|
594
|
+
'PRESERVED, not stripped.');
|
|
595
|
+
require('reap-uses-gc-remote-branches', /dorfl gc --remote-branches\b/.test(text), 'the reap job must run `dorfl gc --remote-branches` (the provider-' +
|
|
596
|
+
'agnostic merged-branch sweep).');
|
|
597
|
+
require('reap-sweep-dispatch-input', /sweepMergedBranches:/.test(text), 'the `sweepMergedBranches` dispatch input (capability F, opt-out) must be ' +
|
|
598
|
+
'preserved.');
|
|
599
|
+
// The ORPHAN-SIDECAR reap (prd
|
|
600
|
+
// `agentic-question-resolution-retire-disposition-vocabulary`, US #10) rides
|
|
601
|
+
// the SAME scheduled `dorfl gc --remote-branches` invocation, so it provably
|
|
602
|
+
// FIRES on the cron tick (not behind an un-passed flag). The reap step that
|
|
603
|
+
// runs `gc --remote-branches` MUST be checked out WITH a working tree (the
|
|
604
|
+
// orphan sweep is working-tree based: it reads `work/questions/` + the
|
|
605
|
+
// lifecycle folders from the checkout). `actions/checkout` provides that, and
|
|
606
|
+
// the step's name/comment names the orphan-sidecar duty so the linkage is not
|
|
607
|
+
// silently lost on a future template edit.
|
|
608
|
+
require('reap-checks-out-working-tree', /reap-merged-branches:[\s\S]*?uses:\s*actions\/checkout/.test(text), 'the reap job must `actions/checkout` a working tree before ' +
|
|
609
|
+
'`gc --remote-branches`: the orphan-sidecar sweep that rides that invocation ' +
|
|
610
|
+
'reads `work/questions/` + the lifecycle folders from the checkout.');
|
|
611
|
+
require('reap-names-orphan-sidecars', /reap-merged-branches:[\s\S]*?orphan sidecar/i.test(text), 'the reap step (running `gc --remote-branches`) must name the ORPHAN ' +
|
|
612
|
+
'SIDECAR reap it ALSO performs (US #10), so the scheduled invocation that ' +
|
|
613
|
+
'fires it is visible and not silently dropped on a future edit.');
|
|
614
|
+
// --- CI runs IN-PLACE: no isolation machinery ------------------------------
|
|
615
|
+
require('no-isolated-flag', !/--isolated\b/.test(operative), 'CI runs IN-PLACE (the container IS the isolation): no `--isolated` flag.');
|
|
616
|
+
// Guard `--remote` the LAPTOP affordance, but NOT `--remote-branches` (the
|
|
617
|
+
// preserved capability-F `gc --remote-branches` sweep): a negative lookahead
|
|
618
|
+
// for a following `-`/word char so the gc flag is not a false positive.
|
|
619
|
+
require('no-remote-flag', !/--remote(?![-\w])/.test(operative), 'CI runs IN-PLACE: no `--remote` flag (laptop-only affordance).');
|
|
620
|
+
// --- A CI concurrency group ------------------------------------------------
|
|
621
|
+
require('concurrency-group', /\bconcurrency:\s*[\s\S]*?group:/.test(text), 'must carry a CI `concurrency.group` so overlapping ticks never collide.');
|
|
622
|
+
// --- US #9: NO `workflows` permission; cannot self-edit triggers ------------
|
|
623
|
+
require('no-workflows-permission', !/\bworkflows:\s*write\b/.test(text), 'the running job must request NO `workflows` permission (US #9: it can ' +
|
|
624
|
+
'never edit `.github/workflows/**` / rewrite its own triggers).');
|
|
625
|
+
require('never-edits-dot-github-workflows', !/\.github\/workflows\//.test(operative), 'no emitted job step may touch `.github/workflows/**` (US #9).');
|
|
626
|
+
// --- Explicit slug prefixes, never bare ------------------------------------
|
|
627
|
+
require('explicit-task-prefix', /"task:" \+ \.slug/.test(text) ||
|
|
628
|
+
/task:/.test(text), 'CI must use explicit `task:`/`spec:` slug prefixes, never bare (ADR ' +
|
|
629
|
+
'command-surface-and-journeys §3a).');
|
|
630
|
+
// --- The propose `enumerate` matrix must UNION taskable prds --------------
|
|
631
|
+
// (`ci-propose-matrix-must-enumerate-sliceable-prds-not-only-slices`): a
|
|
632
|
+
// task-only `jq` would render `DORFL_AUTO_TASK: 'true'` dead on the
|
|
633
|
+
// hourly cron — a ready ungated PRD would never become a matrix leg. The `jq`
|
|
634
|
+
// must enumerate `spec:<slug>` ids from `scan --json`'s taskable-SPEC pool
|
|
635
|
+
// (`repos[].specs[]` + `cwd.repo.specs[]`) alongside the eligible-task legs.
|
|
636
|
+
require('propose-enumerates-taskable-specs', /"spec:" \+ \.slug/.test(text) &&
|
|
637
|
+
/\.specs\[\]/.test(text), 'the propose-mode `enumerate` `jq` must union taskable specs into the ' +
|
|
638
|
+
"matrix as `spec:<slug>` legs (read from `scan --json`'s `repos[].specs[]` " +
|
|
639
|
+
'+ `cwd.repo.specs[]` pools), so a ready ungated SPEC becomes one auto-task ' +
|
|
640
|
+
'matrix leg per item alongside the eligible-task legs ' +
|
|
641
|
+
'(`ci-propose-matrix-must-enumerate-sliceable-prds-not-only-slices`).');
|
|
642
|
+
// --- The propose `enumerate` matrix must UNION the LIFECYCLE pools ----------
|
|
643
|
+
// (`ci-propose-matrix-enumerates-lifecycle-items`): a build/task-only `jq`
|
|
644
|
+
// runs the answer-loop ONLY in merge mode — a `needsAnswers` item is
|
|
645
|
+
// `eligible:false` and untriaged observations are not in the task/prd pools at
|
|
646
|
+
// all, so NO lifecycle rung (triage/surface/apply) ever gets a propose leg. The
|
|
647
|
+
// `jq` must enumerate the three lifecycle sub-pools from `scan --json`
|
|
648
|
+
// (`repos[].lifecycle.*` + `cwd.repo.lifecycle.*`): `triage[]` → `obs:<slug>`,
|
|
649
|
+
// and `surface[]`/`apply[]` → `.namespace + ":" + .slug`. Match all four shape
|
|
650
|
+
// signals so a regression that drops any one leg is caught.
|
|
651
|
+
require('propose-enumerates-lifecycle-items', /"obs:" \+ \.slug/.test(text) &&
|
|
652
|
+
/\.lifecycle\.triage\[\]/.test(text) &&
|
|
653
|
+
/\.lifecycle\.surface\[\]/.test(text) &&
|
|
654
|
+
/\.lifecycle\.apply\[\]/.test(text) &&
|
|
655
|
+
/\.namespace \+ ":" \+ \.slug/.test(text), 'the propose-mode `enumerate` `jq` must union the LIFECYCLE pools into the ' +
|
|
656
|
+
"matrix (read from `scan --json`'s `repos[].lifecycle.*` + " +
|
|
657
|
+
'`cwd.repo.lifecycle.*`): `triage[]` as `obs:<slug>` legs, and ' +
|
|
658
|
+
'`surface[]`/`apply[]` as `.namespace + ":" + .slug` (`task:`/`spec:`, plus ' +
|
|
659
|
+
'`observation:` for an answered-observation apply leg) legs, ' +
|
|
660
|
+
'so the WHOLE answer-loop (triage + surface + apply) runs in propose mode, ' +
|
|
661
|
+
'not only in merge mode ' +
|
|
662
|
+
'(`ci-propose-matrix-enumerates-lifecycle-items`).');
|
|
663
|
+
// --- Wires the SHARED composite setup action -------------------------------
|
|
664
|
+
require('uses-shared-setup-action', /uses:\s*\.\/\.github\/actions\/dorfl-setup\b/.test(text), 'every job must wire the shared composite setup action ' +
|
|
665
|
+
'(`./.github/actions/dorfl-setup`, emitted by the core task).');
|
|
666
|
+
return { ok: problems.length === 0, problems };
|
|
667
|
+
}
|
|
668
|
+
//# sourceMappingURL=advance-lifecycle-template.js.map
|