-
Notifications
You must be signed in to change notification settings - Fork 0
Milestone 0 - ddx-core + scaffolding
#3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
alxmrs
wants to merge
22
commits into
main
Choose a base branch
from
m0
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
be6360c
First attempt at core (M0).
alxmrs ec8de5b
rm duckdb
alxmrs 6cca29b
code review tool
alxmrs ae7956c
added chainlink.
alxmrs 440140c
ignore autogen changelog -- it's not associated with GH issues, just …
alxmrs 18cecad
IAR 0
alxmrs f4d4981
IAR 1
alxmrs 4249759
Primary agent code review tool.
alxmrs b205913
IAR 2: Adversary wrote property/simulation tests. Was able to find an…
alxmrs d4c479e
Fix for the simulation test bug. hardening of the simulation test ora…
alxmrs 7eb3a0c
Copy edits.
alxmrs f55c642
Fuzz on a cron.
alxmrs 67a3cf3
cargo description copy edits.
alxmrs 6d8fbb4
Added copyright and license IDs to all rust code.
alxmrs 19d0689
Added license gen script.
alxmrs af1ee9a
Code attr
alxmrs 51e359d
Found a new bug given a new class of fuzz invariants!
alxmrs f4e781d
Full name as author.
alxmrs e1c65ba
Fixed additional test added through fuzzing.
alxmrs aafa0ba
impler: added CI
alxmrs 45b2ee4
more fuzz invariants
alxmrs dd6674e
more fuzz invariants
alxmrs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # report_fuzz_findings.sh — triage the nightly simulation-soak logs and, if any | ||
| # property failures were found, file (or update) a single GitHub issue with a | ||
| # reproducible repro. Invoked by .github/workflows/nightly-fuzz.yml. | ||
| # | ||
| # Anti-spam policy: at most ONE open `fuzz-finding` issue at a time. If one is | ||
| # already open, this appends the new run's findings as a comment instead of | ||
| # opening a duplicate — a persistent bug accumulates recurrences on one issue, | ||
| # and a fresh issue only opens once a human has triaged and closed the last one. | ||
| # | ||
| # Usage: report_fuzz_findings.sh <log-dir> | ||
| # Reads every `soak-*.log` under <log-dir>. Requires `gh` authenticated with | ||
| # `issues: write` (the workflow's GITHUB_TOKEN). | ||
| # | ||
| # Env (provided by the workflow, all optional — used only to enrich the body): | ||
| # GITHUB_RUN_ID, GITHUB_SHA, GITHUB_SERVER_URL, GITHUB_REPOSITORY | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| LOG_DIR=${1:?"usage: report_fuzz_findings.sh <log-dir>"} | ||
|
|
||
| shopt -s nullglob globstar | ||
| logs=("$LOG_DIR"/**/soak-*.log "$LOG_DIR"/soak-*.log) | ||
| if [ ${#logs[@]} -eq 0 ]; then | ||
| echo "No soak-*.log files found under $LOG_DIR; nothing to report." | ||
| exit 0 | ||
| fi | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Tally failures and collect a bounded, readable set of failure blocks. | ||
| # --------------------------------------------------------------------------- | ||
| total=0 | ||
| blocks="" # up to MAX_BLOCKS failure blocks, across all regions | ||
| env_line="" # rustc / os / sha, recorded by the soak step | ||
| region_summary="" | ||
| MAX_BLOCKS=8 | ||
| block_count=0 | ||
|
|
||
| for log in "${logs[@]}"; do | ||
| [ -f "$log" ] || continue | ||
| n=$(grep -c '^FAILURE (seed' "$log" 2>/dev/null || true) | ||
| n=${n:-0} | ||
| total=$((total + n)) | ||
|
|
||
| # The soak step records one `ENV ...` line at the top of each log. | ||
| if [ -z "$env_line" ]; then | ||
| env_line=$(grep -m1 '^ENV ' "$log" 2>/dev/null || true) | ||
| fi | ||
|
|
||
| base=$(grep -m1 '^SOAK start' "$log" 2>/dev/null | sed -n 's/.*base=\([0-9]*\).*/\1/p') | ||
| iters=$(grep -m1 '^SOAK done' "$log" 2>/dev/null | sed -n 's/.*iters=\([0-9]*\).*/\1/p') | ||
| region_summary+="- \`$(basename "$log")\`: base=${base:-?}, iters=${iters:-?}, failures=${n}"$'\n' | ||
|
|
||
| if [ "$n" -gt 0 ] && [ "$block_count" -lt "$MAX_BLOCKS" ]; then | ||
| # Extract each FAILURE block: the header plus its report lines, stopping at | ||
| # the next heartbeat / failure / summary line. | ||
| while IFS= read -r line; do | ||
| case "$line" in | ||
| "===BLOCK===") | ||
| block_count=$((block_count + 1)) | ||
| [ "$block_count" -ge "$MAX_BLOCKS" ] && break | ||
| ;; | ||
| *) blocks+="$line"$'\n' ;; | ||
| esac | ||
| done < <(awk ' | ||
| /^FAILURE \(seed/ { if (inblk) print "===BLOCK==="; inblk=1; print; next } | ||
| inblk == 1 { | ||
| if ($0 ~ /^HEARTBEAT/ || $0 ~ /^SOAK/ || $0 == "") { inblk=0; print "===BLOCK==="; next } | ||
| } | ||
| END { if (inblk) print "===BLOCK===" } | ||
| ' "$log") | ||
| fi | ||
| done | ||
|
|
||
| if [ "$total" -eq 0 ]; then | ||
| echo "Soak completed with 0 property failures. Nothing to file." | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Found $total property failure(s) across ${#logs[@]} region log(s); preparing issue." | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # A ready-to-paste repro from the first failing seed. The soak's per-iteration | ||
| # seed is `base + iter`, so re-running with DDX_SOAK_BASE set to a failing | ||
| # `seed=` value reproduces that exact case as iteration 0 (same depth + wrt). | ||
| # --------------------------------------------------------------------------- | ||
| first_seed=$(printf '%s' "$blocks" | sed -n 's/^FAILURE (seed=\([0-9]*\).*/\1/p' | head -1) | ||
| first_seed=${first_seed:-0} | ||
|
|
||
| run_url="${GITHUB_SERVER_URL:-https://github.com}/${GITHUB_REPOSITORY:-xqlsystems/ddx}/actions/runs/${GITHUB_RUN_ID:-local}" | ||
| date_utc=$(date -u '+%Y-%m-%d %H:%M UTC') | ||
|
|
||
| body_file=$(mktemp) | ||
| { | ||
| echo "**Nightly simulation-soak fuzz found ${total} property failure(s).**" | ||
| echo | ||
| echo "- Run: [${GITHUB_RUN_ID:-local}](${run_url})" | ||
| echo "- Commit: \`${GITHUB_SHA:-unknown}\`" | ||
| echo "- When: ${date_utc}" | ||
| [ -n "$env_line" ] && echo "- Build: \`${env_line#ENV }\`" | ||
| echo | ||
| echo "### Reproduce" | ||
| echo | ||
| echo "The soak's per-iteration seed is \`base + iter\`, so setting \`DDX_SOAK_BASE\`" | ||
| echo "to a failing \`seed=\` value re-runs that exact case as iteration 0. On the" | ||
| echo "same platform as the build above (floating-point transcendentals are not" | ||
| echo "bit-identical across OS/toolchain):" | ||
| echo | ||
| echo '```bash' | ||
| echo "DDX_SOAK_SECS=15 DDX_SOAK_BASE=${first_seed} \\" | ||
| echo " cargo test -p ddx-core --test simulation --release \\" | ||
| echo " -- --ignored --nocapture soak_continuous_property_fuzz" | ||
| echo '```' | ||
| echo | ||
| echo "The full per-region logs are attached to the workflow run as artifacts." | ||
| echo | ||
| echo "### Per-region summary" | ||
| echo | ||
| printf '%s\n' "$region_summary" | ||
| echo "### Failure samples (up to ${MAX_BLOCKS})" | ||
| echo | ||
| echo '```' | ||
| printf '%s' "$blocks" | ||
| echo '```' | ||
| echo | ||
| echo "> Triage note: the finite-difference oracle is gated against float" | ||
| echo "> cancellation (magnitude cap) and truncation/aliasing (Richardson" | ||
| echo "> self-consistency), so a surviving \`[finite-diff]\` disagreement should be" | ||
| echo "> a real rule bug — but confirm by reproducing before assuming. \`[render]\`" | ||
| echo "> and \`[self-consumption]\` failures are always real." | ||
| echo | ||
| echo "<!-- fuzz-run: ${GITHUB_RUN_ID:-local} -->" | ||
| } > "$body_file" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Ensure labels exist (idempotent), then dedup: comment on the single open | ||
| # fuzz-finding issue if one exists, else create a new one. | ||
| # --------------------------------------------------------------------------- | ||
| gh label create fuzz-finding --color B60205 \ | ||
| --description "Found by the nightly simulation-soak fuzz" 2>/dev/null || true | ||
| gh label create needs-triage --color FBCA04 \ | ||
| --description "Awaiting human triage" 2>/dev/null || true | ||
|
|
||
| existing=$(gh issue list --state open --label fuzz-finding \ | ||
| --json number --jq '.[0].number // empty' 2>/dev/null || true) | ||
|
|
||
| if [ -n "$existing" ]; then | ||
| echo "Open fuzz-finding issue #${existing} exists; commenting instead of filing a duplicate." | ||
| { | ||
| echo "### Recurred — run ${GITHUB_RUN_ID:-local} (${date_utc})" | ||
| echo | ||
| cat "$body_file" | ||
| } | gh issue comment "$existing" --body-file - | ||
| echo "Commented on #${existing}." | ||
| else | ||
| title="Nightly fuzz: ${total} property failure(s) in ddx-core simulation soak" | ||
| url=$(gh issue create --title "$title" \ | ||
| --label fuzz-finding --label needs-triage \ | ||
| --body-file "$body_file") | ||
| echo "Filed new issue: $url" | ||
| fi | ||
|
|
||
| rm -f "$body_file" |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # SPDX-FileCopyrightText: 2026 Alexander Merose <al@merose.com> & ddx Authors | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # Standard PR checks for ddx: formatting, lints, and the deterministic test | ||
| # suite. The property/fuzz suite (crates/ddx-core/tests/simulation.rs) is | ||
| # intentionally NOT run here — it is a separate, on-demand / soak concern (see | ||
| # its module docs) rather than a blocking PR gate — so these checks stay fast | ||
| # and deterministic. | ||
| name: CI | ||
|
|
||
| on: | ||
| pull_request: | ||
| push: | ||
| branches: [main] | ||
|
|
||
| # Cancel superseded runs on the same ref (e.g. a new push to a PR branch). | ||
| concurrency: | ||
| group: ci-${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| env: | ||
| CARGO_TERM_COLOR: always | ||
|
|
||
| jobs: | ||
| lint: | ||
| name: rustfmt + clippy | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| components: rustfmt, clippy | ||
| - uses: Swatinem/rust-cache@v2 | ||
| - name: rustfmt (check only) | ||
| run: cargo fmt --all --check | ||
| - name: clippy (warnings are errors) | ||
| run: cargo clippy --workspace --all-targets -- -D warnings | ||
|
|
||
| test: | ||
| name: tests (non-simulation) | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: dtolnay/rust-toolchain@stable | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth testing more than stable?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth testing more than stable? |
||
| - uses: Swatinem/rust-cache@v2 | ||
| # Everything except tests/simulation.rs (the property/fuzz suite). Split | ||
| # per target so a failure names the suite that broke. | ||
| - name: unit tests | ||
| run: cargo test --workspace --lib --bins | ||
| - name: integration tests | ||
| run: cargo test -p ddx-core --test rules --test rewrite --test roundtrip | ||
| - name: doctests | ||
| run: cargo test --workspace --doc | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| name: Nightly fuzz (ddx-core simulation soak) | ||
|
|
||
| # Runs the seed-reproducible property-fuzz soak (crates/ddx-core/tests/ | ||
| # simulation.rs :: soak_continuous_property_fuzz) over three disjoint random | ||
| # seed regions in parallel, then files/updates a single GitHub issue if any | ||
| # property (finite-difference numeric agreement, render fidelity, higher-order | ||
| # self-consumption) fails. | ||
| # | ||
| # Schedule: 08:00 America/Los_Angeles == 16:00 UTC (PST, UTC-8). GitHub cron is | ||
| # fixed-UTC and does NOT observe daylight saving, so during PDT (roughly | ||
| # Mar–Nov) this fires at 09:00 Pacific. Adjust the cron if you want it pinned to | ||
| # wall-clock Pacific year-round. | ||
| on: | ||
| schedule: | ||
| - cron: '0 16 * * *' | ||
| workflow_dispatch: | ||
| inputs: | ||
| duration_secs: | ||
| description: 'Soak wall-clock budget per region (seconds)' | ||
| required: false | ||
| default: '300' | ||
| base_override: | ||
| description: 'Base seed (optional; blank = derive a fresh one from the run id)' | ||
| required: false | ||
| default: '' | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: write | ||
|
|
||
| concurrency: | ||
| group: nightly-fuzz | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| soak: | ||
| name: soak region ${{ matrix.region }} | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 20 | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| region: [0, 1, 2] | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Toolchain info | ||
| run: rustc --version && cargo --version | ||
|
|
||
| - name: Build soak test binary | ||
| run: cargo test -p ddx-core --test simulation --release --no-run | ||
|
|
||
| - name: Run soak | ||
| run: | | ||
| set -o pipefail | ||
| SECS='${{ github.event.inputs.duration_secs || '300' }}' | ||
| OVERRIDE='${{ github.event.inputs.base_override }}' | ||
| REGION='${{ matrix.region }}' | ||
| # Disjoint region seed windows, monotonic across runs. run_number is a | ||
| # small, strictly-increasing counter — using it (not the ~10-digit | ||
| # run_id) keeps run_number * 1e8 far inside 64-bit range forever, and | ||
| # guarantees each region gets a fresh, non-overlapping seed window | ||
| # (a 5-min region explores < 1e7 seeds; regions are 1e7 apart, runs | ||
| # 1e8 apart). | ||
| if [ -n "$OVERRIDE" ]; then | ||
| BASE=$(( OVERRIDE + REGION * 10000000 )) | ||
| else | ||
| BASE=$(( GITHUB_RUN_NUMBER * 100000000 + REGION * 10000000 )) | ||
| fi | ||
| LOG="$PWD/soak-region-${REGION}.log" | ||
| echo "ENV rustc=$(rustc --version) os=${RUNNER_OS} sha=${GITHUB_SHA}" > "$LOG" | ||
| echo "Running soak: region=$REGION base=$BASE secs=$SECS" | ||
| # The soak asserts on failure (non-zero exit); don't let that abort the | ||
| # job — the report job decides what to do from the log contents. | ||
| set +e | ||
| DDX_SOAK_SECS="$SECS" DDX_SOAK_BASE="$BASE" DDX_SOAK_LOG="$LOG" \ | ||
| cargo test -p ddx-core --test simulation --release \ | ||
| -- --ignored --nocapture soak_continuous_property_fuzz | ||
| echo "soak exit code: $?" | ||
| set -e | ||
| echo "---- log tail ----" | ||
| tail -n 5 "$LOG" || true | ||
|
|
||
| - name: Upload region log | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: soak-log-${{ matrix.region }} | ||
| path: soak-region-${{ matrix.region }}.log | ||
| if-no-files-found: warn | ||
|
|
||
| report: | ||
| name: triage & file issue | ||
| needs: soak | ||
| if: always() | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Download all region logs | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| path: logs | ||
|
|
||
| - name: Triage and file/update issue | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| chmod +x .github/scripts/report_fuzz_findings.sh | ||
| .github/scripts/report_fuzz_findings.sh logs |
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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this addition! Consider also adding a
Makefileorjustfilewhich makes it super easy for developers to make these checks as code is created. This might also help with things like builds / etc.