From 98d3bafabfbfb2bca3b583101a3e5e6d4ba4a13f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 20 Aug 2026 17:24:06 +0000 Subject: [PATCH 1/3] ci: fan distcheck source changes into the SDK workflows The `distcheck` job in dirsql-python-ci and dirsql-typescript-ci invokes `internals/distcheck` (`uv run --project internals/distcheck dirsql-distcheck python` / `... node`), but neither workflow watched that package, and internals-distcheck-ci runs only its conventions lane. A PR changing internals/distcheck/src/** could therefore merge without either publishability flow it changed ever executing. Both workflows now watch `internals/distcheck/src/**` and `internals/distcheck/pyproject.toml` on push and pull_request. `tests/**` stays out: the package's own tests are internals-distcheck-ci's lane, and nothing in the SDK workflows runs them. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01T7Wu2kXb8q3DktFa4H4tqE --- .github/workflows/dirsql-python-ci.yml | 6 ++++++ .github/workflows/dirsql-typescript-ci.yml | 6 ++++++ .github/workflows/internals-distcheck-ci.yml | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dirsql-python-ci.yml b/.github/workflows/dirsql-python-ci.yml index 0df152c44..31d1f98e7 100644 --- a/.github/workflows/dirsql-python-ci.yml +++ b/.github/workflows/dirsql-python-ci.yml @@ -2,12 +2,16 @@ name: dirsql Python CI # packages/rust/** fans in: the core compiles into the binding, and # [e2e].extra_scope means a core change stales this package's attestation. +# internals/distcheck/** fans in: the `distcheck` job below is the only +# executor of those flows; its own tests stay with internals-distcheck-ci. on: push: branches: [main] paths: - 'packages/python/**' - 'packages/rust/**' + - 'internals/distcheck/src/**' + - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' @@ -22,6 +26,8 @@ on: - '!packages/rust/changelog.d/**' - '!packages/rust/migrations.d/**' - '!packages/rust/README.md' + - 'internals/distcheck/src/**' + - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' diff --git a/.github/workflows/dirsql-typescript-ci.yml b/.github/workflows/dirsql-typescript-ci.yml index b2bd5bef3..33da8e10a 100644 --- a/.github/workflows/dirsql-typescript-ci.yml +++ b/.github/workflows/dirsql-typescript-ci.yml @@ -2,12 +2,16 @@ name: dirsql TypeScript CI # packages/rust/** fans in: the core compiles into the binding, and # [e2e].extra_scope means a core change stales this package's attestation. +# internals/distcheck/** fans in: the `distcheck` job below is the only +# executor of those flows; its own tests stay with internals-distcheck-ci. on: push: branches: [main] paths: - 'packages/ts/**' - 'packages/rust/**' + - 'internals/distcheck/src/**' + - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' @@ -22,6 +26,8 @@ on: - '!packages/rust/changelog.d/**' - '!packages/rust/migrations.d/**' - '!packages/rust/README.md' + - 'internals/distcheck/src/**' + - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' diff --git a/.github/workflows/internals-distcheck-ci.yml b/.github/workflows/internals-distcheck-ci.yml index db64e3de5..bf1dcdad1 100644 --- a/.github/workflows/internals-distcheck-ci.yml +++ b/.github/workflows/internals-distcheck-ci.yml @@ -1,8 +1,8 @@ name: Internals distcheck CI # Verification for the internals/distcheck uv package (the dirsql-distcheck -# publishability flows). Consumers (the SDK test workflows' distcheck jobs) -# are deliberately not fanned out to; this lane's own gates are the guard. +# publishability flows). src/** also fans out to the SDK workflows, whose +# distcheck jobs execute those flows; tests/** is this lane's alone. on: pull_request: paths: From 4d0e4b986d0cd13fbf47f81f762d7cf030941729 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 20 Aug 2026 17:35:43 +0000 Subject: [PATCH 2/3] ci: run the distcheck flows in their own lane, not the SDK lanes Reverses the fan-out approach of the previous commit. Adding internals/distcheck/** to the SDK workflows' paths broke the naming contract -- dirsql-python-ci is the Python package's lane -- and pulled 55 check runs (ruff, ty, the 3.10/3.12/3.13 matrices, binding tests, mutation, e2e attestation) into a change to repo tooling none of them touch. That is the fan-out #834 removed. The gap it was closing is real: internals-distcheck-ci runs conventions gates only, none of which invokes a flow, and tests/integration/ self-skips without a built binary that this lane never builds. So the flows this package ships had no CI execution of their own. Close it in the lane that owns the package instead: python-flow and node-flow run `dirsql-distcheck python` / `... node` directly, building the SDK artifacts the flows consume the same way the SDK workflows' distcheck jobs do. The SDK jobs stay -- a packages/python change must still prove the wheel is publishable -- and neither workflow watches the other's directory. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01T7Wu2kXb8q3DktFa4H4tqE --- .github/workflows/dirsql-python-ci.yml | 6 -- .github/workflows/dirsql-typescript-ci.yml | 6 -- .github/workflows/internals-distcheck-ci.yml | 82 +++++++++++++++++++- internals/distcheck/README.md | 8 +- 4 files changed, 86 insertions(+), 16 deletions(-) diff --git a/.github/workflows/dirsql-python-ci.yml b/.github/workflows/dirsql-python-ci.yml index 31d1f98e7..0df152c44 100644 --- a/.github/workflows/dirsql-python-ci.yml +++ b/.github/workflows/dirsql-python-ci.yml @@ -2,16 +2,12 @@ name: dirsql Python CI # packages/rust/** fans in: the core compiles into the binding, and # [e2e].extra_scope means a core change stales this package's attestation. -# internals/distcheck/** fans in: the `distcheck` job below is the only -# executor of those flows; its own tests stay with internals-distcheck-ci. on: push: branches: [main] paths: - 'packages/python/**' - 'packages/rust/**' - - 'internals/distcheck/src/**' - - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' @@ -26,8 +22,6 @@ on: - '!packages/rust/changelog.d/**' - '!packages/rust/migrations.d/**' - '!packages/rust/README.md' - - 'internals/distcheck/src/**' - - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' diff --git a/.github/workflows/dirsql-typescript-ci.yml b/.github/workflows/dirsql-typescript-ci.yml index 33da8e10a..b2bd5bef3 100644 --- a/.github/workflows/dirsql-typescript-ci.yml +++ b/.github/workflows/dirsql-typescript-ci.yml @@ -2,16 +2,12 @@ name: dirsql TypeScript CI # packages/rust/** fans in: the core compiles into the binding, and # [e2e].extra_scope means a core change stales this package's attestation. -# internals/distcheck/** fans in: the `distcheck` job below is the only -# executor of those flows; its own tests stay with internals-distcheck-ci. on: push: branches: [main] paths: - 'packages/ts/**' - 'packages/rust/**' - - 'internals/distcheck/src/**' - - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' @@ -26,8 +22,6 @@ on: - '!packages/rust/changelog.d/**' - '!packages/rust/migrations.d/**' - '!packages/rust/README.md' - - 'internals/distcheck/src/**' - - 'internals/distcheck/pyproject.toml' - 'Cargo.toml' - 'Cargo.lock' - 'testing-conventions.toml' diff --git a/.github/workflows/internals-distcheck-ci.yml b/.github/workflows/internals-distcheck-ci.yml index bf1dcdad1..18d909fe9 100644 --- a/.github/workflows/internals-distcheck-ci.yml +++ b/.github/workflows/internals-distcheck-ci.yml @@ -1,8 +1,9 @@ name: Internals distcheck CI # Verification for the internals/distcheck uv package (the dirsql-distcheck -# publishability flows). src/** also fans out to the SDK workflows, whose -# distcheck jobs execute those flows; tests/** is this lane's alone. +# publishability flows). Consumers -- the SDK workflows' distcheck jobs -- are +# deliberately not fanned out to: a change here runs the flows in this lane, +# not the whole Python and TypeScript matrices. on: pull_request: paths: @@ -30,3 +31,80 @@ jobs: source: internals/distcheck/src base: ${{ github.event.pull_request.base.sha || 'origin/main' }} gates: '["colocated-test", "unit-lint", "integration-lint", "unit-coverage", "mutation"]' + + # The gates above never execute a flow, and tests/integration/ self-skips + # without a built binary, so these two jobs are the only thing that runs the + # code this package ships. They build the SDK artifacts the flows consume for + # the same reason the SDK workflows' distcheck jobs do -- the flows build, + # pack, install and run them. + python-flow: + name: dirsql-distcheck python + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Rust cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: ". -> target" + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + python-version: "3.13" + + - name: Install dependencies (maturin) + run: uv sync + working-directory: packages/python + + - name: Put maturin on PATH + run: echo "$PWD/packages/python/.venv/bin" >> "$GITHUB_PATH" + + - name: Build dirsql CLI binary + run: cargo build -p dirsql --features cli + + - name: Run the python flow (build -> pack -> install -> run) + run: uv run --project internals/distcheck dirsql-distcheck python + + node-flow: + name: dirsql-distcheck node + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Rust cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: ". -> target" + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: "24" + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 11 + + - name: Install uv + uses: astral-sh/setup-uv@v7 + + - name: Install dependencies + working-directory: packages/ts + run: pnpm install + + # No `build` job to pull an artifact from, unlike dirsql-typescript-ci: + # the flow needs the staged host CLI under packages/ts/build/. + - name: Build native module + stage platform + working-directory: packages/ts + run: pnpm build + + - name: Run the node flow (build -> pack -> install -> run) + run: uv run --project internals/distcheck dirsql-distcheck node diff --git a/internals/distcheck/README.md b/internals/distcheck/README.md index d165f6bda..404768e83 100644 --- a/internals/distcheck/README.md +++ b/internals/distcheck/README.md @@ -51,7 +51,7 @@ Each flow follows the same shape (mirroring `internals/checks`): and calls `gate.run`, turning a `DistcheckError` into a non-zero exit. Every module (except empty `__init__.py`s) carries a colocated `*_test.py`, -gated by `conventions.yml`'s `internals-distcheck` job: `colocated-test`, +gated by `internals-distcheck-ci.yml`'s `internals-distcheck` job: `colocated-test`, `unit-lint`, `integration-lint`, `unit-coverage`, and `mutation`. ## Test tiers @@ -64,7 +64,11 @@ gated by `conventions.yml`'s `internals-distcheck` job: `colocated-test`, execution is the `dirsql-distcheck ` job, which builds them first. No e2e tier / attestation: `tests/integration/` is the outermost tier, and the -CI `distcheck` jobs (`python-test.yml` / `ts-test.yml`) run the real flows directly. +`python-flow` / `node-flow` jobs in `internals-distcheck-ci.yml` run the real +flows directly. They are this package's only CI execution of its own code -- the +gates above never invoke a flow. The SDK workflows run the same flows against +their own package, but they do not watch this directory, so a change here must +be verified in this lane. ```bash uv run --project internals/distcheck python -m pytest internals/distcheck/src internals/distcheck/tests -q From c67795cbfba7ffc49951fd9d3b162b239d202936 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 20 Aug 2026 17:45:02 +0000 Subject: [PATCH 3/3] ci: trim the added comments, drop the vestigial CLI build The comments restated what the job names and steps already say; only the "consumers are deliberately not fanned out to" line carries a decision a reader could not infer, so that is what is left. `cargo build -p dirsql --features cli` was copied from dirsql-python-ci's distcheck job without checking whether it is still needed. It is not: python_flow/gate.py records that #738 dropped dirsql/_binary/, so the wheel's extension module carries the CLI and there is nothing to stage. The Rust toolchain stays -- maturin compiles the extension. The same dead step is still in dirsql-python-ci and wants its own cleanup. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01T7Wu2kXb8q3DktFa4H4tqE --- .github/workflows/internals-distcheck-ci.yml | 15 ++------------- internals/distcheck/README.md | 5 +---- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/.github/workflows/internals-distcheck-ci.yml b/.github/workflows/internals-distcheck-ci.yml index 18d909fe9..b37aad4ab 100644 --- a/.github/workflows/internals-distcheck-ci.yml +++ b/.github/workflows/internals-distcheck-ci.yml @@ -1,9 +1,8 @@ name: Internals distcheck CI # Verification for the internals/distcheck uv package (the dirsql-distcheck -# publishability flows). Consumers -- the SDK workflows' distcheck jobs -- are -# deliberately not fanned out to: a change here runs the flows in this lane, -# not the whole Python and TypeScript matrices. +# publishability flows). Consumers (the SDK workflows' distcheck jobs) are +# deliberately not fanned out to; this lane runs the flows itself. on: pull_request: paths: @@ -32,11 +31,6 @@ jobs: base: ${{ github.event.pull_request.base.sha || 'origin/main' }} gates: '["colocated-test", "unit-lint", "integration-lint", "unit-coverage", "mutation"]' - # The gates above never execute a flow, and tests/integration/ self-skips - # without a built binary, so these two jobs are the only thing that runs the - # code this package ships. They build the SDK artifacts the flows consume for - # the same reason the SDK workflows' distcheck jobs do -- the flows build, - # pack, install and run them. python-flow: name: dirsql-distcheck python runs-on: ubuntu-latest @@ -63,9 +57,6 @@ jobs: - name: Put maturin on PATH run: echo "$PWD/packages/python/.venv/bin" >> "$GITHUB_PATH" - - name: Build dirsql CLI binary - run: cargo build -p dirsql --features cli - - name: Run the python flow (build -> pack -> install -> run) run: uv run --project internals/distcheck dirsql-distcheck python @@ -100,8 +91,6 @@ jobs: working-directory: packages/ts run: pnpm install - # No `build` job to pull an artifact from, unlike dirsql-typescript-ci: - # the flow needs the staged host CLI under packages/ts/build/. - name: Build native module + stage platform working-directory: packages/ts run: pnpm build diff --git a/internals/distcheck/README.md b/internals/distcheck/README.md index 404768e83..f143dc79a 100644 --- a/internals/distcheck/README.md +++ b/internals/distcheck/README.md @@ -65,10 +65,7 @@ gated by `internals-distcheck-ci.yml`'s `internals-distcheck` job: `colocated-te No e2e tier / attestation: `tests/integration/` is the outermost tier, and the `python-flow` / `node-flow` jobs in `internals-distcheck-ci.yml` run the real -flows directly. They are this package's only CI execution of its own code -- the -gates above never invoke a flow. The SDK workflows run the same flows against -their own package, but they do not watch this directory, so a change here must -be verified in this lane. +flows directly. ```bash uv run --project internals/distcheck python -m pytest internals/distcheck/src internals/distcheck/tests -q