docs(reborn): agent loop skeleton framework spec + 9 workstream briefs #8658
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Code Style | |
| on: | |
| pull_request: | |
| merge_group: | |
| branches: | |
| - main | |
| types: | |
| - checks_requested | |
| # Pushes to main refresh the rust-cache entries that PR and merge-group | |
| # jobs restore from. Non-push runs stay restore-only. | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: code-style-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| changes: | |
| name: Detect code changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| has_code: ${{ steps.non_pr.outputs.has_code || steps.diff.outputs.has_code }} | |
| has_boundary_check: ${{ steps.non_pr.outputs.has_boundary_check || steps.diff.outputs.has_boundary_check }} | |
| has_reborn_cli: ${{ steps.non_pr.outputs.has_reborn_cli || steps.diff.outputs.has_reborn_cli }} | |
| steps: | |
| - id: non_pr | |
| if: github.event_name == 'push' | |
| run: | | |
| echo "has_code=true" >> "$GITHUB_OUTPUT" | |
| echo "has_boundary_check=true" >> "$GITHUB_OUTPUT" | |
| echo "has_reborn_cli=true" >> "$GITHUB_OUTPUT" | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| if: github.event_name == 'pull_request' || github.event_name == 'merge_group' | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - id: diff | |
| if: github.event_name == 'pull_request' || github.event_name == 'merge_group' | |
| env: | |
| BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.merge_group.base_sha }} | |
| run: | | |
| CHANGED_FILES="$(git diff --name-only "$BASE_SHA"...HEAD)" | |
| if printf '%s\n' "$CHANGED_FILES" | grep -Eq '^(src/|crates/|channels-src/|tools-src/|tests/|migrations/|Cargo\.toml$|Cargo\.lock$|Dockerfile$|build\.rs$|scripts/check_no_panics\.py$|scripts/check_gateway_boundaries\.py$|\.github/workflows/code_style\.yml$)'; then | |
| echo "has_code=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_code=false" >> "$GITHUB_OUTPUT" | |
| echo "No code changes — style checks will be skipped" | |
| fi | |
| if printf '%s\n' "$CHANGED_FILES" | grep -Eq '^(scripts/check_gateway_boundaries\.py$|\.github/workflows/code_style\.yml$)'; then | |
| echo "has_boundary_check=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_boundary_check=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if printf '%s\n' "$CHANGED_FILES" | grep -Eq '^(crates/ironclaw_reborn_cli/|crates/ironclaw_reborn_config/|crates/ironclaw_architecture/tests/reborn_dependency_boundaries\.rs$|Cargo\.toml$|Cargo\.lock$|\.github/workflows/code_style\.yml$)'; then | |
| echo "has_reborn_cli=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_reborn_cli=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| clippy-matrix: | |
| name: Configure clippy matrix | |
| needs: changes | |
| if: needs.changes.outputs.has_code == 'true' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set.outputs.matrix }} | |
| steps: | |
| - id: set | |
| run: | | |
| FULL='[{"name":"all-features","flags":"--all-features"},{"name":"default","flags":""},{"name":"libsql-only","flags":"--no-default-features --features libsql"}]' | |
| SLIM='[{"name":"all-features","flags":"--all-features"}]' | |
| if [ "${{ github.event_name }}" = "pull_request" ] || [ "${{ github.event_name }}" = "merge_group" ]; then | |
| echo "matrix=${SLIM}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "matrix=${FULL}" >> "$GITHUB_OUTPUT" | |
| fi | |
| format: | |
| name: Formatting | |
| needs: changes | |
| if: needs.changes.outputs.has_code == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| components: rustfmt | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| gateway-js-syntax: | |
| name: Gateway JS syntax | |
| needs: changes | |
| if: needs.changes.outputs.has_code == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Node.js | |
| uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4 | |
| with: | |
| node-version: "22" | |
| - name: Check gateway JS syntax | |
| run: | | |
| find crates/ironclaw_gateway/static/js -type f -name '*.js' \ | |
| -exec node --check {} + | |
| deny-check: | |
| name: cargo-deny | |
| needs: changes | |
| if: needs.changes.outputs.has_code == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Run cargo deny | |
| uses: EmbarkStudios/cargo-deny-action@3fd3802e88374d3fe9159b834c7714ec57d6c979 # v2 | |
| clippy: | |
| name: Clippy (${{ matrix.name }}) | |
| needs: [changes, clippy-matrix] | |
| if: needs.changes.outputs.has_code == 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJSON(needs.clippy-matrix.outputs.matrix) }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| components: clippy | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| shared-key: clippy | |
| save-if: ${{ matrix.name == 'all-features' && github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| - name: Check lints | |
| run: cargo clippy --all --tests --examples ${{ matrix.flags }} -- -D warnings | |
| clippy-windows: | |
| name: Clippy Windows (${{ matrix.name }}) | |
| needs: [changes, clippy-matrix] | |
| if: needs.changes.outputs.has_code == 'true' && github.event_name == 'push' | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJSON(needs.clippy-matrix.outputs.matrix) }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| components: clippy | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| key: windows-${{ matrix.name }} | |
| save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| - name: Check lints | |
| run: cargo clippy --all --tests --examples ${{ matrix.flags }} -- -D warnings | |
| reborn-cli-smoke: | |
| name: Reborn CLI smoke tests | |
| needs: changes | |
| if: needs.changes.outputs.has_reborn_cli == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| shared-key: reborn-cli-smoke | |
| save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| - name: Test Reborn boot config crate | |
| run: cargo test -p ironclaw_reborn_config | |
| - name: Test Reborn CLI binary crate | |
| run: cargo test -p ironclaw_reborn_cli | |
| - name: Test Reborn architecture boundaries | |
| run: cargo test -p ironclaw_architecture reborn | |
| no-panics: | |
| name: No panics in production code | |
| needs: changes | |
| if: needs.changes.outputs.has_code == 'true' && github.event_name != 'push' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Check for .unwrap(), .expect(), assert!() in production code | |
| env: | |
| BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.merge_group.base_sha }} | |
| run: python3 scripts/check_no_panics.py --base "$BASE_SHA" --head HEAD | |
| gateway-boundaries: | |
| name: Gateway platform/feature boundaries | |
| needs: changes | |
| if: needs.changes.outputs.has_code == 'true' || needs.changes.outputs.has_boundary_check == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Check that platform/ has no back-edges into handlers/ or features/ | |
| run: python3 scripts/check_gateway_boundaries.py | |
| - name: Self-test the boundary script | |
| run: python3 scripts/check_gateway_boundaries.py test | |
| code-style: | |
| name: Code Style (fmt + clippy) | |
| runs-on: ubuntu-latest | |
| if: always() | |
| needs: | |
| - changes | |
| - clippy-matrix | |
| - format | |
| - gateway-js-syntax | |
| - clippy | |
| - clippy-windows | |
| - deny-check | |
| - reborn-cli-smoke | |
| - no-panics | |
| - gateway-boundaries | |
| steps: | |
| - run: | | |
| if [[ "${{ needs.changes.outputs.has_code }}" == "false" ]]; then | |
| echo "No code changes — style checks skipped correctly" | |
| exit 0 | |
| fi | |
| for job_result in \ | |
| "format=${{ needs.format.result }}" \ | |
| "gateway-js-syntax=${{ needs.gateway-js-syntax.result }}" \ | |
| "clippy=${{ needs.clippy.result }}" \ | |
| "deny-check=${{ needs.deny-check.result }}" \ | |
| "gateway-boundaries=${{ needs.gateway-boundaries.result }}"; do | |
| name="${job_result%%=*}" | |
| result="${job_result##*=}" | |
| if [[ "$result" != "success" ]]; then | |
| echo "$name failed: $result" | |
| exit 1 | |
| fi | |
| done | |
| for job_result in \ | |
| "no-panics=${{ needs.no-panics.result }}" \ | |
| "reborn-cli-smoke=${{ needs.reborn-cli-smoke.result }}" \ | |
| "clippy-windows=${{ needs.clippy-windows.result }}"; do | |
| name="${job_result%%=*}" | |
| result="${job_result##*=}" | |
| if [[ "$result" != "success" && "$result" != "skipped" ]]; then | |
| echo "$name failed: $result" | |
| exit 1 | |
| fi | |
| done |