# Git Workflow Configuration for Sprintpilot
# Worktrees are managed via standard git commands at .worktrees/{name}

git:
  enabled: true # false = all git ops silently skip
  base_branch: main
  # Git status is tracked in git-status.yaml (Sprintpilot-owned), NOT sprint-status.yaml (BMad Method-owned)

  # Branch + PR granularity.
  #   story — one branch + one PR per story (default).
  #   epic  — one branch + one PR per epic; stories committed on it.
  #           Epic branch name: {branch_prefix}epic-{epic_id}.
  #           Epic PR merges with --squash; the PR body lists each
  #           story commit. Set on nano profile by default.
  granularity: story

  # Reuse a user-created branch instead of auto-creating per-story or
  # per-epic branches. When `true`, autopilot detects the current branch
  # on boot (must NOT be base_branch) and commits every story directly
  # onto it. Per-story / per-epic branch creation is suppressed; one PR
  # is opened at sprint-end. Useful for feature-branch workflows where
  # the user already has the branch they want to work on.
  reuse_user_branch: false

  # Merge strategy.
  #   stacked        — every story branch lives until sprint completes,
  #                    PRs are stacked (default; existing behavior).
  #   land_as_you_go — merge each story's PR immediately after STORY_DONE
  #                    to avoid PR pile-up. `land_when` controls when.
  merge_strategy: stacked

  # When to merge under merge_strategy: land_as_you_go.
  #   no_wait        — merge synchronously after STORY_DONE, no CI wait.
  #   ci_pass        — wait for `gh pr checks` (or platform equivalent)
  #                    to report all checks green, then merge.
  #   ci_and_review  — also wait for an `approved` PR review.
  land_when: ci_pass

  # Max minutes to wait for CI / review under land_as_you_go. After this
  # the orchestrator halts and prompts the user.
  land_wait_minutes: 30

  # Max minutes to wait for CI green on the epic branch before MERGE_EPIC
  # invokes `gh pr merge`. Only consulted under granularity=epic +
  # merge_strategy=stacked. Falls back to `land_wait_minutes` if unset,
  # so existing configs with only the land knob keep working. Effective
  # wall time can exceed this by up to ~60s due to the polling cycle
  # (gh pr checks timeout + 30s±5s sleep) — see create-pr.js#runChecksMode.
  epic_merge_wait_minutes: 30

  # Branch naming
  branch_prefix: "story/" # prefix for story branches (e.g., story/1-2-user-auth)
  max_branch_length: 60 # truncate + 6-char hash if longer

  # Commit message templates
  # Placeholders: {story-key}, {epic}, {story-title}, {patch-title}
  commit_templates:
    story: "feat({epic}): {story-title} ({story-key})"
    patch: "fix({story-key}): {patch-title}"

  # Placeholder resolution chain: sprint-status.yaml -> story file -> fallback
  commit_placeholder_resolution:
    story-key: "from sprint-status.yaml development_status key"
    epic: "from story file epic header, fallback to story-key prefix (e.g., '1' from '1-3')"
    story-title: "from story file title, fallback to story-key"
    patch-title: "from review finding title, fallback to 'code review fix'"

  # Linting — runs after dev_green verify passes via
  # scripts/post-green-gates.js (lint-changed + lint-test-pitfalls +
  # ci-parity scan).
  lint:
    enabled: true # gate runs only when true
    blocking: false # true = lint errors reject verify (LLM fix-loops); false = recorded but non-gating
    output_limit: 100 # max lines of lint output injected back into context
    # Per-language linter preference, first-installed wins. Empty list
    # disables linting for that language. `javascript` and `typescript`
    # merge into a single js-ts bucket (both share eslint/biome tooling).
    # To add a new language, add an entry here AND a matching resolver
    # block in scripts/lint-changed.js.
    linters:
      python: [ruff, flake8, pylint]
      javascript: [eslint, biome]
      typescript: [eslint, biome]
      rust: [cargo clippy]
      go: [golangci-lint]
      ruby: [rubocop]
      java: [checkstyle, pmd]
      c: [cppcheck, clang-tidy]
      cpp: [cppcheck, clang-tidy]
      csharp: [dotnet format]
      swift: [swiftlint]
      plsql: [sqlfluff]
      kotlin: [ktlint, detekt]
      php: [phpstan, phpcs]

  # Push & PR
  push:
    auto: true # false = branches stay local, no push or PR
    create_pr: true # true = create PR and wait for approval (no auto-merge)
                     # false = merge directly to base branch after push
    pr_template: "modules/git/templates/pr-body.md" # relative to _Sprintpilot/

  # Worktree settings (location: .worktrees/ in project root)
  worktree:
    submodule_init: auto # auto = only if .gitmodules exists
    submodule_timeout: 30 # seconds
    cleanup_on_merge: true # false = keep worktrees after epic completion for inspection
    health_check_on_boot: true # check for orphaned worktrees from crashed sessions

  # Lock file (.autopilot.lock — prevents concurrent autopilot sessions
  # on the same project). Acquired by `autopilot start`; released by
  # `/sprint-autopilot-off`.
  lock:
    stale_timeout_minutes: 30 # auto-take-over locks older than this (0 disables)

  # Platform detection
  platform:
    provider: auto # auto | github | gitlab | bitbucket | gitea | git_only
    # Detection priority:
    #   1. Explicit provider in this config (if not "auto")
    #   2. CLI detection: which CLIs are installed (gh, glab, bb, tea)
    #   3. Remote URL regex as last resort
    #
    # For self-hosted Gitea:
    #   provider: gitea
    #   base_url: https://git.example.com
    #   # Set GITEA_TOKEN env var for API auth
    #
    # For Bitbucket Server:
    #   provider: bitbucket
    #   # Set BITBUCKET_TOKEN env var for API auth
