Skip to content

Route raw observation keys through a canonical positronic.keys module - #505

Merged
vertix merged 7 commits into
mainfrom
keys-dedup
Jul 27, 2026
Merged

Route raw observation keys through a canonical positronic.keys module#505
vertix merged 7 commits into
mainfrom
keys-dedup

Conversation

@vertix

@vertix vertix commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Defines the wire's raw observation-signal keys once in a leaf positronic/keys.py and migrates every consumer, so a rename is a single-site change the type checker propagates instead of a literal duplicated across codecs, evals, configs, adapters and datasets. This is internal#90 — filed from #495's review, where the molmo adapter had to redefine the keys as its own module-level constants because nothing was importable.

The seven keys: JOINTS/JOINT_VEL/EE_POSE/GRIP/TASK/WRIST_IMAGE/EXTERIOR_IMAGE.

Scope: repo-wide (every occurrence)

~301 literal→constant substitutions across 44 files (30 source, 14 test) — value positions, config-dict keys (state_features={keys.JOINTS: 7}), codec param defaults, .override(tgt_joints_key=...), camera dicts, obs-dict output keys, binarize_grip. from positronic import keys at top level (leaf module, no imports — no circular risk, mirrors from positronic import geom); as obs_keys in the four files that already bind keys.

The grip/task false-positive line (the risk of "every occurrence")

Only the exact literal naming the observation signal was migrated. Deliberately left as literals (different namespaces):

  • action-wire / env-raw grip — the {'command': …, 'grip': …} step payloads, action['grip'], env-server raw obs (libero/robolab env.py/validate.py/e2e.py, test_remote_env.py). keys.GRIP is the observation grip, not the gripper command.
  • vendor state-vector grip (GR00T model-format nested state['grip'], modality dicts) — vendor-encoded, siblings aren't canonical either.
  • scene/reset-token/meta task (proxy.meta['task'], reset tokens, env-scene sim), grouping/server-display task (group_fields), generic test-data task, vendor codec-output task (fixed lerobot column / vendor contract).
  • robot_state.q/ee_pose attribute accesses and error strings.

Tests

ruff check clean. pytest --no-cov: 676 passed, 7 skipped, 1 failed — the failure (pimm/tests/test_world.py::test_background_process) is a pre-existing fork-in-multithreaded flake, unrelated (0 pimm files in the diff; passes in isolation, verified).

Recut from #500's keys work without the packages/positronic-client split (parked until a real out-of-repo consumer exists). Do not merge — pending review.

@vertix

vertix commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 59eac6a01d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@vertix

vertix commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 057298fbdd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread positronic/keys.py
Comment thread positronic/policy/observation.py Outdated
@vertix

vertix commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 5c0d72013b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

vertix added 6 commits July 27, 2026 18:10
Define the wire's raw observation-signal keys once and migrate every
consumer, so a rename is a single-site change instead of a literal
duplicated across codecs, evals, configs, adapters and datasets.

Ticket: Positronic-Robotics/internal#90 #refs
The keys migration line-shifted 20 baselined basedpyright errors in the touched
test files; fix them rather than re-baseline (no grandfathering). Narrow
`dataset[0]` to `Episode` at the two Episode-access sites, type `last_obs` as
`dict[str, Any]`, and pass a mapping (not a list) for the harness state key. The
resolved entries drop out of the ratchet baseline, which shrinks by 20.

Ticket: Positronic-Robotics/internal#90 #refs
…e baseline

The `basedpyright` ratchet runs in a dev-only `.venv-typecheck` (base + dev,
`--exact`) so the check is deterministic regardless of which optional extras a
contributor synced. Under that env `torch` and `lerobot.*` are unresolved, but
three of those foreign-import errors (`cfg/policy.py`, `simulator/robolab/env.py`,
`simulator/robolab/validate.py`) were absent from the baseline — it had been
regenerated in an env where those extras resolved, so the entries auto-pruned.
Recapture them in the canonical env. Pre-existing on `main`; CI does not run the
ratchet, so it went unnoticed. No source change.

Ticket: none pre-existing baseline drift surfaced while landing internal#90
Add `test_no_raw_observation_key_literals`: an AST walk over the package that
fails if any namespaced observation key (`robot_state.q`/`dq`/`ee_pose`,
`image.wrist`/`exterior`) appears as a bare string literal instead of the
`positronic.keys` constant. Matching exact `ast.Constant` values skips docstring
examples and comments, so it flags only live code. `keys.GRIP`/`keys.TASK` are
not guarded — their bare-token values are reused across the action-command,
vendor-state and scene/reset namespaces, so a literal match cannot distinguish
the observation key from those.

The guard caught one occurrence the migration missed (`image.wrist` in
`test_wrappers.py`); migrate it to `keys.WRIST_IMAGE`.

Ticket: Positronic-Robotics/internal#90 #refs
…s literal

Addresses two Codex findings that both stem from `'task'` naming several
concepts. Split them along the read/write seam:

- Recorded-episode task FIELD (written by `data_collection` as `keys.TASK`) is
  now read through `keys.TASK` everywhere it is queried, grouped or filtered:
  `cfg/analysis.py`, `cfg/ds/internal.py` filter, `cfg/policy.py` group_fields,
  `cfg/server.py`/`cfg/phail/v1_0.py` group readers, `gui/eval.py`,
  `server/positronic_server.py`. So a `keys.TASK` rename now propagates to every
  consumer instead of silently breaking analysis/filters/grouping (finding 1).
- Output/display/model field NAMES stay literal `'task'` — the LeRobot model
  field (`ObservationCodec.task_field` default, reverted from `keys.TASK`), the
  server's display-column registries and group-result output keys. These are a
  separate schema bridged from the recorded field by the read, mirroring
  `encode`'s `obs['task'] = inputs[keys.TASK]` (finding 2: a wire-key rename must
  not rename the model field).

Ticket: Positronic-Robotics/internal#90 #refs
The module must stay a dependency-free leaf so an out-of-repo consumer can
import it without pulling in the rest of positronic (or its optional
torch/lerobot deps). Assert its AST carries no import statement.

Requested-by: Vladimir Yakunin
Ticket: Positronic-Robotics/internal#90 #refs
@vertix

vertix commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 262f52466c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread positronic/tests/test_keys.py
The repo-wide keys migration missed the two `utilities/` consumers
(`convert_ds.py`, `fake_dataset_generator.py`) that still spelled the five
namespaced observation keys as literals. Migrate them and extend the
reintroduction guard to scan `utilities/` alongside `positronic/`, so the
single-source-of-truth invariant holds across all first-party code.

Requested-by: Vladimir Yakunin
Ticket: Positronic-Robotics/internal#90 #refs
@vertix

vertix commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e0cae79056

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread positronic/keys.py
@vertix
vertix merged commit 5c1537e into main Jul 27, 2026
24 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.

1 participant