version: '3'

vars:
  DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'

tasks:
  readiness:
    desc: "Report whether story vBRIEFs are ready for concurrent swarm allocation"
    dir: '{{.USER_WORKING_DIR}}'
    deps: [":engine:_ts-build"]
    env:
      PYTHONUTF8: "1"
    cmds:
      # Keep CLI_ARGS bare; go-task shell-escapes pass-through args and quoting breaks globs/multi-arg calls.
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'swarm-readiness {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'

  # swarm:pre-dispatch -- implement-leaf pre-dispatch gate (#3228 / #3143).
  # Before starting a peer implement leaf on a unit, if a non-terminal attempt
  # already exists → exit 1 DENY_DUPLICATE_ACTIVE and do not spawn.
  # begin (default) begins an attempt on allow; complete/cancel terminalise.
  # Takeover = cancel prior attempt, then pre-dispatch begin again.
  # Exit: 0 allow / 1 active deny or gate block / 2 config.
  # Skill citation: skills/deft-directive-swarm/references/core-phase-4.md
  pre-dispatch:
    desc: "Pre-dispatch gate for implement leaves: DENY_DUPLICATE_ACTIVE when unit already has an active attempt (#3228 / #3143). Exit 0 allow / 1 deny / 2 config."
    deps: [":engine:_ts-build"]
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'swarm-pre-dispatch {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'

  # swarm:launch -- deterministic headless launch engine (#1387). Turns an
  # operator-supplied, pre-approved cohort into a ready-to-spawn launch
  # manifest: resolves --stories (issue numbers / story ids / paths) against
  # vbrief/active, enforces the #810 preflight and swarm:readiness gates per
  # story (exiting non-zero and naming the FIRST failing story), and emits
  # the C2 launch-manifest JSON carrying the #1378 allocation-context token
  # for each agent. Bare {{.CLI_ARGS}} per the readiness/verify-review-clean
  # convention -- go-task already shell-escapes pass-through args, so wrapping
  # in double quotes breaks multi-arg / path forwarding (see tasks/vbrief.yml
  # preflight for the full rationale and tests/content/test_taskfile_cli_args.py).
  #
  # Companion script: scripts/swarm_launch.py
  # Companion test:   tests/cli/test_swarm_launch.py
  launch:
    desc: "Resolve a pre-approved cohort, enforce the #810 + swarm:readiness gates and sub-agent backend policy per story, and emit the launch-manifest JSON (#1387, #1531e)"
    deps: [":engine:_ts-build"]
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'swarm-launch {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'

  # swarm:routing-set -- record an operator coding sub-agent model decision
  # (#1739) into the gitignored, per-machine .deft/routing.local.json keyed by
  # (dispatch_provider, worker_role). Supersedes the swarmSubagentBackend enum
  # (#1531 / #1735): the resolved model is threaded into the launch manifest
  # (resolved_model / model_source) so dispatch can actually honor it.
  routing-set:
    desc: "Record an operator coding sub-agent model decision (#1739): --role <role> (--model <slug> | --harness-default) [--provider <p>]. Writes the gitignored, per-machine .deft/routing.local.json."
    deps: [":engine:_ts-build"]
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'swarm-routing-set {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'

  # swarm:verify-review-clean -- cohort-level CLEAN verification gate (#1364).
  # Mandate the monitor invokes this after Phase 6 pollers report and BEFORE
  # the Phase 5 -> 6 merge discussion. Re-uses the Greptile rolling-summary
  # parser from scripts/pr_merge_readiness.py so the per-PR merge gate and
  # the cohort gate stay in lockstep -- a parser fix lands in both surfaces
  # at once. The companion script writes its own diagnostics; this Taskfile
  # target just forwards CLI_ARGS bare per the established convention.
  #
  # Companion script: scripts/swarm_verify_review_clean.py
  # Companion test:   tests/cli/test_swarm_verify_review_clean.py
  # Skill citation:   skills/deft-directive-swarm/SKILL.md Phase 5 Exit Condition + Phase 5 -> 6 gate
  verify-review-clean:
    desc: "Verify EVERY PR in a swarm cohort is CLEAN on current HEAD (confidence > 3, no P0/P1, not errored) before raising the Phase 5 -> 6 merge gate (#1364)"
    deps: [":engine:_ts-build"]
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'swarm-verify-review-clean {{.CLI_ARGS}}'

  # swarm:complete-cohort -- deterministic cohort completion sweep (#1487).
  # The REQUIRED Phase 6 step that moves a finished cohort's story vBRIEFs
  # active/ -> completed/ and completes the decompose-created epic parents
  # once all their children are settled. Routes every move through
  # scripts/scope_lifecycle.py so the #1485 (child-move) and #1487 (parent-
  # move) reference maintenance keeps `task vbrief:validate` green with no
  # manual repair. Bare {{.CLI_ARGS}} per the readiness / verify-review-clean
  # convention -- go-task already shell-escapes pass-through args, so wrapping
  # in double quotes breaks multi-arg / glob forwarding.
  #
  # Companion script: scripts/swarm_complete_cohort.py
  # Companion test:   tests/cli/test_swarm_complete_cohort.py
  # Skill citation:   skills/deft-directive-swarm/SKILL.md Phase 6 cohort completion sweep
  complete-cohort:
    desc: "Sweep a finished swarm cohort's stories active/ -> completed/ and complete their epic parents, keeping vbrief:validate green (#1487)"
    deps: [":engine:_ts-build"]
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'swarm-complete-cohort {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'

  # swarm:finalize-cohort -- post-merge cohort lifecycle automation (#2225).
  # After a cohort's PRs merge, resolves the merged stories (via Closes #N ->
  # active-brief mapping or an explicit --stories list), runs the same
  # completeCohort(...) sweep as swarm:complete-cohort, and lands the
  # active/ -> completed/ moves on a feature branch with an auto-opened PR —
  # eliminating the hand-authored lifecycle-sweep PR tax for stop-at:pr-open
  # swarms. swarm:complete-cohort remains the idempotent manual primitive.
  finalize-cohort:
    desc: "After cohort PRs merge, auto-sweep story briefs active/ -> completed/ and open the lifecycle PR (#2225)"
    deps: [":engine:_ts-build"]
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'swarm-finalize-cohort {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"'
