Skip to content

Bundle ops + atomic SetBundle (credstore §1.5.1/§2.1) #5

@rianjs

Description

@rianjs

Tracks Jira INT-431 (child of epic INT-310). Third discrete unit of cli-common; builds on #3 (Store + memory backend, merged in #4).

Scope

  • ListBundle(profile) ([]string, error) — sorted keys under a profile (config show, pre-write, config clear, migration conflict detection). Not allowlist-gated.
  • DeleteBundle(profile) ([]string, error) — removes every key under the profile; idempotent (empty → (nil, nil)). Not allowlist-gated (§1.7 clears all).
  • SetBundle(profile, kv, ...SetOpt) (Result, error) per §1.5.1: validate-all → (no-overwrite: fail on any existing, name conflicts, nothing written) / (overwrite: snapshot existing) → write-all → on mid-bundle failure restore-from-snapshot (pre-existing) or delete (new) → zero snapshot before return → Result{Written,Restored,Deleted}; rollback failures surfaced explicitly.
  • Extend internal backend interface with key enumeration; deterministic sorted iteration + Result ordering.
  • §2.1 test seam: unexported memoryBackend failure-injection hook (same-package tests only) to drive mid-bundle rollback paths.
  • Tests: list/delete (incl. empty/idempotent), no-overwrite conflict, overwrite snapshot+restore on induced failure, new-key delete-rollback, snapshot clearing, rollback-failure surfacing, allowlist on SetBundle only.

Out of scope (later INT-310 units)

Real OS backends + selection (PR4), Linux fail-closed (PR5), redaction (PR6), migration helpers (PR7), config show/clear surfaces, v0.1.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions