Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ jobs:
python/tests/test_relation_provenance_contract.py
python/tests/test_ci_workflow_contract.py
python/tests/test_source_test_hygiene.py
python/tests/test_structural_debt_ceilings.py
python/tests/test_triangle_benchmark_runner.py

# The CAVIAR and maritime example suites on CPU (review follow-up:
Expand Down
101 changes: 97 additions & 4 deletions .github/workflows/cuda-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ on:
branches: [main]
pull_request:
branches: [main]
# The full workspace test suite is too long to run on every pull request, so
# it runs here every night against main. Before this it ran under
# workflow_dispatch alone, which means it ran only when a human remembered:
# a regression once sat on main until an external run happened to find it.
schedule:
- cron: "0 2 * * *"
workflow_dispatch:
inputs:
reviewed_sha:
Expand All @@ -16,7 +22,11 @@ permissions:
contents: read

concurrency:
group: cuda-ci-${{ github.ref }}
# The event name is part of the group so that a push to main cannot cancel a
# nightly full test run that is already an hour in. Pull-request runs still
# supersede their own earlier commits, which is the behaviour this key exists
# for.
group: cuda-ci-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: true

env:
Expand Down Expand Up @@ -46,7 +56,7 @@ jobs:
run: |
set -euo pipefail
case "$EVENT_NAME" in
workflow_dispatch)
workflow_dispatch|schedule)
relevant=true
;;
pull_request)
Expand Down Expand Up @@ -74,8 +84,9 @@ jobs:

rust-tests:
if: >-
github.event_name == 'workflow_dispatch' &&
github.ref == 'refs/heads/main'
github.event_name == 'schedule' ||
(github.event_name == 'workflow_dispatch' &&
github.ref == 'refs/heads/main')
runs-on: [self-hosted, linux, x64, cuda]
timeout-minutes: 120
steps:
Expand All @@ -96,13 +107,51 @@ jobs:
- name: Cargo test (release)
run: RUST_TEST_THREADS=1 cargo test --workspace --all-targets --release

# The device-facing slice of the Rust suite, on every pull request from this
# repository. `rust-tests` above covers the whole workspace but takes up to
# two hours, so it runs nightly; this job is the part that must not reach main
# unverified — the two crates whose entire purpose is the GPU, including the
# certification suite in `xlog-gpu/tests`.
#
# It carries no path filter on purpose. A filter deciding which pull requests
# get GPU coverage is the same mechanism that let a broken test sit on main:
# whatever the filter misses is exactly what nobody checks. On a warm
# self-hosted runner a documentation-only pull request rebuilds nothing.
cuda-slice:
name: cuda-slice
if: >-
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository
runs-on: [self-hosted, linux, x64, cuda]
timeout-minutes: 60
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ env.TARGET_SHA }}
persist-credentials: false
- name: Verify the exact checked-out commit
shell: bash
run: |
set -euo pipefail
if [[ ! "$TARGET_SHA" =~ ^[0-9a-f]{40}$ ]]; then
echo "TARGET_SHA must be a full lowercase commit SHA" >&2
exit 1
fi
test "$(git rev-parse HEAD)" = "$TARGET_SHA"
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- name: Cargo test (device crates, release)
run: >-
RUST_TEST_THREADS=1 cargo test --all-targets --release
-p xlog-cuda -p xlog-gpu

python-wheel-gpu:
name: python-wheel-gpu
needs: cuda-changes
if: >-
needs.cuda-changes.result == 'success' &&
needs.cuda-changes.outputs.relevant == 'true' &&
(github.event_name == 'push' ||
github.event_name == 'schedule' ||
(github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') ||
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository))
Expand Down Expand Up @@ -564,3 +613,47 @@ jobs:
--relevant "$RELEVANT" \
--classification-result "$CLASSIFICATION_RESULT" \
--gpu-result "$GPU_RESULT"

# A nightly run whose failure reaches nobody is a cron job, not a gate. The
# scheduled full test run therefore reports into an issue: it comments on the
# open one if a previous night already failed, so a long breakage is one
# thread rather than a new issue every morning.
report-scheduled-failure:
name: report-scheduled-failure
needs: [rust-tests, python-wheel]
# Anything but success, not `failure()`. A job no self-hosted runner picks up
# stays queued for 24 hours and is then cancelled, and `failure()` excludes
# a cancellation — so the one outcome that means "the nightly did not run at
# all" would have reported nothing. `always()` is what lets this job run
# after a cancelled dependency.
if: >-
${{ always() && github.event_name == 'schedule' &&
(needs.rust-tests.result != 'success' ||
needs.python-wheel.result != 'success') }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Open or update the nightly failure issue
shell: bash
env:
GH_TOKEN: ${{ github.token }}
TITLE: "cuda-ci: nightly full workspace test run is not green"
RUST_TESTS_RESULT: ${{ needs.rust-tests.result }}
WHEEL_RESULT: ${{ needs.python-wheel.result }}
run: |
set -euo pipefail
run_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
# `cancelled` here usually means no self-hosted CUDA runner accepted the
# job within GitHub's 24-hour queue limit, which reads very differently
# from a test failure. Report the outcome rather than assuming one.
outcome="rust-tests: $RUST_TESTS_RESULT, python-wheel: $WHEEL_RESULT"
existing="$(gh issue list --repo "$GITHUB_REPOSITORY" --state open \
--search "$TITLE in:title" --json number --jq '.[0].number // empty')"
if [ -n "$existing" ]; then
gh issue comment "$existing" --repo "$GITHUB_REPOSITORY" \
--body "Still not green on \`$TARGET_SHA\` ($outcome): $run_url"
else
gh issue create --repo "$GITHUB_REPOSITORY" --title "$TITLE" \
--body "The nightly run of \`cargo test --workspace --all-targets --release\` did not succeed on \`$TARGET_SHA\` ($outcome): $run_url"
fi
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,19 @@ crates/pyxlog/python/pyxlog/*.so

.codex
docs/*.zip

# Local agent-tooling telemetry. Written outside this repository and appended
# to while a checkout sits idle, which made every working tree accumulate an
# uncommitted change to a tracked file.
artifact_gate.jsonl

# Internal working artifacts: audit ledgers, remediation plans, handoffs,
# generated reports and scratch worktrees. Findings live outside this
# repository, one issue per finding, and a release tree carries none of them.
# Named here so an ordinary `git add -A` cannot put them back.
/.analysis/
/wt-*/
/clippy-report.txt
/*-handoff-*.md
/docs/architecture-debt.md
/docs/xlog-*debt*.md
21 changes: 0 additions & 21 deletions ENGINEERING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,6 @@ substitute for the requested implementation.
- Failures must be explicit, typed, and actionable. Never silently fall back to a less
capable backend, stale result, default configuration, host path, or approximate
behavior.
- Selecting a different route that returns the identical result is not a fallback in that
sense, and may be invisible to the caller. The WCOJ dispatcher is the worked example,
and its two kinds of decline have different standing. A real layout or kernel failure
goes through `wcoj_decline_on_error`, which increments a counter, logs, and raises
instead under `XLOG_WCOJ_STRICT` — that one is observable at runtime. A structural
decline — gate off, shape mismatch, missing buffer — returns `Ok(None)`, the
post-optimizer binary-join tree runs verbatim over the same rows, and **nothing observes
it at runtime at all**. Its only check is a source-level cap in
`python/tests/test_structural_debt_ceilings.py`, which stops the class growing but tells
an operator nothing during a run. Adding a structural decline is therefore allowed and
bounded; adding one that changes the answer is not allowed by the rule above, and no
cap makes it so.
- Do not add legacy branches or compatibility shims. When replacing an internal path,
migrate its callers and remove the obsolete path in the same change. A public API
migration that genuinely requires a transition is separate, explicitly approved
Expand All @@ -87,15 +75,6 @@ substitute for the requested implementation.
mapping where applicable.
- Do not merge commented-out code, required behavior left as `TODO` or `FIXME`, knowingly
unreachable paths, unused public functions, or incomplete migrations.
- That rule is not yet met everywhere, and the gap is measured rather than implied: 105
`pub fn` outside `crates/pyxlog` have no reference anywhere in workspace Rust source,
and `crates/xlog-cuda-tests/src/harness/validators.rs` is 709 lines of them. `pub` in a
library crate suppresses `dead_code`, so no lint reports this. `crates/pyxlog` is
excluded on purpose: a `#[pymethods] pub fn` is reached from Python and never from
Rust, so the same measurement would call 21 live entry points dead. The count is held
at its 2026-08-30 value by `python/tests/test_structural_debt_ceilings.py`: a new
unreferenced public function fails CI, and lowering the ceiling is an ordinary pull
request. It bounds a class; it is not a list of items proven safe to delete.
- Do not defer correctness, safety, cleanup, documentation, or required validation as
technical debt. If the proper solution cannot fit the approved scope, stop and obtain
a scope decision instead of landing a temporary substitute.
Expand Down
3 changes: 0 additions & 3 deletions artifact_gate.jsonl

This file was deleted.

Loading
Loading