Skip to content

Scheduled drift detection: weekly full-suite re-run against fresh resolves - #107

Merged
AlexanderFengler merged 2 commits into
mainfrom
drift-detection
Aug 9, 2026
Merged

Scheduled drift detection: weekly full-suite re-run against fresh resolves#107
AlexanderFengler merged 2 commits into
mainfrom
drift-detection

Conversation

@AlexanderFengler

@AlexanderFengler AlexanderFengler commented Aug 6, 2026

Copy link
Copy Markdown
Member

Part of the ecosystem self-healing rollout (aggregation layer: lnccbrown/HSSMSpine#35; siblings: lnccbrown/HSSM#1143, lnccbrown/ssm-simulators#318).

  • new drift.yml: weekly scheduled re-run of the full test workflow via workflow_call against a fresh PyPI resolve of unchanged main — this repo has no push-to-main CI at all, so between PRs nothing else proves main still works
  • failures create/update ONE deduped drift-labeled issue; green runs close it; force_fail dispatch input rehearses the path
  • riding along in run_tests.yml: workflow_call: trigger; setup-uv unpinned from the ancient 0.6.5; the per-PR cache-nuking + --reinstall block removed (every PR cold-downloaded the multi-GB torch/bayesflow/keras/sbi stack), uv caching enabled instead

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added scheduled and manually triggered drift checks.
    • Drift failures now create or update a single tracking issue, while successful checks automatically close it.
    • Cancelled or inconclusive checks leave the existing tracking issue unchanged.
  • Chores

    • Improved automated test workflow reuse and dependency caching.
    • Simplified test environment setup and package installation for more consistent test runs.

- weekly re-run of the full test workflow against a fresh dependency
  resolve of unchanged main; this repo has NO push-to-main CI, so
  between PRs nothing else proves main still works
- failures file ONE deduped drift-labeled issue; green runs close it
- run_tests.yml gains workflow_call; setup-uv unpinned from the ancient
  0.6.5; the per-PR cache-nuking block removed (every run cold-
  downloaded the multi-GB torch/bayesflow/keras/sbi stack) with uv
  caching enabled instead
Copilot AI lite review requested due to automatic review settings August 6, 2026 00:50
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6018ba03-5553-4aa7-a8ed-e1c33dbdcb4b

📥 Commits

Reviewing files that changed from the base of the PR and between 045d6cb and bbc02ff.

📒 Files selected for processing (2)
  • .github/workflows/drift.yml
  • .github/workflows/run_tests.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/run_tests.yml

📝 Walkthrough

Walkthrough

Changes

Drift monitoring

Layer / File(s) Summary
Reusable test workflow
.github/workflows/run_tests.yml
The test workflow now supports workflow_call. uv setup enables caching, removes manual cache handling, and uses uv sync --all-groups.
Drift execution and issue reporting
.github/workflows/drift.yml
A scheduled and manually dispatchable workflow runs tests, supports forced failures, and closes, updates, or creates a deduplicated drift issue based on results.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Trigger as Schedule or manual dispatch
  participant Drift as Drift workflow
  participant Tests as Reusable test workflow
  participant Issues as GitHub Issues
  Trigger->>Drift: Start workflow with optional force_fail
  Drift->>Tests: Run reusable test workflow
  Tests-->>Drift: Return test and rehearsal results
  Drift->>Issues: Close, update, or create deduplicated drift issue
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the scheduled weekly drift detection and full-suite rerun against fresh dependency resolutions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch drift-detection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds scheduled “drift detection” to continuously validate main against fresh dependency resolves by reusing the existing test workflow, and improves CI performance by enabling uv caching and removing the prior cache-nuking/reinstall behavior.

Changes:

  • Add a new scheduled/manual drift.yml workflow that runs the full test suite and creates/updates/closes a single deduped drift-labeled issue based on results.
  • Make run_tests.yml reusable via workflow_call so it can be invoked by drift.yml.
  • Update run_tests.yml to use setup-uv with caching enabled and remove the cache-clearing + uv sync --reinstall behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
.github/workflows/run_tests.yml Adds workflow_call trigger and enables uv caching / removes forced reinstall for the main test job.
.github/workflows/drift.yml New scheduled workflow that calls the test workflow and manages a deduped drift-tracking issue.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +23 to +25
tests:
uses: ./.github/workflows/run_tests.yml

Comment on lines 28 to +33
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.6.5"
# enable-cache: true
# cache-dependency-glob: "pyproject.toml pdm.lock"

- name: Clear all caches
run: |
rm -rf ~/.cache/pip
rm -rf ~/.cache/uv
rm -rf ~/.cache/conda
rm -rf ~/.cache/npm

version: "latest"
enable-cache: true
cache-dependency-glob: "pyproject.toml"

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/drift.yml:
- Around line 42-59: Update the FAILED_JOBS decision logic in the drift workflow
so an existing issue is closed only when RESULT_TESTS equals success. Treat
cancelled, skipped, and any other non-success test results as inconclusive by
keeping the issue open, while preserving the existing force-fail handling.
- Around line 26-31: Add a job-level concurrency group to the report job in
drift.yml, with cancel-in-progress set to false, so overlapping scheduled or
manual runs serialize the issue list-and-create sequence used by the report
steps.
- Around line 23-24: Update the drift workflow’s tests and reporting jobs so
they only execute when the workflow ref is the repository’s default branch,
including manually dispatched runs with a supplied ref. Apply the same
default-branch condition to the job that uses needs.tests.result for shared
drift issue updates, while preserving the existing test and reporting behavior
on the default branch.
- Around line 18-20: Restrict the issues: write permission to the report job in
the workflow, and remove it from the top-level permissions inherited by the
reusable tests job. Keep contents: read at the appropriate shared scope and
ensure report retains issues: write.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b6a9efdc-aa3b-4c12-9ce9-1ca446901527

📥 Commits

Reviewing files that changed from the base of the PR and between d725ae3 and 045d6cb.

📒 Files selected for processing (2)
  • .github/workflows/drift.yml
  • .github/workflows/run_tests.yml

Comment thread .github/workflows/drift.yml Outdated
Comment on lines +23 to +24
tests:
uses: ./.github/workflows/run_tests.yml

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files .github/workflows || true

echo "== drift workflow =="
sed -n '1,220p' .github/workflows/drift.yml 2>/dev/null || true

echo "== tests workflow outline =="
if [ -f .github/workflows/run_tests.yml ]; then
  wc -l .github/workflows/run_tests.yml
  ast-grep outline .github/workflows/run_tests.yml --view expanded || true
  sed -n '1,260p' .github/workflows/run_tests.yml
fi

echo "== references to issue/drift/main/reusable workflow =="
rg -n "issue|drift|main|workflow_dispatch|uses: \./\.github/workflows/run_tests|needs:|result|close|open|gh" .github/workflows/. 2>/dev/null || true

Repository: lnccbrown/LANfactory

Length of output: 8701


🌐 Web query:

GitHub reusable workflows github.ref default branch input ref workflow_dispatch workflow_call

💡 Result:

In GitHub Actions, the github.ref context and the calling mechanism for reusable workflows have specific behaviors you should be aware of regarding branches, workflow dispatch, and workflow calls. ### Using References in Reusable Workflows You cannot use expressions or context variables (like ${{ github.ref }} or ${{ github.sha }}) inside the uses keyword when calling a reusable workflow [1][2][3]. GitHub Actions requires a static reference—a branch name, tag, or commit SHA—to parse the workflow file at execution time [2][3]. * Same Repository: If your reusable workflow is in the same repository, you should omit the @{ref} suffix entirely (e.g., uses: ./.github/workflows/my-workflow.yml) [1][2][3]. When you omit this, GitHub automatically executes the workflow version from the same commit as the caller workflow [1][2]. * External Repositories: If calling a workflow from another repository, you must hardcode the version (e.g., uses: octo-org/repo/.github/workflows/my-workflow.yml@v1) [1][3]. ### The github Context in Reusable Workflows When a reusable workflow is triggered, the github context (including github.ref) is associated with the caller workflow, not the called reusable workflow [4][5]. This means the reusable workflow does not inherently "know" which specific branch or tag was used to call it if it was referenced by a tag or branch name [5]. If your reusable workflow needs to act on a specific branch or tag (e.g., for actions/checkout), you must explicitly pass that reference as an input [5][3]: 1. Define an input in the reusable workflow's on.workflow_call.inputs section [6][4]. 2. Pass the value from the caller using ${{ github.ref }} or ${{ github.ref_name }} inside the jobs.<job_id>.with block [4][5]. ### Workflow Dispatch vs. Workflow Call * Workflow Dispatch: The workflow_dispatch event allows you to trigger a workflow manually [6][7]. It is distinct from workflow_call (reusable workflows) and only receives events when the workflow file exists on the default branch [6]. * Inputs: While both workflow_dispatch and workflow_call support inputs, they serve different purposes [6][4]. workflow_call allows one workflow to use another as a component, whereas workflow_dispatch is typically used for on-demand execution [6][7]. Remember that the inputs context inside a reusable workflow is populated only by the values defined in its own on.workflow_call configuration [4][8]. Attempting to access inputs in the caller workflow's job-level if conditions will fail, as those inputs exist only within the scope of the called workflow [8].

Citations:


🌐 Web query:

site:docs.github.com GitHub Actions reusable workflows workflow_dispatch branch workflow_call ref input github.ref default branch

💡 Result:

GitHub Actions utilizes specific mechanisms for triggering, referencing, and passing data to workflows, with distinct behaviors for reusable and manually dispatched workflows. 1. Reusable Workflows (workflow_call) Reusable workflows are defined using the workflow_call trigger [1][2]. They can be called from another workflow (the caller) by referencing their file path and a specific version (ref) [1][3]. - Referencing: You can reference a reusable workflow using the syntax {owner}/{repo}/.github/workflows/{filename}@{ref} [1][4]. The {ref} can be a branch name, a release tag, or a commit SHA [4][5]. - Context and Inputs: When a reusable workflow is triggered, the github context is associated with the caller workflow, not the called workflow [5][6]. Inputs are defined in the called workflow under on.workflow_call.inputs [2] and passed from the caller workflow using the with keyword in a job [1][2]. - Repository Context: Actions within a reusable workflow run as if they were part of the caller workflow; for example, actions/checkout will check out the caller repository's code, not the reusable workflow's repository [3]. 2. Manually Triggered Workflows (workflow_dispatch) The workflow_dispatch trigger allows workflows to be run manually [7]. - Default Branch Requirement: Traditionally, for a workflow to be triggered via workflow_dispatch, the workflow file must exist on the repository's default branch [8][7]. - Branch Execution: While the file must reside on the default branch to be visible and available for manual triggering, you can execute the workflow on a different branch by specifying the ref (e.g., using the --ref flag in the GitHub CLI: gh workflow run WORKFLOW --ref BRANCH) [7]. - Inputs: Inputs for workflow_dispatch are defined in the workflow file and accessed within the workflow via the inputs context or github.event.inputs [8][2][9]. 3. Key Considerations for github.ref - github.ref: This context variable represents the fully-formed ref (e.g., refs/heads/<branch_name> or refs/tags/<tag_name>) of the branch or tag that triggered the workflow [10]. In the context of reusable workflows, because the github context is inherited from the caller [5][6], github.ref will point to the branch or tag of the caller repository that initiated the run, not the branch of the repository hosting the reusable workflow [10].

Citations:


Restrict drift reporting to the default branch.

workflow_dispatch can run this call from a non-default branch when a ref is supplied. The tests job then runs that branch, but report: always() uses needs.tests.result to create or close the shared drift issue, so a passing branch can close an open issue and a failing branch can create a false drift issue. Drive both jobs from the default branch before using the result for issue updates.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/drift.yml around lines 23 - 24, Update the drift
workflow’s tests and reporting jobs so they only execute when the workflow ref
is the repository’s default branch, including manually dispatched runs with a
supplied ref. Apply the same default-branch condition to the job that uses
needs.tests.result for shared drift issue updates, while preserving the existing
test and reporting behavior on the default branch.

Comment thread .github/workflows/drift.yml
Comment thread .github/workflows/drift.yml
…ebooks

Addresses the review on #107.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 23:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (3)

.github/workflows/drift.yml:28

  • run_tests.yml uses secrets.CODECOV_TOKEN (Codecov upload). When calling it from drift.yml, that secret is not passed unless explicitly forwarded, which can cause the drift run to fail or skip coverage upload unexpectedly. Pass the token explicitly (or use secrets: inherit if preferred).
    # third-party test code should not carry it.
    permissions:
      contents: read
    uses: ./.github/workflows/run_tests.yml

.github/workflows/drift.yml:47

  • inputs.force_fail is referenced in the env: block, but inputs context only exists for workflow_dispatch / workflow_call. On the scheduled trigger this can fail workflow expression evaluation (or set an unexpected empty value), breaking drift runs. Use github.event.inputs.force_fail with a default instead so schedule runs work.
        env:
          GH_TOKEN: ${{ github.token }}
          RESULT_TESTS: ${{ needs.tests.result }}
          FORCE_FAIL: ${{ inputs.force_fail }}
        run: |

.github/workflows/run_tests.yml:5

  • run_tests.yml is now a reusable workflow (workflow_call), but it references secrets.CODECOV_TOKEN. Reusable workflows must explicitly declare which secrets they accept; otherwise callers cannot pass them and the Codecov step may fail or behave differently when invoked from drift.yml. Declare CODECOV_TOKEN under on.workflow_call.secrets.
on:
  pull_request:
  workflow_call: # Called by drift.yml (scheduled drift detection)

@AlexanderFengler

Copy link
Copy Markdown
Member Author

Thanks — I worked through all six findings. Two were real and are now fixed; the rest I've assessed below.

Fixed

  1. Cancelled/skipped treated as green (CodeRabbit, drift.yml). Real, and the most important one. report runs under if: always(), which includes cancellation, and only an exact failure populated FAILED_JOBS — so a cancelled run took the close path and would have retired an open drift issue on no evidence. Now only a genuine success closes; anything inconclusive logs a notice and leaves issue state alone. Verified by running the extracted shell logic over all four values of needs.tests.result.

  2. test_notebooks still pinned uv 0.6.5 (Copilot, run_tests.yml). Real inconsistency, and it matters more than cosmetically in a drift workflow: half the file would have exercised uv 0.12.x while the notebook path stayed on a March-2025 uv, so the notebook leg never tested current toolchain resolution. Now latest with the same cache configuration as run_tests.

Also applied (not flagged): issues: write moved from workflow level down to the report job. Previously the reusable test workflow inherited it, so the token carried issue-write while uv sync installed freshly-resolved third-party packages.

Applied, with a caveat about the stated severity

  1. Concurrency race (CodeRabbit). The TOCTOU is real — read and write aren't atomic — so I added the three-line guard. But reachability is near-nil: the only schedule is a weekly cron and observed runs take 12–31 minutes, so scheduled runs can't overlap each other; it needs a manual dispatch fired inside a scheduled run's window, and the worst case is a duplicate tracking issue rather than a wrong signal.

Not applied, with reasons

  1. Restrict drift reporting to the default branch (CodeRabbit). The mechanism is real, but the proposed fix gates both jobs on the default branch, which would disable the force_fail rehearsal path this PR deliberately added — the rehearsal has to run from a feature branch before the workflow is on main. Dispatching drift from a branch is a deliberate maintainer act with write access, not an attack surface. If we want the guard later, it belongs only on the issue-mutating job.

  2. CODECOV_TOKEN not passed to the reusable workflow (Copilot). The premise is right — secrets aren't inherited — but the stated consequence isn't: codecov-action defaults fail_ci_if_error to false and token is optional, so an empty token warns and moves on rather than failing the drift run. Worth noting that secrets: inherit would be the wrong fix here anyway, since this repo also holds PYPI_TOKEN and TEST_PYPI_TOKEN and that job runs freshly-resolved third-party code.

On removing the cache-nuking block — I checked the history since it's the kind of thing that looks load-bearing. git log -S "reinstall" turns up exactly one commit, inside a single undiagnosed hour of trial and error in June 2025 ("small change to git actions" → "trying different setting" → "more changes" → "last attempt"), with no explanation in any message. The real bug it was flailing at was the SIGILL from ssm-simulators' -march=native wheels, which is fixed upstream and pinned out by ssm-simulators>=0.13.1. I've added that fact to the comment block so nobody reinstates it on a hunch.

@AlexanderFengler

Copy link
Copy Markdown
Member Author

The three red run_tests legs here are not from this PRmain currently fails its own lint step, and every PR based on it inherits that.

The failing step is uv run ruff check src/lanfactory, with 111 errors in src/lanfactory — files this PR does not touch (its whole diff is .github/workflows/). I checked whether it was a ruff version bump, since that is the usual cause and the run that broke coincided with ruff 0.16.1 → 0.16.2. It isn't:

ruff 0.16.1  ->  Found 111 errors.  [*] 42 fixable
ruff 0.16.2  ->  Found 111 errors.  [*] 42 fixable

Identical on both, against unmodified main source. So this is accumulated lint debt that the Linting step in run_tests.yml surfaces on every PR, not a toolchain drift event. Top codes: I001 (19), BLE001 (14), SIM115 (12), EXE002 (10), B008 (8).

#103 is already the fix and has been open since 31 July: it adds [tool.ruff.lint] ignore = [B008, EXE001, EXE002, BLE001], cleans up the rest across src/ and tests/, and moves lint/format out of run_tests.yml into a dedicated linting_formatting.yml. Nothing for me to do here except wait for it — fixing 111 errors inside a drift-detection PR would be exactly the scope creep worth avoiding.

Three interactions worth settling before either merges, since #103 and this PR edit the same region of run_tests.yml and will conflict:

  1. setup-uv version. 102 separate linting workflow in ci #103 pins version: "0.12.0"; this PR uses version: "latest" with caching. For a drift workflow, latest is the point — pinning the toolchain hides exactly the class of breakage the weekly run exists to catch. Suggest latest in the drift path; happy to defer on the PR path.
  2. The cache-nuking block. 102 separate linting workflow in ci #103 keeps rm -rf ~/.cache/{pip,uv,conda,npm} (reindented); this PR deletes it. Per the history, that block came from an undiagnosed hour of trial and error in June 2025, and the SIGILL it was chasing was ssm-simulators' -march=native wheels, fixed upstream and pinned out by ssm-simulators>=0.13.1. Keeping it costs a multi-GB cold download of the torch/bayesflow/keras/sbi stack on every run, for no benefit I can find.
  3. Lint coverage would silently leave the weekly drift run. Once 102 separate linting workflow in ci #103 moves linting into linting_formatting.yml, drift.yml's tests job no longer exercises it, so an unpinned-linter break — the very incident that started this workstream — would stop being caught weekly. The fix is one line in 102 separate linting workflow in ci #103: add workflow_call: alongside pull_request: in the new workflow, and I'll add a lint job here that calls it.

Suggested order: #103 first, then I rebase this on top, resolve run_tests.yml, and add the lint job. If #103 needs longer, this can merge first and I'll take the conflict instead — but the lint failures block it either way until #103 lands.

@AlexanderFengler

Copy link
Copy Markdown
Member Author

Copilot's re-review of the current head produced no new comments; its three suppressed notes are the only open items. Two are the CODECOV_TOKEN point I addressed above (fail-soft: codecov-action defaults fail_ci_if_error to false and token is optional, so an absent token warns rather than failing — and secrets: inherit would be the wrong fix, since this repo also holds PYPI_TOKEN and TEST_PYPI_TOKEN and the called job runs freshly-resolved third-party code).

The third is new and worth answering properly, because it concerns the one path no rehearsal can exercise:

inputs.force_fail is referenced in the env: block, but inputs context only exists for workflow_dispatch / workflow_call. On the scheduled trigger this can fail workflow expression evaluation (or set an unexpected empty value), breaking drift runs.

Checked, and it doesn't hold. The evidence is in the sibling repo, on exactly this construct. lnccbrown/HSSM's run_tests.yml triggers on both pull_request and workflow_call, and references the inputs context in an env: block — the same shape as mine:

on:
  pull_request:
  workflow_call:
    inputs: { run_slow_tests: ..., test_args: ... }
jobs:
  run_tests:
    env:
      HSSM_TEST_ARGS: ${{ inputs.test_args }}     # <- env block, same as FORCE_FAIL
    steps:
      - name: Run fast tests
        if: ${{ !inputs.run_slow_tests }}

On a pull_request event the inputs context is unavailable, exactly as on schedule. The most recent such run (31295907037) is green, with Run fast tests: success and Run all tests: skipped — so inputs.run_slow_tests evaluated falsy and inputs.test_args resolved to empty, with no expression error. Unavailable contexts degrade to empty rather than failing evaluation.

That maps directly onto the drift case: on the weekly cron, FORCE_FAIL is the empty string, [ "$FORCE_FAIL" = "true" ] is false, and the rehearsal branch stays off. Which is the intended behavior.

I considered switching to github.event.inputs.force_fail defensively anyway, and decided against it: it is strictly worse here. For a workflow_dispatch boolean, inputs.force_fail yields a real boolean while github.event.inputs.force_fail yields a string — both happen to compare correctly against "true", so the change would buy nothing and add a second spelling of the same idea across five repos.

Worth being explicit that this is a genuine gap in what the rehearsals prove: every validation so far has been via workflow_dispatch, so the schedule path has never actually executed anywhere. The first real cron run is tomorrow (Mon 05:10 UTC for ssm-simulators). I'll confirm it behaves as analyzed rather than leaving it on reasoning alone.

@AlexanderFengler
AlexanderFengler merged commit 8b794e1 into main Aug 9, 2026
6 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants