Skip to content

Merge pull request #557 from escoffier-labs/feat/490-adversarial-fixt… #1098

Merge pull request #557 from escoffier-labs/feat/490-adversarial-fixt…

Merge pull request #557 from escoffier-labs/feat/490-adversarial-fixt… #1098

Workflow file for this run

name: ci
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
changes:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
code_graph: ${{ steps.filter.outputs.code_graph }}
evidence_ledger: ${{ steps.filter.outputs.evidence_ledger }}
notify: ${{ steps.filter.outputs.notify }}
steps:
- uses: actions/checkout@v5
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
code_graph:
- 'engines/code-graph/**'
- 'src/brigade/templates/components/manifest-v1.json'
- '.github/workflows/ci.yml'
evidence_ledger:
- 'engines/evidence-ledger/**'
- 'src/brigade/templates/components/manifest-v1.json'
- '.github/workflows/ci.yml'
notify:
- 'stations/notify/**'
- 'src/brigade/templates/components/manifest-v1.json'
- '.github/workflows/ci.yml'
code-graph-msrv:
name: MSRV (Rust 1.85)
needs: changes
if: ${{ needs.changes.outputs.code_graph == 'true' }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: engines/code-graph
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@1.85.0
- uses: Swatinem/rust-cache@v2
with:
workspaces: engines/code-graph
- name: Check locked all-features build
run: cargo check --locked --all-features
code-graph-build-and-test:
name: build-and-test
needs: changes
if: ${{ needs.changes.outputs.code_graph == 'true' }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: engines/code-graph
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: engines/code-graph
- name: Format
run: cargo fmt --check
- name: Clippy
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Test
run: cargo test --all-features
- name: Build (default, no-network)
run: cargo build --release
code-graph-feature-configurations:
name: Feature configuration (${{ matrix.name }})
needs: changes
if: ${{ needs.changes.outputs.code_graph == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: no-default
cargo_args: --no-default-features
- name: default
cargo_args: ""
- name: watch-only
cargo_args: --no-default-features --features watch
- name: codesearch-only
cargo_args: --no-default-features --features codesearch
- name: miseledger-only
cargo_args: --no-default-features --features miseledger
- name: all-features
cargo_args: --all-features
defaults:
run:
working-directory: engines/code-graph
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: engines/code-graph
- name: Check locked feature configuration
run: cargo check --locked ${{ matrix.cargo_args }}
code-graph-windows:
name: Windows (stable, default features)
needs: changes
if: ${{ needs.changes.outputs.code_graph == 'true' }}
runs-on: windows-latest
defaults:
run:
working-directory: engines/code-graph
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: engines/code-graph
- name: Test locked default features
run: cargo test --locked
evidence-ledger-test:
needs: changes
if: ${{ needs.changes.outputs.evidence_ledger == 'true' }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: engines/evidence-ledger
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v5
with:
go-version: stable
- run: go test ./...
- run: go vet ./...
- run: go install golang.org/x/vuln/cmd/govulncheck@v1.3.0
- run: govulncheck ./...
- run: go build -o bin/miseledger ./cmd/miseledger
- run: go build -o bin/sessionfind ./cmd/sessionfind
- run: scripts/check_release_workflow.sh
- run: scripts/smoke_archive.sh
- run: scripts/smoke_mcp.sh
- run: scripts/smoke_http.sh
notify-build-and-test:
name: notify-build-and-test (ubuntu-latest)
needs: changes
if: ${{ needs.changes.outputs.notify == 'true' }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: stations/notify
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version: '1.22'
cache-dependency-path: stations/notify/go.sum
- name: Build
run: go build ./...
- name: Vet
run: go vet ./...
- name: Test
run: go test -race ./...
- name: Setup stable Go for govulncheck
uses: actions/setup-go@v5
with:
go-version: stable
cache-dependency-path: stations/notify/go.sum
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@v1.3.0
- name: Vulncheck
run: govulncheck ./...
notify-windows:
name: notify-build-and-test (windows-latest)
needs: changes
if: ${{ needs.changes.outputs.notify == 'true' }}
runs-on: windows-latest
defaults:
run:
working-directory: stations/notify
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version: '1.22'
cache-dependency-path: stations/notify/go.sum
- name: Build
run: go build ./...
- name: Vet
run: go vet ./...
- name: Test
run: go test -race ./...
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Ruff check
run: python -m ruff check .
- name: Ruff format
run: python -m ruff format --check .
- name: Mypy
run: python -m mypy
- name: Version sync
run: python scripts/version_sync.py --check
- name: Managed snapshot
run: python scripts/managed_snapshot.py --check
test:
runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Pytest
if: matrix.python != '3.12'
run: python -m pytest -q
- name: Pytest with coverage gate
if: matrix.python == '3.12'
run: python -m pytest -q --cov=brigade --cov-report=term --cov-fail-under=78
component-manifest-provenance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Exercise generated-release provenance contract
run: python -m pytest tests/test_component_manifest_provenance.py -q
content-guard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
path: brigade
- uses: actions/checkout@v5
with:
repository: solomonneas/content-guard
ref: v0.1.1
path: content-guard
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Scan
run: |
cd brigade
PYTHONPATH=../content-guard/src python -m content_guard scan . \
--policy ../content-guard/policies/public-repo.json
repo-metadata:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Command Inventory
run: brigade roadmap commands --check
env:
BRIGADE_EXTRAS: "1"
- name: Template Audit
run: brigade security template-audit --target . --json
install-from-source:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
combo:
- name: "repo+claude"
flags: "--depth repo --harnesses claude"
- name: "repo+codex"
flags: "--depth repo --harnesses codex"
- name: "workspace+claude+openclaw"
flags: "--depth workspace --harnesses claude,openclaw"
- name: "workspace+codex+openclaw"
flags: "--depth workspace --harnesses codex,openclaw"
- name: "workspace+hermes"
flags: "--depth workspace --harnesses hermes"
- name: "kitchen-sink"
flags: "--depth workspace --harnesses claude,codex,openclaw,hermes"
- name: "workspace+none"
flags: "--depth workspace --harnesses none"
- name: "repo+claude+publisher"
flags: "--depth repo --harnesses claude --include publisher"
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: pipx install
run: |
python -m pip install --upgrade pip pipx
pipx install .
brigade --version
- name: Init + doctor
run: |
target="$(mktemp -d)"
git init -q -b main "$target"
brigade init --target "$target" ${{ matrix.combo.flags }}
brigade doctor --target "$target"
case "${{ matrix.combo.flags }}" in
*hermes*)
test -f "$target/.hermes/memory-handoffs/TEMPLATE.md"
test -d "$target/.hermes/memory-handoffs/processed"
test -f "$target/.brigade/hermes/workspace.harness.json"
test -f "$target/.brigade/hermes/memory-handoff.harness.json"
grep -q '"handoff_inbox": ".hermes/memory-handoffs"' "$target/.brigade/hermes/workspace.harness.json"
grep -q '"inbox_dir": ".hermes/memory-handoffs"' "$target/.brigade/hermes/memory-handoff.harness.json"
! grep -R '.claude/memory-handoffs' "$target/.brigade/hermes"
brigade handoff sources init --target "$target" --force
brigade handoff draft --target "$target" --inbox hermes \
--title "Hermes CI smoke" \
--summary "Hermes can write a local Brigade handoff." \
--content "### Hermes CI smoke
The Hermes inbox follows the shared Brigade handoff contract."
brigade operator verify-harness --harness hermes --target "$target"
;;
esac
quickstart-smoke:
name: quickstart-smoke (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: pipx install
run: |
python -m pip install --upgrade pip pipx
pipx install .
brigade --version
- name: Quickstart (minimal default, Linux/macOS)
if: runner.os != 'Windows'
run: |
target="$(mktemp -d)"
git init -q -b main "$target"
brigade operator quickstart --target "$target" --harnesses codex --json
brigade operator doctor --target "$target" --profile local-operator --json
test -f "$target/.brigade/config.json"
test -d "$target/.codex/memory-handoffs"
test -f "$target/.codex/skills/brigade-work/SKILL.md"
test -f "$target/AGENTS.md"
test ! -e "$target/tools"
test ! -e "$target/rules"
test ! -e "$target/INSTALL_FOR_AGENTS.md"
- name: Quickstart (minimal default, PowerShell)
if: runner.os == 'Windows'
shell: pwsh
run: |
$target = Join-Path $env:RUNNER_TEMP "brigade-quickstart-minimal"
git init -q -b main $target
brigade operator quickstart --target $target --harnesses codex --json
brigade operator doctor --target $target --profile local-operator --json
if (-not (Test-Path (Join-Path $target ".brigade/config.json"))) { throw "missing Brigade config" }
if (-not (Test-Path (Join-Path $target ".codex/memory-handoffs"))) { throw "missing Codex handoff inbox" }
if (-not (Test-Path (Join-Path $target ".codex/skills/brigade-work/SKILL.md"))) { throw "missing brigade-work skill" }
if (-not (Test-Path (Join-Path $target "AGENTS.md"))) { throw "missing AGENTS.md" }
if (Test-Path (Join-Path $target "tools")) { throw "minimal install unexpectedly created tools" }
if (Test-Path (Join-Path $target "rules")) { throw "minimal install unexpectedly created rules" }
if (Test-Path (Join-Path $target "INSTALL_FOR_AGENTS.md")) { throw "minimal install unexpectedly created full-kit guide" }
- name: Quickstart (--full, Linux/macOS)
if: runner.os != 'Windows'
run: |
target="$(mktemp -d)"
git init -q -b main "$target"
brigade operator quickstart --target "$target" --harnesses codex --full --json
brigade operator doctor --target "$target" --profile local-operator --json
test -f "$target/.codex/skills/frontend/SKILL.md"
test -f "$target/tools/antislop.md"
test -f "$target/INSTALL_FOR_AGENTS.md"
test -f "$target/rules/issue-tdd-loop.md"
- name: Quickstart (--full, PowerShell)
if: runner.os == 'Windows'
shell: pwsh
run: |
$target = Join-Path $env:RUNNER_TEMP "brigade-quickstart-full"
git init -q -b main $target
brigade operator quickstart --target $target --harnesses codex --full --json
brigade operator doctor --target $target --profile local-operator --json
if (-not (Test-Path (Join-Path $target ".codex/skills/frontend/SKILL.md"))) { throw "missing frontend skill" }
if (-not (Test-Path (Join-Path $target "tools/antislop.md"))) { throw "missing antislop tool" }
if (-not (Test-Path (Join-Path $target "INSTALL_FOR_AGENTS.md"))) { throw "missing full-kit guide" }
if (-not (Test-Path (Join-Path $target "rules/issue-tdd-loop.md"))) { throw "missing issue/TDD rule" }
windows-native-acceptance:
name: windows-native-acceptance
runs-on: windows-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Run Windows native acceptance (source install)
shell: powershell
run: |
& "${{ github.workspace }}\scripts\windows-native-acceptance.ps1" -InstallMode source -RepoRoot "${{ github.workspace }}"