feat(set): schema-aware vaultctl set with extend prompt (#40 phase 3, closes #40)#52
Merged
feat(set): schema-aware vaultctl set with extend prompt (#40 phase 3, closes #40)#52
Conversation
Phase 3 closes the #40 lifecycle loop. After computing the new vault data but before encrypting, `set` validates against `.vaultctl/vault.cue` (if baseline + cue both available). When the new structure isn't covered: - shows the schema diff for the change being made - prompts to extend the baseline (default: no), then prompts to proceed with drift (default: no — abort, leave vault unchanged) Non-interactive flags: - --extend-schema: write the new baseline silently and continue - --no-extend-schema: skip both prompts, accept drift (validate flags later) - --force without flag: same as --no-extend-schema (safer default for scripts) Detail: `_previous` backup keys are stripped from the validation input, because the schema deliberately excludes them. Without this, every set on an existing-key would falsely report "schema does not cover" simply because pre-existing backups aren't in the schema. 7 new CLI tests cover: no baseline (skipped), existing-key set (silent), both schema flags, --force-without-flag default, interactive accept, interactive decline-and-abort. Closes #40.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #40 — phase 3 of the schema lifecycle. `vaultctl set` now consults the project's CUE baseline before encrypting and reacts to structural changes that the schema doesn't cover.
The static foundation from phases 1+2 (`schema infer` + `schema sync`) lets users bootstrap and sync the schema explicitly. This phase makes the schema part of normal day-to-day flow: when a `set` would introduce a new key (or change a key's structure), the user sees the diff, and decides whether to accept it as a schema change or as drift.
UX
```
$ vaultctl set new_token "abc123"
Schema does not cover this change:
--- /home/.../vault.cue (current)
+++ /home/.../vault.cue (inferred)
@@ -3,4 +3,5 @@
#VaultFile: {
existing_key: string
}
Extend .vaultctl/vault.cue with this change? [y/N]:
```
If "y": the baseline is rewritten to cover the new structure, then the vault is encrypted as usual.
If "n": a follow-up prompt asks "Proceed without updating schema?" — "y" continues with drift, "n" aborts and leaves the vault unchanged.
Non-Interactive Flags
The schema diff is still printed to stderr in non-interactive runs, so CI logs show what changed.
Implementation
Test Coverage
7 new CLI tests:
Total tests: 373 → 380. Coverage stable at 88%.
What's NOT in This PR
The big-picture design from #40 is now complete:
Possible future polish, not part of this PR:
Closes #40.
Refs #34.