Skip to content

feat(manager): suggest what to put in, on the first screen - #211

Merged
stormer78 merged 1 commit into
mainfrom
feat/starter-attributes
Sep 9, 2026
Merged

feat(manager): suggest what to put in, on the first screen#211
stormer78 merged 1 commit into
mainfrom
feat/starter-attributes

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

The guided setup's first step opened a free-text claim type and an empty value. That is the right editor and the wrong first question: someone who has never seen this model does not know name.given is a thing they may write, and the vocabulary that would tell them is not on the screen. So they add one attribute or none, and the face they build in step two has nothing to choose from.

Step one now offers the ordinary things in the holder's own words, with a skip to the free-form editor at any point. No wire change — it writes the same persona/attribute/put the editor beneath it does.

What it suggests

Shown on arrival — the ones that resolve to mask: none, so what you type stays legible on your own screen: first name, last name, what you like to be called, personal email, pronouns, country, language.

Folded behind a disclosure — mostly sensitivity: high, worth having rather than worth insisting on: mobile, date of birth, home address, work email, where you work, what you do there.

Three decisions worth reviewing

Nothing under gov.* or payment.* is offered, and the screen says why. A passport number somebody typed has provenance selfAsserted — on screen that reads you said so, and to a verifier it is worth exactly that. Asking for one in the first five minutes teaches the reflex this model exists to break, in exchange for a value no counterparty can rely on. They also resolve to release: stepUp, which is a real cost to accept before anyone has seen the model work once. The wizard points at credentials instead. offersWithheldType() is asserted, so adding one means deleting a test.

Every suggestion is marked against the agent in front of it. An undeclared leaf resolves to the more protective of its family and the unregistered floor, so offering person.pronouns to an agent that has never heard of it produces a value masked as though it were a passport number. The row says so before anyone types. The check is for an exact registry entry rather than isRegisteredType's family walk — §4 rule 3 only ever tightens, so person being declared lends nothing to person.pronouns, and the walk would answer true for a token that is about to be masked anyway. A null registry marks everything undeclared rather than assuming the tokens are fine.

Partial failures say which half happened. There is no batch put, so writes are sequential and independent and the fifth can fail with four already stored. Reporting only the error would leave someone believing none of it landed, and a retry would then duplicate the four that did. Writes carry expectedVersion: 0 so a create stays a create.

Tests

15 new — 8 model (manager-starter-set.test.mts), 7 rendered (persona-starter.render.test.mts). Full suite 431/431, tsc -b clean.

Not in this PR

Grouping faces into worlds (persona/facet/*), which needs a spec change first. Stacks cleanly on top of this — a suggested set and a world are independent.

The guided setup's first step opened a free-text claim type and an empty
value. That is the right editor and the wrong first question: someone who
has never seen this model does not know `name.given` is a thing they may
write, and the vocabulary that would tell them is not on the screen. So they
add one attribute or none, and the face they build in step two has nothing
to choose from.

Step one now offers the ordinary things in the holder's own words — first
name, what you like to be called, personal email, country, pronouns,
language — with the ones sites ask for most (mobile, date of birth, home
address, work email, workplace, role) folded behind a disclosure, because
most of those resolve to `sensitivity: high` and are worth having rather
than worth insisting on before anyone has seen what a face does.

**Nothing under `gov.*` or `payment.*` is suggested, and the screen says
why.** A passport number somebody typed has provenance `selfAsserted` — it
reads *you said so* and is worth exactly that to a verifier. Asking for one
in the first five minutes teaches the reflex this model exists to break, in
exchange for a value no counterparty can rely on. `offersWithheldType` is
asserted, so adding one has to delete a test.

**Every suggestion is marked against the agent in front of it.** An
undeclared leaf resolves to the most protective treatment the agent has, so
a row the registry does not declare warns *before* anyone types rather than
coming back masked afterwards. The check is for an exact entry rather than
`isRegisteredType`'s family walk: rule 3 only tightens, so `person` being
declared does not lend anything to `person.pronouns`, and the walk would
answer a different question.

Writes carry `expectedVersion: 0`, so a retry after a partial failure cannot
duplicate what already landed — and a partial failure says which half
happened, because reporting only the error would leave someone believing
none of it did.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 merged commit c546b42 into main Sep 9, 2026
3 checks passed
@stormer78
stormer78 deleted the feat/starter-attributes branch September 9, 2026 06:02
@affinidi-appsecurity-bot

Copy link
Copy Markdown

🛡️ AI Agentic Security Code Review

🔎 A manual security review is recommended before merging. Please contact the Security team for specifics and remediation guidance.

ℹ️ Detailed findings are not published on public repositories; the Security team holds the complete report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants