Conversation
…st env expansion
`dora record` handed the original dataflow YAML to the record node as
the `env:` value `DORA_RECORD_DESCRIPTOR`. Every `env:` value is
`$VAR`-expanded each time the descriptor is parsed (by the CLI, then
again by the daemon), so:
- a `$NAME` anywhere in the dataflow file, even in a comment, failed
`dora record` with "data did not match any variant of untagged enum
EnvValue" when `NAME` was unset;
- when set, its value was substituted, so the `.drec` header stored a
descriptor that differed from the user's file, e.g. with the real
value of an `${API_TOKEN}` reference in plain text.
Escaping `$` as `$$` does not survive the second parse, so pass the
bytes base64-encoded as `DORA_RECORD_DESCRIPTOR_BASE64` instead: no `$`
in the alphabet, 1.33x the size, and exact bytes rather than a lossy
UTF-8 conversion. The record node decodes it and still accepts
`DORA_RECORD_DESCRIPTOR` from an older CLI.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R8CSx6yQ4JbrB3dqSiU2ME
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
`cargo deny check advisories` fails every PR's Audit job with `error[yanked]: detected yanked crate` for yoke-derive 0.8.3 (via url -> idna -> icu). `cargo update -p yoke-derive` moves it to 0.8.4; no other lock entry changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R8CSx6yQ4JbrB3dqSiU2ME (cherry picked from commit 2132289)
|
The Audit job fails on every PR right now: Generated by Claude Code |
|
🤖 Fully automated review by Claude Code. No human checked it. The underlying bug is real. A raw descriptor containing 1. A new CLI with an existing record-node binary silently writes recordings that can't be replayed. The legacy fallback in 2. The new test doesn't exercise the changed code. I ran the test with the Generated by Claude Code |
Problem
dora recordhands the original dataflow YAML to the record node as anenv:value:Every
EnvValueis deserialized withwith_expand_envs(shellexpand::env), and that happens each time the generated descriptor is parsed: once by the CLI, and again by the daemon. So the raw YAML text was$VAR-expanded:$NAMEanywhere in the dataflow file, even in a comment such as# set $ROS_DOMAIN_ID first, madedora recordfail with the opaquedata did not match any variant of untagged enum EnvValue..drecheader stored a descriptor different from the user's file. For example,env: {TOKEN: ${API_TOKEN}}put the real token, in plain text, into a recording that is meant to be shared.Escaping
$as$$does not help, because the second parse on the daemon would expand it again.Fix
DORA_RECORD_DESCRIPTOR_BASE64. The base64 alphabet has no$, the value is 1.33× the size, and the bytes survive exactly instead of going through a lossy UTF-8 conversion.DORA_RECORD_DESCRIPTORfrom an older CLI.base64 = "0.22"dependency todora-clianddora-record-node. It was already inCargo.lock, so nothing new is compiled.Validation
Class: C (record/replay)
record::tests::descriptor_env_value_survives_env_expansion. It builds the record node'senv:entry for a YAML containing$DORA_TEST_SURELY_UNSET_VAR(in a comment) and${HOME}, deserializes it asEnvValue(the real expansion path), and asserts it decodes back to the exact original bytes.data did not match any variant of untagged enum EnvValue, the same error users see.cargo test -p dora-cli -p dora-record-node: ✅.cargo clippy -p dora-cli -p dora-record-node --all-targets -D warnings: ✅.cargo fmt --check: ✅.Not addressed
PATH: one that predates this change reads onlyDORA_RECORD_DESCRIPTOR, so it writes an empty descriptor header when paired with this CLI. Setting both variables would bring the bug back.DORA_RECORD_FILEandDORA_RECORD_TOPICSare still rawenv:values, so an output path containing$has the same problem. That is rarer, and left as a follow-up.🤖 Generated with Claude Code
https://claude.ai/code/session_01R8CSx6yQ4JbrB3dqSiU2ME
Generated by Claude Code