dorfl 0.1.1 → 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 +76 -76
- 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 +20 -20
- 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 +14 -13
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +12 -24
- 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/prompt.d.ts +16 -19
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +17 -19
- package/dist/prompt.js.map +1 -1
- 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 +4 -4
- 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 +88 -86
- 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 +83 -83
- 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 +47 -47
- package/src/drop-source.ts +2 -2
- package/src/env-config.ts +8 -8
- package/src/format.ts +3 -3
- package/src/frontmatter.ts +23 -33
- 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/prompt.ts +20 -25
- 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 +5 -5
- 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 +123 -121
- 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
|
|
@@ -498,7 +498,7 @@ function printPrdToSpecReport(result) {
|
|
|
498
498
|
return;
|
|
499
499
|
}
|
|
500
500
|
if (result.leaks.length === 0) {
|
|
501
|
-
console.log('Leak scan: GREEN (no surviving
|
|
501
|
+
console.log('Leak scan: GREEN (no surviving spec data ref).');
|
|
502
502
|
}
|
|
503
503
|
else {
|
|
504
504
|
console.error(`Leak scan: FAILED (${result.leaks.length} leak(s)):`);
|
|
@@ -513,11 +513,12 @@ function printLeak(leak) {
|
|
|
513
513
|
/**
|
|
514
514
|
* Resolve a task-only command's slug argument through the §3a namespace guard
|
|
515
515
|
* (`resolveTaskOnlyArg`): accept bare (= task) + `task:` (explicit alias),
|
|
516
|
-
* REJECT `spec:` with a clear "operates on tasks, not specs" error
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
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.)
|
|
521
522
|
*
|
|
522
523
|
* `do` is the ONE command that spans both namespaces; it consumes the full
|
|
523
524
|
* `resolveSlug` (with the cross-namespace collision check) in the `do-in-place`
|
|
@@ -595,10 +596,10 @@ function buildInteractiveLauncher(flags, configPath, repoPath) {
|
|
|
595
596
|
* switching to its `work/<slug>` branch WITHOUT claiming). The runtime
|
|
596
597
|
* difference is exactly the `resume` flag — `resume` forces it on (its only mode
|
|
597
598
|
* is to re-engage), while `start` honours the (now hidden) `--resume` alias.
|
|
598
|
-
* Both are task-only (§3a: accept bare + `task:`, reject `
|
|
599
|
+
* Both are task-only (§3a: accept bare + `task:`, reject `spec:`).
|
|
599
600
|
*/
|
|
600
601
|
async function runStartAction(rawSlug, flags, resume) {
|
|
601
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
602
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
602
603
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
603
604
|
const cwd = process.cwd();
|
|
604
605
|
// `resume --isolated <slug>`: re-engage the slug's RETAINED job worktree (the
|
|
@@ -914,7 +915,7 @@ export function buildProgram() {
|
|
|
914
915
|
.option('--dry-run', 'show the intended push without mutating the arbiter')
|
|
915
916
|
.option('--ignore-not-ready', 'override the readiness guard: claim despite an unmet blockedBy, and silence the needsAnswers warning (loud, never default)')
|
|
916
917
|
.action(async (rawSlug, flags) => {
|
|
917
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
918
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
918
919
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
919
920
|
// Wrap ONLY this CLI surface's `performClaim` call with the spinner
|
|
920
921
|
// helper (task `claim-cas-spinner`): the push can take seconds, so the
|
|
@@ -1022,7 +1023,7 @@ export function buildProgram() {
|
|
|
1022
1023
|
const remote = flags.remote !== undefined && flags.remote.trim() !== ''
|
|
1023
1024
|
? flags.remote
|
|
1024
1025
|
: undefined;
|
|
1025
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1026
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1026
1027
|
const theSlug = resolveTaskOnlySlug(rawSlug);
|
|
1027
1028
|
const configPath = flags.config ?? defaultConfigPath();
|
|
1028
1029
|
const { dir: configuredRoot, config } = loadHumanWorktreesDir(configPath);
|
|
@@ -1066,10 +1067,10 @@ export function buildProgram() {
|
|
|
1066
1067
|
program
|
|
1067
1068
|
.command('prompt')
|
|
1068
1069
|
.helpGroup(ADVANCED_GROUP)
|
|
1069
|
-
.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.")
|
|
1070
1071
|
.argument('[slug]', 'the slug to render (inferred from a work/<slug> branch if omitted)')
|
|
1071
1072
|
.action((rawSlug) => {
|
|
1072
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1073
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1073
1074
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
1074
1075
|
// Resolve the `promptGuidance` NUDGE namespace through the SAME chain the
|
|
1075
1076
|
// gate family uses (env > per-repo > global > default), so e.g. a
|
|
@@ -1112,7 +1113,7 @@ export function buildProgram() {
|
|
|
1112
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')
|
|
1113
1114
|
.option('--merge-retries <n>', 'cross-job merge-serialiser CAS-retry cap (see `run --help`); resolved flag > env > per-repo > global > default 1000.')
|
|
1114
1115
|
.action(async (rawSlug, flags) => {
|
|
1115
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1116
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1116
1117
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
1117
1118
|
const cwd = process.cwd();
|
|
1118
1119
|
const { global, override } = loadGlobalAndOverride(flags.config);
|
|
@@ -1172,7 +1173,7 @@ export function buildProgram() {
|
|
|
1172
1173
|
// `--fresh-worktree-gate`/`--no-fresh-worktree-gate` rides the SAME chain.
|
|
1173
1174
|
...freshWorktreeGateFlagOverrides(flags),
|
|
1174
1175
|
// `--merge-retries <n>` rides the SAME chain: the cross-job merge-serialiser
|
|
1175
|
-
// CAS-retry cap (
|
|
1176
|
+
// CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5
|
|
1176
1177
|
// / Applied Answer q1 (a)).
|
|
1177
1178
|
...mergeRetriesFlagOverrides(flags),
|
|
1178
1179
|
// `--no-pr` (the PR-INTENT axis) rides the SAME chain.
|
|
@@ -1212,7 +1213,7 @@ export function buildProgram() {
|
|
|
1212
1213
|
// a single-job path, so the resolved flag is passed UNCONDITIONALLY (no
|
|
1213
1214
|
// fleet downgrade).
|
|
1214
1215
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
1215
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
1216
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
1216
1217
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — the resolved
|
|
1217
1218
|
// per-repo value reaches the merge loop via `performComplete`→
|
|
1218
1219
|
// `performIntegration`.
|
|
@@ -1243,13 +1244,13 @@ export function buildProgram() {
|
|
|
1243
1244
|
program
|
|
1244
1245
|
.command('do')
|
|
1245
1246
|
.helpGroup(HEADLINE_GROUP)
|
|
1246
|
-
.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.')
|
|
1247
1248
|
// EXTENSIBLE argument grammar (the three do-* tasks grow this one block):
|
|
1248
1249
|
// `do-autopick` widens the single optional positional into a VARIADIC one so
|
|
1249
1250
|
// `do` (zero args = auto-pick), `do <a> <b> …` (named, in sequence), and
|
|
1250
1251
|
// `do <slug>` (exactly one) all share the one command. `-n <x>` is the count
|
|
1251
1252
|
// for the auto-pick form. `do` stays SEQUENTIAL (parallelism is `run`).
|
|
1252
|
-
.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.')
|
|
1253
1254
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
1254
1255
|
.option('--arbiter <remote>', 'name of the arbiter git remote (default: per-repo/global defaultArbiter)')
|
|
1255
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.')
|
|
@@ -1258,7 +1259,7 @@ export function buildProgram() {
|
|
|
1258
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).")
|
|
1259
1260
|
.option('--merge', 'integrate in merge mode this invocation (mutually exclusive with --propose; overrides config)')
|
|
1260
1261
|
.option('--propose', 'integrate in propose mode this invocation (default; mutually exclusive with --merge; overrides config)')
|
|
1261
|
-
.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.')
|
|
1262
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.')
|
|
1263
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.')
|
|
1264
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.')
|
|
@@ -1272,9 +1273,9 @@ export function buildProgram() {
|
|
|
1272
1273
|
.option('--no-review', 'do NOT run Gate 2 this invocation (overrides config)')
|
|
1273
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.')
|
|
1274
1275
|
.option('--review-max-rounds <n>', 'bound the revise/review loop; on exhaustion force needs-attention (default 2)')
|
|
1275
|
-
.option('--tasker-loop', 'run the tasker IMPROVER loop on `do
|
|
1276
|
-
.option('--no-tasker-loop', 'skip the tasker improver loop on `do
|
|
1277
|
-
.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)')
|
|
1278
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.')
|
|
1279
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.')
|
|
1280
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")
|
|
@@ -1411,7 +1412,7 @@ export function buildProgram() {
|
|
|
1411
1412
|
// Host-only runner IDENTITY — scopes git/provider ops only (not the
|
|
1412
1413
|
// agent launch); absent ⇒ ambient.
|
|
1413
1414
|
identity: remoteConfig.identity,
|
|
1414
|
-
// `do --remote
|
|
1415
|
+
// `do --remote spec:<slug>` tasking-gate policy (task-build path ignores it).
|
|
1415
1416
|
autoTask: remoteConfig.autoTask,
|
|
1416
1417
|
// The resolved `promptGuidance` nudge — threaded into the remote worker
|
|
1417
1418
|
// prompt (runRemotePipeline → buildAgentPrompt), mirroring in-place `do`.
|
|
@@ -1419,7 +1420,7 @@ export function buildProgram() {
|
|
|
1419
1420
|
integration: remoteConfig.integration,
|
|
1420
1421
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule.
|
|
1421
1422
|
explicitMerge: flagMode === 'merge',
|
|
1422
|
-
// Per-TRANSITION TASKING override (the `do --remote
|
|
1423
|
+
// Per-TRANSITION TASKING override (the `do --remote spec:` tasking path).
|
|
1423
1424
|
taskingIntegration: remoteConfig.taskingIntegration,
|
|
1424
1425
|
// TASK-PLACEMENT: the configured default + the EXPLICIT operator override
|
|
1425
1426
|
// (`--tasks-land-in`), the top of the placement precedence — mirrors
|
|
@@ -1431,7 +1432,7 @@ export function buildProgram() {
|
|
|
1431
1432
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1432
1433
|
freshWorktreeGate: remoteConfig.freshWorktreeGate,
|
|
1433
1434
|
// Cross-job merge-serialiser CAS-retry cap (resolved through the per-repo
|
|
1434
|
-
// chain on the arbiter-side `.dorfl.json` too) —
|
|
1435
|
+
// chain on the arbiter-side `.dorfl.json` too) — spec
|
|
1435
1436
|
// `land-time-reverify-and-parallel-merge-ceiling` Story 5.
|
|
1436
1437
|
mergeRetries: remoteConfig.mergeRetries,
|
|
1437
1438
|
noPR: remoteConfig.noPR,
|
|
@@ -1448,7 +1449,7 @@ export function buildProgram() {
|
|
|
1448
1449
|
agentCmd: remoteConfig.agentCmd,
|
|
1449
1450
|
})
|
|
1450
1451
|
: undefined,
|
|
1451
|
-
// The tasker IMPROVER loop on the `do --remote
|
|
1452
|
+
// The tasker IMPROVER loop on the `do --remote spec:` path is ON by default
|
|
1452
1453
|
// (auto-tasking has no `verify` floor, so the loop is the task path's
|
|
1453
1454
|
// quality engine). `--tasker-loop`/`--no-tasker-loop` gates wiring the seam;
|
|
1454
1455
|
// `taskerLoopMax`/`taskerLoopModel` resolve per-repo (flag > env > per-repo
|
|
@@ -1461,7 +1462,7 @@ export function buildProgram() {
|
|
|
1461
1462
|
: undefined,
|
|
1462
1463
|
taskerLoopMax: remoteConfig.taskerLoopMax,
|
|
1463
1464
|
taskerLoopModel: remoteConfig.taskerLoopModel,
|
|
1464
|
-
// The task-SET ACCEPTANCE GATE on the `do --remote
|
|
1465
|
+
// The task-SET ACCEPTANCE GATE on the `do --remote spec:` path too.
|
|
1465
1466
|
taskReviewGate: remoteConfig.review
|
|
1466
1467
|
? harnessTaskAcceptanceGate({
|
|
1467
1468
|
harness: remoteHarness,
|
|
@@ -1565,7 +1566,7 @@ export function buildProgram() {
|
|
|
1565
1566
|
// ops (claim, push, integrate, `gh`) — NEVER the agent launch. Absent ⇒
|
|
1566
1567
|
// ambient (today's behaviour). Mapped Config → DoOptions like model/agentCmd.
|
|
1567
1568
|
identity: config.identity,
|
|
1568
|
-
// `do
|
|
1569
|
+
// `do spec:<slug>` tasking-gate policy (the task-build path ignores it).
|
|
1569
1570
|
autoTask: config.autoTask,
|
|
1570
1571
|
// The resolved `promptGuidance` NUDGE namespace (e.g. `testFirst`),
|
|
1571
1572
|
// threaded into the worker prompt by performDo → buildAgentPrompt so a
|
|
@@ -1578,11 +1579,11 @@ export function buildProgram() {
|
|
|
1578
1579
|
// typed `--merge` (`flagMode`), never when `merge` came from config — so an
|
|
1579
1580
|
// untrusted-origin task still forces propose under a config `merge`.
|
|
1580
1581
|
explicitMerge: flagMode === 'merge',
|
|
1581
|
-
// Per-TRANSITION TASKING override: the `do
|
|
1582
|
+
// Per-TRANSITION TASKING override: the `do spec:` tasking path threads
|
|
1582
1583
|
// `taskingIntegration ?? integration`; the task-build path stays on
|
|
1583
1584
|
// `integration`. Unset ⇒ tasking falls back to `integration` (today's behaviour).
|
|
1584
1585
|
taskingIntegration: config.taskingIntegration,
|
|
1585
|
-
// TASK-PLACEMENT (`do
|
|
1586
|
+
// TASK-PLACEMENT (`do spec:` tasking output): the configured default rung +
|
|
1586
1587
|
// the EXPLICIT operator override `--tasks-land-in` (top of the precedence).
|
|
1587
1588
|
// `explicitTasksLandIn` is set ONLY when the flag was typed (mirrors
|
|
1588
1589
|
// `explicitMerge`), so an untrusted-origin staging force still wins under a
|
|
@@ -1595,7 +1596,7 @@ export function buildProgram() {
|
|
|
1595
1596
|
verify: config.verify,
|
|
1596
1597
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1597
1598
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
1598
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
1599
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
1599
1600
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — resolved per-repo
|
|
1600
1601
|
// and threaded to `performComplete`→`performIntegration`.
|
|
1601
1602
|
mergeRetries: config.mergeRetries,
|
|
@@ -1619,7 +1620,7 @@ export function buildProgram() {
|
|
|
1619
1620
|
reviewGate: config.review
|
|
1620
1621
|
? harnessReviewGate({ harness, agentCmd: config.agentCmd })
|
|
1621
1622
|
: undefined,
|
|
1622
|
-
// The tasker IMPROVER loop on the `do
|
|
1623
|
+
// The tasker IMPROVER loop on the `do spec:` tasking path is ON by default
|
|
1623
1624
|
// (auto-tasking has no `verify` floor — the loop is the task path's quality
|
|
1624
1625
|
// engine). `--tasker-loop`/`--no-tasker-loop` gates wiring the seam;
|
|
1625
1626
|
// `taskerLoopMax`/`taskerLoopModel` resolve per-repo (flag > env > per-repo
|
|
@@ -1646,7 +1647,7 @@ export function buildProgram() {
|
|
|
1646
1647
|
note: (message) => console.error(`>> ${message}`),
|
|
1647
1648
|
noteBlock: (message) => console.error(message),
|
|
1648
1649
|
};
|
|
1649
|
-
// `--allow-backlog` is EXPLICIT-SINGLE-TASK-ONLY (
|
|
1650
|
+
// `--allow-backlog` is EXPLICIT-SINGLE-TASK-ONLY (spec
|
|
1650
1651
|
// `do-allow-backlog-drive-staged-tasks-without-promotion`, decision 4): it
|
|
1651
1652
|
// drives ONE named staged task in place. It must NOT combine with the
|
|
1652
1653
|
// AUTO-PICK (zero-args / -n) or MULTI-ITEM forms — those select FROM the
|
|
@@ -1700,33 +1701,33 @@ export function buildProgram() {
|
|
|
1700
1701
|
process.exit(result.exitCode);
|
|
1701
1702
|
});
|
|
1702
1703
|
// `advance` — the SIBLING top-level verb (NOT a `do` subcommand; `do`
|
|
1703
|
-
// subcommands + a standalone `task` verb are REJECTED in
|
|
1704
|
+
// subcommands + a standalone `task` verb are REJECTED in spec `advance-loop`).
|
|
1704
1705
|
// It reuses the SAME shared `prefix:arg` resolver `do` uses, EXTENDED with the
|
|
1705
1706
|
// `obs:` namespace, and wires the classify → lock → execute SKELETON: classify
|
|
1706
1707
|
// the rung (read-only, no model, no lock), take the `advancing` CAS borrow, then
|
|
1707
|
-
// dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do
|
|
1708
|
+
// dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do spec:` (never a
|
|
1708
1709
|
// duplicate), surface/apply/triage dispatch to a named executor seam later
|
|
1709
1710
|
// tasks fill. The DRIVERS (one-shot/loop) + `-n` + per-action gates and the
|
|
1710
1711
|
// rung BODIES are LATER tasks; the bare eligible-SET form errors clearly here.
|
|
1711
1712
|
program
|
|
1712
1713
|
.command('advance')
|
|
1713
1714
|
.helpGroup(HEADLINE_GROUP)
|
|
1714
|
-
.description('Advance work/ item(s) one lifecycle rung toward ready/built (
|
|
1715
|
-
.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.')
|
|
1716
1717
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
1717
1718
|
.option('--arbiter <remote>', 'name of the arbiter git remote (default: per-repo/global defaultArbiter)')
|
|
1718
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.')
|
|
1719
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.")
|
|
1720
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.')
|
|
1721
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`).')
|
|
1722
|
-
.option('--surface-blockers', 'the declared-blocked-work gate (the orthogonal peer of --observation-triage): render a task/
|
|
1723
|
-
.option('--no-surface-blockers', 'leave a needsAnswers:true task/
|
|
1724
|
-
.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.')
|
|
1725
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)')
|
|
1726
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.')
|
|
1727
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.')
|
|
1728
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).')
|
|
1729
|
-
.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.')
|
|
1730
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.")
|
|
1731
1732
|
.action(async (rawSlugs, flags) => {
|
|
1732
1733
|
// Variadic grammar (mirrors `do`): zero args = AUTO-PICK; one = the single
|
|
@@ -1842,7 +1843,7 @@ export function buildProgram() {
|
|
|
1842
1843
|
integration: remoteConfig.integration,
|
|
1843
1844
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule.
|
|
1844
1845
|
explicitMerge: flagMode === 'merge',
|
|
1845
|
-
// Per-TRANSITION TASKING override (the isolated `do --remote
|
|
1846
|
+
// Per-TRANSITION TASKING override (the isolated `do --remote spec:` path).
|
|
1846
1847
|
taskingIntegration: remoteConfig.taskingIntegration,
|
|
1847
1848
|
// TASK-PLACEMENT: configured default + EXPLICIT `--tasks-land-in` override
|
|
1848
1849
|
// (set only when typed, mirroring `explicitMerge`).
|
|
@@ -1852,7 +1853,7 @@ export function buildProgram() {
|
|
|
1852
1853
|
verify: remoteConfig.verify,
|
|
1853
1854
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1854
1855
|
freshWorktreeGate: remoteConfig.freshWorktreeGate,
|
|
1855
|
-
// Cross-job merge-serialiser CAS-retry cap —
|
|
1856
|
+
// Cross-job merge-serialiser CAS-retry cap — spec
|
|
1856
1857
|
// `land-time-reverify-and-parallel-merge-ceiling` Story 5.
|
|
1857
1858
|
mergeRetries: remoteConfig.mergeRetries,
|
|
1858
1859
|
noPR: remoteConfig.noPR,
|
|
@@ -1980,7 +1981,7 @@ export function buildProgram() {
|
|
|
1980
1981
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule (a
|
|
1981
1982
|
// bare `advance` auto-pick passes no flag ⇒ unset ⇒ untrusted forces propose).
|
|
1982
1983
|
explicitMerge: flagMode === 'merge',
|
|
1983
|
-
// Per-TRANSITION TASKING override (the `do
|
|
1984
|
+
// Per-TRANSITION TASKING override (the `do spec:` tasking path threads
|
|
1984
1985
|
// `taskingIntegration ?? integration`; the build path stays on `integration`).
|
|
1985
1986
|
taskingIntegration: config.taskingIntegration,
|
|
1986
1987
|
// TASK-PLACEMENT: configured default + EXPLICIT `--tasks-land-in` override
|
|
@@ -1991,7 +1992,7 @@ export function buildProgram() {
|
|
|
1991
1992
|
verify: config.verify,
|
|
1992
1993
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
1993
1994
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
1994
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
1995
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
1995
1996
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)).
|
|
1996
1997
|
mergeRetries: config.mergeRetries,
|
|
1997
1998
|
noPR: config.noPR,
|
|
@@ -2118,7 +2119,7 @@ export function buildProgram() {
|
|
|
2118
2119
|
.action(async (flags) => {
|
|
2119
2120
|
const config = resolveGlobalConfig(loadConfig(flags.config), {});
|
|
2120
2121
|
const workspacesDir = flags.workspace ?? config.workspacesDir;
|
|
2121
|
-
// The `gc`-STYLE ledger SWEEP (
|
|
2122
|
+
// The `gc`-STYLE ledger SWEEP (spec `ledger-integrity` story 3): a SEPARATE
|
|
2122
2123
|
// surface from the worktree reaper below — it REPORTS one-slug-one-folder
|
|
2123
2124
|
// violations in a repo's `work/` lifecycle ledger and NEVER deletes (a human
|
|
2124
2125
|
// resolves each). Distinct `work/`: the ledger, not the execution substrate.
|
|
@@ -2126,7 +2127,7 @@ export function buildProgram() {
|
|
|
2126
2127
|
const repoPath = typeof flags.ledger === 'string' ? flags.ledger : process.cwd();
|
|
2127
2128
|
const result = sweepLedgerDuplicates(repoPath);
|
|
2128
2129
|
// The UNIFIED-LOCK stuck/orphaned-lock REPORT (task
|
|
2129
|
-
// `release-lock-verb-and-gc-stuck-report`,
|
|
2130
|
+
// `release-lock-verb-and-gc-stuck-report`, spec
|
|
2130
2131
|
// `ledger-status-per-item-lock-refs` US #12/#13/#14): generalises the
|
|
2131
2132
|
// advancing-marker report from advancing-only to the unified per-item
|
|
2132
2133
|
// lock. The locks live on the ARBITER ref (`refs/dorfl/lock/*`),
|
|
@@ -2202,7 +2203,7 @@ export function buildProgram() {
|
|
|
2202
2203
|
// ALL are REPORTED here (never auto-deleted — no automatic sweep exists; a
|
|
2203
2204
|
// human clears a NAMED unified lock via `release-lock`).
|
|
2204
2205
|
//
|
|
2205
|
-
// SCOPED to the ATTENTION verdicts only (
|
|
2206
|
+
// SCOPED to the ATTENTION verdicts only (spec US#14/#21, ADR
|
|
2206
2207
|
// `ledger-status-on-per-item-lock-refs`: this surface is the STUCK /
|
|
2207
2208
|
// crash-orphaned lock, NOT every held one): a `kept-stuck` (terminal +
|
|
2208
2209
|
// stuck) or a `cleared-stale`-eligible (terminal + stale active = orphaned)
|
|
@@ -2229,7 +2230,7 @@ export function buildProgram() {
|
|
|
2229
2230
|
dryRun: flags.dryRun === true,
|
|
2230
2231
|
note: (message) => console.error(`>> ${message}`),
|
|
2231
2232
|
});
|
|
2232
|
-
// The ORPHAN-SIDECAR sweep (
|
|
2233
|
+
// The ORPHAN-SIDECAR sweep (spec
|
|
2233
2234
|
// `agentic-question-resolution-retire-disposition-vocabulary`, US #10) rides
|
|
2234
2235
|
// the SAME `--remote-branches` invocation the SCHEDULED CI lifecycle workflow
|
|
2235
2236
|
// runs (`dorfl gc --remote-branches --arbiter origin`) — so the reap of a
|
|
@@ -2427,7 +2428,7 @@ export function buildProgram() {
|
|
|
2427
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.')
|
|
2428
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)')
|
|
2429
2430
|
.action(async (rawSlug, flags) => {
|
|
2430
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
2431
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
2431
2432
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
2432
2433
|
const cwd = flags.cwd ?? process.cwd();
|
|
2433
2434
|
// Route the requeue (default keep+continue / --reset discard / -m handoff)
|
|
@@ -2463,12 +2464,12 @@ export function buildProgram() {
|
|
|
2463
2464
|
: ' (kept the work branch; next claim continues from its tip)';
|
|
2464
2465
|
console.log(`Requeued '${slug}' to backlog for re-claiming.${how}`);
|
|
2465
2466
|
});
|
|
2466
|
-
// `promote [item]` (
|
|
2467
|
+
// `promote [item]` (spec `staging-pool-position-gate-and-trust-model`, tasks
|
|
2467
2468
|
// `pre-backlog-staging-folder-and-promote-step-a` /
|
|
2468
2469
|
// `pre-prd-staging-pool-split-and-untrusted-prd-placement`): the HUMAN/runner-
|
|
2469
2470
|
// owned verb that moves a STAGED item into its agent-eligible POOL — a task
|
|
2470
|
-
// `work/pre-backlog/<slug>.md → work/backlog/<slug>.md`, a
|
|
2471
|
-
// `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
|
|
2472
2473
|
// arbiter, the SAME trust model + mechanism as `requeue`. The agent emits STAGED;
|
|
2473
2474
|
// only this verb (a human, or the runner) admits it to the pool. With NO argument
|
|
2474
2475
|
// it LISTS what is promotable (the "what is staged waiting for me?" discovery), so
|
|
@@ -2476,7 +2477,7 @@ export function buildProgram() {
|
|
|
2476
2477
|
program
|
|
2477
2478
|
.command('promote [item]')
|
|
2478
2479
|
.helpGroup(HEADLINE_GROUP)
|
|
2479
|
-
.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.`)
|
|
2480
2481
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2481
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')
|
|
2482
2483
|
.option('--arbiter <remote>', 'the arbiter git remote the promotion is CAS-published to / the staging folders are listed from (default: origin)')
|
|
@@ -2495,7 +2496,7 @@ export function buildProgram() {
|
|
|
2495
2496
|
process.exit(1);
|
|
2496
2497
|
}
|
|
2497
2498
|
if (listed.items.length === 0) {
|
|
2498
|
-
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).`);
|
|
2499
2500
|
return;
|
|
2500
2501
|
}
|
|
2501
2502
|
console.log('Staged, awaiting promotion (run `promote <item>`):');
|
|
@@ -2504,11 +2505,10 @@ export function buildProgram() {
|
|
|
2504
2505
|
}
|
|
2505
2506
|
return;
|
|
2506
2507
|
}
|
|
2507
|
-
// AN ITEM → promote it. `task:`/`spec:` are explicit
|
|
2508
|
-
//
|
|
2509
|
-
//
|
|
2510
|
-
//
|
|
2511
|
-
// 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.
|
|
2512
2512
|
const parsed = parseSlugArg(rawItem);
|
|
2513
2513
|
if (parsed.explicit === 'observation') {
|
|
2514
2514
|
console.error(`error: promote takes a task or spec, not an observation ('${rawItem}'). Observations have no agent pool.`);
|
|
@@ -2535,7 +2535,7 @@ export function buildProgram() {
|
|
|
2535
2535
|
// the `work/advancing/<entry>.md` marker is gone and an advance hold is now just
|
|
2536
2536
|
// `action: advance` on the UNIFIED per-item lock, so `release-lock <item>` (below)
|
|
2537
2537
|
// is the SOLE named human release for ALL holds (implement/task/advance).
|
|
2538
|
-
// `release-lock <item>` (task `release-lock-verb-and-gc-stuck-report`,
|
|
2538
|
+
// `release-lock <item>` (task `release-lock-verb-and-gc-stuck-report`, spec
|
|
2539
2539
|
// `ledger-status-per-item-lock-refs` US #14): the HUMAN-invoked named release of
|
|
2540
2540
|
// a stuck/orphaned UNIFIED per-item lock (`refs/dorfl/lock/<entry>`) —
|
|
2541
2541
|
// the GENERALISATION of `release-advancing` from the advancing-only marker to
|
|
@@ -2551,7 +2551,7 @@ export function buildProgram() {
|
|
|
2551
2551
|
program
|
|
2552
2552
|
.command('release-lock <item>')
|
|
2553
2553
|
.helpGroup(HEADLINE_GROUP)
|
|
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>` / `
|
|
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).')
|
|
2555
2555
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2556
2556
|
.option('--cwd <dir>', 'the repo/working clone whose arbiter remote the lock ref is DELETED on (default: cwd)')
|
|
2557
2557
|
.option('--arbiter <remote>', 'the arbiter git remote the lock ref is deleted on (default: origin)')
|
|
@@ -2580,7 +2580,7 @@ export function buildProgram() {
|
|
|
2580
2580
|
console.error(`error: ${result.message}`);
|
|
2581
2581
|
process.exit(1);
|
|
2582
2582
|
});
|
|
2583
|
-
// `drop <slug>` (
|
|
2583
|
+
// `drop <slug>` (spec `agentic-question-resolution-retire-disposition-vocabulary`,
|
|
2584
2584
|
// US #5/#11; task `direct-delete-question-cli-helper`): the DIRECT "throw it
|
|
2585
2585
|
// away" verb — `git rm` a source item AND its question sidecar (when present) in
|
|
2586
2586
|
// ONE revertible commit, the reason in the commit MESSAGE (git history is the
|
|
@@ -2594,7 +2594,7 @@ export function buildProgram() {
|
|
|
2594
2594
|
program
|
|
2595
2595
|
.command('drop <slug>')
|
|
2596
2596
|
.helpGroup(HEADLINE_GROUP)
|
|
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>` / `
|
|
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).')
|
|
2598
2598
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2599
2599
|
.option('--cwd <dir>', 'the working clone the revertible delete commit is made in (default: cwd)')
|
|
2600
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.')
|
|
@@ -2664,7 +2664,7 @@ export function buildProgram() {
|
|
|
2664
2664
|
console.error(`>> ${resolved.message}`);
|
|
2665
2665
|
}
|
|
2666
2666
|
const config = resolved.config;
|
|
2667
|
-
// Resolve the PER-OUTCOME integration modes (
|
|
2667
|
+
// Resolve the PER-OUTCOME integration modes (spec US #9): `intake` decides
|
|
2668
2668
|
// the artifact TYPE at runtime, so a single --merge/--propose can't express
|
|
2669
2669
|
// a type-conditional policy. The granular flags override the aggregate; an
|
|
2670
2670
|
// UNSET type falls back to the per-repo/global `integration` (the SAME chain
|
|
@@ -2740,17 +2740,17 @@ export function buildProgram() {
|
|
|
2740
2740
|
}
|
|
2741
2741
|
process.exit(result.exitCode);
|
|
2742
2742
|
});
|
|
2743
|
-
// The CI CLOSE-JOB driver (
|
|
2743
|
+
// The CI CLOSE-JOB driver (spec `runner-in-ci`, capability E; task
|
|
2744
2744
|
// `install-ci-close-job-workflow`). The thin JOB the emitted close-job workflow
|
|
2745
2745
|
// invokes on a merge to main: resolve which source issue(s) the landed work
|
|
2746
|
-
// closes (resolveClosingIssue), run the "
|
|
2746
|
+
// closes (resolveClosingIssue), run the "spec complete?" query for the spec case
|
|
2747
2747
|
// (prd-complete-query, done), and close via the IssueProvider seam — all
|
|
2748
2748
|
// UNCHANGED engine pieces, CONSUMED not re-built (the Out-of-Scope fence). CI
|
|
2749
2749
|
// owns ONLY the job + trigger. Local-runnable too (a manual catch-up close).
|
|
2750
2750
|
program
|
|
2751
2751
|
.command('close-merged-issues')
|
|
2752
2752
|
.helpGroup(ADVANCED_GROUP)
|
|
2753
|
-
.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.')
|
|
2754
2754
|
.option('--cwd <dir>', 'the repo working dir whose work/ tree to scan (default: cwd)')
|
|
2755
2755
|
.option('--gh-bin <bin>', 'the gh CLI binary (default: gh on PATH)')
|
|
2756
2756
|
.option('--json', 'output the raw result as JSON')
|