omk 0.5.0

A Rust runtime for Kimi CLI. Turns prompts into proof-backed engineering runs with gates, worktrees, and replay.
Documentation
name: CI

on:
  push:
    branches: [master, main]
  pull_request:
    branches: [master, main]
  schedule:
    - cron: '18 5 * * 1'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always

jobs:
  changes:
    name: Classify Changes
    runs-on: ubuntu-latest
    outputs:
      rust: ${{ steps.filter.outputs.rust }}
      deps: ${{ steps.filter.outputs.deps }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Detect Rust-relevant paths
        id: filter
        shell: bash
        run: |
          if [[ "${GITHUB_EVENT_NAME}" != "pull_request" ]]; then
            echo "rust=true" >> "$GITHUB_OUTPUT"
            echo "deps=true" >> "$GITHUB_OUTPUT"
            exit 0
          fi

          git fetch --no-tags --depth=1 origin "${GITHUB_BASE_REF}:refs/remotes/origin/${GITHUB_BASE_REF}"
          git diff --name-only "refs/remotes/origin/${GITHUB_BASE_REF}" HEAD > changed-files.txt

          if grep -Eq '^(Cargo\.toml|Cargo\.lock|deny\.toml|build\.rs|rust-toolchain(\.toml)?|\.cargo/|src/|tests/|benches/|examples/|\.github/workflows/)' changed-files.txt; then
            echo "rust=true" >> "$GITHUB_OUTPUT"
          else
            echo "rust=false" >> "$GITHUB_OUTPUT"
          fi

          if grep -Eq '^(Cargo\.toml|Cargo\.lock|deny\.toml|\.github/workflows/ci\.yml)$' changed-files.txt; then
            echo "deps=true" >> "$GITHUB_OUTPUT"
          else
            echo "deps=false" >> "$GITHUB_OUTPUT"
          fi

  lint:
    name: Lint & Audit
    needs: changes
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Clone kimi-wire dependency
        run: git clone --depth=1 https://github.com/ekhodzitsky/kimi-wire.git ../kimi-wire

      - name: Skip docs-only PR
        if: github.event_name == 'pull_request' && needs.changes.outputs.rust != 'true'
        run: echo "No Rust paths changed."

      - name: Install Rust
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9
        with:
          toolchain: stable
          components: rustfmt, clippy

      - name: Cache Rust dependencies
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8

      - name: Check formatting
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo fmt -- --check

      - name: Run clippy
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo clippy --all-targets --all-features -- -D warnings

      - name: Check all targets and features
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo check --all-targets --all-features

      - name: Check server-only feature set
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo check --no-default-features --features server

      - name: Check supply chain
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        # SHA-pinned third-party action (v2.0.18 at time of pin).
        uses: EmbarkStudios/cargo-deny-action@a531616d8ce3b9177443e48a1159bc945a099823
        with:
          command: check advisories licenses sources
          arguments: --all-features

  cargo-deny:
    name: Audit Dependencies
    needs: changes
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Clone kimi-wire dependency
        run: git clone --depth=1 https://github.com/ekhodzitsky/kimi-wire.git ../kimi-wire

      - name: Skip unchanged dependency graph
        if: github.event_name == 'pull_request' && needs.changes.outputs.deps != 'true'
        run: echo "Cargo dependency inputs did not change; dependency audit is a cheap no-op."

      - name: Check supply chain
        if: github.event_name != 'pull_request' || needs.changes.outputs.deps == 'true'
        # SHA-pinned third-party action (v2.0.18 at time of pin).
        uses: EmbarkStudios/cargo-deny-action@a531616d8ce3b9177443e48a1159bc945a099823
        with:
          command: check advisories licenses sources
          arguments: --all-features

  msrv:
    name: MSRV
    needs: changes
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Clone kimi-wire dependency
        run: git clone --depth=1 https://github.com/ekhodzitsky/kimi-wire.git ../kimi-wire

      - name: Skip docs-only PR
        if: github.event_name == 'pull_request' && needs.changes.outputs.rust != 'true'
        run: echo "No Rust paths changed."

      - name: Install Rust (MSRV)
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9
        with:
          toolchain: '1.78'

      - name: Cache Rust dependencies
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8

      - name: Check MSRV
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo check --all-targets --all-features

  build-test:
    name: Build & Test (${{ matrix.os }})
    needs: changes
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: macos-latest
            full: true
          - os: ubuntu-latest
            full: true
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Clone kimi-wire dependency
        run: git clone --depth=1 https://github.com/ekhodzitsky/kimi-wire.git ../kimi-wire

      - name: Skip docs-only PR
        if: github.event_name == 'pull_request' && needs.changes.outputs.rust != 'true'
        run: echo "No Rust paths changed; keeping required CI check green."

      - name: Install Rust
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9
        with:
          toolchain: stable
          components: rustfmt, clippy

      - name: Cache Rust dependencies
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8

      - name: Check all targets and features
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo check --all-targets --all-features

      - name: Run tests
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo test

      - name: Run doctests
        if: (github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true') && matrix.full
        run: cargo test --doc

      - name: Validate module contracts
        if: (github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true') && matrix.full
        run: cargo run --bin validate-contracts

      - name: Build release binary
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: cargo build --release

      - name: Smoke test release binary
        if: github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true'
        run: ./target/release/omk --version

      - name: Build docs
        if: (github.event_name != 'pull_request' || needs.changes.outputs.rust == 'true') && matrix.full
        run: cargo doc --no-deps