Add pixi-workspace skill#1
Merged
Merged
Conversation
Operational distillation of the pixi workspace interface protocol (ratified 2026-07-05; rationale in the dev tree's AGENTS.md, public walkthrough in Humanoid-Control-Website docs/how_to/use_pixi_tasks.md): the three command levels (lifecycle tasks / packaged hc toolbox / scenario tasks), reserved vocabulary + single-qualifier rule, task authoring and activation/env rules, and the empirically-verified gotchas (cached vcs-import setup shape, bin/ shim for PATH-visible CLIs, colcon-defaults split). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Preserves the ratified RFC (rationale, research base, normative text, migration map) alongside the skill for traceability; Status section updated from review-copy to ratified, with links to the implementing PRs. SKILL.md points at it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The full protocol RFC lives in Skills#1's description for traceability; SKILL.md points there instead of a references/ copy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reference tables replace the prose bullets: Level 1 lists the five required lifecycle tasks with meaning + authoring rules per row; Level 2 lists every standardized hc verb with what it does. Scenario naming, task authoring, environment, and gotchas sections unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The packaged hc toolbox is retired: its verbs become ordinary workspace tasks (ping-bus/scan-bus/profile-bus, viz, calibrate), deploy-sim/ deploy-real are reserved for one-command bringup+policy, sim/real mean plant bringup only, and rarely-used tools (profile report, URDF inspector, motor slider) get no task — canonical commands documented instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Adds a skill capturing the pixi workspace interface protocol — now at rev 2 (2026-07-05), which dissolves rev 1's packaged
hcCLI tier into workspace tasks — so any Claude session touching apixi.toml, pixi task, or workspace script applies the conventions automatically.skills/pixi-workspace/SKILL.mdcarries the operational rules: the two-level command model (lifecycle core + workspace tasks), the reserved scenario vocabulary incl.deploy-sim/deploy-real(one-command bring-up + policy;sim/realmean plant bring-up only, uniformly) and the at-most-one-qualifier rule (secondary parameters stay launch args), the utility one-liner tasks (ping-bus/scan-bus/profile-bus— pure aliases of their canonicalros2 runcommands), the rarely-used-tools-get-no-task rule, the canonical cachedsetuptask shape and guardedactivate.sh, environment rules, and the empirically-verified gotchas. Registered inmarketplace.json; matches the terse imperative style ofrobotics-conventions.Rev 1 was implemented via humanoid_control#16, Lite-Deployment#1, Humanoid-Control-Website#13; the rev-2 migration ships as a second round of PRs alongside this one: humanoid_control#18 (CLI retired,
deploy.launch.pyadded), Lite-Deployment#2 (deploy-sim/deploy-real+viz/calibrate), Humanoid-Control-Website#14 (two-level docs); the dev workspace and Lite-Specialist-Deployment manifests are adopted locally.The full RFC (rev 2) follows below for traceability.
🤖 Generated with Claude Code
Pixi Workspace Interface Protocol
hcCLI tier into workspace tasksAbstract
This document defines how every Berkeley Humanoids pixi workspace exposes
its environment, tasks, and scripts. It establishes a two-level command
model:
(
setup,build,test,clean,doctor), and(
sim,real,policy,deploy-sim,deploy-real,viz,calibrate, …) whose semantics each workspace defines, plus freekebab-case utility tasks (
ping-bus,profile-bus, …) that wrapcanonical commands one-to-one.
It further specifies a one-command day-one ritual (
pixi run build),rules for authoring tasks, and an environment-activation protocol. The
goal is that anyone who has learned one workspace can operate any other,
and that the canonical ROS 2 commands keep working verbatim underneath.
Status
Rev 1 was ratified and implemented 2026-07-05 (humanoid_control#16,
Lite-Deployment#1, Humanoid-Control-Website#13). Rev 2 — this text —
is ratified; its migration is being executed via a second round of
PRs. The durable normative text lives in
AGENTS.md→ "Environment,tooling & version control", and the public walkthrough in the docs
site (
Humanoid-Control-Website). This file is the review copy; themigration plan in
Appendix A is transitional
and will be dropped once executed.
Scope
This protocol governs:
humanoid_control_ws— the development workspace,*-Deploymentrepositories — operator workspaces,humanoid_controlrepo-root buildfarm manifest — packaging(a maintainer-CI surface, partially exempt; see
Lifecycle tasks).
There is no official pixi task style guide beyond this document; it sets
convention rather than follows one. Its choices were informed by the
official pixi/RoboStack guidance, a survey of ~15 real pixi + ROS 2
projects (ros2/ros2, NVIDIA IsaacSim, NASA-JSC, ros-controls, bit-bots,
RobotecAI, rerun, …), and the uv ecosystem's day-one conventions. Key
findings from that survey are cited inline as rationale.
Throughout, must, must not, should, and may are used in
the RFC 2119 sense.
Audiences and design goals
Three audiences must find the interface natural:
uv sync→uv run <thing>and one runner verb for everything. Pixi maps 1:1:pixi install→pixi run.colcon build,ros2 launch pkg file.launch.py,key:=valuelaunch arguments, and asourced overlay. All of that must keep working verbatim inside
pixi shell/pixi run --; tasks are shortcuts over canonicalcommands, never a replacement layer.
one health check, one command per everyday scenario.
When to deviate
Reserved names carry the weight of this protocol: a reserved name
must not be repurposed, and its reserved semantics must not be
altered. Beyond that, the protocol is deliberately thin:
§3.1) provided each carries a
descriptionand is never required of other workspaces.ros2/colconcommands are part of the interface(see §7.5); when no task fits, documenting the
canonical command is preferred over inventing a task.
deviate — and record why in the task description or workspace README
so the deviation reads as a decision, not an accident.
1. The two command levels
Every command a user types belongs to exactly one level:
setupbuildtestcleandoctorpixi.toml(re-declared — pixi tasks cannot ship with a dependency)simrealpolicydeploy-*vizcalibrate+ qualifiers), utility tasks (ping-bus,profile-bus,teleop, …)pixi.tomlonly1.1 Why no packaged CLI tier
Pixi offers no mechanism for tasks that travel with a dependency —
[tasks]are strictly workspace-manifest-level — so a command eitherlives in each workspace's manifest or ships as a packaged executable.
The first draft packaged the invariant-meaning commands into an
hcdispatcher. In practice the cost side dominated: the dispatcher needed a
bin/-shim install mechanism (ament_python puts console scripts inlib/<pkg>/, offPATH), a litmus test to police its scope, and adeferred ament-index extension mechanism — while the benefit was
avoiding a few one-line task declarations per workspace, in scenario
tiers that barely overlap anyway.
Rev 2 therefore keeps everything a pixi task and neutralizes the drift
risk (the original motivation — two broken aliases in the dev workspace)
by rule instead of by packaging:
ros2 run/ros2 launchcommand (§4.2) — there is nothing todrift but the one line;
utility tasks for new/consumer workspaces (A.5).
2. The day-one ritual
Day one, in every developer-facing workspace, must be one command:
2.1 How it collapses to one command
pixi runself-heals the environment (installs from the lockfile ifneeded).
pixi installremains an optional explicit step, kept inthe docs for uv users who expect a
syncverb.setupmust be safe to chain frombuild, achieved by twomechanisms together (both verified empirically):
vcs import --skip-existing— exits 0 on re-run, and unlikeplain
vcs importit never resets a locally-checked-out branch ina third-party repo back to its pin.
pixi
inputs/outputscaching — because--skip-existingalone still fetches every remote (and exits 1 offline; a bare
chain would put the network in front of every build and make an
offline robot unable to rebuild):
Verified semantics: cache hit (no network) when nothing changed;
re-runs on a
.reposedit; re-runs aftercleanor on a freshclone (the stamp lives under
build/).Caveat (must be documented on the task):
--skip-existingnevermoves an existing checkout to a new pin — after a
.repospin bump,delete that repo directory and re-run
setup. This is no worse thanthe pre-protocol behavior.
2.2 Nothing else auto-builds
The chain stops at
build → setupby design. No scenario or utilitytask may ever auto-build — hardware bringups must not trigger
surprise rebuilds.
doctoris the staleness/health check instead, andcolcon owns build incrementality.
2.3 The
doctorcheckdoctormust check: workspace root, environment active, overlaybuilt and sourced,
/opt/roscontamination (fail hard),ROS_DOMAIN_ID, source tree present, key packages visible. Fixablefindings are warnings; fatal findings exit non-zero.
3. Level 1 — lifecycle tasks
These five names are the only fully reserved names — reserved in
both name and semantics. Every developer-facing workspace must
provide them (with the
testexception noted):setupbuildbuildsetup)testcleanbuild/ install/ log/; never touchessrc/or.pixi/doctorRationale. The de-facto standard task core across every credible
surveyed project is
build/test/clean— kebab-case, flat;nobody namespaces. Workspace-type repos keep tasks to lifecycle only;
demo/deployment repos add scenario tasks. prefix.dev's only official
task-set prose adds
lintand acheckaggregate, which this protocoltreats as archetype-local (§3.1) rather than universal.
3.1 Archetype-local extras
Allowed, described, never required of other workspaces:
build-all(include the EtherCAT/Prime lane),test-result(singular, matching the colcon verb),lint(the.githooksament linter set),check(test+lintpure alias;the local pre-push gate — its description notes local linter versions
≠ CI),
gen-dds,test-dds.setup(aggregating hidden_import+_overlay),package(build
.condaartifacts — deliberately notbuild, ending thecollision with the colcon verb),
publish.Convenience variants that duplicate an existing mechanism must not
be added. Deleted at migration:
build-pkg(equivalent topixi run build --packages-select <pkg>via trailing-argumentforwarding),
test-lint,test-results,launch-policy-tracking.4. Level 2 — workspace tasks
4.1 Scenario vocabulary and grammar
Scenario tasks follow
<scenario>[-<qualifier>], kebab-case, withat most one qualifier. The reserved scenario words below must
be used by every workspace that has the concept;
launch-*prefixesmust not be used:
simrealhardware_config:=,calibration_file:=)policywandb_run_path:=/checkpoint_file:=)deploy-simsimbringup + policy in onedeploy-realhardware_config:=,calibration_file:=)vizviewer:=viserdefault;viewer:=rerun,viewer:=rviz)calibratecalibration.yamlsim/realmean plant bringup only — uniformly, in everyworkspace (rev 2 change: the first draft let deployment workspaces
overload
sim/realas the full stack). Thedeploy-*pair is thefull pipeline. A workspace where a plant-only bringup is not meaningful
may declare only the
deploy-*pair. Becausesimandpolicyare both blocking launches,
deploy-*must wrap a combined launchfile — two blocking tasks cannot be chained with
depends-on.The unqualified name is the workspace's default target; the suffix
selects the primary task variant only. Every secondary parameter
(robot, backend, checkpoint, scene, …) must remain a ROS launch
argument, forwarded verbatim — task names must never stack qualifiers.
With a robot × task × backend × policy matrix:
Which axis is "primary" is the workspace's call (in the dev workspace
today it is the robot or scene:
-prime,-piano; fordeployit isthe target:
-sim,-real); everything else rides the launch-argumentsurface, which is exactly what
ros2 launchusers expect and what §6forwarding preserves. The task
descriptionmust state the scopeand the main launch arguments.
Examples — dev workspace:
sim,real,sim-prime,real-prime,sim-piano,policy,policy-piano,deploy-sim,deploy-real(unqualified = Lite). Lite-Deployment:
simis the plant bringup,deploy-sim/deploy-realrun the full reach-task pipeline, plusteleopfor its repo-local gamepad script.Names outside the reserved vocabulary may be used for concepts the
vocabulary doesn't cover (
teleop), in free kebab-case.4.2 Utility tasks
Diagnostics and small tools are ordinary workspace tasks in free
kebab-case, verb-first where natural. Each must be a one-line
wrapper over the canonical
ros2 run/ros2 launchcommand — thetask is an alias, never a place where behavior lives — and must
carry a
description. The current set:ping-busscan-busprofile-busOnly workspaces whose robots have the underlying hardware/tooling
declare them; the docs reference block (A.5) is the copy source, which
keeps the one-liners from drifting apart across workspaces.
Rarely-used companions deliberately get no task (§5 rule 4): the
profile-busreport/plot generator, the static URDF inspector(
view_lite.launch.py), and the MIT-mode slider GUI are documented intheir canonical
ros2 run/launchforms instead.4.3 Size cap
The workspace-task tier should stay under roughly a screenful. A
launch file gets a task only if it is an everyday entry point;
everything else is documented in canonical
ros2 launchform, whichalways works (§7.5).
5. Choosing where a new entry point goes
Apply the first rule that matches:
task, universal names only.
§4.1 reserved vocabulary where it applies (
sim,real,policy,deploy-*,viz,calibrate), free kebab-case otherwise(
teleop,ping-bus).scripts/*.sh, run explicitly withsudo, never a task.ros2 …command.6. Task authoring rules
6.1 Every public task has a description
pixi task listis the workspace menu. A task without adescriptionis invisible to onboarding.
Plumbing tasks are prefixed with
_(hidden from the menu).6.2 Launch-wrapping tasks are arg-less strings
Trailing
key:=valuearguments must forward verbatim:Typed pixi
args(defaults/choices) are reserved for non-launch taskswhere they collapse variants; they must not appear on tasks whose
users pass launch arguments.
6.3 Chaining and caching
buildchainssetup(idempotent, §2.1); nothing elseauto-chains.
inputscaching onbuild— colcon owns incrementality.6.4 Task strings are legible
The task string shows the canonical command it wraps; non-obvious flags
get a why-first comment above the task. Style flags belong in
COLCON_DEFAULTS_FILE, not the task string (§7.3).6.5 Forbidden names
installorshell— they shadow pixi's own verbs.runorstart—pixi run runreads badly, and thescenario vocabulary already names what starts.
launch-*prefixes — the scenario vocabulary replaces them.(
deploy-*was banned in the first draft; rev 2 reserves it instead— see §4.1.)
build:all).picker breaks CI.
7. Environment and activation protocol
7.1 Overlay sourcing
Every colcon workspace must source its overlay through a guarded
activation script (NASA-JSC pattern):
POSIX
setup.sh, notsetup.bash. The guard makes the first,pre-build activation a no-op instead of an error.
7.2
[activation.env]carries the workspace identityROS_DOMAIN_ID(Lite = 5 perthe lab guide; Lite-Specialist = 6). The dev workspace leaves it
unpinned, and
doctorprints it.RCUTILS_COLORIZED_OUTPUT=1and the standardRCUTILS_CONSOLE_OUTPUT_FORMATgo in every workspace.7.3 Colcon flags
Style flags move to
COLCON_DEFAULTS_FILE(
config/colcon-defaults.yaml:--symlink-install, compile-commandsexport) so plain
colcon buildinsidepixi shellbehaves exactlylike
pixi run build. Semantic selection flags(
--packages-skip-regex,--packages-up-to) stay visible in the taskstring — policy, not preference.
7.4 Channels and environments
https://prefix.dev/robostack-jazzybeforehttps://prefix.dev/conda-forge, full URLs. Binary-consumermanifests put
https://prefix.dev/berkeley-humanoidsfirst.dependencies genuinely diverge (the same criterion as the Tier-2 rule
in AGENTS.md).
7.5 Escape hatches
Escape hatches are part of the interface and must be documented in
every README:
pixi shell— allros2/colconcommands work verbatim,pixi run -- <any command>,ros2 launchforms for anything without a task.7.6 The
scripts/directoryscripts/at the workspace root holds host-side helpers that can't runinside the environment or as tasks:
activate.sh,canup.sh(sudo),doctor.sh.Appendix A — Migration map (non-normative)
Transitional; describes how the repos move from the implemented
rev 1 state (landed via humanoid_control#16, Lite-Deployment#1,
Humanoid-Control-Website#13, and the local
humanoid_control_wsmanifest) to rev 2. Delete once executed.
A.1
humanoid_control_cli(retire)Rev 1 shipped the
hcdispatcher with abin/shim(
data_files('bin', …); colcon emits thepath.shhook) so it is onPATHin any activated environment. Rev 2 retires it: the verbs arepure
execvpdispatchers — the wrapped executables live in theirowning packages — so retirement means deleting the package (and its
buildfarm manifest entry) once the A.2 workspace tasks cover its
surface. The
_DISPATCHchecklist comment incli.py(hc-verbchanges must update usage/tests/skill/docs) retires with it; the same
duty moves to the utility-task tables (A.5 reference block and the
pixi-workspaceskill).A.2
humanoid_control_ws/pixi.toml(19 tasks → 25)setup build build-all test test-result lint check clean doctor gen-dds test-ddsdoctordrops itshc-on-PATHchecksim real sim-prime real-prime sim-piano policy policy-pianohcdeploy-sim,deploy-realhumanoid_bringup_liteviz,calibratehc viz/hc calibratedispatched toping-bus,scan-bus,profile-bushc bus ping|discover|probedispatched to (discoverrenamedscan,proberenamedprofile)hc bus probe-report,hc viz urdf,hc motor sliderros2 run/launchformsFinal dev-ws task list:
setup build build-all test test-result lint check clean doctor gen-dds test-dds sim real sim-prime real-prime sim-piano policy policy-piano deploy-sim deploy-real viz calibrate ping-bus scan-bus profile-bus.A.3
Lite-Deployment/pixi.toml(7 tasks → 9)Rev 1 gave this workspace
setup build clean doctor sim real teleop,with
sim/realas the full reach-task pipeline. Under the uniformrev 2 semantics:
setup build clean doctor teleopbuilddropshumanoid_control_clifrom--packages-up-to;doctordrops its hc checksim/realdeploy-sim/deploy-realtask_reach.launch.py backend:=…)viz,calibratehumanoid_bringup_lite's launches (replacehc viz/hc calibrate, both part of this workspace's operator flow)sim,policyros2 launchforms (§7.5)Lite-Specialist-Deployment(pre-protocol, local-only) adoptsdirectly:
launch-mujoco/launch-real/launch-grippers→sim/real/real-grippers(plant-only semantics are already correctthere — no policy exists yet;
deploy-*lands with the first one),dxl-scan→scan-bus(the Dynamixel bus), plusclean, thestamp-cached
setup, thebuild→setupchain, andconfig/colcon-defaults.yaml. Itsbackends:=stays a launch arg;ROS_DOMAIN_IDstays 6.A.4
humanoid_controlrepo-root buildfarm manifestMigrated at rev 1 (
_import/_overlayaggregated bysetup,package,publish; CI workflow updated in the same PR). No rev 2changes beyond dropping the
humanoid_control_clipackage when A.1lands.
A.5 Documentation
Humanoid-Control-WebsitePR #13 (the rev 1 three-level rewrite ofhow_to/use_pixi_tasks.md) must be reworked to the two-level modelbefore merge; its reference block becomes the anti-drift copy source
for the scenario + utility tasks (§4.2).
AGENTS.md→ "Command interface": update to two levels; refresh thedecision-log rows (Appendix B).
pixi-workspaceskill (Berkeley-Humanoids/Skills): updated alongsidethis revision.
Appendix B — Decision log entries (for AGENTS.md)
pixi task list); scenario tiers barely overlap across workspaces so re-declaration is nominal. vs the first draft's packagedhcCLI tier (dispatcher needed a PATH-shim mechanism, scope policing, and an extension mechanism to avoid a few one-line tasks) or convention-only with no reserved names (per-tool alias sprawl).ros2 run/launchcommands, copied from a docs reference blocksetup build test clean doctoronlydeploy-sim/deploy-realreserved = bringup + policy in one;sim/realuniformly = plant bringup onlysim/realsemantics across workspaces (first draft overloaded them per-workspace). Lifts the first draft'sdeploy-*ban — safe oncelaunch-*aliases are gone anddeployhas reserved semantics.pixi run build(env auto-installs; chainedsetupis--skip-existing+ stamp-cached on the.reposfile)build→setupchain only; scenario and utility tasks never auto-build;doctorfor healthscripts/activate.shsourcinginstall/setup.shconfig/colcon-defaults.yaml, selection flags in task stringscolcon build==pixi run build; policy stays visible.package(notbuild*)build-alldouble meaning.