Skip to content

Prune orphan prior prompt values on pack removal #340

@bguidolim

Description

@bguidolim

Summary

When a pack is deselected via mcs sync or removed via mcs pack remove, its declared prompt keys linger in state.resolvedValues indefinitely. Nothing reads them, but a later-installed pack that happens to declare the same key will see the stale value as a "prior" and try to reuse it through the #339 reuse flow.

Why this matters

Cross-pack key reuse is rare but plausible — BRANCH_PREFIX, LABEL_PREFIX, DEFAULT_ASSIGNEE are the realistic collision candidates (conventional keys multiple packs would reasonably reuse). The worst-case symptom after a pack swap:

  • User removes pack A (which used BRANCH_PREFIX = "bruno")
  • User adds pack B (also declares BRANCH_PREFIX)
  • First mcs sync after adding B shows the Reuse N values? gate with B's "prior" of "bruno" — which was actually A's answer the user never intended to share

No data corruption: the user can say n and re-answer. But the gate surfaces a value the current selection never authored, which is surprising.

Proposed fix

In Configurator.unconfigurePack (Sources/mcs/Sync/Configurator.swift), after removing the pack from state:

  1. Walk the removed pack's declared prompt keys.
  2. For each, check whether any remaining selected pack still declares the same key (via declaredPrompts(context:)).
  3. If no remaining pack declares the key, delete it from state.resolvedValues.

declaredPrompts(context:) needs a ProjectConfigContext — the pack being unconfigured is already in memory at that point, and a minimal context can be synthesized.

Scope

  • Sources/mcs/Sync/Configurator.swiftunconfigurePack augmentation
  • Sources/mcs/Core/ProjectState.swift — new helper like mutating func removeResolvedValues(keys:) (or inline the dict mutation)
  • Tests: add a lifecycle case to PromptValueReuseLifecycleTests — pack A with key X → remove A → pack B declaring same X → assert B is asked fresh

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions