##### Context In August 2026 Matt Kelly delivered a five-document framework package (`READ_FIRST` states it supersedes the July handoff) together with a working HTML prototype of the customer dashboard and a content-blind task page. Three of those documents specify the Plan Protector: its own **Post-Designation Framework**, and the verification sections of **Vault Box — Post-Order** and **Scheduled Gifts — Post-Order**. This ADR covers only the first: the protector as a party. What consumes a protector's confirmation is deferred, and §"Deliberately out of scope" says why. **What exists today.** `Rempla.Core/Services/PlanProtectorService` adds and removes one `RemembrancePlanRole` row — `PersonId` → `RelatedPersonId`, `RemembrancePlanRoleTypeId = 2`. That is the entire implementation. It is idempotent, it authorizes the target against the owner's planning tree, and it does nothing else. Measured against the framework, what is absent is everything after the designation itself: - **No status.** A designation exists or it does not. The framework's four-state vocabulary — accepted, pending, declined, unresponsive — has nowhere to live. - **No contact of its own, and no adulthood check.** A protector must be reachable by email *and* SMS and must be an adult (PP §2: "every designation form requires a date of birth and declines a minor"). `Person.DateOfBirth` exists and nothing consults it here. - **No clock.** The annual wellness cycle (PP §3.3) has no last-confirmed date, no due date, and no escalation record. - **No invitation and no acceptance.** PP §3.1–3.2 require an invitation by both channels, an accept/decline response, an identity check, and an acknowledgment of three specific things. None of it is modelled. - **No confirmation record.** A protector's answer to "has this person passed away" or "did this milestone happen" has no row. **Designation is wired to one product only.** `VaultController` owns `AddPlanProtector`, `RemovePlanProtector`, and `GetProtectorsModel`. `GiftController` contains no protector reference at all — verified by grep. Yet both product frameworks make a protector **mandatory** for a milestone-triggered delivery (Gifts §4.5: "choosing a milestone delivery requires designating a Plan Protector to confirm it"; Vault §4.7 states the same). A milestone gift can currently be created with no protector. **The customer-facing page is a stale copy of an older prototype.** `Views/RemembrancePlan/Protectors.cshtml` renders one hardcoded protector — "Susan Harlow / Sister / Active" — as literal markup. `protectors.js` has an empty `render()`. `RemembrancePlanController.Protectors()` returns the view and nothing else. The current prototype's `#dashboard-protectors` panel carries three seeded protectors spanning all four states, with per-state follow-up copy. The page is not a draft to improve; it is a snapshot of a design that has since moved. **ADR-004 already chose the right subject.** It made Person the universal node, `RemembrancePlanRole` a functional Person→Person edge explicitly described as "multi-plan (a person can hold roles across multiple plan owners)", and `PlanProtector` both a role-type value (`Id = 2`) and a `UserType` (`Id = 3`). The frameworks agree, independently: PP §3.6 says the relationship "persists, quietly, for any future events on that plan **and for any other plans the person protects**"; PP §4 says the protector sees "which customers they protect"; and both product frameworks say protectors are "managed from their own dashboard section" rather than on the plan. The prototype's `PP_MGR` is one flat per-customer list. **So a designation is account-level, and ADR-004's edge already models that correctly.** This ADR does not revisit the subject. It adds the dimensions the edge cannot carry. **What a confirmation is for.** Vault §7 and Gifts §7 specify one evidence engine, in identical terms: | Evidence | What it authorizes | |---|---| | Certified death certificate | Proceed after recipient-identity verification. **No 30-day window** — it would be moot. | | No certificate, plus two independent sources (obituary, funeral home, SSA) **and any one** designated protector's confirmation | A ~30-day escalating email + SMS outreach window with a one-tap **"I'm alive"** reversal, then release. | | No protector designated **or reachable** | The two independent sources plus the same window **suffice on their own**. | | Detection hit alone, or weak corroboration | **Not a release.** Long-hold while corroboration continues. | Two properties of that table drive the model here. **Any one** confirmation satisfies the protector term, so confirmations are not votes and must not be aggregated as such. And the protector term is *conditional on a protector existing to give it* — so "no confirmation" and "no protector" are different facts, and the model must be able to tell them apart. ##### Decision **1. A designation becomes its own record. The role edge stays, and stays generic.** Add `PlanProtectorDesignation`: | Field | Meaning | |---|---| | `OwnerPersonId` | the customer whose plans are protected | | `ProtectorPersonId` | the protector | | `Status` | `{Pending, Accepted, Declined, Removed}` — see the amendment below | | `EmailAddress`, `MobileNumber` | the designation's own contact, snapshotted at designation | | `DateOfBirthAtDesignation` | the adulthood evidence, recorded rather than re-derived | | `DateInvited`, `DateResponded` | the invitation round-trip | | `DateLastConfirmed`, `DateNextConfirmationDue` | the annual clock | | `ConfirmationAttemptCount` | escalation state within the current cycle | | `AcknowledgedRole`, `AcknowledgedContentBlind`, `AcknowledgedNotSworn` | the three acceptance acknowledgments (PP §3.2), each recorded separately | | `PrefersAccount` | link-only or full account — the channel the protector chose | `RemembrancePlanRole` is **not** extended. It is a three-value generic edge shared with `GiftRecipient` and `DigitalLegacyBeneficiary`, and hanging protector-specific columns on it would push nullable protector state onto two unrelated roles. ADR-004 made it generic deliberately. `PlanProtectorDesignation` is **authoritative**; the `PlanProtector` role edge becomes its projection into the planning tree, written by the same service in the same transaction. This is a deliberate exception to the derived-beats-stored rule ADR-013 and ADR-014 apply, and it is bounded: the tree query (`PlanningTreeService:169`) and six call sites read roles generically by name, and rewriting all of them to union a second table would spread protector knowledge across the tree rather than contain it. **One writer, two rows** is acceptable; two writers of one fact is not. The projection is written nowhere else, and no code may add or remove a `PlanProtector` role edge directly — `PlanProtectorService` becomes the only path. **2. Four states are customer-visible. `Removed` is not.** `Pending` (invited, no response), `Accepted`, `Declined`, and `Unresponsive` are exactly the vocabulary the customer sees, and the prototype's chips and per-state copy map to them one-for-one. `Removed` is a fifth stored state so that a removal is a transition rather than a deletion — PP §5 requires that removal **notifies the person**, and a deleted row cannot be notified about, nor can it answer "what did we tell whom, and when" later. `Unresponsive` is **derived from the clock, not set by hand**: a designation whose confirmation window has closed unanswered. Recording it as an independently-writable status would create a second source for a fact the dates already carry. **3. Adulthood is checked at designation, and the check is evidence, not a gate that vanishes.** A designation requires a date of birth and refuses a minor (PP §2). `DateOfBirthAtDesignation` is stored on the designation rather than read live from `Person.DateOfBirth`, because the question "were they an adult when designated" must stay answerable if the person record is later corrected. The prototype enforces the same rule on its picker: adults only, and **no self option** — a protector is another person. **4. Contact belongs to the designation, snapshotted.** Email and mobile are copied onto the designation at the moment it is created, following the same rule as `Notification.ToAddress` and every other snapshot in this system: an address that changes between designation and use would silently redirect a request about someone's death to whoever holds the address now. The protector may update their own contact through their own flow; that writes here, deliberately and with an identity check. **5. Two wellness clocks exist. This ADR builds one.** The protector's annual confirmation (PP §3.3) and the *customer's* annual wellness contact (Vault §4.6, Gifts §4.3) are different cycles with different subjects, and the prototype's task page distinguishes them (`wellness`/`pp-annual2` versus `customer-wellness`). Only the protector clock is in scope here. Both share one rule worth stating once: **any interaction resets the clock**, so an active party is rarely asked, and **silence is never a signal about the customer** (PP §3.3) — a protector who stops answering says something about the protector. A protector is **never removed automatically** for missing a check. `Unresponsive` prompts the customer to re-confirm or replace; it does not act. **6. A confirmation is its own row, written once and never mutated.** Add `PlanProtectorConfirmation`: | Field | Meaning | |---|---| | `PlanProtectorDesignationId` | who confirmed | | `Subject` | `{Passing, Milestone, AnnualWellness}` | | `SubjectReference` | the event this confirmation is scoped to | | `Answer` | the plain answer given, including "not sure" and "not going to happen" | | `ReportedDate` | the milestone date, where one was supplied | | `DateConfirmed`, `IdentityVerifiedAt` | when, and when the one-time code passed | Three framework properties make this a row rather than a field. **Authority is event-scoped** — PP §3.6: "a protector's authority is always tied to a specific event and is never open-ended", so a confirmation must name its event. **Any one confirmation suffices**, so the engine needs to ask "does a confirmation exist for this case" rather than read a flag off the protector. And **the answer is a plain acknowledgment, never a sworn statement** (PP §2, restated in the acceptance acknowledgments) — recording it as an immutable dated row with the identity check attached is what keeps that claim honest afterwards. `Answer` deliberately admits **"I'm not sure"**. The prototype offers it as a first-class button on `pp-confirm-passing`, and collapsing it into a null or a "no" would discard the one answer that most accurately describes a protector's state of knowledge. **7. Content-blind is enforced by the query, not the view.** PP §2 is explicit that the boundary "is enforced by the account itself, not merely hidden in the interface", and Recipient §3.4 says the same of its own existence-only view. Protector-scoped reads must therefore return a projection that *cannot* carry plan contents — customer first name, whether a confirmation is due, whether one is pending — rather than a filtered view of a fuller model. Where one person holds several roles, PP §4 governs: each role renders in its own separated view, and **the most restrictive view wins**. This is a decision about where the boundary lives, not a claim that it is built. The projection type is in scope; the authorization principal that selects it is not (see below). **8. A milestone-triggered delivery requires a protector, and the check belongs to submission.** Both product frameworks state it as a requirement of *choosing* the trigger. The gift and vault submission services are the only places that can enforce it against the plan as configured, and `GiftScheduleProjection` already refuses to project a milestone with a comment naming the missing actor ("Someone has to set one when the milestone happens"). This ADR names the requirement and places it; it does not specify the wizard step. ##### Rationale - **The edge was never wrong — it was only thin.** The tempting reading of "promote the protector to a party" is that ADR-004's role edge modelled the wrong thing. It did not: the frameworks independently arrive at exactly ADR-004's account-level, multi-plan, one-identity shape. Naming this explicitly matters, because the alternative reading leads to a per-plan designation table that would contradict both the frameworks and the prototype, and would be expensive to reverse. - **Status, contact, and clock are three different kinds of fact, and only one of them is a state machine.** Keeping `Unresponsive` derived from the clock rather than stored as a settable status is the specific defect this system keeps re-learning — `VendorOfferStatus`, `Product.Status`, and `VendorProduct.Availability` all went wrong by giving one fact two writers. A status a human can set *and* a scheduler can set is that same shape. - **A confirmation that is a boolean on the protector cannot answer the question the engine asks.** The engine asks whether *this case* has a protector confirmation. A flag on the designation answers "has this person ever confirmed anything", which is a different question that happens to look the same while there is only one case. - **"No protector" and "no confirmation" must stay distinguishable**, because the evidence table branches on exactly that: where a protector exists, their confirmation is required; where none is designated or reachable, two independent sources suffice alone. A model that cannot tell the two apart will either block releases that should proceed or proceed on releases that should block. - **Removal is a notification event, so it cannot be a delete.** PP §5 requires telling the person plainly that they have stepped back. This is the same reasoning `Notification` already carries in its own doc comment: "what did we tell whom, and when" is a question somebody eventually answers from data. - **Snapshotting contact follows the house rule** already applied to `Notification.ToAddress`, `Product.ImagePath` at submit, and the vendor offer fields on a transaction. The horizon here is decades; nothing about a contact detail should be resolved late. ##### Consequences - **Status: proposed, not implemented.** As of this ADR the role edge, the vault-only wiring, and the hardcoded page are all still present. - **Migration, additive first.** Adds `PlanProtectorDesignation` and `PlanProtectorConfirmation`; backfills one designation per existing `PlanProtector` role edge — **`Pending` with `DateInvited` null**, see the amendment below. Contact and date of birth backfill from `Person` where present and stay null where not; **a null contact is a designation that cannot yet be invited**, and the screen must say so rather than render it as ready. - **Nothing is dropped in this change.** The `PlanProtector` role rows and role type stay, now written as a projection. This avoids the shared-database sequencing problem entirely — the Azure sites run pre-migration code against the same database, and additive-only means they continue to read the role edge exactly as they do now. If the projection is ever retired, that is a second migration with a deploy between, per the pattern ADR-014 sets out. - **`PlanProtectorService` gains the invariant it does not have today.** It becomes the sole writer of both tables and the only path that may touch a `PlanProtector` role edge. `PersonRemovalService` currently deletes plan-role rows directly (`PersonRemoval.cs:61-64`) and would orphan a designation; it must route through the service or the removal becomes a silent partial delete. - **Six read sites are unaffected by design** — they continue to read the role edge by name. That is the point of keeping the projection. - **The customer screen is a rewrite, not an edit.** `Protectors.cshtml` and `protectors.js` are replaced by a data-bound panel matching the current prototype's `#dashboard-protectors`, including the per-state follow-up blocks, the redundancy nudge, and the accepted-only stat with a separate pending sub-count. - **`GiftController` gains protector wiring it has never had**, and gift submission gains the milestone requirement. Vault submission gains the same check. - **Testing** per the two-layer strategy: pure-unit for the status transitions, the adulthood refusal, the clock arithmetic and its reset-on-interaction, and the derivation of `Unresponsive`; SQLite round-trip for the designation/confirmation FK behaviour, the backfill mapping, the projection staying in step across add/remove/remove-person, and the immutability of a written confirmation. The case that matters most is the one where a designation exists with a null contact — a passing test and an uninvitable protector look identical from the outside. ##### Deliberately out of scope Each of these is specified in the framework package and **not** decided here. They are named so that a later reader does not mistake this ADR's silence for a claim that they are unnecessary. - **The verification case and its evidence engine** (Vault §7, Gifts §7) — the consumer of a passing confirmation. This ADR gives it a confirmation to read. - **PASD** — the automated death-detection layer that opens a case. Nothing like it exists in the code. - **The one-time code channel.** Every confirmation is gated by a code texted **on request**, never auto-sent with the link (the prototype records this as a specific ruling). There is no SMS capability anywhere in this codebase today, and the only OTP machinery present is Descope's login and password reset. - **The secure single-use link and the account-optional principal.** `PrefersAccount` records the protector's choice; what serves the link, and what principal a link-only protector acts as, is an authorization decision of its own. - **Notification dispatch.** The six protector messages (PP §6) are transactional, dual-channel, daytime-local, and opt-outable. The existing outbox requires a non-nullable `DeliveryId` and structurally cannot carry an invitation or an annual check; generalizing it is its own change, and there is still no mail provider. - **The customer's own wellness clock**, and bereavement mode as a household communications state. - **Milestone resolution downstream**, which differs by product: a Scheduled Gift winds down and refunds (with a customer-set backstop expressed as a duration after the passing), while a Vault Box is **delivered to the recipient** and has no backstop at all. Neither the backstop field nor the wind-down path exists. - **The recipient milestone fallback** (Recipient framework; PP §3.4), which needs the recipient side. - **The protector's existence-only notice for the Document Safe.** Document Safe §7 lists notifying protectors that a document exists as a release function, then **explicitly defers** what that notice contains to a future recipient-side specification. That is Matt's own open item, not ours to close. ##### Note on an existing behaviour this supersedes `Person.DateOfPassing` shipped on 2026-08-28. Recording a date there activates every non-voided after-passing gift on the account immediately — no evidence tier, no recipient-identity verification, no reversal window. All three verification sections of the framework package contradict that, and none of the August revisions softens it. The current behaviour is not wrong for what it was built to do; it is a one-step record that predates the gate. When the verification case lands, recording a passing must become the *outcome* of a case rather than its own act, and `Person.DateOfPassing` becomes what the case writes. Flagging it here so that the supersession is a decision rather than a surprise. ##### Amendment (2026-08-31): the stored status carries no `Unresponsive`, and the backfill is `Pending` Both corrections came out of building the model, and both are places where the ADR as first written said two things that could not both be true. **1. `Unresponsive` is not a stored status.** The Decision listed `Status` as `{Pending, Accepted, Declined, Unresponsive, Removed}` and, two paragraphs later, said `Unresponsive` is derived from the clock rather than settable. That is exactly the two-writers shape this ADR argues against, written into its own table. The split it should have made: | | Values | Where it lives | |---|---|---| | `PlanProtectorStatuses` (**stored**) | `Pending`, `Accepted`, `Declined`, `Removed` | a record of what the protector *did* | | `PlanProtectorStandings` (**derived**) | the four above plus `Unresponsive` | `PlanProtectorDesignation.StandingAt(now)` | The stored enum holds acts; the derived one holds what the customer is shown. `StandingAt` takes `now` as a parameter rather than reading the clock, because an answer that changes with time and hides where it got the time from cannot be tested. The derivation is also **narrower than "the date has passed"**: only an `Accepted` designation can go unresponsive, because only an accepted protector was ever asked. A pending or declined designation carrying an old date is not a protector who failed to answer. Implementing it the obvious way — check the date first, fall back to the status — is wrong, and it is wrong precisely for the rows the backfill creates. **2. The backfill is `Pending` with `DateInvited` null, not `Accepted`.** The original text argued `Accepted` because "treating them as pending would fabricate an invitation that was never sent". That reasoning is defeated by `DateInvited` being nullable, which the model gained after the ADR was written: **`Pending` + `DateInvited = null` states the truth exactly** — the customer named this person, we never invited them, and they never answered. Nothing is fabricated. `Accepted` would have been the worse error, and not only because it asserts a consent nobody gave. Any one protector's confirmation helps satisfy the no-certificate release threshold, so **a fabricated acceptance is a fabricated evidence source** — a row that could contribute to releasing someone's estate on the strength of a migration's guess. `Pending` fails safe, and the remedy is to send the invitation. The three acknowledgment flags backfill `false` for the same reason: nobody acknowledged anything, and a backfill must not manufacture a record of somebody agreeing to something. Contact details and date of birth come across where the person has them and stay null where they do not. A null contact is a designation that **cannot be invited** (`IsInvitable` requires both email and mobile, because the invitation goes out on both channels), and the screen must render that as a gap to close rather than as a protector who is ready. > **Superseded by the 2026-09-02 amendments below.** New designations require an email address, and `IsInvitable` no longer exists. This paragraph describes the backfill as it was performed on 2026-08-31 and the behaviour that stood until 2026-09-02; the rows it created are being retired through the UI. **Amendment Date**: August 31, 2026 ##### Amendment (2026-09-02): contact is required to designate, and the invitation is its own act Two changes, both narrowing what the original decision allowed. Requested by Joshua after seeing the built screen against Matt's prototype (`rempla.Website.Demo.extension.v1.html`, `#tab-protectors`). **1. A designation now requires an email address, and refuses without one.** The original decision said the opposite, in the Decision section and again in the 08-31 amendment: contact "stay[s] null where they do not [have it]", producing a designation that "cannot be invited" which "the screen must render as a gap to close rather than as a protector who is ready". That was defensible and it is now reversed. The gap-to-close framing assumed the customer would close it. Measured on the shared dev database on 2026-08-31, **all three existing designations had neither an email nor a mobile**, and every one had been sitting in that state since the backfill. What the rule produced in practice was not a prompt but a list of rows that could only ever say "cannot be invited yet" — a permanent notice rather than a temporary one. `AddAsync` therefore refuses with `EmailMissing`, checked **after** the age rules so that a fifteen-year-old with no email is refused for being fifteen. > **Revised later the same day.** This first went in requiring **both** an email address and a mobile number, on the framework's reading that the invitation goes out on both channels. It was cut back to email within hours, and the reason is worth keeping: requiring the mobile put back exactly what the rule was meant to remove. The person editor requires a date of birth and is expected to require an email, but **not** a phone number — so a mobile requirement would have gone on refusing perfectly ordinary people, with the refusal now the *only* thing the picker could say. A mobile number is still snapshotted where the person has one. Whether SMS can actually be used for a given protector is the invitation's problem (ADR-016), not a reason to refuse naming somebody. > **Superseded by the 2026-09-04 amendment below: the mobile requirement is back.** The paragraph above is kept because its *reasoning* is what got reversed, not its conclusion. It is right that a requirement the entry form cannot satisfy will go on refusing ordinary people — and wrong to have fixed that by dropping the requirement, when the thing to fix was the form. Note also that the code comments asserting "both channels" were never swept when this was written, so between 09-02 and 09-04 the source said one thing and the ADR another. `PlanProtectorDesignation.IsInvitable` is **removed**, along with everything that branched on it: the "cannot be invited yet" card note, the dashboard's un-invitable quick-action copy and its guide step, and the property's own tests. `AddAsync` is the sole writer of `EmailAddress` and `MobileNumber` — the contact is a snapshot, unaffected by later edits to the person — so with the refusal in place every live designation carries both by construction and the property was a constant `true`. Keeping it would have meant maintaining screens for a state with no producer. The columns stay nullable in the schema. Rows predating this rule still exist and are being retired through the UI rather than by migration; once they are gone, nothing can write a null. Tightening the schema is deferred rather than decided against — it is a migration against the shared database, and that is not a change to make in passing. The consequence to accept deliberately: **a person cannot be named as a Plan Protector until they have an email address.** The picker offers an "add someone new" path into the planning tree's own person editor rather than a second form of its own. It does **not** offer a fix-it action on a refused candidate. It briefly did — every refusal carried an "add their details" button into the editor — and that came out on 2026-09-02 with the mobile requirement. The affordance made sense while the refusals were mostly gaps in what we know; once the editor itself requires the missing fields, what reaches the picker is a fact about the person, and a button offering to fix a fifteen-year-old's age is not a fix. > **Superseded by the 2026-09-04 amendment below: the fix-it path is back, and is now the primary way a protector gets named.** The conditional in this paragraph is the load-bearing part — "once the editor itself requires the missing fields". It never did, and on 2026-09-04 it was decided it never will. **2. `DateInvited` records the customer's request, not a dispatch.** Designating no longer implies inviting; `InviteAsync` is a separate call behind a separate button. Since no mail provider exists, **nothing is sent**, and this is the honest reading of what the column now holds: *when the customer asked us to invite this person.* This matters because it is a claim the screen can get wrong in the dangerous direction. The chip therefore reads **"Pending — invitation queued"**, never "sent", and the card says plainly that Rempla cannot send email or text yet. When a provider lands, **dispatch must become what flips this** — the customer's click must not remain the thing that reports an invitation as delivered. The existing `INotificationDispatcher` seam is the model, and the same rule applies: a queue that reports itself as sent is the worst available lie. Note the outbox is **not** reused here: `Notification` requires a `DeliveryId`, and an invitation concerns no delivery. Wiring invitations into it needs either a nullable delivery or a second outbox, and that decision is deferred until a provider exists to send anything. **Amendment Date**: September 2, 2026 ##### Amendment (2026-09-04): requirements belong to the role, not to the person record Reverses the direction of travel of the two preceding amendments without reversing what they were for. Requested by Joshua, against the standing thread "make an email address required in the person editor": *"we don't want to have this be required for all. we want them to be able to enter people as easy as possible."* **1. The person editor asks for a name and a relationship. Nothing else.** A date of birth was required of everybody and no longer is. Relationship stays, because it is structural rather than descriptive — it decides where the person lands on the planning tree, and there is nowhere to put someone without it. This is the premise both 09-02 amendments were written against, and it went the other way. They assumed the editor would grow *towards* requiring contact details of everyone; the decision is that it will not. Making every person carry a protector's requirements taxes every casual entry — a grandchild added to hang a birthday off — for the sake of the few people who will ever hold a role that needs them. **2. What a role needs is declared once, in `PersonRoleRequirements`.** | Role | Requires | |---|---| | `PlanProtector` | date of birth, adult, email address, **mobile number** | | `GiftRecipient` | email address | | `VaultRecipient` | email address | Everything that asks the question reads this declaration: the picker's verdict on a candidate, the person editor's required-field list for a given opening, and the server's refusal. Before this there were two implementations of the protector rule — `PlanProtectorService.AddAsync` decided the outcome and `RemembrancePlanController.ProtectorEligibility` independently decided the reason shown on the row, each with a comment noting that the other existed and that they must not drift. Three roles across three enforcement points would have made six. The controller's copy is deleted. The client is handed **field keys**, never a role, so the person editor holds no opinion about what a Plan Protector is. **3. The mobile requirement is reinstated, and this is the second reversal of it.** The framework says the invitation goes out on both channels; a protector reachable on one is half a protector. It was dropped on 09-02 because the editor did not ask for a phone number, so the rule refused ordinary people and offered them no way through. Role-scoped requirements remove that dead end rather than the rule — the protector step now collects the number. The general form is worth stating, because this is the third time this shape has appeared in this ADR: **a validation rule is only as good as what the entry form guarantees.** The 09-02 amendment drew the conclusion that the rule must weaken to match the form. The better conclusion is that whichever of the two is wrong should move — and here it was the form, which was asking the wrong people for the wrong things at the wrong time. **4. A candidate who is not ready is pickable, and picking them collects what is missing.** Three states on a picker row, not two: ready; missing something we can ask for; and underage, which is the only one that is a fact about the person rather than a gap in what we know. Only the last is disabled. Picking an incomplete candidate opens the planning tree's own person editor scoped to exactly the missing fields, and designates them on save — one act from the customer's side, the shape "add someone new" already had. Creating a person *from* the protector screen demands the role's fields up front in the same editor. The server refuses again on the way in regardless. The editor is told what to ask for; it is not the authority on it. **Amendment Date**: September 4, 2026