Robotic teams need a single repository that bundles model appearance, motion policies, and environment maps for the 22‑DoF crab robot Jumper. Existing toolchains are fragmented across separate projects, making it hard to keep hardware, learning, and deployment in sync.
What This Does
jumper is the AI toolkit that ties those pieces together.
Python core – controller/__main__.py launches the CLI, loads the robot definition (assets/jumper/jumper.xml) and motor configuration (assets/jumper/motor/motor_config.yaml), and dispatches tasks.
Rust FSM – deploy/fsm/src/lib.rs implements a finite‑state machine that drives runtime behaviour; it is compiled as a library referenced by the Python side.
Task libraries – tasks/jumper/five_foot/deploy/lib.rs is a Rust module that packages motion primitives into a deployable .app.
Build & CI – pyproject.toml pulls Python dependencies; deploy/fsm/Cargo.toml pulls Rust dependencies; Dockerfiles in deploy/convert and deploy/fsm enable image builds for conversion and FSM runtime.
How It Is Wired
Entry Point – python -m controller runs controller/__main__.py.
__main__ parses sys.argv and imports tasks modules.
For deployment, it imports the Rust library via ctypes or cffi: import tasks.jumper.five_foot.deploy.lib.
tasks in turn calls into the FSM: import deploy.fsm.src.lib.
deploy.fsm.src.lib loads its own Rust‑compiled binary (libfsm.so) and executes state transitions, writing logs to out/ and generating a .app bundle in deploy/.
The process ends by writing the bundle and exiting; no network traffic is emitted unless ROS topics are explicitly enabled (not shown in the source tree).
The call chain is linear: __main__ → tasks/.../lib → deploy.fsm.src.lib → OS file writes. The only external effect is filesystem I/O; the code never opens sockets or writes to a database.
assets/jumper/motor/motor_config.yaml – motor limits.
Running a Task
python -m controller deploy --task five_foot
The command triggers tasks/jumper/five_foot/deploy/lib.rs to produce an .app bundle under deploy/.
Real‑World Use
A typical workflow for training a gait and deploying it:
# Train (see docs/TUTORIAL.md for details)
python -m training.train --config configs/quad_walk.yaml
# Package the policy
python -m controller deploy --task quad_walk
# Flash to robot
./scripts/flash_app.sh deploy/quad_walk.app
Code Health & Issues
Low (Secret) – .env present but empty; no secrets committed.
No linting or static analysis reports were found.
Tests are present (tests/), but CI only runs checks.yml which covers linting and basic unit tests.
The Bottom Line
The repo offers a solid bridge between Python learning code and Rust‑based deployment for the Jumper robot. Its modular layout and Docker support simplify continuous integration, but the lack of comprehensive static analysis and limited documentation on the Rust/Python interface could slow onboarding. It is well‑suited for developers who build custom motions and need a reproducible deployment pipeline.
What the analyser found
Deployment readiness
6/7
✓Container image
✓CI pipeline
✓Lockfile committed
✓Test suite
✓README
✓License
✗No committed secrets
Composition
938 files
Python499
Markdown60
JSON51
Rust25
YAML10
Shell4
DockerPyTorchONNX
Architecture
Top-level areas of the codebase, sized by module count. Arrows show how many imports cross from one area into another.
Ranked by severity × confidence × production reach. Reach is the honest discriminator across a collection that is mostly other people's code: the same finding matters more in something that ships.
critical1
high3
medium7
low1
Upgrade the pinned dependency carrying a critical advisorycritical43 occurrences
onnx@1.16.1 CVE-2024-7776 (critical) +19 more; torch@2.4.0+cpu CVE-2025-32434 (critical) +22 more
The manifest pins the exact version the advisory covers, so this is not a warning about drift: the vulnerable code is what installs, and a critical rating means it is reachable over the network without credentials or user interaction.
Fix: Upgrade to the fixed version named in the advisory, then commit the lockfile.
Upgrade the pinned dependency carrying a published advisoryhigh7 occurrences
pyo3@0.22 GHSA-36hh-v3qg-5jq4 (high) +6 more
The pinned version is the one that installs, so a published advisory against it describes this deployment rather than a hypothetical one, and the advisory is also a public description of how to exploit it.
Fix: Upgrade to the fixed version named in the advisory, then commit the lockfile.
Commit a lockfile beside the manifesthigh
pyproject.toml
manifest with no lockfile in scope
An unlocked range means the artifact you tested and the artifact you ship can contain different transitive code, so a malicious patch release reaches production with no diff.
Fix: Run the package manager once and commit the generated lockfile.
Remove the committed .env and rotate what it holdshigh
.env
.env
A tracked .env is the most common route for a working key to reach a public clone, and it is the file the app actually loads, so the value is usually live.
Fix: git rm --cached the file, add it to .gitignore, rotate every credential it names, commit a .env.example with empty values.
Enable Dependabot or Renovatemedium
3 manifest(s), no update bot configured
Without a bot a published advisory sits unpatched until someone audits by hand, which across 1,322 repositories means never.
Fix: Commit .github/dependabot.yml covering the repo ecosystems plus github-actions.
Pin the container base image by digestmedium
deploy/convert/Dockerfile
python:3.12-slim
An untagged or mutable base means today's build and last month's contain different libc and a different CVE set, with no record of which shipped.
Fix: Use image:tag@sha256:<digest> and enable Dependabot's docker ecosystem.
Gate pull requests on a dependency vulnerability scanmedium
.github/workflows
no dependency scan in CI
This is the one gate that would catch a known-vulnerable package before it reaches a build, and no repository in the sample had it.
Fix: Add dependency-review-action on pull_request, or osv-scanner on push and a schedule.
Add a pre-commit secret gatemedium
a secret-shaped file is tracked and no repo-level gate is visible
Without a gate the same class of leak recurs on the next commit, so a leak finding is the symptom and this is the cause.
Fix: Add a pre-commit hook scanning staged content, and enable push protection.
Move large binaries to Git LFS or out of the repositorymedium18 occurrences
tasks/jumper/dance/media/demo.npz
18 blobs over 5MB: demo.npz 28.9MB, jumper.app 25.5MB, model_74800.pt 10.0MB
One repository here carries twenty blobs over 5MB including a 10.9MB spreadsheet, so every clone and every CI checkout pays for data nobody diffs.
Fix: Track those extensions with LFS, or move datasets to object storage and fetch them in a setup step.
Set persist-credentials: false on checkoutmedium
.github/workflows/checks.yml
checkout keeps the token, then dependencies are installed
The token stays in .git/config for every later step, so a malicious postinstall script reads a pushable credential without one ever being passed to it.
Fix: Add with: persist-credentials: false, and pass an explicit token only to the step that pushes.
Add a non-root USER to the imagemedium
deploy/convert/Dockerfile
CMD or ENTRYPOINT with no USER directive
A process running as root in the container is root against every mounted volume, and it turns any container escape or writable-mount mistake from a contained problem into a host one.
Fix: Create an unprivileged user, chown what it needs, and end the Dockerfile with USER.
Add the repository convention files this project lackslow3 occurrences
missing .editorconfig, .gitattributes, a formatter config
Without them one contributor's editor writes tabs into a Python file, a shell script commits with CRLF and fails in the container, and a notebook diff is unreviewable.
Fix: Add .editorconfig, .gitattributes with text=auto eol=lf, and a formatter config.
Checked deterministically against the repository tree and a bounded set of its files: committed credentials, unpinned actions and base images, missing lockfiles and update bots, workflows that discard failures, published advisories against the declared dependencies, runtime configuration, licensing and notebook reproducibility. No language model is involved in this section.