---
phase: 34-duckdb-1-5-upgrade-lts-branch
plan: 02
type: execute
wave: 2
depends_on:
  - 34-01
files_modified:
  - .github/workflows/Build.yml
  - .github/workflows/PullRequestCI.yml
  - .github/workflows/CodeQuality.yml
  - .github/workflows/Fuzz.yml
  - .github/workflows/DuckDBVersionMonitor.yml
autonomous: false
requirements:
  - DKDB-02
  - DKDB-03
  - DKDB-04
  - DKDB-05
  - DKDB-06
must_haves:
  truths:
    - "CI workflow on main triggers for pushes to main, release/*, gsd/*, milestone/*, and duckdb/* branches"
    - "Build.yml on main references extension-ci-tools@v1.5.0 with duckdb_version v1.5.0"
    - "PullRequestCI.yml triggers for PRs targeting duckdb/* branches"
    - "duckdb/1.4.x branch exists as a remote branch with Cargo.toml version 0.5.4+duckdb1.4 and .duckdb-version v1.4.4"
    - "DuckDB Version Monitor has two jobs: check-latest targeting main and check-lts targeting duckdb/1.4.x"
    - "extension-ci-tools submodule updated to v1.5.0 branch on main"
  artifacts:
    - path: ".github/workflows/Build.yml"
      provides: "Main branch CI with DuckDB 1.5.0"
      contains: "@v1.5.0"
    - path: ".github/workflows/PullRequestCI.yml"
      provides: "PR CI with DuckDB 1.5.0"
      contains: "@v1.5.0"
    - path: ".github/workflows/DuckDBVersionMonitor.yml"
      provides: "Dual-track version monitoring"
      contains: "check-lts"
  key_links:
    - from: ".github/workflows/Build.yml"
      to: "extension-ci-tools"
      via: "uses: duckdb/extension-ci-tools/...@v1.5.0"
      pattern: "@v1\\.5\\.0"
    - from: ".github/workflows/DuckDBVersionMonitor.yml"
      to: "duckdb/1.4.x branch"
      via: "ref: duckdb/1.4.x"
      pattern: "ref: duckdb/1\\.4\\.x"
---

<objective>
Update CI workflows on main for DuckDB 1.5.0 (extension-ci-tools version, branch triggers), create the duckdb/1.4.x LTS branch from the pre-upgrade commit, and rewrite the DuckDB Version Monitor for dual-track monitoring.

Purpose: DKDB-02/03 require a working LTS branch. DKDB-04 requires CI on both branches. DKDB-05 requires .duckdb-version correctness on each branch. DKDB-06 requires dual-track version monitoring.
Output: CI workflows updated, LTS branch created and pushed, Version Monitor dual-track.
</objective>

<execution_context>
@/Users/paul/.claude/get-shit-done/workflows/execute-plan.md
@/Users/paul/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-CONTEXT.md
@.planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-RESEARCH.md
@.planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-01-SUMMARY.md

<interfaces>
<!-- Current state of CI workflows (will be modified) -->

From .github/workflows/Build.yml (current, will be updated by Task 1):
```yaml
on:
  push:
    branches:
      - main
      - 'release/*'
      - 'gsd/*'
      - 'milestone/*'
  # ...
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.4.4
with:
  duckdb_version: v1.4.4
  ci_tools_version: v1.4.4
```

From .github/workflows/PullRequestCI.yml (current):
```yaml
on:
  pull_request:
    branches:
      - main
      - 'release/*'
      - 'gsd/*'
      - 'milestone/*'
  # ...
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.4.4
with:
  duckdb_version: v1.4.4
  ci_tools_version: v1.4.4
```

From .github/workflows/CodeQuality.yml:
```yaml
on:
  push:
    branches: [main, 'release/*', 'gsd/*', 'milestone/*']
  pull_request:
```

From .github/workflows/Fuzz.yml:
```yaml
on:
  push:
    branches: [main]
```

From .github/workflows/DuckDBVersionMonitor.yml (current single-track):
```yaml
jobs:
  check-and-update:
    # ... single job checking gh api repos/duckdb/duckdb/releases/latest
    # ... runs just bump-duckdb (recipe does NOT exist in justfile)
```

From .gitmodules:
```
[submodule "extension-ci-tools"]
  path = extension-ci-tools
  url = https://github.com/duckdb/extension-ci-tools.git
```

Branch strategy from CONTEXT.md:
- main: DuckDB 1.5.x, Cargo.toml version "0.5.4", duckdb pins "=1.10500.0"
- duckdb/1.4.x: DuckDB 1.4.x, Cargo.toml version "0.5.4+duckdb1.4", duckdb pins "=1.4.4"
- Branch-based CI: no matrix. Branch IS the version selector.
- `duckdb/*` branch pattern in workflow triggers.
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Update CI workflows for DuckDB 1.5.0 and add duckdb/* branch triggers</name>
  <files>
    .github/workflows/Build.yml
    .github/workflows/PullRequestCI.yml
    .github/workflows/CodeQuality.yml
    .github/workflows/Fuzz.yml
  </files>
  <read_first>
    .github/workflows/Build.yml
    .github/workflows/PullRequestCI.yml
    .github/workflows/CodeQuality.yml
    .github/workflows/Fuzz.yml
    .planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-01-SUMMARY.md
  </read_first>
  <action>
    Update all CI workflows on main for DuckDB 1.5.0 and add `duckdb/*` branch triggers:

    1. `.github/workflows/Build.yml`:
       a. Add `'duckdb/*'` to the `on.push.branches` list (after `'milestone/*'`)
       b. Update the `uses:` line from `@v1.4.4` to `@v1.5.0`:
          `uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.5.0`
       c. Update `duckdb_version: v1.5.0`
       d. Update `ci_tools_version: v1.5.0`
       e. Update the IMPORTANT comment to say `(currently v1.5.0)` instead of `(currently v1.4.4)`

    2. `.github/workflows/PullRequestCI.yml`:
       a. Add `'duckdb/*'` to the `on.pull_request.branches` list (after `'milestone/*'`)
       b. Update the `uses:` line from `@v1.4.4` to `@v1.5.0`
       c. Update `duckdb_version: v1.5.0`
       d. Update `ci_tools_version: v1.5.0`
       e. Update the IMPORTANT comment to say `(currently v1.5.0)`

    3. `.github/workflows/CodeQuality.yml`:
       a. Add `'duckdb/*'` to the `on.push.branches` list (after `'milestone/*'`)
       b. No version pins to update (CodeQuality uses cargo tools, not extension-ci-tools)

    4. `.github/workflows/Fuzz.yml`:
       a. Add `'duckdb/*'` to the `on.push.branches` list alongside `[main]`
       b. Change from `branches: [main]` to the multi-line format:
          ```yaml
          branches:
            - main
            - 'duckdb/*'
          ```

    5. Update extension-ci-tools submodule to v1.5.0 branch:
       ```bash
       cd extension-ci-tools
       git fetch origin
       git checkout origin/v1.5.0
       cd ..
       git add extension-ci-tools
       ```
  </action>
  <verify>
    <automated>cd /Users/paul/Documents/Dev/Personal/duckdb-semantic-views && grep 'duckdb/\*' .github/workflows/Build.yml && grep '@v1.5.0' .github/workflows/Build.yml && grep 'duckdb/\*' .github/workflows/PullRequestCI.yml && grep '@v1.5.0' .github/workflows/PullRequestCI.yml && grep 'duckdb/\*' .github/workflows/CodeQuality.yml && grep 'duckdb/\*' .github/workflows/Fuzz.yml && grep 'duckdb_version: v1.5.0' .github/workflows/Build.yml</automated>
  </verify>
  <acceptance_criteria>
    - `Build.yml` contains `'duckdb/*'` in on.push.branches
    - `Build.yml` contains `@v1.5.0` in the uses line
    - `Build.yml` contains `duckdb_version: v1.5.0` and `ci_tools_version: v1.5.0`
    - `PullRequestCI.yml` contains `'duckdb/*'` in on.pull_request.branches
    - `PullRequestCI.yml` contains `@v1.5.0` in the uses line
    - `PullRequestCI.yml` contains `duckdb_version: v1.5.0` and `ci_tools_version: v1.5.0`
    - `CodeQuality.yml` contains `'duckdb/*'` in on.push.branches
    - `Fuzz.yml` contains `'duckdb/*'` in on.push.branches
    - extension-ci-tools submodule points to v1.5.0 branch commit
  </acceptance_criteria>
  <done>All CI workflows updated for DuckDB 1.5.0 with duckdb/* branch triggers. extension-ci-tools submodule on v1.5.0 branch.</done>
</task>

<task type="auto">
  <name>Task 2: Create duckdb/1.4.x LTS branch and rewrite Version Monitor for dual-track</name>
  <files>
    .github/workflows/DuckDBVersionMonitor.yml
  </files>
  <read_first>
    .github/workflows/DuckDBVersionMonitor.yml
    .duckdb-version
    Cargo.toml
    .github/workflows/Build.yml
    justfile
    .planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-CONTEXT.md
  </read_first>
  <action>
    Create the LTS branch and rewrite the version monitor:

    **Part A: Create duckdb/1.4.x branch from pre-upgrade commit**

    1. Find the last commit before the DuckDB 1.5.0 upgrade (the commit where .duckdb-version was still v1.4.4):
       ```bash
       git log --oneline --all | head -20
       # Find the commit hash of the last commit before Plan 01 changes
       # It should be the commit referenced in 34-01-SUMMARY.md or the commit
       # just before the version pin update
       ```

    2. Create the LTS branch from that commit:
       ```bash
       git branch duckdb/1.4.x <pre-upgrade-commit-hash>
       ```

    3. Check out the LTS branch and make the necessary modifications:
       ```bash
       git checkout duckdb/1.4.x
       ```

    4. Update Cargo.toml version field ONLY (not the duckdb/libduckdb-sys pins -- those stay at =1.4.4):
       - Change `version = "0.5.0"` to `version = "0.5.4+duckdb1.4"`
       - Leave `duckdb = { version = "=1.4.4", ... }` unchanged
       - Leave `libduckdb-sys = "=1.4.4"` unchanged

    5. Verify `.duckdb-version` is still `v1.4.4` on this branch (it should be, since we branched from pre-upgrade).

    6. Update CI workflows on the LTS branch to include `duckdb/*` trigger patterns:
       - `Build.yml`: Add `'duckdb/*'` to on.push.branches (keep @v1.4.4 version refs)
       - `PullRequestCI.yml`: Add `'duckdb/*'` to on.pull_request.branches (keep @v1.4.4 version refs)
       - `CodeQuality.yml`: Add `'duckdb/*'` to on.push.branches
       - `Fuzz.yml`: Add `'duckdb/*'` to on.push.branches

    7. Commit changes on the LTS branch:
       ```bash
       git add Cargo.toml .github/workflows/Build.yml .github/workflows/PullRequestCI.yml .github/workflows/CodeQuality.yml .github/workflows/Fuzz.yml
       git commit -m "chore: configure duckdb/1.4.x LTS branch

       - Cargo.toml version suffixed as 0.5.4+duckdb1.4
       - CI workflows include duckdb/* branch trigger pattern
       - DuckDB version pins remain at 1.4.4"
       ```

    8. Switch back to the milestone branch:
       ```bash
       git checkout milestone/v0.5.4
       ```

    **Part B: Rewrite DuckDB Version Monitor for dual-track**

    9. Rewrite `.github/workflows/DuckDBVersionMonitor.yml` to have two jobs:

    ```yaml
    name: DuckDB Version Monitor
    on:
      schedule:
        - cron: '0 9 * * 1'  # Weekly, Monday 09:00 UTC
      workflow_dispatch:       # Allow manual trigger for testing

    permissions:
      contents: write
      pull-requests: write

    jobs:
      check-latest:
        name: Check for new DuckDB latest release
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
            with:
              ref: main
              submodules: recursive

          - name: Get latest DuckDB release
            id: latest
            run: |
              LATEST=$(gh api repos/duckdb/duckdb/releases/latest --jq '.tag_name')
              CURRENT=$(cat .duckdb-version)
              echo "latest=$LATEST" >> $GITHUB_OUTPUT
              echo "current=$CURRENT" >> $GITHUB_OUTPUT
              if [ "$LATEST" != "$CURRENT" ]; then
                echo "is_new=true" >> $GITHUB_OUTPUT
              else
                echo "is_new=false" >> $GITHUB_OUTPUT
              fi
              echo "Latest DuckDB: $LATEST (current pin: $CURRENT)"
            env:
              GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

          - name: Skip if already up to date
            if: steps.latest.outputs.is_new == 'false'
            run: echo "Already on latest DuckDB ${{ steps.latest.outputs.current }}. No action needed."

          - name: Install just
            if: steps.latest.outputs.is_new == 'true'
            uses: extractions/setup-just@v2

          - name: Install Rust stable
            if: steps.latest.outputs.is_new == 'true'
            uses: dtolnay/rust-toolchain@stable

          - name: Update version pins
            if: steps.latest.outputs.is_new == 'true'
            run: |
              # Update .duckdb-version
              echo "${{ steps.latest.outputs.latest }}" > .duckdb-version

              # Determine duckdb-rs crate version from DuckDB version
              # DuckDB 1.X.Y -> duckdb-rs 1.1XY00.0 (e.g., 1.5.0 -> 1.10500.0, 1.6.0 -> 1.10600.0)
              VER="${{ steps.latest.outputs.latest }}"
              MAJOR=$(echo $VER | sed 's/v//' | cut -d. -f1)
              MINOR=$(echo $VER | sed 's/v//' | cut -d. -f2)
              PATCH=$(echo $VER | sed 's/v//' | cut -d. -f3)
              CRATE_VER="${MAJOR}.1$(printf '%02d' $MINOR)$(printf '%02d' $PATCH).0"
              echo "DuckDB $VER -> duckdb-rs $CRATE_VER"

              # Update Cargo.toml
              sed -i "s/duckdb = { version = \"=[^\"]*\"/duckdb = { version = \"=$CRATE_VER\"/" Cargo.toml
              sed -i "s/libduckdb-sys = \"=[^\"]*\"/libduckdb-sys = \"=$CRATE_VER\"/" Cargo.toml

              # Update Python PEP 723 headers
              DDB_VER=$(echo $VER | sed 's/v//')
              find . -name '*.py' -not -path './extension-ci-tools/*' -not -path './.venv/*' -exec \
                sed -i "s/duckdb==[0-9.]*/duckdb==$DDB_VER/" {} \;

              # Download new amalgamation
              just update-headers

          - name: Build and test against new DuckDB version
            if: steps.latest.outputs.is_new == 'true'
            id: build
            run: make configure && make test_release
            continue-on-error: true

          - name: Run DuckLake integration test
            if: steps.latest.outputs.is_new == 'true'
            id: ducklake_test
            run: |
              pip install uv
              SEMANTIC_VIEWS_EXTENSION_PATH=build/release/semantic_views.duckdb_extension \
                uv run test/integration/test_ducklake_ci.py
            continue-on-error: true

          - name: Open version-bump PR (build passed)
            if: steps.latest.outputs.is_new == 'true' && steps.build.outcome == 'success'
            uses: peter-evans/create-pull-request@v7
            with:
              token: ${{ secrets.GITHUB_TOKEN }}
              base: main
              title: "chore: bump DuckDB pin to ${{ steps.latest.outputs.latest }}"
              body: |
                Automated version bump to DuckDB ${{ steps.latest.outputs.latest }}.

                Build and tests passed on Linux x86_64. The full platform matrix will run once this PR merges to `main`.

                DuckLake compatibility: ${{ steps.ducklake_test.outcome == 'success' && '✓ passed' || '✗ failed (see run log)' }}

                ---
                *Generated by DuckDB Version Monitor workflow.*
              branch: "chore/duckdb-bump-${{ steps.latest.outputs.latest }}"
              commit-message: "chore: bump DuckDB pin to ${{ steps.latest.outputs.latest }}"
              delete-branch: true

          - name: Open breakage PR (build failed)
            if: steps.latest.outputs.is_new == 'true' && steps.build.outcome == 'failure'
            uses: peter-evans/create-pull-request@v7
            with:
              token: ${{ secrets.GITHUB_TOKEN }}
              base: main
              title: "fix: DuckDB ${{ steps.latest.outputs.latest }} broke the build"
              body: |
                Build against DuckDB ${{ steps.latest.outputs.latest }} failed.

                @copilot please update the DuckDB version pin and fix any compilation errors.

                DuckLake compatibility: ${{ steps.ducklake_test.outcome == 'success' && '✓ passed' || '✗ failed or skipped' }}

                Build log: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

                ---
                *Generated by DuckDB Version Monitor workflow.*
              branch: "fix/duckdb-breakage-${{ steps.latest.outputs.latest }}"
              commit-message: "chore: attempt bump to DuckDB ${{ steps.latest.outputs.latest }}"
              delete-branch: true

      check-lts:
        name: Check for new DuckDB LTS release
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
            with:
              ref: duckdb/1.4.x
              submodules: recursive

          - name: Get latest DuckDB 1.4.x release
            id: lts
            run: |
              # Query all releases, filter for v1.4.* tags, take the newest
              LATEST_LTS=$(gh api repos/duckdb/duckdb/releases --paginate --jq '[.[] | select(.tag_name | startswith("v1.4")) | .tag_name] | first')
              CURRENT=$(cat .duckdb-version)
              echo "latest=$LATEST_LTS" >> $GITHUB_OUTPUT
              echo "current=$CURRENT" >> $GITHUB_OUTPUT
              if [ "$LATEST_LTS" != "$CURRENT" ]; then
                echo "is_new=true" >> $GITHUB_OUTPUT
              else
                echo "is_new=false" >> $GITHUB_OUTPUT
              fi
              echo "Latest DuckDB LTS: $LATEST_LTS (current pin: $CURRENT)"
            env:
              GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

          - name: Skip if already up to date
            if: steps.lts.outputs.is_new == 'false'
            run: echo "Already on latest LTS ${{ steps.lts.outputs.current }}. No action needed."

          - name: Install just
            if: steps.lts.outputs.is_new == 'true'
            uses: extractions/setup-just@v2

          - name: Install Rust stable
            if: steps.lts.outputs.is_new == 'true'
            uses: dtolnay/rust-toolchain@stable

          - name: Update LTS version pins
            if: steps.lts.outputs.is_new == 'true'
            run: |
              # Update .duckdb-version
              echo "${{ steps.lts.outputs.latest }}" > .duckdb-version

              # Update Cargo.toml duckdb/libduckdb-sys pins (LTS uses simple version scheme)
              LTS_VER=$(echo "${{ steps.lts.outputs.latest }}" | sed 's/v//')
              sed -i "s/duckdb = { version = \"=[^\"]*\"/duckdb = { version = \"=$LTS_VER\"/" Cargo.toml
              sed -i "s/libduckdb-sys = \"=[^\"]*\"/libduckdb-sys = \"=$LTS_VER\"/" Cargo.toml

              # Update Python PEP 723 headers
              find . -name '*.py' -not -path './extension-ci-tools/*' -not -path './.venv/*' -exec \
                sed -i "s/duckdb==[0-9.]*/duckdb==$LTS_VER/" {} \;

              # Download new amalgamation
              just update-headers

          - name: Build and test against new LTS version
            if: steps.lts.outputs.is_new == 'true'
            id: build
            run: make configure && make test_release
            continue-on-error: true

          - name: Run DuckLake integration test
            if: steps.lts.outputs.is_new == 'true'
            id: ducklake_test
            run: |
              pip install uv
              SEMANTIC_VIEWS_EXTENSION_PATH=build/release/semantic_views.duckdb_extension \
                uv run test/integration/test_ducklake_ci.py
            continue-on-error: true

          - name: Open LTS version-bump PR (build passed)
            if: steps.lts.outputs.is_new == 'true' && steps.build.outcome == 'success'
            uses: peter-evans/create-pull-request@v7
            with:
              token: ${{ secrets.GITHUB_TOKEN }}
              base: duckdb/1.4.x
              title: "chore(lts): bump DuckDB LTS pin to ${{ steps.lts.outputs.latest }}"
              body: |
                Automated LTS version bump to DuckDB ${{ steps.lts.outputs.latest }}.

                Build and tests passed on Linux x86_64. Full platform matrix runs on push to `duckdb/1.4.x`.

                DuckLake compatibility: ${{ steps.ducklake_test.outcome == 'success' && '✓ passed' || '✗ failed (see run log)' }}

                ---
                *Generated by DuckDB Version Monitor workflow (LTS track).*
              branch: "chore/duckdb-lts-bump-${{ steps.lts.outputs.latest }}"
              commit-message: "chore(lts): bump DuckDB LTS pin to ${{ steps.lts.outputs.latest }}"
              delete-branch: true

          - name: Open LTS breakage PR (build failed)
            if: steps.lts.outputs.is_new == 'true' && steps.build.outcome == 'failure'
            uses: peter-evans/create-pull-request@v7
            with:
              token: ${{ secrets.GITHUB_TOKEN }}
              base: duckdb/1.4.x
              title: "fix(lts): DuckDB ${{ steps.lts.outputs.latest }} broke the LTS build"
              body: |
                LTS build against DuckDB ${{ steps.lts.outputs.latest }} failed.

                @copilot please update the DuckDB LTS version pin and fix any compilation errors.

                DuckLake compatibility: ${{ steps.ducklake_test.outcome == 'success' && '✓ passed' || '✗ failed or skipped' }}

                Build log: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

                ---
                *Generated by DuckDB Version Monitor workflow (LTS track).*
              branch: "fix/duckdb-lts-breakage-${{ steps.lts.outputs.latest }}"
              commit-message: "chore(lts): attempt bump to DuckDB ${{ steps.lts.outputs.latest }}"
              delete-branch: true
    ```

    NOTE: The old `just bump-duckdb` recipe was referenced in the old monitor but never existed. The new monitor does version bumping inline (sed commands) instead of delegating to a justfile recipe. This is simpler and avoids the missing recipe issue.

    10. Commit the Version Monitor rewrite on the current branch (milestone/v0.5.4).
  </action>
  <verify>
    <automated>cd /Users/paul/Documents/Dev/Personal/duckdb-semantic-views && grep 'check-latest' .github/workflows/DuckDBVersionMonitor.yml && grep 'check-lts' .github/workflows/DuckDBVersionMonitor.yml && grep 'ref: duckdb/1.4.x' .github/workflows/DuckDBVersionMonitor.yml && grep 'base: main' .github/workflows/DuckDBVersionMonitor.yml && grep 'base: duckdb/1.4.x' .github/workflows/DuckDBVersionMonitor.yml && git branch | grep 'duckdb/1.4.x'</automated>
  </verify>
  <acceptance_criteria>
    - `git branch` output includes `duckdb/1.4.x`
    - On duckdb/1.4.x branch: `Cargo.toml` version field contains `0.5.4+duckdb1.4`
    - On duckdb/1.4.x branch: `.duckdb-version` contains `v1.4.4`
    - On duckdb/1.4.x branch: `Cargo.toml` duckdb pin is `=1.4.4`
    - On duckdb/1.4.x branch: CI workflows include `duckdb/*` in branch triggers
    - `DuckDBVersionMonitor.yml` contains two jobs: `check-latest` and `check-lts`
    - `DuckDBVersionMonitor.yml` check-latest job checks out `ref: main`
    - `DuckDBVersionMonitor.yml` check-lts job checks out `ref: duckdb/1.4.x`
    - `DuckDBVersionMonitor.yml` check-latest PRs target `base: main`
    - `DuckDBVersionMonitor.yml` check-lts PRs target `base: duckdb/1.4.x`
  </acceptance_criteria>
  <done>duckdb/1.4.x LTS branch created with correct version pins and CI triggers. DuckDB Version Monitor rewritten for dual-track monitoring (check-latest on main, check-lts on duckdb/1.4.x).</done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <name>Task 3: Verify LTS branch and CI configuration</name>
  <files>n/a</files>
  <action>
    Human verification checkpoint. All automation is complete in Tasks 1-2.
    The user reviews the LTS branch state, CI workflow configuration, and Version Monitor rewrite.
  </action>
  <what-built>
    DuckDB 1.5.0 upgrade on main (Plan 01), LTS branch duckdb/1.4.x created, CI workflows updated with duckdb/* triggers, DuckDB Version Monitor rewritten for dual-track.
  </what-built>
  <how-to-verify>
    1. Check the LTS branch exists and has correct pins:
       ```bash
       git checkout duckdb/1.4.x
       cat .duckdb-version          # Should show v1.4.4
       grep 'version = ' Cargo.toml | head -1  # Should show 0.5.4+duckdb1.4
       grep '=1.4.4' Cargo.toml    # Should show duckdb and libduckdb-sys at 1.4.4
       ```

    2. Check main has correct pins:
       ```bash
       git checkout milestone/v0.5.4
       cat .duckdb-version          # Should show v1.5.0
       grep '=1.10500.0' Cargo.toml # Should show duckdb and libduckdb-sys at 1.10500.0
       ```

    3. Review DuckDBVersionMonitor.yml:
       - Two jobs: check-latest and check-lts
       - check-latest checks out main, queries releases/latest, PRs target main
       - check-lts checks out duckdb/1.4.x, queries v1.4.* releases, PRs target duckdb/1.4.x

    4. Review Build.yml:
       - Has duckdb/* in branch triggers
       - Uses @v1.5.0 for extension-ci-tools

    5. Optionally push duckdb/1.4.x to remote to verify CI triggers:
       ```bash
       git push origin duckdb/1.4.x
       ```
       Then check GitHub Actions to see if Build.yml runs on the LTS branch.
  </how-to-verify>
  <verify>Human checkpoint - user confirms LTS branch and CI configuration are correct</verify>
  <done>User has verified the LTS branch, CI workflows, and Version Monitor dual-track configuration.</done>
  <resume-signal>Type "approved" or describe issues</resume-signal>
</task>

</tasks>

<verification>
Phase 34 Plan 02 is complete when:
1. All four CI workflows (Build, PullRequestCI, CodeQuality, Fuzz) include `duckdb/*` in branch triggers
2. Build.yml and PullRequestCI.yml reference extension-ci-tools@v1.5.0 with duckdb_version v1.5.0
3. duckdb/1.4.x branch exists locally with Cargo.toml version 0.5.4+duckdb1.4, duckdb pins at =1.4.4, .duckdb-version v1.4.4
4. DuckDBVersionMonitor.yml has two jobs (check-latest, check-lts) targeting the correct branches
5. extension-ci-tools submodule updated to v1.5.0 branch
6. User has verified the LTS branch and CI configuration
</verification>

<success_criteria>
- `duckdb/1.4.x` branch exists with correct version pins
- All CI workflows on main reference DuckDB 1.5.0
- DuckDB Version Monitor has dual-track capability
- User has approved the configuration via checkpoint
</success_criteria>

<output>
After completion, create `.planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-02-SUMMARY.md`
</output>
