lifecycle: the runtime half of a declared promotion or suppression #43
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Meta/Campaign
Meta/Epic
Meta/Session
Priority/Critical
Priority/High
Priority/Low
Priority/Medium
Reviewed/Confirmed
Reviewed/Curated
Reviewed/Duplicate
Reviewed/Invalid
Reviewed/Won't Fix
Scope/Campaign
Status/Abandoned
Status/Blocked
Status/Conflicted
Status/In Progress
Status/In Review
Status/Need Grooming
Status/Need More Info
Status/Ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Ting/Vedanta!43
Loading…
Reference in a new issue
No description provided.
Delete branch "tango/18-declared-lifecycle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
#18 and #19, one session, one PR. Complete — no
WIP:.just checkgreen: 127 tests, 14 of them new.Both records said their bodies predate OpenSpec 85 and owed a refinement pass before a build. That pass is on the records (#18, #19); this is what it settled.
The gate is the directory, not a state file
Both records gate on "the provider-observed projection" and neither says how Vedanta reads one. It cannot — nixops4's state lives on whichever operator's machine ran the apply, and Vedanta is a service on another host.
It does not need to.
nixops-kanidmpublishes outputs read back from the directory after its write, never the declared values — that is its own stated rule, for exactly this reason: an output that echoed the declaration would report success for a write kanidm refused. So "what the provider observed" and "what the directory holds" are one fact, and only one of the two couples this service to a deployment tool it does not run.It is also the stronger reading. A state file records what a tool believed at apply time. When the two disagree the directory is right, and the disagreement is drift — #11's to observe, not this module's to trust.
Inertness is judged, not read — and this is the sharpest thing here
#19's body asks this endpoint to gate on "the UUID tombstone". There is no tombstone attribute. The council's rendering emits
accountexpireand nothing else (flake-ops#473): a second, estate-named attribute would have carried this estate's vocabulary into a provider published for anyone to consume, and would have collided with kanidm'srecycled, which names entries that have been deleted.So the gate cannot look for a marker. It asks whether the instant has passed, not whether the attribute is set.
That is not pedantry. An
accountexpireof 2099 is a converged declaration and a fully live principal. A gate asking "is it set" would admit it and invalidate the credentials of an identity the directory still authorizes — a suppression complete from one side only, which is the exact failure #19's own gating paragraph names. It is a test:An unreadable expiry is a third answer, not folded into "live": the two need different fixes, and resolving it to the safe-looking one would cost the operator the reason.
Invalidate before mint
Fail-closed, and asserted as an order. Minting first and failing to invalidate leaves two live credentials, one carrying the authority the promotion moved away from. The reverse leaves none — a workflow that must ask again, which is a stoppage rather than an over-grant.
What
Directorycannot doThree methods: observe, invalidate one named token, mint one. There is no fourth.
checkout.rs'sOccupancy, where the missing method is the assertion.Verification
Capture doubles throughout; nothing reaches a network.
Not here
Wiring these into
private_api.rsas callable endpoints, and whatever supplies the token IDs a suppression names. Both want a caller, and no caller is declared yet.Closes #18
Closes #19