feat(persona): say which claim types the agent could not apply - #208
Merged
Conversation
The agent now refuses a bad claim-type row instead of refusing to start
(verifiable-trust-infrastructure#1331), which is right for a hosted deployment
and leaves a hole: a refused row is **invisible**. Its token resolves from the
core table exactly as it would with no file at all, so the screen looks entirely
normal while the operator's intended tightening is not in force. A fault whose
only symptom is a value masked more than intended is a fault nobody reports.
So the console reads what the agent reports and says it, twice:
- a banner at the top of the persona pane, in the loudest tone the console has,
naming each type and the agent's own reason for refusing it — with the
consequence spelled out ("treated as the most private kind, as though they had
never been declared") and what to do ("fix or remove the declaration");
- a `type not applied` pill on any attribute card using one, because the banner
sits at the top of a long page and the card is where the value whose masking
is wrong actually is.
A file the agent could not read at all is a different sentence rather than a
count of zero: then *nothing* the deployment declares is in force.
`unappliedClaimTypes` reads it member by member, because `ext` is
vendor-namespaced and the schema does not constrain it — nothing upstream has
checked the shape. A malformed report is dropped rather than rendered, since a
banner built from `undefined` is a second fault reported as the first; but a
well-formed row beside a malformed one still gets through, because dropping the
whole report over one bad row is the mistake the agent just stopped making one
layer down.
590 core tests (5 new), 405 extension (4 new); `tsc -b` and `npm run build`
clean.
Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
🛡️ AI Agentic Security Code Review🔎 A manual security review is recommended before merging. Please contact the Security team for specifics and remediation guidance.
|
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.
The console half of verifiable-trust-infrastructure#1331, which made a bad claim-type row refused rather than fatal — right for a hosted agent, and it leaves a hole this closes.
A refused row is invisible
Its token resolves from the core table exactly as it would with no file at all. The screen looks entirely normal while the operator's intended tightening is not in force. A fault whose only symptom is a value masked more than intended is a fault nobody reports.
Said twice, in the two places a person is
A banner at the top of the persona pane, in the loudest tone the console has:
The reason is the agent's own words, not a paraphrase — the operator has to find that line in their own file.
A
type not appliedpill on the attribute card. The banner sits at the top of a long page; the card is where the value whose masking is wrong actually is.A file the agent could not read is a different sentence, not a count of zero: then nothing the deployment declares is in force, and the console says that instead.
Reading
extdefensivelyunappliedClaimTypeschecks member by member.extis vendor-namespaced and the schema does not constrain it, so nothing upstream has validated the shape, and a banner built fromundefinedwould be a second fault reported as the first.But a well-formed row beside a malformed one still gets through — dropping the whole report over one bad row is precisely the mistake the agent stopped making one layer down, and it would hide a real refusal.
Tests
Five in core over the reader: both report shapes, the ordinary silent case (which every existing deployment is in), four malformed reports dropped, and the mixed good/bad case getting through. Four rendered against the real pane: the banner and its consequence, the file-error sentence, silence when there is nothing to report, and the card pill.
590 core, 405 extension;
tsc -bandnpm run buildclean.