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
67 changes: 43 additions & 24 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
# SPDX-License-Identifier: MPL-2.0
# Dependabot configuration for RSR-compliant repositories
# Covers common ecosystems - remove unused ones for your project
# Dependabot configuration for vcl-ut.
#
# Trimmed from the RSR template on 2026-07-21. Only ecosystems with an actual
# manifest in this repository are declared. Declaring an ecosystem with no
# manifest makes the corresponding Dependabot job fail on EVERY run — this
# repository was failing `hex`, `pip`, `nix` and `npm_and_yarn` weekly for
# exactly that reason (measured: 5 consecutive red runs from 2026-07-13).
#
# vcl-ut is Rust-only. Verified absent at the root: mix.exs, package.json,
# requirements.txt, pyproject.toml, flake.nix.
#
# Cargo note: this repository has FIVE cargo workspace roots, not one. A single
# `directory: "/"` entry covers the root workspace only, so the crates holding
# most of the actual code were invisible to Dependabot. Each self-contained
# workspace root is now declared explicitly:
#
# / root workspace (vcl-ut, fmt, lint, core)
# /src/interface/parse parser + decider + vclt-gate <- the real spine
# /src/interface/attest depends on ../parse (in-repo)
# /src/interface/recompute-wasm depends on ../parse (in-repo)
#
# DELIBERATELY EXCLUDED: /src/interface/echidna-client. It depends on
# ../../interface, which in turn carries an out-of-tree path dependency
# (`echidna-core = { path = "../../../echidna/..." }`). Dependabot cannot
# resolve a path dependency outside the repository, so declaring it would
# reintroduce exactly the always-red job this trim removes.

version: 2
updates:
# GitHub Actions - always include
# GitHub Actions always include.
- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand All @@ -14,38 +38,33 @@ updates:
patterns:
- "*"

# Rust/Cargo
# Rust/Cargo — one entry per self-contained workspace root.
#
# `open-pull-requests-limit: 0` suppresses routine version-update PRs while
# leaving Dependabot SECURITY PRs flowing. The previous `ignore: "*" patch`
# rule also silenced security PRs under GitHub's current Dependabot
# behaviour. See rsr-template-repo commit 78b050e and
# 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md.
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
# `open-pull-requests-limit: 0` suppresses routine version-update PRs
# while leaving Dependabot SECURITY PRs flowing. The previous
# `ignore: "*" patch` rule also silenced security PRs under GitHub\'s
# current Dependabot behaviour. See rsr-template-repo commit 78b050e
# and 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md.
open-pull-requests-limit: 0

# Elixir/Mix
- package-ecosystem: "mix"
directory: "/"
schedule:
interval: "weekly"

# Node.js/npm
- package-ecosystem: "npm"
directory: "/"
- package-ecosystem: "cargo"
directory: "/src/interface/parse"
schedule:
interval: "weekly"
open-pull-requests-limit: 0

# Python/pip
- package-ecosystem: "pip"
directory: "/"
- package-ecosystem: "cargo"
directory: "/src/interface/attest"
schedule:
interval: "weekly"
open-pull-requests-limit: 0

# Nix flakes
- package-ecosystem: "nix"
directory: "/"
- package-ecosystem: "cargo"
directory: "/src/interface/recompute-wasm"
schedule:
interval: "weekly"
open-pull-requests-limit: 0
40 changes: 20 additions & 20 deletions .github/workflows/dogfood-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -280,26 +280,26 @@ jobs:

# Validate TOML structure using Python 3.11+ tomllib
python3 -c "
import tomllib, sys
with open('eclexiaiser.toml', 'rb') as f:
data = tomllib.load(f)
project = data.get('project', {})
if not project.get('name', '').strip():
print('ERROR: project.name is required', file=sys.stderr)
sys.exit(1)
functions = data.get('functions', [])
if not functions:
print('ERROR: at least one [[functions]] entry is required', file=sys.stderr)
sys.exit(1)
for fn in functions:
if not fn.get('name', '').strip():
print('ERROR: function name cannot be empty', file=sys.stderr)
sys.exit(1)
if not fn.get('source', '').strip():
print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr)
sys.exit(1)
print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))')
" || {
import tomllib, sys
with open('eclexiaiser.toml', 'rb') as f:
data = tomllib.load(f)
project = data.get('project', {})
if not project.get('name', '').strip():
print('ERROR: project.name is required', file=sys.stderr)
sys.exit(1)
functions = data.get('functions', [])
if not functions:
print('ERROR: at least one [[functions]] entry is required', file=sys.stderr)
sys.exit(1)
for fn in functions:
if not fn.get('name', '').strip():
print('ERROR: function name cannot be empty', file=sys.stderr)
sys.exit(1)
if not fn.get('source', '').strip():
print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr)
sys.exit(1)
print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))')
" || {
echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details"
exit 1
}
Expand Down
43 changes: 32 additions & 11 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
# SPDX-License-Identifier: MPL-2.0
#
# e2e.yml — Root-workspace test gate.
#
# The root workspace has four members (vcl-total, vcltotal-fmt, vcltotal-lint,
# vcltotal-core) and its whole test surface lives in `tests/`, because the root
# crate is a re-export facade over fmt + lint. Per-crate UNIT counts are
# therefore all zero, which makes a truncated `cargo test` log look like an
# empty gate; it is not. Measured 2026-07-21: 102 tests.
#
# tests/e2e_test.rs 20
# tests/fuzz_test.rs 13
# tests/integration_test.rs 59
# tests/property_test.rs 10
#
# This job previously ran only property_test + integration_test, so 33 of the
# 102 — every e2e and fuzz test — never ran in CI. It now runs the whole
# workspace.
#
# The former "Provide echidna sibling" steps have been removed. They cloned a
# whole repository on every run for nothing: `src/interface` (the member that
# carries the external `echidna-core` path-dep) is deliberately NOT a root
# workspace member, so neither `cargo test --workspace` nor `tests/e2e.sh`
# ever resolves it. Verified 2026-07-21 by running both with no sibling
# present: 102 tests pass, e2e.sh reports 19/19. echidna-client is gated
# separately in backend-matrix.yml, which does need the sibling.

name: E2E, Property and Aspect Tests
on:
push: { branches: [main] }
Expand All @@ -15,27 +41,22 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
# echidna-core path-dependency (src/interface/Cargo.toml) — provide as sibling.
- name: Provide echidna sibling
run: git clone --depth 1 https://github.com/hyperpolymath/echidna ../echidna
- name: Run E2E validation
run: bash tests/e2e.sh
property:
name: Property and integration tests
name: Root workspace tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Install Rust
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
# echidna-core path-dependency (src/interface/Cargo.toml) — provide as sibling.
- name: Provide echidna sibling
run: git clone --depth 1 https://github.com/hyperpolymath/echidna ../echidna
- name: Run property tests
run: cargo test --test property_test
- name: Run integration tests
run: cargo test --test integration_test
# Whole workspace, all targets — not a hand-picked subset. Previously
# `--test property_test` + `--test integration_test` only, which silently
# skipped tests/e2e_test.rs and tests/fuzz_test.rs.
- name: Run root workspace tests (expect 102)
run: cargo test --workspace --all-targets --locked
aspect:
name: Aspect tests
runs-on: ubuntu-latest
Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/satellite-crates-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# satellite-crates-gate.yml — Gates the self-contained satellite workspaces.
#
# vcl-ut has FIVE cargo workspace roots, not one. Before this workflow, CI
# covered only three of them:
#
# / e2e.yml
# /src/interface/parse parse-gate.yml
# /src/interface/echidna-client backend-matrix.yml (needs echidna sibling)
# /src/interface/attest NOTHING <- gated here
# /src/interface/recompute-wasm NOTHING <- gated here
#
# The cost of that gap was measured on 2026-07-21: both ungated crates had
# stopped compiling. `ast::Statement` gained the S1 consonance field `verb`
# (DECLARE / ASSERT / RETRACT / MERGE / ...), and neither crate's test module
# was updated, so both failed with E0063 `missing field 'verb'`. Their
# libraries still built, so nothing downstream noticed; 12 tests had simply
# stopped running. Silent rot in exactly the crates that carry the
# attestation and recompute boundaries.
#
# Both crates are self-contained (in-repo path deps only), so unlike
# echidna-client they need no sibling checkout and can be gated cheaply.
#
# Tracked: vcl-ut#25.

name: Satellite Crates Gate

on:
pull_request:
branches: ['**']
push:
branches: [main, master]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
satellite-gate:
name: ${{ matrix.crate }} — clippy / tests
runs-on: ubuntu-latest
timeout-minutes: 15

strategy:
fail-fast: false
matrix:
crate: [attest, recompute-wasm]

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

# rustup is preinstalled on ubuntu-latest; no third-party action
# (avoids the action-pinning / deprecated-cache hazards). Mirrors
# parse-gate.yml deliberately.
- name: Pin toolchain + components
run: |
set -euo pipefail
rustup show active-toolchain || rustup default stable
rustup component add clippy
cargo --version && cargo clippy --version

# Operate via the manifest path so CI never traverses the parent
# virtual workspace, whose `src/interface` member carries an external
# path-dep that does not resolve in a standalone checkout.
#
# `--locked` is deliberately NOT used: these two lockfiles drifted while
# the crates were ungated. They are regenerated and committed as part of
# the repair; once a Dependabot cycle has run against them, `--locked`
# should be restored here to make lockfile drift itself a gate.
- name: Clippy — warnings are errors
run: |
set -euo pipefail
cargo clippy --manifest-path src/interface/${{ matrix.crate }}/Cargo.toml \
--all-targets -- -D warnings

- name: Tests
run: |
set -euo pipefail
cargo test --manifest-path src/interface/${{ matrix.crate }}/Cargo.toml
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ version = "0.1.0"
edition = "2021"
license = "MPL-2.0"
authors = ["Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>"]
repository = "https://github.com/hyperpolymath/vql-ut"
repository = "https://github.com/hyperpolymath/vcl-ut"
description = "VCL-total: 10-level type-safe query language for VeriSimDB"

# The top-level crate re-exports the formatter and linter for integration testing.
Expand Down
Loading
Loading