Skip to content

feat(persona): say which claim types the agent could not apply - #208

Merged
stormer78 merged 1 commit into
mainfrom
feat/say-what-the-agent-could-not-apply
Sep 8, 2026
Merged

feat(persona): say which claim types the agent could not apply#208
stormer78 merged 1 commit into
mainfrom
feat/say-what-the-agent-could-not-apply

Conversation

@stormer78

@stormer78 stormer78 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

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:

Your agent could not apply 1 of its own claim types.
Those types are treated as the most private kind, as though they had never been declared. Fix or remove the declaration.
profile.githubprofile github is not a vocabulary token

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 applied pill 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 ext defensively

unappliedClaimTypes checks member by member. ext is vendor-namespaced and the schema does not constrain it, so nothing upstream has validated the shape, and a banner built from undefined would 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 -b and npm run build clean.

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>
@stormer78
stormer78 merged commit e0eb9b0 into main Sep 8, 2026
3 checks passed
@stormer78
stormer78 deleted the feat/say-what-the-agent-could-not-apply branch September 8, 2026 19:54
@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