Skip to content

Behavioral spec: op_picker

Status: Open — Phase 1, no confirmation needed

src/console/widgets/op_picker/mod.rs is now 2331L total (was ~1712L at original analysis — +36% growth). It has a //! doc but no INV-format invariant contract. The 4-level drill-down state machine has subtle invariants around the op:// reference format and the absence of secret values in the picker path.

The render counterpart src/console/widgets/op_picker/render.rs is 865L (separate file).

INVDescriptionVerify by
INV-1Field selection commits OpField::reference verbatim when present; only fixtures missing reference use the synthesized op://<vault>/<item>/<label> fallbackselection path returns field.reference.clone() first, then falls back to format!("op://{}/{}/{}"...)
INV-2No secret values in picker path — RawOpField struct has no value field; serde drops it silentlygrep value in op_picker/mod.rs; exhaustive destructure test at operator_env.rs:~2055
INV-3Loading is async (background worker + channel); key handlers stay synchronous and only advance UI state / poll_load()background loaders use std::thread::spawn; key handlers do not call the CLI directly

4 stages: AccountsVaultsItemsFields. Each stage has a background loader and a key handler. Loaders post results via channel; poll_load() drains them before each render.

  1. Create docs/src/content/docs/internal/specs/op-picker.mdx (once Developer Reference setup exists).
  2. Use INV-N template for the three invariants above.
  3. Add sidebar entry under Developer Reference → Specs.
  4. Link from the op_picker/mod.rs //! doc to the spec URL once the internal docs section exists.