chore: update rhiza to v1.2.5 - #25
Conversation
|
Warning Review limit reached
Next review available in: 28 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (37)
📝 WalkthroughWalkthroughThis change refreshes Rhiza’s GitHub workflows, release pipeline, Make targets, shell completions, validation suite, documentation, and development tooling. It adds repository governance configurations, new workflow checks, cached completions, metadata tests, and updated dependency provisioning. ChangesGitHub automation and repository governance
Estimated code review effort: 4 (Complex) | ~60 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant BuildJob
participant Attestation
participant ArtifactStore
participant DraftRelease
participant PyPI
BuildJob->>Attestation: Create SBOM and provenance bundles
Attestation->>BuildJob: Return bundle paths
BuildJob->>ArtifactStore: Stage release assets
DraftRelease->>ArtifactStore: Download staged artifacts
DraftRelease->>DraftRelease: Attach SBOM and provenance files
BuildJob->>PyPI: Remove provenance files before publishing
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR syncs the repository with the jebel-quant/rhiza template update from v0.18.8 to v1.2.5, refreshing the repo’s shared tooling, CI workflow stubs, and Rhiza-managed developer experience (Make targets, linting, and test harness).
Changes:
- Update Rhiza template reference/lock and refresh Rhiza-managed Make targets, pytest settings, and Ruff/pre-commit configuration.
- Add new template files for changelog generation (
cliff.toml), GitHub repo governance stubs (rulesets, discussion templates, config docs), and additional CI workflows (Scorecard/Fuzzing/Mutation). - Restructure the synced
.rhiza/testssuite and adjust docs to match the new template behavior (notably around pytest live logging and dependency provisioning).
Reviewed changes
Copilot reviewed 42 out of 44 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ruff.toml | Expands Ruff rule selection and per-file ignores; removes explicit target-version. |
| pytest.ini | Adds .rhiza/tests to pythonpath, disables live logs by default, and hardens warning filtering. |
| Makefile | Updates repo-owned overrides and delegates to .rhiza/rhiza.mk. |
| docs/index.md | Minor formatting tweak (removes trailing blank line). |
| docs/development/TESTS.md | Documents new default pytest logging behavior and uv-based dependency provisioning. |
| cliff.toml | Adds git-cliff configuration for CHANGELOG generation. |
| .rhiza/tests/test_readme_validation.py | Adds README code-block execution/syntax validation tests. |
| .rhiza/tests/test_pyproject.py | Adds pyproject structure/metadata validation tests. |
| .rhiza/tests/test_docstrings.py | Adds doctest discovery runner for project modules. |
| .rhiza/tests/README.md | Updates synced test-suite documentation and layout. |
| .rhiza/tests/conftest.py | Simplifies synced fixtures to root and logger. |
| .rhiza/template.yml | Bumps template ref to v1.2.5. |
| .rhiza/template.lock | Updates pinned upstream commit and synced file manifest for v1.2.5. |
| .rhiza/rhiza.mk | Updates Rhiza core Make logic (Windows shell checks, uv/pytest provisioning, target cleanup). |
| .rhiza/make.d/test.mk | Updates test/benchmark/typecheck/security/docs-coverage targets and uv provisioning strategy. |
| .rhiza/make.d/quality.mk | Refactors deptry scanning into bundle-contributed folder lists; removes suppression audit target. |
| .rhiza/make.d/marimo.mk | Integrates Marimo folder into shared deptry scan. |
| .rhiza/make.d/github.mk | Adds gh-CLI helper targets for PR/issue/workflow/release visibility. |
| .rhiza/make.d/completions.mk | Adds a Make target to install shell completion scripts. |
| .rhiza/make.d/bootstrap.mk | Updates install semantics (uv sync --inexact) and improves branch cleanup logic. |
| .rhiza/make.d/book.mk | Switches Marimo export to uv run --with marimo. |
| .rhiza/completions/rhiza-completion.zsh | Adds caching for target discovery and updates variable completions. |
| .rhiza/completions/rhiza-completion.bash | Adds caching for target discovery and updates variable completions. |
| .rhiza/completions/README.md | Documents quick install and caching behavior for completions. |
| .rhiza/.env | Adds documented defaults/overrides for Rhiza Make variables. |
| .rhiza/.cfg.toml | Hardens bumpversion search/replace to avoid unintended rewrites and adds workflow-pin rewriting. |
| .pre-commit-config.yaml | Pins Node runtime, bumps hook revisions, and adds betterleaks. |
| .github/workflows/rhiza_weekly.yml | Bumps reusable workflow ref to v1.2.5. |
| .github/workflows/rhiza_scorecard.yml | Adds Scorecard workflow stub pinned to v1.2.5. |
| .github/workflows/rhiza_release.yml | Updates release workflow behavior, permissions, attestations, and artifacts handling. |
| .github/workflows/rhiza_mutation.yml | Adds opt-in mutation testing workflow pinned to v1.2.5. |
| .github/workflows/rhiza_marimo.yml | Bumps reusable workflow ref to v1.2.5. |
| .github/workflows/rhiza_fuzzing.yml | Adds fuzzing workflow stub pinned to v1.2.5. |
| .github/workflows/rhiza_codeql.yml | Bumps reusable workflow ref and tightens permissions to least-privilege. |
| .github/workflows/rhiza_ci.yml | Bumps reusable workflow ref to v1.2.5 and documents matrix source of truth. |
| .github/workflows/rhiza_book.yml | Bumps reusable workflow ref and broadens trigger to validate builds on all pushes. |
| .github/workflows/rhiza_benchmark.yml | Bumps reusable workflow ref to v1.2.5. |
| .github/rulesets/tag-protection.json | Adds tag protection ruleset stub (JSON). |
| .github/rulesets/main-branch-protection.json | Adds main branch protection ruleset stub (JSON). |
| .github/pull_request_template.md | Adds changelog checklist item. |
| .github/DISCUSSION_TEMPLATE/ideas.yml | Adds ideas discussion template. |
| .github/DISCUSSION_TEMPLATE/help-wanted.yml | Adds help-wanted discussion template. |
| .github/dependabot.yml | Whitespace-only cleanup. |
| .github/CONFIG.md | Adds documentation for required/optional GitHub Actions secrets (PAT_TOKEN, release secrets). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "A", # flake8-builtins - Don't shadow Python builtins | ||
| "ANN001", # flake8-annotations - Require function argument annotations | ||
| "ANN2", # flake8-annotations - Require function return annotations | ||
| "ARG", # flake8-unused-arguments - Unused arguments (tests exempt below: pytest fixtures) | ||
| "B", # flake8-bugbear - Find likely bugs and design problems |
| # Which static type checker(s) the 'typecheck' target runs: ty, mypy, or both. | ||
| # Running both is the default for backward compatibility, but ty and mypy | ||
| # occasionally disagree (e.g. one accepts a suppression the other still flags), | ||
| # forcing duplicate `# type: ignore` / `# ty: ignore` comments. Set this to | ||
| # 'ty' or 'mypy' in local.mk or .rhiza/.env to run a single checker instead. | ||
| TYPECHECKER ?= both |
| def test_no_license_classifier(self, project: dict) -> None: | ||
| """No deprecated 'License :: ' classifier may be present. | ||
|
|
||
| PyPI has deprecated the ``License ::`` trove classifiers in favor of the SPDX | ||
| ``license`` expression field, so the shipped pyproject must not declare one. | ||
| """ | ||
| classifiers = project.get("classifiers", []) | ||
| license_classifiers = [c for c in classifiers if c.startswith("License ::")] | ||
| assert not license_classifiers, ( | ||
| f"classifiers must not include any deprecated 'License :: ' entry; found {license_classifiers}" | ||
| ) |
| @git fetch --prune | ||
|
|
||
| @git branch -vv | awk '/: gone]/{print $$1}' | xargs -r git branch -D | ||
| @git branch -vv | awk '/: gone]/ && $$1 != "*" && $$1 != "+" {print $$1}' | xargs -r git branch -D |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
ruff.toml (1)
150-150: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRestore the
.rhiza/utils/*.pylinter exemptions or delete the unused files.
.rhiza/utils/pip_audit_policy.pyand.rhiza/utils/suppression_audit.pystill exist, so removing the per-file ignore entry exposes multiple new linter failures under the current config.🤖 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 `@ruff.toml` at line 150, Restore the per-file linter exemptions for .rhiza/utils/pip_audit_policy.py and .rhiza/utils/suppression_audit.py in ruff.toml, or remove those unused utility files; preserve a clean lint run under the current configuration.
🤖 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/rhiza_benchmark.yml:
- Around line 23-24: Replace broad secrets: inherit usage at the
reusable-workflow call sites in .github/workflows/rhiza_benchmark.yml lines
23-24, rhiza_book.yml lines 32-33, rhiza_ci.yml lines 29-30, rhiza_codeql.yml
lines 29-30, and rhiza_fuzzing.yml lines 37-38 with only the named secrets each
workflow consumes, or omit secrets forwarding where none are required.
- Line 23: Replace the mutable Rhiza workflow tag with the immutable commit SHA
e5d7005e2d9fc3d5a23b96d13b203b4f2afe3cce in all workflow references:
.github/workflows/rhiza_benchmark.yml:23, .github/workflows/rhiza_book.yml:32,
.github/workflows/rhiza_ci.yml:29, .github/workflows/rhiza_codeql.yml:29, and
.github/workflows/rhiza_fuzzing.yml:37.
In @.github/workflows/rhiza_book.yml:
- Around line 25-28: Restrict the deployment job and its pages/id-token write
permissions to pushes on the default branch only. Update the workflow’s branch
trigger and reusable-workflow job configuration so non-default branch builds
retain only the permissions needed to build or upload artifacts, without
deployment access.
In @.github/workflows/rhiza_mutation.yml:
- Around line 45-46: Pin every jebel-quant/rhiza reusable workflow reference to
its verified 40-character commit SHA instead of the mutable v1.2.5 tag, and
replace secrets: inherit with mappings containing only the secrets each called
workflow explicitly requires. Apply this in .github/workflows/rhiza_mutation.yml
(45-46), .github/workflows/rhiza_scorecard.yml (39-40),
.github/workflows/rhiza_marimo.yml (31), .github/workflows/rhiza_weekly.yml
(31), and all three referenced jobs in .github/workflows/rhiza_release.yml (290,
317, 603), preserving each workflow’s required secret contract.
In @.rhiza/completions/README.md:
- Line 27: Update the wording in the README sentence around the manual methods
to use the American-English spelling “afterward” instead of “afterwards,”
without changing the surrounding instructions.
In @.rhiza/completions/rhiza-completion.bash:
- Around line 40-45: Update the cache refresh logic in
.rhiza/completions/rhiza-completion.bash at lines 40-45 to write the parsed
targets to a temporary file, verify the complete make/awk/grep/sort pipeline
succeeds, then atomically rename it to the final targets-* cache; update
.rhiza/completions/rhiza-completion.zsh at lines 48-72 to generate both .desc
and .plain outputs in temporary files, publish both only after the full refresh
succeeds, and clean up temporary files on failure.
In @.rhiza/completions/rhiza-completion.zsh:
- Around line 76-89: The cache-unavailable branch should populate described
targets as well as plain_targets. Update the fallback around the make/awk
extraction to run the same description-aware target extraction used to build
targets from .desc, preserving ## descriptions when the cache directory cannot
be read or written.
In @.rhiza/make.d/github.mk:
- Around line 21-27: Update the `gh-install` target’s help description to state
that it checks whether the `gh` CLI is installed and reports its status, rather
than claiming it installs extensions. Leave the existing command behavior
unchanged.
In `@docs/development/TESTS.md`:
- Around line 75-83: Update the code fence around the pytest command in the
“Opting in to live DEBUG logs” section to use the project’s tilde-style fence,
replacing both opening and closing backtick fences with matching tildes while
preserving the bash language marker and command.
---
Outside diff comments:
In `@ruff.toml`:
- Line 150: Restore the per-file linter exemptions for
.rhiza/utils/pip_audit_policy.py and .rhiza/utils/suppression_audit.py in
ruff.toml, or remove those unused utility files; preserve a clean lint run under
the current configuration.
🪄 Autofix (Beta)
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: a5c5e14a-902c-4736-b650-3f3a8744255d
⛔ Files ignored due to path filters (1)
.rhiza/template.lockis excluded by!**/*.lock
📒 Files selected for processing (43)
.github/CONFIG.md.github/DISCUSSION_TEMPLATE/help-wanted.yml.github/DISCUSSION_TEMPLATE/ideas.yml.github/dependabot.yml.github/pull_request_template.md.github/rulesets/main-branch-protection.json.github/rulesets/tag-protection.json.github/workflows/rhiza_benchmark.yml.github/workflows/rhiza_book.yml.github/workflows/rhiza_ci.yml.github/workflows/rhiza_codeql.yml.github/workflows/rhiza_fuzzing.yml.github/workflows/rhiza_marimo.yml.github/workflows/rhiza_mutation.yml.github/workflows/rhiza_release.yml.github/workflows/rhiza_scorecard.yml.github/workflows/rhiza_weekly.yml.pre-commit-config.yaml.rhiza/.cfg.toml.rhiza/.env.rhiza/completions/README.md.rhiza/completions/rhiza-completion.bash.rhiza/completions/rhiza-completion.zsh.rhiza/make.d/book.mk.rhiza/make.d/bootstrap.mk.rhiza/make.d/completions.mk.rhiza/make.d/github.mk.rhiza/make.d/marimo.mk.rhiza/make.d/quality.mk.rhiza/make.d/test.mk.rhiza/rhiza.mk.rhiza/template.yml.rhiza/tests/README.md.rhiza/tests/conftest.py.rhiza/tests/test_docstrings.py.rhiza/tests/test_pyproject.py.rhiza/tests/test_readme_validation.pyMakefilecliff.tomldocs/development/TESTS.mddocs/index.mdpytest.iniruff.toml
💤 Files with no reviewable changes (1)
- docs/index.md
| jobs: | ||
| benchmark: | ||
| uses: jebel-quant/rhiza/.github/workflows/rhiza_benchmark.yml@v0.19.9 | ||
| uses: jebel-quant/rhiza/.github/workflows/rhiza_benchmark.yml@v1.2.5 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Repository files around workflows:"
fd -a 'rhiza_(benchmark|book|ci|codeql|fuzzing)\.yml$' .github/workflows 2>/dev/null || true
echo
echo "Relevant workflow lines:"
for f in \
.github/workflows/rhiza_benchmark.yml \
.github/workflows/rhiza_book.yml \
.github/workflows/rhiza_ci.yml \
.github/workflows/rhiza_codeql.yml \
.github/workflows/rhiza_fuzzing.yml
do
if [ -f "$f" ]; then
echo "--- $f"
rg -n "uses: jebel-quant/rhiza/.github/workflows/rhiza|`@v1.2.5`|secrets: inherit|permissions:|jobs:" "$f" || true
else
echo "MISSING $f"
fi
done
echo
echo "Check whether declared pin resolves to claimed commit:"
if command -v gh >/dev/null 2>&1; then
gh api repos/jebel-quant/rhiza/git/ref/tags/v1.2.5 --jq '{ref:.ref, object_type:.object.type, sha:.object.sha}'
ref=$(gh api repos/jebel-quant/rhiza/git/ref/tags/v1.2.5 --jq '.object.sha')
type=$(gh api repos/jebel-quant/rhiza/git/ref/tags/v1.2.5 --jq '.object.type')
if [ "$type" = "tag" ]; then
tagobject=$(gh api repos/jebel-quant/rhiza/git/tags/"$ref" --jq '.object.sha')
echo "dereferenced_commit=$tagobject"
echo "$(gh api repos/jebel-quant/rhiza/commits/"$tagobject" --jq '.sha')" >/dev/null && echo "commit_exists=true"
else
echo "commit_exists=true"
fi
else
echo "gh CLI not available"
fi
echo
echo "GitHub ref existence checks:"
if command -v gh >/dev/null 2>&1; then
for ref in e5d7005e2d9f e5d7005e2d9f3095456222963a8236edf2ec2915 v1.2.5; do
echo "--- $ref"
gh api "repos/jebel-quant/rhiza/git/ref/tags/$ref" --jq '{ref:.ref, object_type:.object.type, sha:.object.sha}' 2>&1 || true
done
fiRepository: tschm/pycharting
Length of output: 1998
Pin the Rhiza workflow references to the immutable full commit SHA.
All five callers use the mutable @v1.2.5 tag, so a retagged upstream release can change privileged workflow code. Pin each reference to e5d7005e2d9fc3d5a23b96d13b203b4f2afe3cce.
.github/workflows/rhiza_benchmark.yml#L23-L23.github/workflows/rhiza_book.yml#L32-L32.github/workflows/rhiza_ci.yml#L29-L29.github/workflows/rhiza_codeql.yml#L29-L29.github/workflows/rhiza_fuzzing.yml#L37-L37
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 23-23: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow
(secrets-inherit)
📍 Affects 5 files
.github/workflows/rhiza_benchmark.yml#L23-L23(this comment).github/workflows/rhiza_book.yml#L32-L32.github/workflows/rhiza_ci.yml#L29-L29.github/workflows/rhiza_codeql.yml#L29-L29.github/workflows/rhiza_fuzzing.yml#L37-L37
🤖 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/rhiza_benchmark.yml at line 23, Replace the mutable Rhiza
workflow tag with the immutable commit SHA
e5d7005e2d9fc3d5a23b96d13b203b4f2afe3cce in all workflow references:
.github/workflows/rhiza_benchmark.yml:23, .github/workflows/rhiza_book.yml:32,
.github/workflows/rhiza_ci.yml:29, .github/workflows/rhiza_codeql.yml:29, and
.github/workflows/rhiza_fuzzing.yml:37.
| uses: jebel-quant/rhiza/.github/workflows/rhiza_benchmark.yml@v1.2.5 | ||
| secrets: inherit |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow call sites =="
for f in .github/workflows/rhiza_benchmark.yml .github/workflows/rhiza_book.yml .github/workflows/rhiza_ci.yml .github/workflows/rhiza_codeql.yml .github/workflows/rhiza_fuzzing.yml; do
if [ -f "$f" ]; then
echo "--- $f ---"
nl -ba "$f" | sed -n '1,80p'
else
echo "MISSING $f"
fi
done
echo "== repo-local referenced reusable workflows =="
for f in .github/workflows/rhiza_benchmark.yml .github/workflows/rhiza_book.yml .github/workflows/rhiza_ci.yml .github/workflows/rhiza_codeql.yml .github/workflows/rhiza_fuzzing.yml; do
if [ -f "$f" ]; then
echo "--- referenced by repo $f contains secrets in workflow body? ---"
rg -n "secrets\.|env:|GITHUB_TOKEN|steps:|permissions:" "$f" || true
fi
done
echo "== all workflow uses syntax with inherit/workflows =="
rg -n "uses:\s*jebel-quant/rhiza/.github/workflows/.*`@v1`\.2\.5|secrets:\s*inherit" .github/workflows || true
echo "== git diff stat/name =="
git diff --stat || true
git diff --name-only || trueRepository: tschm/pycharting
Length of output: 266
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== location =="
find .github/workflows -maxdepth 1 -type f -printf '%p\n' | sort
echo "== call sites with sed =="
for f in .github/workflows/rhiza_benchmark.yml .github/workflows/rhiza_book.yml .github/workflows/rhiza_ci.yml .github/workflows/rhiza_codeql.yml .github/workflows/rhiza_fuzzing.yml; do
if [ -f "$f" ]; then
echo "--- $f ---"
sed -n '1,100p' "$f"
else
echo "MISSING $f"
fi
done
echo "== reusable workflow uses and callable syntax in files =="
for f in .github/workflows/rhiza_benchmark.yml .github/workflows/rhiza_book.yml .github/workflows/rhiza_ci.yml .github/workflows/rhiza_codeql.yml .github/workflows/rhiza_fuzzing.yml; do
if [ -f "$f" ]; then
echo "--- referenced workflow path in $f ---"
grep -nE 'uses:\s*[^@]+@v1\.2\.5|secrets:\s*inherit|needs\.|on:\s*workflow_call|jobs:\s*|permissions:|env:' "$f" || true
fi
done
echo "== grep inherit/secrets uses in .github/workflows =="
grep -RInE 'uses:\s*jebel-quant/rhiza/.github/workflows/|secrets:\s*inherit' .github/workflows || trueRepository: tschm/pycharting
Length of output: 8448
Scope secrets passed to every reusable workflow.
All .github/workflows/rhiza_* call sites forward access to every workflow-secret with secrets: inherit. Replace this with named secret mappings for each workflow, or omit inheritance where no secret is consumed.
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 23-23: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow
(secrets-inherit)
📍 Affects 5 files
.github/workflows/rhiza_benchmark.yml#L23-L24(this comment).github/workflows/rhiza_book.yml#L32-L33.github/workflows/rhiza_ci.yml#L29-L30.github/workflows/rhiza_codeql.yml#L29-L30.github/workflows/rhiza_fuzzing.yml#L37-L38
🤖 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/rhiza_benchmark.yml around lines 23 - 24, Replace broad
secrets: inherit usage at the reusable-workflow call sites in
.github/workflows/rhiza_benchmark.yml lines 23-24, rhiza_book.yml lines 32-33,
rhiza_ci.yml lines 29-30, rhiza_codeql.yml lines 29-30, and rhiza_fuzzing.yml
lines 37-38 with only the named secrets each workflow consumes, or omit secrets
forwarding where none are required.
Source: Linters/SAST tools
| - '**' | ||
|
|
||
| permissions: | ||
| contents: read |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | rg '(^|/)\.github/workflows/rhiza_book\.yml$|\.github/workflows/' || true
echo
echo "Target workflow (with line numbers):"
cat -n .github/workflows/rhiza_book.yml || true
echo
callers=$(grep -RIn "\.github/workflows/rhiza_book\.yml@\|github/workflows/rhiza_book\.yml@" .github/workflows || true)
echo
echo "Callers:"
echo "$callers"
echo
echo "Relevant workflow snippets with permissions triggers and usages:"
rg -n "on:|permissions:|pages:|id-token:|secrets:|needs:|uses:|github/workflows/rhiza_book|branches:|branches-ignore:" .github/workflows -S || true
# Read-only parse-ish invariant checks
python3 - <<'PY'
from pathlib import Path
p=Path('.github/workflows/rhiza_book.yml')
text=p.read_text()
lines=text.splitlines()
print("\nParsed-ish checks:")
print("trigger_has_push_branches_star:", any('branches:' in l and "'**'" in l for l in lines))
print("workflow_has_permissions_id_token_write:", any('id-token:' in l and 'write' in l for l in lines))
print("workflow_has_permissions_pages_write:", any('pages:' in l and 'write' in l for l in lines))
calls=[('\n'.join(lines[max(0,i-5):i+5]), i) for i,l in enumerate(lines) if 'uses:' in l and 'rhiza_book.yml' in l]
print("rhiza_book_usage_count:", len(calls))
for chunk,line in calls:
print("at line:", line)
print(chunk)
PYRepository: tschm/pycharting
Length of output: 11752
🌐 Web query:
GitHub Actions reusable workflows permissions passed to called workflow documentation
💡 Result:
In GitHub Actions, permissions for reusable workflows follow specific rules regarding inheritance and restriction [1][2]. Key points regarding permissions and reusable workflows include: 1. Permission Inheritance and Defaulting: If the permissions key is not specified in the calling job, the called reusable workflow will operate with the default GITHUB_TOKEN permissions [1][3]. 2. Restriction (Downgrading Only): The GITHUB_TOKEN permissions passed from a caller workflow can be downgraded (made more restrictive) by the called workflow, but they cannot be elevated [1][4]. 3. Nested Workflows: In a chain of nested reusable workflows (e.g., A calls B, and B calls C), permissions must be maintained or reduced throughout the chain; they cannot be elevated [2][5]. If workflow A has specific permissions, subsequent workflows (B and C) cannot have broader permissions [1][4]. 4. Configuration: You can use the permissions key at the top level of a workflow or within a specific job (jobs.<job_id>.permissions) to modify these access levels [6][7]. These rules ensure that the GITHUB_TOKEN used by the reusable workflow remains as restrictive as intended by the caller [6]. If you specify permissions within a job, all actions and run commands within that job that use the GITHUB_TOKEN will be limited to those specified rights [6][7].
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 2: https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows
- 3: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 4: https://github.com/github/docs/blob/main/content/actions/reference/workflows-and-actions/reusing-workflow-configurations.md
- 5: https://github.com/github/docs/blob/main/content/actions/how-tos/reuse-automations/reuse-workflows.md
- 6: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax?use_case=
- 7: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
🌐 Web query:
site:docs.github.com actions reusable workflows permissions key called workflow caller passes permissions
💡 Result:
In GitHub Actions, you control the permissions granted to the GITHUB_TOKEN in a reusable workflow using the permissions key [1][2]. When calling a reusable workflow, the caller workflow can specify these permissions within the job that invokes the reusable workflow [3][4][5]. Key points regarding permissions and reusable workflows: 1. How permissions are passed: You define the permissions in the caller workflow using the jobs.<job_id>.permissions key within the job that contains the uses keyword [1][4][2]. 2. Default behavior: If you do not explicitly define jobs.<job_id>.permissions in the calling job, the called reusable workflow will run with the default GITHUB_TOKEN permissions [3][6][5]. 3. Downgrading only: The permissions granted to the GITHUB_TOKEN can be maintained or reduced (downgraded) by the called workflow, but they cannot be elevated [7][3][6][5]. 4. Nested workflows: This restriction on permission elevation applies to the entire chain of reusable workflows [7][3][6][5]. If you have a chain of workflows (e.g., A > B > C), each subsequent workflow must have permissions that are the same as or more restrictive than the preceding one [3][6][5]. Example of passing permissions in a caller workflow: jobs: call-workflow: permissions: contents: read pull-requests: write uses: octo-org/example-repo/.github/workflows/reusable-workflow.yml@main
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax?use_case=
- 2: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
- 3: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 4: https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/reuse-automations/reuse-workflows
- 5: https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 6: https://docs.github.com/en/enterprise-server@3.13/actions/reference/reusable-workflows-reference
- 7: https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows
🌐 Web query:
site:docs.github.com reusable workflows reference caller permissions "passed to the called workflow"
💡 Result:
In GitHub Actions, reusable workflows interact with caller permissions according to the following rules: 1. Permission Inheritance and Defaulting: If the jobs.<job_id>.permissions key is not explicitly defined in the calling job, the called reusable workflow will operate with the default GITHUB_TOKEN permissions [1][2]. 2. Downgrading Permissions: If you define permissions in the calling job, these are passed to the called workflow [1]. Importantly, these permissions can only be downgraded (made more restrictive) by the called workflow; they cannot be elevated [1][3]. 3. Nested Workflows: In a chain of nested workflows (e.g., A > B > C), permissions can only be maintained or reduced throughout the chain [3][4]. A nested workflow cannot have higher permissions than the workflow that called it [3][5]. Essentially, the called workflow inherits the scope defined by the caller, subject to its own internal configuration which can further restrict—but never expand—that scope [1][2].
Citations:
- 1: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 2: https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 3: https://docs.github.com/en/enterprise-server@3.21/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 4: https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/reuse-automations/reuse-workflows
- 5: https://docs.github.com/en/enterprise-server@3.13/actions/reference/reusable-workflows-reference
Keep deployment permissions off non-default branch builds.
The trigger runs on every pushed branch, but the reusable-workflow job grants pages: write and id-token: write on every invocation; caller job permissions are passed to the reusable workflow. Split the default-branch deploy into its own branch-scoped job, or remove the deployment permissions from branches that should only build/upload artifacts.
🤖 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/rhiza_book.yml around lines 25 - 28, Restrict the
deployment job and its pages/id-token write permissions to pushes on the default
branch only. Update the workflow’s branch trigger and reusable-workflow job
configuration so non-default branch builds retain only the permissions needed to
build or upload artifacts, without deployment access.
| uses: jebel-quant/rhiza/.github/workflows/rhiza_mutation.yml@v1.2.5 | ||
| secrets: inherit |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
for repo_ref in \
"jebel-quant/rhiza v1.2.5" \
"actions/attest v4.2.0" \
"actions/attest-build-provenance v4.1.0" \
"devcontainers/ci v0.3.1900000450"
do
read -r repo tag <<<"$repo_ref"
printf '\n%s@%s\n' "$repo" "$tag"
git ls-remote --tags "https://github.com/${repo}.git" "refs/tags/${tag}*"
done
for workflow in rhiza_marimo.yml rhiza_mutation.yml rhiza_scorecard.yml rhiza_weekly.yml
do
printf '\nDeclared secrets in %s:\n' "$workflow"
curl -fsSL "https://raw.githubusercontent.com/jebel-quant/rhiza/v1.2.5/.github/workflows/${workflow}" \
| sed -n '/workflow_call:/,/^[^[:space:]]/p'
doneRepository: tschm/pycharting
Length of output: 942
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
for f in .github/workflows/rhiza_mutation.yml .github/workflows/rhiza_scorecard.yml .github/workflows/rhiza_marimo.yml .github/workflows/rhiza_weekly.yml .github/workflows/rhiza_release.yml; do
if [ -f "$f" ]; then
echo "=== $f ==="
sed -n '1,70p' "$f"
else
echo "Missing: $f"
fi
done
echo "=== release lines around pin usage ==="
sed -n '280,325p' .github/workflows/rhiza_release.yml
sed -n '590,612p' .github/workflows/rhiza_release.yml
echo "=== git diff stat if available ==="
git diff --stat HEAD~1..HEAD 2>/dev/null || trueRepository: tschm/pycharting
Length of output: 15748
Pin reusable workflows to full commit SHAs
The jebel-quant/rhiza@v1.2.5 reusable workflows use a mutable tag, and .github/workflows/rhiza_* jobs pass secrets: inherit, giving the called workflow access to secrets it does not declare as required. Pin the reusable workflow refs to verified 40-character commit SHAs and map only explicitly required secrets instead of inheriting.
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 45-45: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow
(secrets-inherit)
📍 Affects 5 files
.github/workflows/rhiza_mutation.yml#L45-L46(this comment).github/workflows/rhiza_scorecard.yml#L39-L40.github/workflows/rhiza_marimo.yml#L31-L31.github/workflows/rhiza_weekly.yml#L31-L31.github/workflows/rhiza_release.yml#L290-L290.github/workflows/rhiza_release.yml#L317-L317.github/workflows/rhiza_release.yml#L603-L603
🤖 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/rhiza_mutation.yml around lines 45 - 46, Pin every
jebel-quant/rhiza reusable workflow reference to its verified 40-character
commit SHA instead of the mutable v1.2.5 tag, and replace secrets: inherit with
mappings containing only the secrets each called workflow explicitly requires.
Apply this in .github/workflows/rhiza_mutation.yml (45-46),
.github/workflows/rhiza_scorecard.yml (39-40),
.github/workflows/rhiza_marimo.yml (31), .github/workflows/rhiza_weekly.yml
(31), and all three referenced jobs in .github/workflows/rhiza_release.yml (290,
317, 603), preserving each workflow’s required secret contract.
Source: Linters/SAST tools
| This copies the appropriate script into your user completion directory | ||
| (`${XDG_DATA_HOME:-~/.local/share}/bash-completion/completions/make` for bash, | ||
| `${XDG_DATA_HOME:-~/.local/share}/zsh/site-functions/_make` for zsh) and prints | ||
| any follow-up step. Start a new shell afterwards. The manual methods below remain |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use American-English “afterward.”
Replace “afterwards” with “afterward” for consistency with the configured locale.
🧰 Tools
🪛 LanguageTool
[locale-violation] ~27-~27: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...s any follow-up step. Start a new shell afterwards. The manual methods below remain availa...
(AFTERWARDS_US)
🤖 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 @.rhiza/completions/README.md at line 27, Update the wording in the README
sentence around the manual methods to use the American-English spelling
“afterward” instead of “afterwards,” without changing the surrounding
instructions.
Source: Linters/SAST tools
| if _rhiza_make_cache_stale "$cache_file" && mkdir -p "$cache_dir" 2>/dev/null; then | ||
| # Extract make targets from Makefile and all included .mk files | ||
| make -qp 2>/dev/null | \ | ||
| awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' | \ | ||
| grep -v '^Makefile$' | \ | ||
| sort -u > "$cache_file" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Publish completion caches only after a successful parse.
Both implementations write directly to final cache files. A failed or interrupted make -qp can leave a fresh empty/partial cache that suppresses regeneration until a tracked Make source changes. Generate temporary files, verify parsing succeeded, then atomically rename them into place.
.rhiza/completions/rhiza-completion.bash#L40-L45: write the target list to a temporary file and replacetargets-*only after successful parsing..rhiza/completions/rhiza-completion.zsh#L48-L72: generate both.descand.plaintemporary files, then publish both only after the full refresh succeeds.
📍 Affects 2 files
.rhiza/completions/rhiza-completion.bash#L40-L45(this comment).rhiza/completions/rhiza-completion.zsh#L48-L72
🤖 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 @.rhiza/completions/rhiza-completion.bash around lines 40 - 45, Update the
cache refresh logic in .rhiza/completions/rhiza-completion.bash at lines 40-45
to write the parsed targets to a temporary file, verify the complete
make/awk/grep/sort pipeline succeeds, then atomically rename it to the final
targets-* cache; update .rhiza/completions/rhiza-completion.zsh at lines 48-72
to generate both .desc and .plain outputs in temporary files, publish both only
after the full refresh succeeds, and clean up temporary files on failure.
| if [[ -r "$cache_file.desc" ]]; then | ||
| targets=(${(f)"$(cat "$cache_file.desc")"}) | ||
| plain_targets=(${(f)"$(cat "$cache_file.plain" 2>/dev/null)"}) | ||
| else | ||
| # Cache unavailable (e.g. unwritable HOME): fall back to direct parsing | ||
| plain_targets=(${(f)"$( | ||
| make -qp 2>/dev/null | \ | ||
| awk -F':' '/^[a-zA-Z0-9_-]+:([^=]|$)/ { | ||
| split($1,A,/ /) | ||
| for(i in A) print A[i] | ||
| }' | \ | ||
| grep -v '^Makefile$' | \ | ||
| sort -u | ||
| )"}) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Preserve described targets in the cache-unavailable fallback.
Lines 81-89 rebuild only plain_targets; targets stays empty, so Zsh completion loses ## descriptions whenever the cache directory is unavailable. Run the same described-target extraction used for .desc in this branch.
🤖 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 @.rhiza/completions/rhiza-completion.zsh around lines 76 - 89, The
cache-unavailable branch should populate described targets as well as
plain_targets. Update the fallback around the make/awk extraction to run the
same description-aware target extraction used to build targets from .desc,
preserving ## descriptions when the cache directory cannot be read or written.
| gh-install: ## check for gh cli existence and install extensions | ||
| @if ! command -v gh >/dev/null 2>&1; then \ | ||
| printf "${YELLOW}[WARN] gh cli not found.${RESET}\n"; \ | ||
| printf "${BLUE}[INFO] Please install it from: https://github.com/cli/cli?tab=readme-ov-file#installation${RESET}\n"; \ | ||
| else \ | ||
| printf "${GREEN}[INFO] gh cli is installed.${RESET}\n"; \ | ||
| fi |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
gh-install help text doesn't match its behavior.
The description says "install extensions" but the target only checks for gh CLI presence and prints a warning/info message; it never installs anything.
✏️ Proposed fix
-gh-install: ## check for gh cli existence and install extensions
+gh-install: ## check for gh cli existence📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| gh-install: ## check for gh cli existence and install extensions | |
| @if ! command -v gh >/dev/null 2>&1; then \ | |
| printf "${YELLOW}[WARN] gh cli not found.${RESET}\n"; \ | |
| printf "${BLUE}[INFO] Please install it from: https://github.com/cli/cli?tab=readme-ov-file#installation${RESET}\n"; \ | |
| else \ | |
| printf "${GREEN}[INFO] gh cli is installed.${RESET}\n"; \ | |
| fi | |
| gh-install: ## check for gh cli existence | |
| `@if` ! command -v gh >/dev/null 2>&1; then \ | |
| printf "${YELLOW}[WARN] gh cli not found.${RESET}\n"; \ | |
| printf "${BLUE}[INFO] Please install it from: https://github.com/cli/cli?tab=readme-ov-file#installation${RESET}\n"; \ | |
| else \ | |
| printf "${GREEN}[INFO] gh cli is installed.${RESET}\n"; \ | |
| fi |
🤖 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 @.rhiza/make.d/github.mk around lines 21 - 27, Update the `gh-install`
target’s help description to state that it checks whether the `gh` CLI is
installed and reports its status, rather than claiming it installs extensions.
Leave the existing command behavior unchanged.
| ### Opting in to live DEBUG logs | ||
|
|
||
| By default, the template disables live pytest CLI logging (`log_cli = false`) to keep normal test output concise. | ||
| When you need detailed live logs for debugging, enable them per-run: | ||
|
|
||
| ```bash | ||
| uv run pytest -o log_cli=true --log-cli-level=DEBUG | ||
| ``` | ||
|
|
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Code fence style mismatch (MD048).
markdownlint-cli2 flags this fence as backtick where the project's config expects tilde-style fences.
📝 Proposed fix
-```bash
+~~~bash
uv run pytest -o log_cli=true --log-cli-level=DEBUG
-```
+~~~📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Opting in to live DEBUG logs | |
| By default, the template disables live pytest CLI logging (`log_cli = false`) to keep normal test output concise. | |
| When you need detailed live logs for debugging, enable them per-run: | |
| ```bash | |
| uv run pytest -o log_cli=true --log-cli-level=DEBUG | |
| ``` | |
| ### Opting in to live DEBUG logs | |
| By default, the template disables live pytest CLI logging (`log_cli = false`) to keep normal test output concise. | |
| When you need detailed live logs for debugging, enable them per-run: | |
| ~~~bash | |
| uv run pytest -o log_cli=true --log-cli-level=DEBUG | |
| ~~~ |
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)
[warning] 80-80: Code fence style
Expected: tilde; Actual: backtick
(MD048, code-fence-style)
🤖 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 `@docs/development/TESTS.md` around lines 75 - 83, Update the code fence around
the pytest command in the “Opting in to live DEBUG logs” section to use the
project’s tilde-style fence, replacing both opening and closing backtick fences
with matching tildes while preserving the bash language marker and command.
Source: Linters/SAST tools
The v1.2.5 template turned on gates this codebase had never been checked against. Six CI checks were failing: Pre-commit, Type checking on 3.12/ 3.13/3.14, docs-coverage, and the CI gate. Type checking (mypy --strict: 67 errors -> 0; ty stays clean) - Add a `typecheck` dependency group with pandas-stubs, in default-groups so `uv run --with mypy` resolves them from the project environment. - Make SubplotSpec a real PEP 695 type alias; as a bare assignment mypy rejected it as "not valid as a type", which also broke narrowing. - Annotate DataManager's stored arrays so the public properties no longer return Any, and declare final_open/high/low/close up front so both chart-mode branches can assign either an array or None. - Annotate the nested FastAPI handlers, DataResponse's bare `list` fields, ChartServer._server (inferred as None, so `.run()` was an attr-defined error), and __enter__/__exit__. - Test ndarray before pd.Index/pd.Series when normalizing the index: the tuple isinstance left an ndarray/Index intersection that fails to_numpy's Self bound once the real pandas stubs are visible. Lint (ruff: 27 errors -> 0) - Annotate the remaining handlers, helpers and demo.generate_ohlc. - Keep `open` as an OHLC keyword and silence A001/A002 locally with the rationale: it is the domain vocabulary and part of the public API, so renaming it would break callers. - Silence BLE001 where the broad catch is deliberate (best-effort static mount, browser launch that falls back to printing the URL). docs-coverage (98.4% -> 100%) - Docstring the 8 nested test helpers interrogate reported as missed. pyproject - Drop the deprecated "License :: OSI Approved :: MIT License" classifier and move to the PEP 639 SPDX form (`license = "MIT"`), which is what .rhiza/tests/test_pyproject.py now requires. Verified `uv build` emits Metadata-Version 2.4 with License-Expression: MIT. Orphaned files - Delete the 31 paths this PR previously left unstaged. They are leftovers from v0.18.8 that the v1.2.5 lock does not own, and one of them (.rhiza/utils/suppression_audit.py) was itself failing the ruff gate. Verified none are in template.lock and no lock-owned file imports them. Verified locally: typecheck, test (154 passed, 100% coverage), docs-coverage, rhiza-test, deptry, security and pre-commit all pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Superseded by alihaskar#80, which takes this same branch ( Nothing changed and nothing is lost — both PRs were fed by the identical branch, and Reopen if the upstream route is not wanted. |
Syncs this repo to a new release of its template.
jebel-quant/rhizav0.18.8→v1.2.5(upstream commite5d7005e2d9f).rhiza/template.ymland.rhiza/template.lock)This is a major bump (0.x → 1.x), confirmed before running.
Conflicts
7 files conflicted and were resolved by taking the upstream (template) side — a
rhiza-managed file is the template's to own, so local divergence is drift to undo:
.github/workflows/rhiza_benchmark.yml.github/workflows/rhiza_book.yml.github/workflows/rhiza_ci.yml.github/workflows/rhiza_codeql.yml.github/workflows/rhiza_marimo.yml.github/workflows/rhiza_release.yml(2 blocks).github/workflows/rhiza_weekly.ymlLeft unstaged — your call
The sync removed 31 files from disk that v1.2.5 no longer ships, but those
deletions are not in this PR: the new lock doesn't list them, so
stage_synced.pyleft them in the working tree rather than staging deletions forpaths it no longer owns. They are still deleted locally — decide whether to commit
the removals or restore them (
git checkout -- <path>):31 paths
Note that
.rhiza/requirements/*.txtand.rhiza/make.d/releasing.mkdisappearingis a structural change in 1.x — worth a look before merging.
No gates were run
/rhiza:updatesyncs only. Run/rhiza:qualityfor a scorecard,/rhiza:statusfor what is now synced.
Summary by CodeRabbit
New Features
Improvements
Documentation
Tests