dorfl 0.1.0 → 0.1.2
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 +3 -3
- package/dist/advance-ci-template.js +1 -1
- package/dist/advance-ci-template.js.map +1 -1
- package/dist/advance-classify.d.ts +5 -5
- package/dist/advance-classify.d.ts.map +1 -1
- package/dist/advance-classify.js +4 -4
- package/dist/advance-drivers.d.ts +7 -7
- package/dist/advance-drivers.d.ts.map +1 -1
- package/dist/advance-drivers.js +5 -5
- package/dist/advance-drivers.js.map +1 -1
- package/dist/advance-isolated.d.ts +3 -3
- package/dist/advance-isolated.d.ts.map +1 -1
- package/dist/advance-isolated.js +1 -1
- package/dist/advance-lifecycle-template.d.ts +2 -2
- package/dist/advance-lifecycle-template.js +9 -9
- package/dist/advance-lifecycle-template.js.map +1 -1
- package/dist/advance-loop-driver.d.ts +3 -3
- package/dist/advance-loop-driver.d.ts.map +1 -1
- package/dist/advance-loop-driver.js +1 -1
- package/dist/advance-treeless-publish.d.ts +1 -1
- package/dist/advance.d.ts +11 -11
- package/dist/advance.d.ts.map +1 -1
- package/dist/advance.js +21 -21
- package/dist/advance.js.map +1 -1
- package/dist/advancing-lock.d.ts +1 -1
- package/dist/advancing-lock.js +5 -5
- package/dist/apply-decide.d.ts +2 -2
- package/dist/apply-decide.js +2 -2
- package/dist/apply-merge-action.d.ts +4 -4
- package/dist/apply-merge-action.js +2 -2
- package/dist/apply-persist.d.ts +5 -5
- package/dist/apply-persist.d.ts.map +1 -1
- package/dist/apply-persist.js +7 -7
- package/dist/apply-persist.js.map +1 -1
- package/dist/buildable-body.d.ts +14 -14
- package/dist/buildable-body.js +9 -9
- package/dist/claim-cas.d.ts +3 -3
- package/dist/claim-cas.js +1 -1
- package/dist/claim-cas.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +83 -77
- package/dist/cli.js.map +1 -1
- package/dist/close-job-template.d.ts +3 -3
- package/dist/close-job-template.js +8 -8
- package/dist/close-job.d.ts +8 -8
- package/dist/close-job.js +25 -25
- package/dist/close-job.js.map +1 -1
- package/dist/complete.d.ts +3 -3
- package/dist/complete.js +8 -8
- package/dist/complete.js.map +1 -1
- package/dist/concurrency.d.ts +1 -1
- package/dist/concurrency.js +1 -1
- package/dist/config.d.ts +32 -32
- package/dist/config.js +5 -5
- package/dist/config.js.map +1 -1
- package/dist/continue-branch.d.ts +1 -1
- package/dist/continue-branch.js +1 -1
- package/dist/cwd-section.js +1 -1
- package/dist/cwd-section.js.map +1 -1
- package/dist/decision-engine.d.ts +2 -2
- package/dist/do-autopick.d.ts +6 -6
- package/dist/do-autopick.d.ts.map +1 -1
- package/dist/do-autopick.js +5 -5
- package/dist/do-autopick.js.map +1 -1
- package/dist/do-config.d.ts +3 -3
- package/dist/do-config.js +3 -3
- package/dist/do-config.js.map +1 -1
- package/dist/do-remote-auto.d.ts +2 -2
- package/dist/do-remote-auto.js +1 -1
- package/dist/do.d.ts +25 -25
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +22 -22
- package/dist/do.js.map +1 -1
- package/dist/drop-source.d.ts +2 -2
- package/dist/env-config.js +8 -8
- package/dist/env-config.js.map +1 -1
- package/dist/format.js +3 -3
- package/dist/format.js.map +1 -1
- package/dist/frontmatter.d.ts +33 -39
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +18 -31
- package/dist/frontmatter.js.map +1 -1
- package/dist/install-ci-branch-protection.d.ts +1 -1
- package/dist/install-ci-branch-protection.js +1 -1
- package/dist/install-ci-capabilities/advance-lifecycle.d.ts +1 -1
- package/dist/install-ci-capabilities/advance-lifecycle.js +1 -1
- package/dist/install-ci-capabilities/close-job.d.ts +1 -1
- package/dist/install-ci-capabilities/close-job.js +1 -1
- package/dist/install-ci-capabilities/example-noop.d.ts +1 -1
- package/dist/install-ci-capabilities/example-noop.js +1 -1
- package/dist/install-ci-capabilities/intake.d.ts +2 -2
- package/dist/install-ci-capabilities/intake.js +2 -2
- package/dist/install-ci-capabilities/verify.d.ts +1 -1
- package/dist/install-ci-capabilities/verify.js +1 -1
- package/dist/install-ci-core.d.ts +3 -3
- package/dist/install-ci-core.js +2 -2
- package/dist/install-ci-core.js.map +1 -1
- package/dist/install-ci-github.d.ts +1 -1
- package/dist/install-ci-github.js +1 -1
- package/dist/install-ci.d.ts +1 -1
- package/dist/install-ci.js +4 -4
- package/dist/install-ci.js.map +1 -1
- package/dist/intake-event.d.ts +6 -6
- package/dist/intake-event.js +6 -6
- package/dist/intake-marker.d.ts +3 -3
- package/dist/intake-marker.d.ts.map +1 -1
- package/dist/intake-triage.d.ts +1 -1
- package/dist/intake-triage.js +2 -2
- package/dist/intake-trigger-template.d.ts +8 -8
- package/dist/intake-trigger-template.d.ts.map +1 -1
- package/dist/intake-trigger-template.js +16 -16
- package/dist/intake-trigger-template.js.map +1 -1
- package/dist/intake.d.ts +50 -50
- package/dist/intake.d.ts.map +1 -1
- package/dist/intake.js +70 -70
- package/dist/intake.js.map +1 -1
- package/dist/integration-core.d.ts +17 -17
- package/dist/integration-core.js +17 -17
- package/dist/integration-core.js.map +1 -1
- package/dist/isolation.d.ts +3 -3
- package/dist/issue-provider.d.ts +4 -4
- package/dist/issue-provider.js +1 -1
- package/dist/item-lock.d.ts +21 -21
- package/dist/item-lock.d.ts.map +1 -1
- package/dist/item-lock.js +16 -16
- package/dist/item-path.d.ts +2 -2
- package/dist/item-path.js +2 -2
- package/dist/ledger-lint.d.ts +9 -9
- package/dist/ledger-lint.js +9 -9
- package/dist/ledger-read.d.ts +57 -57
- package/dist/ledger-read.d.ts.map +1 -1
- package/dist/ledger-read.js +24 -24
- package/dist/ledger-read.js.map +1 -1
- package/dist/ledger-write.d.ts +2 -2
- package/dist/ledger-write.js +1 -1
- package/dist/lifecycle-gather.d.ts +1 -1
- package/dist/lifecycle-gather.js +16 -16
- package/dist/lifecycle-gather.js.map +1 -1
- package/dist/lifecycle-pools.d.ts +4 -4
- package/dist/lifecycle-pools.js +1 -1
- package/dist/merge-question-surfacer.d.ts +3 -3
- package/dist/merge-question-surfacer.js +2 -2
- package/dist/merge-question-surfacer.js.map +1 -1
- package/dist/mint-adr.js +4 -4
- package/dist/mirror-pool-scan.d.ts +2 -2
- package/dist/mirror-pool-scan.js +3 -3
- package/dist/mirror-pool-scan.js.map +1 -1
- package/dist/needs-attention.d.ts +13 -13
- package/dist/needs-attention.d.ts.map +1 -1
- package/dist/needs-attention.js +11 -11
- package/dist/needs-attention.js.map +1 -1
- package/dist/orphan-sidecar.d.ts +2 -2
- package/dist/placement.d.ts +6 -6
- package/dist/placement.js +2 -2
- package/dist/prd-to-spec.d.ts +15 -1
- package/dist/prd-to-spec.d.ts.map +1 -1
- package/dist/prd-to-spec.js +36 -14
- package/dist/prd-to-spec.js.map +1 -1
- package/dist/prompt.d.ts +24 -24
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +29 -31
- package/dist/prompt.js.map +1 -1
- package/dist/protocol/CLAIM-PROTOCOL.md +4 -4
- package/dist/protocol/REVIEW-PROTOCOL.md +1 -1
- package/dist/protocol/TASKING-PROTOCOL.md +12 -12
- package/dist/protocol/WORK-CONTRACT.md +39 -39
- package/dist/protocol/spec-template.md +1 -1
- package/dist/protocol/task-template.md +3 -3
- package/dist/readiness.d.ts +1 -1
- package/dist/recover-isolated.js +1 -1
- package/dist/repo-config.js +12 -12
- package/dist/repo-config.js.map +1 -1
- package/dist/review-gate.d.ts +3 -3
- package/dist/review-gate.d.ts.map +1 -1
- package/dist/review-gate.js +11 -10
- package/dist/review-gate.js.map +1 -1
- package/dist/review-verdict.d.ts +2 -2
- package/dist/review-verdict.d.ts.map +1 -1
- package/dist/review-verdict.js +1 -1
- package/dist/run.d.ts +1 -1
- package/dist/run.js +5 -5
- package/dist/run.js.map +1 -1
- package/dist/scan.d.ts +10 -10
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +8 -8
- package/dist/scan.js.map +1 -1
- package/dist/select-order.d.ts +1 -1
- package/dist/select-priority.d.ts +12 -12
- package/dist/select-priority.d.ts.map +1 -1
- package/dist/select-priority.js +5 -5
- package/dist/select-priority.js.map +1 -1
- package/dist/sidecar.d.ts +2 -2
- package/dist/sidecar.js +2 -2
- package/dist/sidecar.js.map +1 -1
- package/dist/slug-namespace.d.ts +1 -1
- package/dist/slug-namespace.js +3 -3
- package/dist/slug-namespace.js.map +1 -1
- package/dist/spec-complete.js +2 -2
- package/dist/spec-complete.js.map +1 -1
- package/dist/start.d.ts +1 -1
- package/dist/start.js +3 -3
- package/dist/start.js.map +1 -1
- package/dist/status.d.ts +3 -3
- package/dist/status.js +4 -4
- package/dist/status.js.map +1 -1
- package/dist/surface-gate.d.ts +2 -2
- package/dist/surface-gate.d.ts.map +1 -1
- package/dist/surface-persist.d.ts +2 -2
- package/dist/surface-persist.d.ts.map +1 -1
- package/dist/tasker-review-loop.d.ts +8 -8
- package/dist/tasker-review-loop.d.ts.map +1 -1
- package/dist/tasker-review-loop.js +8 -8
- package/dist/tasker-review-loop.js.map +1 -1
- package/dist/tasking-eligibility.d.ts +21 -21
- package/dist/tasking-eligibility.d.ts.map +1 -1
- package/dist/tasking-eligibility.js +10 -10
- package/dist/tasking-lock.d.ts +8 -8
- package/dist/tasking-lock.d.ts.map +1 -1
- package/dist/tasking-lock.js +20 -21
- package/dist/tasking-lock.js.map +1 -1
- package/dist/tasking.d.ts +33 -33
- package/dist/tasking.d.ts.map +1 -1
- package/dist/tasking.js +89 -88
- package/dist/tasking.js.map +1 -1
- package/dist/triage-gate.d.ts +1 -1
- package/dist/triage-persist.d.ts +5 -5
- package/dist/triage-persist.js +15 -15
- package/dist/triage-persist.js.map +1 -1
- package/dist/verify-workflow-template.d.ts +1 -1
- package/dist/verify-workflow-template.js +2 -2
- package/dist/work-layout.d.ts +9 -7
- package/dist/work-layout.d.ts.map +1 -1
- package/dist/work-layout.js +9 -7
- package/dist/work-layout.js.map +1 -1
- package/dist/workspace.d.ts +1 -1
- package/package.json +1 -1
- package/src/advance-ci-template.ts +4 -4
- package/src/advance-classify.ts +5 -5
- package/src/advance-drivers.ts +10 -10
- package/src/advance-isolated.ts +3 -3
- package/src/advance-lifecycle-template.ts +9 -9
- package/src/advance-loop-driver.ts +3 -3
- package/src/advance-treeless-publish.ts +1 -1
- package/src/advance.ts +30 -30
- package/src/advancing-lock.ts +6 -6
- package/src/apply-decide.ts +2 -2
- package/src/apply-merge-action.ts +5 -5
- package/src/apply-persist.ts +8 -8
- package/src/buildable-body.ts +14 -14
- package/src/claim-cas.ts +4 -4
- package/src/cli.ts +94 -84
- package/src/close-job-template.ts +8 -8
- package/src/close-job.ts +26 -26
- package/src/complete.ts +11 -11
- package/src/concurrency.ts +1 -1
- package/src/config.ts +37 -37
- package/src/continue-branch.ts +1 -1
- package/src/cwd-section.ts +1 -1
- package/src/decision-engine.ts +3 -3
- package/src/do-autopick.ts +9 -9
- package/src/do-config.ts +6 -6
- package/src/do-remote-auto.ts +2 -2
- package/src/do.ts +49 -49
- package/src/drop-source.ts +2 -2
- package/src/env-config.ts +8 -8
- package/src/format.ts +3 -3
- package/src/frontmatter.ts +42 -60
- package/src/install-ci-branch-protection.ts +1 -1
- package/src/install-ci-capabilities/advance-lifecycle.ts +1 -1
- package/src/install-ci-capabilities/close-job.ts +1 -1
- package/src/install-ci-capabilities/example-noop.ts +1 -1
- package/src/install-ci-capabilities/intake.ts +2 -2
- package/src/install-ci-capabilities/verify.ts +1 -1
- package/src/install-ci-core.ts +4 -4
- package/src/install-ci-github.ts +1 -1
- package/src/install-ci.ts +4 -4
- package/src/intake-event.ts +6 -6
- package/src/intake-marker.ts +3 -3
- package/src/intake-triage.ts +2 -2
- package/src/intake-trigger-template.ts +17 -17
- package/src/intake.ts +97 -97
- package/src/integration-core.ts +35 -35
- package/src/isolation.ts +3 -3
- package/src/issue-provider.ts +4 -4
- package/src/item-lock.ts +21 -21
- package/src/item-path.ts +2 -2
- package/src/ledger-lint.ts +9 -9
- package/src/ledger-read.ts +81 -81
- package/src/ledger-write.ts +3 -3
- package/src/lifecycle-gather.ts +16 -16
- package/src/lifecycle-pools.ts +4 -4
- package/src/merge-question-surfacer.ts +4 -4
- package/src/mint-adr.ts +4 -4
- package/src/mirror-pool-scan.ts +5 -5
- package/src/needs-attention.ts +22 -22
- package/src/orphan-sidecar.ts +2 -2
- package/src/placement.ts +6 -6
- package/src/prd-to-spec.ts +51 -15
- package/src/prompt.ts +33 -35
- package/src/readiness.ts +1 -1
- package/src/recover-isolated.ts +1 -1
- package/src/repo-config.ts +12 -12
- package/src/review-gate.ts +12 -11
- package/src/review-verdict.ts +2 -2
- package/src/run.ts +6 -6
- package/src/scan.ts +15 -15
- package/src/select-order.ts +1 -1
- package/src/select-priority.ts +13 -13
- package/src/sidecar.ts +3 -3
- package/src/slug-namespace.ts +3 -3
- package/src/spec-complete.ts +2 -2
- package/src/start.ts +4 -4
- package/src/status.ts +7 -7
- package/src/surface-gate.ts +2 -2
- package/src/surface-persist.ts +2 -2
- package/src/tasker-review-loop.ts +15 -15
- package/src/tasking-eligibility.ts +21 -21
- package/src/tasking-lock.ts +27 -28
- package/src/tasking.ts +124 -123
- package/src/triage-gate.ts +1 -1
- package/src/triage-persist.ts +16 -16
- package/src/verify-workflow-template.ts +2 -2
- package/src/work-layout.ts +9 -7
- package/src/workspace.ts +1 -1
package/dist/cli.js
CHANGED
|
@@ -218,10 +218,10 @@ function buildRegistrySetAdvanceTick(options) {
|
|
|
218
218
|
lifecycleGates: {
|
|
219
219
|
triage: config.observationTriage !== 'off',
|
|
220
220
|
surface: config.surfaceBlockers,
|
|
221
|
-
// `surfaceStaging` widens the SURFACE candidate set into STAGING (
|
|
221
|
+
// `surfaceStaging` widens the SURFACE candidate set into STAGING (spec
|
|
222
222
|
// `staging-surface-and-apply-promote-safety` F2). Default `true` — a
|
|
223
|
-
// tasked `needsAnswers` task in `tasks/backlog/` (or
|
|
224
|
-
// `
|
|
223
|
+
// tasked `needsAnswers` task in `tasks/backlog/` (or spec in
|
|
224
|
+
// `specs/proposed/`) surfaces its questions BEFORE promotion. BUILD/claim
|
|
225
225
|
// stays pool-only either way.
|
|
226
226
|
surfaceStaging: config.surfaceStaging,
|
|
227
227
|
},
|
|
@@ -249,10 +249,10 @@ function buildRegistrySetAdvanceTick(options) {
|
|
|
249
249
|
identity: config.identity,
|
|
250
250
|
autoTask: config.autoTask,
|
|
251
251
|
integration: config.integration,
|
|
252
|
-
// The per-TRANSITION TASKING override: the `do
|
|
252
|
+
// The per-TRANSITION TASKING override: the `do spec:` tasking path threads
|
|
253
253
|
// `taskingIntegration ?? integration`; the build path stays on `integration`.
|
|
254
254
|
taskingIntegration: config.taskingIntegration,
|
|
255
|
-
// The TASK-PLACEMENT configured default (`do
|
|
255
|
+
// The TASK-PLACEMENT configured default (`do spec:` tasking output:
|
|
256
256
|
// `pre-backlog` staged vs `ready` pool). No operator flag on this
|
|
257
257
|
// registry-driven advance context, so only the configured default rung is
|
|
258
258
|
// threaded (the resolver still layers untrusted-origin force + built-in floor).
|
|
@@ -261,7 +261,7 @@ function buildRegistrySetAdvanceTick(options) {
|
|
|
261
261
|
verify: config.verify,
|
|
262
262
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
263
263
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
264
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
264
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
265
265
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — resolved per-repo
|
|
266
266
|
// and threaded so the registry-driven advance path's `do` inherits it.
|
|
267
267
|
mergeRetries: config.mergeRetries,
|
|
@@ -300,7 +300,7 @@ function buildRegistrySetAdvanceTick(options) {
|
|
|
300
300
|
triageGate: harnessTriageGate({ harness, agentCmd: config.agentCmd }),
|
|
301
301
|
triageModel: config.model,
|
|
302
302
|
// The ANSWERED-MERGE LAND DISPATCH context (task
|
|
303
|
-
// `apply-rung-merge-disposition`,
|
|
303
|
+
// `apply-rung-merge-disposition`, spec `land-time-reverify-and-parallel-
|
|
304
304
|
// merge-ceiling`): the dispatcher cuts a per-job worktree via
|
|
305
305
|
// `workspace.ts` `createJob` off the hub mirror (so we thread the resolved
|
|
306
306
|
// `workspacesDir` + the real arbiter URL — the per-mirror tree-less
|
|
@@ -396,7 +396,7 @@ function runFlagOverrides(flags, command) {
|
|
|
396
396
|
// fleet conditional lives in `runOnce`, not in this flag mapping).
|
|
397
397
|
Object.assign(overrides, freshWorktreeGateFlagOverrides(flags));
|
|
398
398
|
// `--merge-retries <n>` rides the SAME chain: the cross-job merge-serialiser
|
|
399
|
-
// CAS-retry cap (
|
|
399
|
+
// CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5 /
|
|
400
400
|
// Applied Answer q1 (a)). The `run` fleet inherits the resolved cap through
|
|
401
401
|
// the converged `performIntegration` core (config.mergeRetries threads into
|
|
402
402
|
// the merge loop, replacing the bare `DEFAULT_MERGE_RETRIES` fallback).
|
|
@@ -409,7 +409,7 @@ function formatItemLine(item) {
|
|
|
409
409
|
}
|
|
410
410
|
/**
|
|
411
411
|
* Resolve the EXPLICIT operator placement override from `--tasks-land-in <where>`
|
|
412
|
-
* (the top of the `do
|
|
412
|
+
* (the top of the `do spec:` tasking-placement precedence — task
|
|
413
413
|
* `runner-deterministic-slice-placement-policy-and-precedence`). Mirrors the
|
|
414
414
|
* `flagMode === 'merge'` ⇒ `explicitMerge: true` shape: it contributes
|
|
415
415
|
* `explicitTasksLandIn` ONLY when the operator actually typed the flag, so an
|
|
@@ -469,9 +469,15 @@ function printPrdToSpecReport(result) {
|
|
|
469
469
|
? '=== prd-to-spec (DRY RUN — nothing written) ==='
|
|
470
470
|
: '=== prd-to-spec ===');
|
|
471
471
|
if (result.resync) {
|
|
472
|
-
const changed = result.resync.docs.filter((d) => !d.unchanged).length;
|
|
472
|
+
const changed = result.resync.docs.filter((d) => !d.unchanged && !d.skipped).length;
|
|
473
473
|
console.log(`Contract re-sync: ${verb} sync ${result.resync.docs.length} protocol ` +
|
|
474
474
|
`doc(s) (${changed} changed) + bump ${result.resync.versionPath}.`);
|
|
475
|
+
// Surface any doc whose SOURCE could not be resolved LOUDLY: it was NOT
|
|
476
|
+
// copied, so the contract in the target repo is incomplete for that doc.
|
|
477
|
+
for (const skipped of result.resync.docs.filter((d) => d.skipped)) {
|
|
478
|
+
console.warn(` !! ${skipped.name}: SOURCE could not be resolved — NOT copied ` +
|
|
479
|
+
`(the contract doc is missing/unchanged in the target repo).`);
|
|
480
|
+
}
|
|
475
481
|
}
|
|
476
482
|
console.log(`Folders: ${verb} move ${result.folderMoves.length} folder(s).`);
|
|
477
483
|
for (const m of result.folderMoves) {
|
|
@@ -492,7 +498,7 @@ function printPrdToSpecReport(result) {
|
|
|
492
498
|
return;
|
|
493
499
|
}
|
|
494
500
|
if (result.leaks.length === 0) {
|
|
495
|
-
console.log('Leak scan: GREEN (no surviving
|
|
501
|
+
console.log('Leak scan: GREEN (no surviving spec data ref).');
|
|
496
502
|
}
|
|
497
503
|
else {
|
|
498
504
|
console.error(`Leak scan: FAILED (${result.leaks.length} leak(s)):`);
|
|
@@ -507,11 +513,12 @@ function printLeak(leak) {
|
|
|
507
513
|
/**
|
|
508
514
|
* Resolve a task-only command's slug argument through the §3a namespace guard
|
|
509
515
|
* (`resolveTaskOnlyArg`): accept bare (= task) + `task:` (explicit alias),
|
|
510
|
-
* REJECT `spec:` with a clear "operates on tasks, not specs" error
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
516
|
+
* REJECT `spec:` with a clear "operates on tasks, not specs" error. On rejection
|
|
517
|
+
* it prints the error to stderr and exits 1 (the task-only commands never act on
|
|
518
|
+
* a spec). An OMITTED slug (`start`/`complete`/`prompt` infer it from the branch)
|
|
519
|
+
* passes through untouched. (The legacy `prd:` prefix is a DEAD namespace token
|
|
520
|
+
* after the hard cutover — it is neither special-cased nor rejected here; a
|
|
521
|
+
* `prd:<slug>` arg resolves as a bare literal task slug.)
|
|
515
522
|
*
|
|
516
523
|
* `do` is the ONE command that spans both namespaces; it consumes the full
|
|
517
524
|
* `resolveSlug` (with the cross-namespace collision check) in the `do-in-place`
|
|
@@ -589,10 +596,10 @@ function buildInteractiveLauncher(flags, configPath, repoPath) {
|
|
|
589
596
|
* switching to its `work/<slug>` branch WITHOUT claiming). The runtime
|
|
590
597
|
* difference is exactly the `resume` flag — `resume` forces it on (its only mode
|
|
591
598
|
* is to re-engage), while `start` honours the (now hidden) `--resume` alias.
|
|
592
|
-
* Both are task-only (§3a: accept bare + `task:`, reject `
|
|
599
|
+
* Both are task-only (§3a: accept bare + `task:`, reject `spec:`).
|
|
593
600
|
*/
|
|
594
601
|
async function runStartAction(rawSlug, flags, resume) {
|
|
595
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
602
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
596
603
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
597
604
|
const cwd = process.cwd();
|
|
598
605
|
// `resume --isolated <slug>`: re-engage the slug's RETAINED job worktree (the
|
|
@@ -908,7 +915,7 @@ export function buildProgram() {
|
|
|
908
915
|
.option('--dry-run', 'show the intended push without mutating the arbiter')
|
|
909
916
|
.option('--ignore-not-ready', 'override the readiness guard: claim despite an unmet blockedBy, and silence the needsAnswers warning (loud, never default)')
|
|
910
917
|
.action(async (rawSlug, flags) => {
|
|
911
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
918
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
912
919
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
913
920
|
// Wrap ONLY this CLI surface's `performClaim` call with the spinner
|
|
914
921
|
// helper (task `claim-cas-spinner`): the push can take seconds, so the
|
|
@@ -1016,7 +1023,7 @@ export function buildProgram() {
|
|
|
1016
1023
|
const remote = flags.remote !== undefined && flags.remote.trim() !== ''
|
|
1017
1024
|
? flags.remote
|
|
1018
1025
|
: undefined;
|
|
1019
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1026
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1020
1027
|
const theSlug = resolveTaskOnlySlug(rawSlug);
|
|
1021
1028
|
const configPath = flags.config ?? defaultConfigPath();
|
|
1022
1029
|
const { dir: configuredRoot, config } = loadHumanWorktreesDir(configPath);
|
|
@@ -1060,10 +1067,10 @@ export function buildProgram() {
|
|
|
1060
1067
|
program
|
|
1061
1068
|
.command('prompt')
|
|
1062
1069
|
.helpGroup(ADVANCED_GROUP)
|
|
1063
|
-
.description("Print to stdout the work-agent prompt for a task: the canonical CLAIM-PROTOCOL wrapper + the task's own ## Prompt (with <slug> and source
|
|
1070
|
+
.description("Print to stdout the work-agent prompt for a task: the canonical CLAIM-PROTOCOL wrapper + the task's own ## Prompt (with <slug> and source spec substituted). Resolves work/in-progress/<slug>.md then work/backlog/<slug>.md; infers <slug> from a work/<slug> branch when omitted. Read-only, stdout only — the same assembly the autonomous runner feeds agentCmd.")
|
|
1064
1071
|
.argument('[slug]', 'the slug to render (inferred from a work/<slug> branch if omitted)')
|
|
1065
1072
|
.action((rawSlug) => {
|
|
1066
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1073
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1067
1074
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
1068
1075
|
// Resolve the `promptGuidance` NUDGE namespace through the SAME chain the
|
|
1069
1076
|
// gate family uses (env > per-repo > global > default), so e.g. a
|
|
@@ -1106,7 +1113,7 @@ export function buildProgram() {
|
|
|
1106
1113
|
.option('--no-fresh-worktree-gate', 'run the acceptance gate in the current checkout (the pre-rebase tree) — the opt-out for when the per-gate install cost is too high')
|
|
1107
1114
|
.option('--merge-retries <n>', 'cross-job merge-serialiser CAS-retry cap (see `run --help`); resolved flag > env > per-repo > global > default 1000.')
|
|
1108
1115
|
.action(async (rawSlug, flags) => {
|
|
1109
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1116
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1110
1117
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
1111
1118
|
const cwd = process.cwd();
|
|
1112
1119
|
const { global, override } = loadGlobalAndOverride(flags.config);
|
|
@@ -1166,7 +1173,7 @@ export function buildProgram() {
|
|
|
1166
1173
|
// `--fresh-worktree-gate`/`--no-fresh-worktree-gate` rides the SAME chain.
|
|
1167
1174
|
...freshWorktreeGateFlagOverrides(flags),
|
|
1168
1175
|
// `--merge-retries <n>` rides the SAME chain: the cross-job merge-serialiser
|
|
1169
|
-
// CAS-retry cap (
|
|
1176
|
+
// CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5
|
|
1170
1177
|
// / Applied Answer q1 (a)).
|
|
1171
1178
|
...mergeRetriesFlagOverrides(flags),
|
|
1172
1179
|
// `--no-pr` (the PR-INTENT axis) rides the SAME chain.
|
|
@@ -1206,7 +1213,7 @@ export function buildProgram() {
|
|
|
1206
1213
|
// a single-job path, so the resolved flag is passed UNCONDITIONALLY (no
|
|
1207
1214
|
// fleet downgrade).
|
|
1208
1215
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
1209
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
1216
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
1210
1217
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — the resolved
|
|
1211
1218
|
// per-repo value reaches the merge loop via `performComplete`→
|
|
1212
1219
|
// `performIntegration`.
|
|
@@ -1237,13 +1244,13 @@ export function buildProgram() {
|
|
|
1237
1244
|
program
|
|
1238
1245
|
.command('do')
|
|
1239
1246
|
.helpGroup(HEADLINE_GROUP)
|
|
1240
|
-
.description('The per-repo WORKER (the CI command): claim + onboard onto work/<slug>, run the agent, gate, integrate, and exit. In the CURRENT checkout by default (refuses on a dirty tree, integrates in-place). With --remote <r>: against a REGISTERED repo with NO checkout — materialise a hub mirror + job worktree in the agents\u2019 area, run the same pipeline there, then reap. do <slug> | do task:<slug> | do spec:<slug> (the tasking path
|
|
1247
|
+
.description('The per-repo WORKER (the CI command): claim + onboard onto work/<slug>, run the agent, gate, integrate, and exit. In the CURRENT checkout by default (refuses on a dirty tree, integrates in-place). With --remote <r>: against a REGISTERED repo with NO checkout — materialise a hub mirror + job worktree in the agents\u2019 area, run the same pipeline there, then reap. do <slug> | do task:<slug> | do spec:<slug> (the tasking path) | do (auto-pick one) | do <a> <b> (those, in sequence) | do -n <x> (x eligible, in sequence). Auto-pick draws TASKS-FIRST then SPECS-to-task by default (per-repo selectionOrder reorders the pools). --propose (default) / --merge resolved at integrate-time. Supersedes ar-run.sh.')
|
|
1241
1248
|
// EXTENSIBLE argument grammar (the three do-* tasks grow this one block):
|
|
1242
1249
|
// `do-autopick` widens the single optional positional into a VARIADIC one so
|
|
1243
1250
|
// `do` (zero args = auto-pick), `do <a> <b> …` (named, in sequence), and
|
|
1244
1251
|
// `do <slug>` (exactly one) all share the one command. `-n <x>` is the count
|
|
1245
1252
|
// for the auto-pick form. `do` stays SEQUENTIAL (parallelism is `run`).
|
|
1246
|
-
.argument('[slugs...]', 'the item(s) to do: bare (= the task), task:<slug>, or spec:<slug> (task the spec
|
|
1253
|
+
.argument('[slugs...]', 'the item(s) to do: bare (= the task), task:<slug>, or spec:<slug> (task the spec). Zero args = auto-pick; multiple = do them in sequence.')
|
|
1247
1254
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
1248
1255
|
.option('--arbiter <remote>', 'name of the arbiter git remote (default: per-repo/global defaultArbiter)')
|
|
1249
1256
|
.option('-n, --number <x>', 'AUTO-PICK x eligible items and do them IN SEQUENCE (ordered by selectionOrder, default drain = tasks-first then prds-to-task). Sequential — never a parallelism knob (that is `run`). Mutually exclusive with naming items.')
|
|
@@ -1252,7 +1259,7 @@ export function buildProgram() {
|
|
|
1252
1259
|
.option('--isolated', "build in an ISOLATED job worktree off THIS repo's arbiter (inferred from cwd) instead of taking over the current checkout, then integrate + reap \u2014 the in-place-but-isolated form. Shares the same grammar as the no-checkout forms: a single named item, multiple named items (in sequence), AND -n/auto-pick over the mirror-side eligible-pool scan. Always SEQUENTIAL (parallelism is `run` / the CI matrix). Orthogonal to --remote (a foreign repo); with --remote, remote wins (isolation is already implied).")
|
|
1253
1260
|
.option('--merge', 'integrate in merge mode this invocation (mutually exclusive with --propose; overrides config)')
|
|
1254
1261
|
.option('--propose', 'integrate in propose mode this invocation (default; mutually exclusive with --merge; overrides config)')
|
|
1255
|
-
.option('--tasks-land-in <where>', 'where `do
|
|
1262
|
+
.option('--tasks-land-in <where>', 'where `do spec:<slug>` tasking output lands: `pre-backlog` (staged, not agent-eligible) or `ready` (the agent POOL). The EXPLICIT operator override at the top of the placement precedence (explicit flag > untrusted-origin forces staging > tasksLandIn default > built-in). Resolved flag > env (DORFL_TASKS_LAND_IN) > per-repo > global > built-in.')
|
|
1256
1263
|
.option('--no-pr', 'propose without opening a PR: push the branch but deliberately skip the review request, even on an authed GitHub arbiter (the explicit suppress-PR intent). Resolved flag > env > per-repo > global > default off.')
|
|
1257
1264
|
.option('--ignore-diverged-main', 'override the in-place divergence guard: run even when local main is ahead of <arbiter>/main (unpushed). The work still lands on the arbiter; local main is left for you to `git rebase`. In-place only; loud, never default.')
|
|
1258
1265
|
.option('--allow-backlog', 'do task:<slug> ONLY: also FIND, CLAIM, and COMPLETE a task that lives in tasks/backlog/ (staging), driving it in place WITHOUT promoting it to the pool (so no advance leg / run daemon can claim it out from under you). The done-move goes tasks/backlog/ -> tasks/done/ directly (your explicit drive IS the promotion). EXPLICIT-INVOCATION-ONLY: default off, never set by run/auto-pick/advance or config/env.')
|
|
@@ -1266,9 +1273,9 @@ export function buildProgram() {
|
|
|
1266
1273
|
.option('--no-review', 'do NOT run Gate 2 this invocation (overrides config)')
|
|
1267
1274
|
.option('--review-model <id>', 'model the Gate-2 review agent runs on (de-correlated from the builder; routing intent). Resolved flag > env > per-repo > global > default.')
|
|
1268
1275
|
.option('--review-max-rounds <n>', 'bound the revise/review loop; on exhaustion force needs-attention (default 2)')
|
|
1269
|
-
.option('--tasker-loop', 'run the tasker IMPROVER loop on `do
|
|
1270
|
-
.option('--no-tasker-loop', 'skip the tasker improver loop on `do
|
|
1271
|
-
.option('--tasker-loop-max <n>', 'cap the tasker improver loop on `do
|
|
1276
|
+
.option('--tasker-loop', 'run the tasker IMPROVER loop on `do spec:<slug>` (review→edit→converge over the produced task set). ON by default; --no-tasker-loop skips it. DISTINCT from the acceptance gate (--review).')
|
|
1277
|
+
.option('--no-tasker-loop', 'skip the tasker improver loop on `do spec:<slug>`')
|
|
1278
|
+
.option('--tasker-loop-max <n>', 'cap the tasker improver loop on `do spec:<slug>` (in-context review passes); on exhaustion with blockers, reject via needsAnswers / route the spec to needs-attention (default 3)')
|
|
1272
1279
|
.option('--tasker-loop-model <id>', 'model the tasker improver loop review agent runs on (de-correlated from the tasker; routing intent). Resolved flag > env > per-repo > global > default. DISTINCT from --review-model.')
|
|
1273
1280
|
.option('--fresh-worktree-gate', 'run the acceptance gate (prepare then verify) against the REBASED tip in a CLEAN throwaway worktree (the tree that actually integrates), so a green gate provably describes the merged artifact. ON by default. Resolved flag > env > per-repo > global > default on.')
|
|
1274
1281
|
.option('--no-fresh-worktree-gate', "run the acceptance gate in the agent's build worktree (the pre-rebase tree) as before — the opt-out for when the per-gate install cost is too high")
|
|
@@ -1405,7 +1412,7 @@ export function buildProgram() {
|
|
|
1405
1412
|
// Host-only runner IDENTITY — scopes git/provider ops only (not the
|
|
1406
1413
|
// agent launch); absent ⇒ ambient.
|
|
1407
1414
|
identity: remoteConfig.identity,
|
|
1408
|
-
// `do --remote
|
|
1415
|
+
// `do --remote spec:<slug>` tasking-gate policy (task-build path ignores it).
|
|
1409
1416
|
autoTask: remoteConfig.autoTask,
|
|
1410
1417
|
// The resolved `promptGuidance` nudge — threaded into the remote worker
|
|
1411
1418
|
// prompt (runRemotePipeline → buildAgentPrompt), mirroring in-place `do`.
|
|
@@ -1413,7 +1420,7 @@ export function buildProgram() {
|
|
|
1413
1420
|
integration: remoteConfig.integration,
|
|
1414
1421
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule.
|
|
1415
1422
|
explicitMerge: flagMode === 'merge',
|
|
1416
|
-
// Per-TRANSITION TASKING override (the `do --remote
|
|
1423
|
+
// Per-TRANSITION TASKING override (the `do --remote spec:` tasking path).
|
|
1417
1424
|
taskingIntegration: remoteConfig.taskingIntegration,
|
|
1418
1425
|
// TASK-PLACEMENT: the configured default + the EXPLICIT operator override
|
|
1419
1426
|
// (`--tasks-land-in`), the top of the placement precedence — mirrors
|
|
@@ -1425,7 +1432,7 @@ export function buildProgram() {
|
|
|
1425
1432
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1426
1433
|
freshWorktreeGate: remoteConfig.freshWorktreeGate,
|
|
1427
1434
|
// Cross-job merge-serialiser CAS-retry cap (resolved through the per-repo
|
|
1428
|
-
// chain on the arbiter-side `.dorfl.json` too) —
|
|
1435
|
+
// chain on the arbiter-side `.dorfl.json` too) — spec
|
|
1429
1436
|
// `land-time-reverify-and-parallel-merge-ceiling` Story 5.
|
|
1430
1437
|
mergeRetries: remoteConfig.mergeRetries,
|
|
1431
1438
|
noPR: remoteConfig.noPR,
|
|
@@ -1442,7 +1449,7 @@ export function buildProgram() {
|
|
|
1442
1449
|
agentCmd: remoteConfig.agentCmd,
|
|
1443
1450
|
})
|
|
1444
1451
|
: undefined,
|
|
1445
|
-
// The tasker IMPROVER loop on the `do --remote
|
|
1452
|
+
// The tasker IMPROVER loop on the `do --remote spec:` path is ON by default
|
|
1446
1453
|
// (auto-tasking has no `verify` floor, so the loop is the task path's
|
|
1447
1454
|
// quality engine). `--tasker-loop`/`--no-tasker-loop` gates wiring the seam;
|
|
1448
1455
|
// `taskerLoopMax`/`taskerLoopModel` resolve per-repo (flag > env > per-repo
|
|
@@ -1455,7 +1462,7 @@ export function buildProgram() {
|
|
|
1455
1462
|
: undefined,
|
|
1456
1463
|
taskerLoopMax: remoteConfig.taskerLoopMax,
|
|
1457
1464
|
taskerLoopModel: remoteConfig.taskerLoopModel,
|
|
1458
|
-
// The task-SET ACCEPTANCE GATE on the `do --remote
|
|
1465
|
+
// The task-SET ACCEPTANCE GATE on the `do --remote spec:` path too.
|
|
1459
1466
|
taskReviewGate: remoteConfig.review
|
|
1460
1467
|
? harnessTaskAcceptanceGate({
|
|
1461
1468
|
harness: remoteHarness,
|
|
@@ -1559,7 +1566,7 @@ export function buildProgram() {
|
|
|
1559
1566
|
// ops (claim, push, integrate, `gh`) — NEVER the agent launch. Absent ⇒
|
|
1560
1567
|
// ambient (today's behaviour). Mapped Config → DoOptions like model/agentCmd.
|
|
1561
1568
|
identity: config.identity,
|
|
1562
|
-
// `do
|
|
1569
|
+
// `do spec:<slug>` tasking-gate policy (the task-build path ignores it).
|
|
1563
1570
|
autoTask: config.autoTask,
|
|
1564
1571
|
// The resolved `promptGuidance` NUDGE namespace (e.g. `testFirst`),
|
|
1565
1572
|
// threaded into the worker prompt by performDo → buildAgentPrompt so a
|
|
@@ -1572,11 +1579,11 @@ export function buildProgram() {
|
|
|
1572
1579
|
// typed `--merge` (`flagMode`), never when `merge` came from config — so an
|
|
1573
1580
|
// untrusted-origin task still forces propose under a config `merge`.
|
|
1574
1581
|
explicitMerge: flagMode === 'merge',
|
|
1575
|
-
// Per-TRANSITION TASKING override: the `do
|
|
1582
|
+
// Per-TRANSITION TASKING override: the `do spec:` tasking path threads
|
|
1576
1583
|
// `taskingIntegration ?? integration`; the task-build path stays on
|
|
1577
1584
|
// `integration`. Unset ⇒ tasking falls back to `integration` (today's behaviour).
|
|
1578
1585
|
taskingIntegration: config.taskingIntegration,
|
|
1579
|
-
// TASK-PLACEMENT (`do
|
|
1586
|
+
// TASK-PLACEMENT (`do spec:` tasking output): the configured default rung +
|
|
1580
1587
|
// the EXPLICIT operator override `--tasks-land-in` (top of the precedence).
|
|
1581
1588
|
// `explicitTasksLandIn` is set ONLY when the flag was typed (mirrors
|
|
1582
1589
|
// `explicitMerge`), so an untrusted-origin staging force still wins under a
|
|
@@ -1589,7 +1596,7 @@ export function buildProgram() {
|
|
|
1589
1596
|
verify: config.verify,
|
|
1590
1597
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1591
1598
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
1592
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
1599
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
1593
1600
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — resolved per-repo
|
|
1594
1601
|
// and threaded to `performComplete`→`performIntegration`.
|
|
1595
1602
|
mergeRetries: config.mergeRetries,
|
|
@@ -1613,7 +1620,7 @@ export function buildProgram() {
|
|
|
1613
1620
|
reviewGate: config.review
|
|
1614
1621
|
? harnessReviewGate({ harness, agentCmd: config.agentCmd })
|
|
1615
1622
|
: undefined,
|
|
1616
|
-
// The tasker IMPROVER loop on the `do
|
|
1623
|
+
// The tasker IMPROVER loop on the `do spec:` tasking path is ON by default
|
|
1617
1624
|
// (auto-tasking has no `verify` floor — the loop is the task path's quality
|
|
1618
1625
|
// engine). `--tasker-loop`/`--no-tasker-loop` gates wiring the seam;
|
|
1619
1626
|
// `taskerLoopMax`/`taskerLoopModel` resolve per-repo (flag > env > per-repo
|
|
@@ -1640,7 +1647,7 @@ export function buildProgram() {
|
|
|
1640
1647
|
note: (message) => console.error(`>> ${message}`),
|
|
1641
1648
|
noteBlock: (message) => console.error(message),
|
|
1642
1649
|
};
|
|
1643
|
-
// `--allow-backlog` is EXPLICIT-SINGLE-TASK-ONLY (
|
|
1650
|
+
// `--allow-backlog` is EXPLICIT-SINGLE-TASK-ONLY (spec
|
|
1644
1651
|
// `do-allow-backlog-drive-staged-tasks-without-promotion`, decision 4): it
|
|
1645
1652
|
// drives ONE named staged task in place. It must NOT combine with the
|
|
1646
1653
|
// AUTO-PICK (zero-args / -n) or MULTI-ITEM forms — those select FROM the
|
|
@@ -1694,33 +1701,33 @@ export function buildProgram() {
|
|
|
1694
1701
|
process.exit(result.exitCode);
|
|
1695
1702
|
});
|
|
1696
1703
|
// `advance` — the SIBLING top-level verb (NOT a `do` subcommand; `do`
|
|
1697
|
-
// subcommands + a standalone `task` verb are REJECTED in
|
|
1704
|
+
// subcommands + a standalone `task` verb are REJECTED in spec `advance-loop`).
|
|
1698
1705
|
// It reuses the SAME shared `prefix:arg` resolver `do` uses, EXTENDED with the
|
|
1699
1706
|
// `obs:` namespace, and wires the classify → lock → execute SKELETON: classify
|
|
1700
1707
|
// the rung (read-only, no model, no lock), take the `advancing` CAS borrow, then
|
|
1701
|
-
// dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do
|
|
1708
|
+
// dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do spec:` (never a
|
|
1702
1709
|
// duplicate), surface/apply/triage dispatch to a named executor seam later
|
|
1703
1710
|
// tasks fill. The DRIVERS (one-shot/loop) + `-n` + per-action gates and the
|
|
1704
1711
|
// rung BODIES are LATER tasks; the bare eligible-SET form errors clearly here.
|
|
1705
1712
|
program
|
|
1706
1713
|
.command('advance')
|
|
1707
1714
|
.helpGroup(HEADLINE_GROUP)
|
|
1708
|
-
.description('Advance work/ item(s) one lifecycle rung toward ready/built (
|
|
1709
|
-
.argument('[slugs...]', 'the item(s) to advance: bare (= the task), task:<slug>, spec:<slug
|
|
1715
|
+
.description('Advance work/ item(s) one lifecycle rung toward ready/built (SPEC advance-loop), the SEQUENTIAL one-shot driver over the advance tick. advance <slug> (bare = the task) | advance spec:<slug> (the spec tasking rung) | advance obs:<slug> (triage an observation) | advance (auto-pick one eligible) | advance <a> <b> (those, in sequence) | advance -n <x> (x eligible, in sequence). Each item: classify (read-only, no model, no lock) → take the `advancing` CAS lock → dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do spec:`, surface/apply always run, triage respects observationTriage (off|ask|auto). The bare/`-n` selection respects the per-action gates (build→autoBuild, task→autoTask, triage→observationTriage); `-n` is ALWAYS sequential (parallelism is `run` / the CI matrix).')
|
|
1716
|
+
.argument('[slugs...]', 'the item(s) to advance: bare (= the task), task:<slug>, spec:<slug>, or obs:<slug> (an observation). Zero args = auto-pick one eligible; multiple = advance them in sequence.')
|
|
1710
1717
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
1711
1718
|
.option('--arbiter <remote>', 'name of the arbiter git remote (default: per-repo/global defaultArbiter)')
|
|
1712
1719
|
.option('-n, --number <x>', 'AUTO-PICK x eligible items and advance them IN SEQUENCE (ordered by selectionOrder, default drain = tasks-first then prds-to-task). Sequential — never a parallelism knob (that is `run` / the CI matrix). Mutually exclusive with naming items.')
|
|
1713
1720
|
.option('--isolated', "advance in an ISOLATED worktree off THIS repo's arbiter (inferred from cwd) instead of taking over the current checkout, then integrate + reap — the in-place-but-isolated form. Shares the same grammar: a single named item, multiple named items (in sequence), AND -n/auto-pick over the mirror-side eligible-pool scan. Always SEQUENTIAL (parallelism is `run` / the CI matrix). Lets you advance from a busy/dirty checkout or anywhere with a participating arbiter.")
|
|
1714
1721
|
.option('--selection-order <order>', 'order the auto-pick pools (build/task/surface/triage; apply is always first): a preset keyword (drain (default) | groom) or an explicit comma-separated pool list. Resolved flag > env > per-repo > global > default.')
|
|
1715
1722
|
.option('--observation-triage <mode>', 'the observation-inbox gate (off|ask|auto): off (default) leaves observations untouched (the triage pool is dropped from auto-pick); ask surfaces a promote/keep/delete question for each untriaged observation; auto auto-disposes the no-question cases (duplicate/map) and asks about the rest. Resolved flag > env > per-repo > global > default. An explicit `advance obs:<slug>` bypasses the selection gate and runs in ask-mode (auto-disposes only under `auto`).')
|
|
1716
|
-
.option('--surface-blockers', 'the declared-blocked-work gate (the orthogonal peer of --observation-triage): render a task/
|
|
1717
|
-
.option('--no-surface-blockers', 'leave a needsAnswers:true task/
|
|
1718
|
-
.option('--strict-merge-approval', 'opt in to the host-agnostic "dismiss stale approvals on base change" discipline (
|
|
1723
|
+
.option('--surface-blockers', 'the declared-blocked-work gate (the orthogonal peer of --observation-triage): render a task/spec carrying needsAnswers:true into an answerable question sidecar (the needsAnswers-blocked pool is enumerated into auto-pick). Resolved flag > env > per-repo > global > default off. An explicit `advance <slug>`/`advance spec:<slug>` bypasses this selection gate and surfaces regardless. Does NOT gate apply (an answered sidecar still applies) or needs-attention (always on).')
|
|
1724
|
+
.option('--no-surface-blockers', 'leave a needsAnswers:true task/spec silently blocked (default; the blocked pool is dropped from auto-pick)')
|
|
1725
|
+
.option('--strict-merge-approval', 'opt in to the host-agnostic "dismiss stale approvals on base change" discipline (spec `land-time-reverify-and-parallel-merge-ceiling` sidecar OQ6): when the merge-base CHANGED between the human’s merge-answer and the apply step, RE-SURFACE the merge-question (clear the answer back to no-answer; re-author the question on main/runner under the advancing lock) instead of auto-landing on a green re-verify. Default OFF (a green re-verify is trusted as sufficient; honour the prior answer). Story #16’s RED-re-verify refusal is UNCHANGED and independent of this flag. Resolved flag > env > per-repo > global > default off.')
|
|
1719
1726
|
.option('--no-strict-merge-approval', 'honour the prior merge-answer and land when the rebased tip re-verifies GREEN even if the merge-base changed (default; the cheap green-re-verify-is-enough path)')
|
|
1720
1727
|
.option('--merge-questions <mode>', 'the merge-question SURFACER gate (off|ask|auto): off drops the surfacer (only for a repo that lands by some other means); ask (default) enumerates unmerged `work/*` branches and surfaces a merge-question sidecar a human answers; auto self-supplies the `merge` answer and lands via the SAME deterministic apply-time re-verify (the merge-mode-like fast path). SEPARATE axis from --observation-triage with a HIGHER default (a dropped merge-question means pushed work never lands). Resolved flag > env > per-repo > global > default ask.')
|
|
1721
1728
|
.option('--merge', 'integrate the advanced item(s) in merge mode this invocation (mutually exclusive with --propose; overrides config). The CI merge shape is a SINGLE SEQUENTIAL job, so this rides the `-n`/named-sequence path, never the matrix.')
|
|
1722
1729
|
.option('--propose', 'integrate the advanced item(s) in propose mode this invocation (default; mutually exclusive with --merge; overrides config). The CI propose shape is the parallel matrix (one PR per item).')
|
|
1723
|
-
.option('--tasks-land-in <where>', 'where `advance
|
|
1730
|
+
.option('--tasks-land-in <where>', 'where `advance spec:<slug>` tasking output lands: `pre-backlog` (staged) or `ready` (the agent POOL). The EXPLICIT operator override at the top of the placement precedence. Resolved flag > env (DORFL_TASKS_LAND_IN) > per-repo > global > built-in.')
|
|
1724
1731
|
.option('--watch', "stream the build agent's high-signal events live by tailing the pi session log (requires harness: pi; READ-ONLY observer — does not change outcome/gate/git). The same view `do --watch` gives, threaded through the build rung; CI uses it so the job log shows the agent working instead of freezing.")
|
|
1725
1732
|
.action(async (rawSlugs, flags) => {
|
|
1726
1733
|
// Variadic grammar (mirrors `do`): zero args = AUTO-PICK; one = the single
|
|
@@ -1836,7 +1843,7 @@ export function buildProgram() {
|
|
|
1836
1843
|
integration: remoteConfig.integration,
|
|
1837
1844
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule.
|
|
1838
1845
|
explicitMerge: flagMode === 'merge',
|
|
1839
|
-
// Per-TRANSITION TASKING override (the isolated `do --remote
|
|
1846
|
+
// Per-TRANSITION TASKING override (the isolated `do --remote spec:` path).
|
|
1840
1847
|
taskingIntegration: remoteConfig.taskingIntegration,
|
|
1841
1848
|
// TASK-PLACEMENT: configured default + EXPLICIT `--tasks-land-in` override
|
|
1842
1849
|
// (set only when typed, mirroring `explicitMerge`).
|
|
@@ -1846,7 +1853,7 @@ export function buildProgram() {
|
|
|
1846
1853
|
verify: remoteConfig.verify,
|
|
1847
1854
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1848
1855
|
freshWorktreeGate: remoteConfig.freshWorktreeGate,
|
|
1849
|
-
// Cross-job merge-serialiser CAS-retry cap —
|
|
1856
|
+
// Cross-job merge-serialiser CAS-retry cap — spec
|
|
1850
1857
|
// `land-time-reverify-and-parallel-merge-ceiling` Story 5.
|
|
1851
1858
|
mergeRetries: remoteConfig.mergeRetries,
|
|
1852
1859
|
noPR: remoteConfig.noPR,
|
|
@@ -1974,7 +1981,7 @@ export function buildProgram() {
|
|
|
1974
1981
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule (a
|
|
1975
1982
|
// bare `advance` auto-pick passes no flag ⇒ unset ⇒ untrusted forces propose).
|
|
1976
1983
|
explicitMerge: flagMode === 'merge',
|
|
1977
|
-
// Per-TRANSITION TASKING override (the `do
|
|
1984
|
+
// Per-TRANSITION TASKING override (the `do spec:` tasking path threads
|
|
1978
1985
|
// `taskingIntegration ?? integration`; the build path stays on `integration`).
|
|
1979
1986
|
taskingIntegration: config.taskingIntegration,
|
|
1980
1987
|
// TASK-PLACEMENT: configured default + EXPLICIT `--tasks-land-in` override
|
|
@@ -1985,7 +1992,7 @@ export function buildProgram() {
|
|
|
1985
1992
|
verify: config.verify,
|
|
1986
1993
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1987
1994
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
1988
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
1995
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
1989
1996
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)).
|
|
1990
1997
|
mergeRetries: config.mergeRetries,
|
|
1991
1998
|
noPR: config.noPR,
|
|
@@ -2112,7 +2119,7 @@ export function buildProgram() {
|
|
|
2112
2119
|
.action(async (flags) => {
|
|
2113
2120
|
const config = resolveGlobalConfig(loadConfig(flags.config), {});
|
|
2114
2121
|
const workspacesDir = flags.workspace ?? config.workspacesDir;
|
|
2115
|
-
// The `gc`-STYLE ledger SWEEP (
|
|
2122
|
+
// The `gc`-STYLE ledger SWEEP (spec `ledger-integrity` story 3): a SEPARATE
|
|
2116
2123
|
// surface from the worktree reaper below — it REPORTS one-slug-one-folder
|
|
2117
2124
|
// violations in a repo's `work/` lifecycle ledger and NEVER deletes (a human
|
|
2118
2125
|
// resolves each). Distinct `work/`: the ledger, not the execution substrate.
|
|
@@ -2120,7 +2127,7 @@ export function buildProgram() {
|
|
|
2120
2127
|
const repoPath = typeof flags.ledger === 'string' ? flags.ledger : process.cwd();
|
|
2121
2128
|
const result = sweepLedgerDuplicates(repoPath);
|
|
2122
2129
|
// The UNIFIED-LOCK stuck/orphaned-lock REPORT (task
|
|
2123
|
-
// `release-lock-verb-and-gc-stuck-report`,
|
|
2130
|
+
// `release-lock-verb-and-gc-stuck-report`, spec
|
|
2124
2131
|
// `ledger-status-per-item-lock-refs` US #12/#13/#14): generalises the
|
|
2125
2132
|
// advancing-marker report from advancing-only to the unified per-item
|
|
2126
2133
|
// lock. The locks live on the ARBITER ref (`refs/dorfl/lock/*`),
|
|
@@ -2196,7 +2203,7 @@ export function buildProgram() {
|
|
|
2196
2203
|
// ALL are REPORTED here (never auto-deleted — no automatic sweep exists; a
|
|
2197
2204
|
// human clears a NAMED unified lock via `release-lock`).
|
|
2198
2205
|
//
|
|
2199
|
-
// SCOPED to the ATTENTION verdicts only (
|
|
2206
|
+
// SCOPED to the ATTENTION verdicts only (spec US#14/#21, ADR
|
|
2200
2207
|
// `ledger-status-on-per-item-lock-refs`: this surface is the STUCK /
|
|
2201
2208
|
// crash-orphaned lock, NOT every held one): a `kept-stuck` (terminal +
|
|
2202
2209
|
// stuck) or a `cleared-stale`-eligible (terminal + stale active = orphaned)
|
|
@@ -2223,7 +2230,7 @@ export function buildProgram() {
|
|
|
2223
2230
|
dryRun: flags.dryRun === true,
|
|
2224
2231
|
note: (message) => console.error(`>> ${message}`),
|
|
2225
2232
|
});
|
|
2226
|
-
// The ORPHAN-SIDECAR sweep (
|
|
2233
|
+
// The ORPHAN-SIDECAR sweep (spec
|
|
2227
2234
|
// `agentic-question-resolution-retire-disposition-vocabulary`, US #10) rides
|
|
2228
2235
|
// the SAME `--remote-branches` invocation the SCHEDULED CI lifecycle workflow
|
|
2229
2236
|
// runs (`dorfl gc --remote-branches --arbiter origin`) — so the reap of a
|
|
@@ -2421,7 +2428,7 @@ export function buildProgram() {
|
|
|
2421
2428
|
.option('--reset', 'DISCARD the kept work: delete the remote work/<slug> branch FIRST, then move to backlog so the next claim starts FRESH (guarded; a deliberate departure from the never-delete-the-remote-branch invariant). Never the default.')
|
|
2422
2429
|
.option('-m, --message <note>', 'append a dated handoff note to the item body for the next agent (append-only; applies to both default and --reset)')
|
|
2423
2430
|
.action(async (rawSlug, flags) => {
|
|
2424
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
2431
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
2425
2432
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
2426
2433
|
const cwd = flags.cwd ?? process.cwd();
|
|
2427
2434
|
// Route the requeue (default keep+continue / --reset discard / -m handoff)
|
|
@@ -2457,12 +2464,12 @@ export function buildProgram() {
|
|
|
2457
2464
|
: ' (kept the work branch; next claim continues from its tip)';
|
|
2458
2465
|
console.log(`Requeued '${slug}' to backlog for re-claiming.${how}`);
|
|
2459
2466
|
});
|
|
2460
|
-
// `promote [item]` (
|
|
2467
|
+
// `promote [item]` (spec `staging-pool-position-gate-and-trust-model`, tasks
|
|
2461
2468
|
// `pre-backlog-staging-folder-and-promote-step-a` /
|
|
2462
2469
|
// `pre-prd-staging-pool-split-and-untrusted-prd-placement`): the HUMAN/runner-
|
|
2463
2470
|
// owned verb that moves a STAGED item into its agent-eligible POOL — a task
|
|
2464
|
-
// `work/pre-backlog/<slug>.md → work/backlog/<slug>.md`, a
|
|
2465
|
-
// `work/
|
|
2471
|
+
// `work/pre-backlog/<slug>.md → work/backlog/<slug>.md`, a spec
|
|
2472
|
+
// `work/specs/proposed/<slug>.md → work/specs/ready/<slug>.md` — as a tree-less CAS on the
|
|
2466
2473
|
// arbiter, the SAME trust model + mechanism as `requeue`. The agent emits STAGED;
|
|
2467
2474
|
// only this verb (a human, or the runner) admits it to the pool. With NO argument
|
|
2468
2475
|
// it LISTS what is promotable (the "what is staged waiting for me?" discovery), so
|
|
@@ -2470,7 +2477,7 @@ export function buildProgram() {
|
|
|
2470
2477
|
program
|
|
2471
2478
|
.command('promote [item]')
|
|
2472
2479
|
.helpGroup(HEADLINE_GROUP)
|
|
2473
|
-
.description(
|
|
2480
|
+
.description(`Admit a STAGED item into its agent-eligible POOL (the runner/human side of the staging gate): a task \`work/pre-backlog/<slug>.md → work/backlog/<slug>.md\`, a spec \`${workFolderPrefix('specs-proposed')}<slug>.md → ${workFolderPrefix('specs-ready')}<slug>.md\`, published as a TREE-LESS compare-and-swap to the arbiter ref (EXACTLY like requeue/claim — it never stages/commits in the cwd tree). The agent only ever CREATES staged; this verb is the gate a human (or the runner) opens. Accepts \`task:<slug>\` / \`spec:<slug>\` / a bare \`<slug>\` (= task). With NO argument, LISTS every promotable item (the tasks in pre-backlog/ + the specs in specs/proposed/ on the arbiter) so you can see what is staged waiting for promotion. Idempotent: promoting an already-pooled slug is a clean no-op success.`)
|
|
2474
2481
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2475
2482
|
.option('--cwd <dir>', 'the repo/working clone whose arbiter remote the tree-less move is resolved FROM (default: cwd) — an ORIGIN SOURCE only; the move is published to the arbiter, never to this tree')
|
|
2476
2483
|
.option('--arbiter <remote>', 'the arbiter git remote the promotion is CAS-published to / the staging folders are listed from (default: origin)')
|
|
@@ -2489,7 +2496,7 @@ export function buildProgram() {
|
|
|
2489
2496
|
process.exit(1);
|
|
2490
2497
|
}
|
|
2491
2498
|
if (listed.items.length === 0) {
|
|
2492
|
-
console.log(`Nothing staged to promote on ${arbiter}/main (work/pre-backlog/ and
|
|
2499
|
+
console.log(`Nothing staged to promote on ${arbiter}/main (work/pre-backlog/ and ${workFolderPrefix('specs-proposed')} are empty).`);
|
|
2493
2500
|
return;
|
|
2494
2501
|
}
|
|
2495
2502
|
console.log('Staged, awaiting promotion (run `promote <item>`):');
|
|
@@ -2498,11 +2505,10 @@ export function buildProgram() {
|
|
|
2498
2505
|
}
|
|
2499
2506
|
return;
|
|
2500
2507
|
}
|
|
2501
|
-
// AN ITEM → promote it. `task:`/`spec:` are explicit
|
|
2502
|
-
//
|
|
2503
|
-
//
|
|
2504
|
-
//
|
|
2505
|
-
// no pool).
|
|
2508
|
+
// AN ITEM → promote it. `task:`/`spec:` are explicit; a bare slug defaults to
|
|
2509
|
+
// a task (mirrors `requeue`). An `obs:`/`observation:` prefix is rejected
|
|
2510
|
+
// (observations have no pool). A legacy `prd:` prefix is a DEAD namespace token
|
|
2511
|
+
// after the hard cutover — it resolves as a bare literal task slug, not a spec.
|
|
2506
2512
|
const parsed = parseSlugArg(rawItem);
|
|
2507
2513
|
if (parsed.explicit === 'observation') {
|
|
2508
2514
|
console.error(`error: promote takes a task or spec, not an observation ('${rawItem}'). Observations have no agent pool.`);
|
|
@@ -2529,7 +2535,7 @@ export function buildProgram() {
|
|
|
2529
2535
|
// the `work/advancing/<entry>.md` marker is gone and an advance hold is now just
|
|
2530
2536
|
// `action: advance` on the UNIFIED per-item lock, so `release-lock <item>` (below)
|
|
2531
2537
|
// is the SOLE named human release for ALL holds (implement/task/advance).
|
|
2532
|
-
// `release-lock <item>` (task `release-lock-verb-and-gc-stuck-report`,
|
|
2538
|
+
// `release-lock <item>` (task `release-lock-verb-and-gc-stuck-report`, spec
|
|
2533
2539
|
// `ledger-status-per-item-lock-refs` US #14): the HUMAN-invoked named release of
|
|
2534
2540
|
// a stuck/orphaned UNIFIED per-item lock (`refs/dorfl/lock/<entry>`) —
|
|
2535
2541
|
// the GENERALISATION of `release-advancing` from the advancing-only marker to
|
|
@@ -2545,7 +2551,7 @@ export function buildProgram() {
|
|
|
2545
2551
|
program
|
|
2546
2552
|
.command('release-lock <item>')
|
|
2547
2553
|
.helpGroup(HEADLINE_GROUP)
|
|
2548
|
-
.description('Clear a NAMED stuck/orphaned UNIFIED per-item lock (refs/dorfl/lock/<entry>) by DELETING the ref on the arbiter — the recovery verb for a lock the system orphaned (a crashed build/task/advance that left the hold behind). The generalisation of `release-advancing` from the advancing marker to the ONE lock per item. Same trust model as `requeue`: a HUMAN asserts the lock is dead by NAMING it; the tool never guesses liveness (the lock has NO heartbeat, so there is NO automatic sweep / age-based reaper anywhere). Accepts the same item forms as the lock API: `task:<slug>` / `
|
|
2554
|
+
.description('Clear a NAMED stuck/orphaned UNIFIED per-item lock (refs/dorfl/lock/<entry>) by DELETING the ref on the arbiter — the recovery verb for a lock the system orphaned (a crashed build/task/advance that left the hold behind). The generalisation of `release-advancing` from the advancing marker to the ONE lock per item. Same trust model as `requeue`: a HUMAN asserts the lock is dead by NAMING it; the tool never guesses liveness (the lock has NO heartbeat, so there is NO automatic sweep / age-based reaper anywhere). Accepts the same item forms as the lock API: `task:<slug>` / `spec:<slug>` / `obs:<slug>` / a bare `<slug>` (= task). Idempotent — re-running on an already-cleared lock is a clean exit-0 no-op (deleting the lock ref is “all locks released”, recoverable). NEVER `--force`. Discoverable via `gc --ledger` (it REPORTS every lingering lock, never deletes).')
|
|
2549
2555
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2550
2556
|
.option('--cwd <dir>', 'the repo/working clone whose arbiter remote the lock ref is DELETED on (default: cwd)')
|
|
2551
2557
|
.option('--arbiter <remote>', 'the arbiter git remote the lock ref is deleted on (default: origin)')
|
|
@@ -2574,7 +2580,7 @@ export function buildProgram() {
|
|
|
2574
2580
|
console.error(`error: ${result.message}`);
|
|
2575
2581
|
process.exit(1);
|
|
2576
2582
|
});
|
|
2577
|
-
// `drop <slug>` (
|
|
2583
|
+
// `drop <slug>` (spec `agentic-question-resolution-retire-disposition-vocabulary`,
|
|
2578
2584
|
// US #5/#11; task `direct-delete-question-cli-helper`): the DIRECT "throw it
|
|
2579
2585
|
// away" verb — `git rm` a source item AND its question sidecar (when present) in
|
|
2580
2586
|
// ONE revertible commit, the reason in the commit MESSAGE (git history is the
|
|
@@ -2588,7 +2594,7 @@ export function buildProgram() {
|
|
|
2588
2594
|
program
|
|
2589
2595
|
.command('drop <slug>')
|
|
2590
2596
|
.helpGroup(HEADLINE_GROUP)
|
|
2591
|
-
.description('DIRECTLY delete a source item + its question sidecar (when present) in ONE revertible commit — the "I just want to throw this away" path that does NOT round-trip through the decision engine or any agent. Resolves the source by its namespaced identity (`task:<slug>` / `
|
|
2597
|
+
.description('DIRECTLY delete a source item + its question sidecar (when present) in ONE revertible commit — the "I just want to throw this away" path that does NOT round-trip through the decision engine or any agent. Resolves the source by its namespaced identity (`task:<slug>` / `spec:<slug>` / `obs:<slug>` / a bare `<slug>` = task), `git rm`s the source AND its sidecar together, and records your --reason in the commit MESSAGE (git history is the archive). A single revertible commit, so a wrong delete is recoverable via `git revert`. DISTINCT from `remote rm` (the hub-mirror deleter). A LOCAL working-tree commit (like the apply rung); it does not touch the arbiter — push/integrate it as you normally would. If the named source is already gone it is a clean no-op (nothing to throw away).')
|
|
2592
2598
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2593
2599
|
.option('--cwd <dir>', 'the working clone the revertible delete commit is made in (default: cwd)')
|
|
2594
2600
|
.option('--reason <text>', 'why you are throwing this away — recorded in the commit MESSAGE (git history is the archive). Optional; recorded as "(no reason given)" when omitted.')
|
|
@@ -2658,7 +2664,7 @@ export function buildProgram() {
|
|
|
2658
2664
|
console.error(`>> ${resolved.message}`);
|
|
2659
2665
|
}
|
|
2660
2666
|
const config = resolved.config;
|
|
2661
|
-
// Resolve the PER-OUTCOME integration modes (
|
|
2667
|
+
// Resolve the PER-OUTCOME integration modes (spec US #9): `intake` decides
|
|
2662
2668
|
// the artifact TYPE at runtime, so a single --merge/--propose can't express
|
|
2663
2669
|
// a type-conditional policy. The granular flags override the aggregate; an
|
|
2664
2670
|
// UNSET type falls back to the per-repo/global `integration` (the SAME chain
|
|
@@ -2734,17 +2740,17 @@ export function buildProgram() {
|
|
|
2734
2740
|
}
|
|
2735
2741
|
process.exit(result.exitCode);
|
|
2736
2742
|
});
|
|
2737
|
-
// The CI CLOSE-JOB driver (
|
|
2743
|
+
// The CI CLOSE-JOB driver (spec `runner-in-ci`, capability E; task
|
|
2738
2744
|
// `install-ci-close-job-workflow`). The thin JOB the emitted close-job workflow
|
|
2739
2745
|
// invokes on a merge to main: resolve which source issue(s) the landed work
|
|
2740
|
-
// closes (resolveClosingIssue), run the "
|
|
2746
|
+
// closes (resolveClosingIssue), run the "spec complete?" query for the spec case
|
|
2741
2747
|
// (prd-complete-query, done), and close via the IssueProvider seam — all
|
|
2742
2748
|
// UNCHANGED engine pieces, CONSUMED not re-built (the Out-of-Scope fence). CI
|
|
2743
2749
|
// owns ONLY the job + trigger. Local-runnable too (a manual catch-up close).
|
|
2744
2750
|
program
|
|
2745
2751
|
.command('close-merged-issues')
|
|
2746
2752
|
.helpGroup(ADVANCED_GROUP)
|
|
2747
|
-
.description('Close source issues whose work has landed on main (CI capability E,
|
|
2753
|
+
.description('Close source issues whose work has landed on main (CI capability E, spec runner-in-ci). Resolves each closing issue from the work/ tree (resolveClosingIssue: a lone task closes its own `issue:`; a fanned task reaches the number via `task.spec: → spec issue:`), runs the existing "spec complete?" query for the spec case (closes ONLY when ALL its spec:<slug> tasks are in work/done/), and closes via the IssueProvider seam (atomic comment+close; NO direct gh). Re-implements NONE of the resolution/query/close — it WIRES them. Invoked by the emitted close-job workflow on a merge to main; DEGRADES (never crashes) on a missing/unauthenticated gh.')
|
|
2748
2754
|
.option('--cwd <dir>', 'the repo working dir whose work/ tree to scan (default: cwd)')
|
|
2749
2755
|
.option('--gh-bin <bin>', 'the gh CLI binary (default: gh on PATH)')
|
|
2750
2756
|
.option('--json', 'output the raw result as JSON')
|