Skip to content

Commit a741be5

Browse files
committed
chore(persona): take trust-tasks 0.17.1, where a resolved entry is a projection
`@openvtc/trust-tasks` 0.16.11 -> 0.17.1, and `task-surface.json` resynced to vta-sdk 0.33.0. The change that reaches a caller is `persona/profile/get`'s `resolved` array, retyped from the pool `Attribute` to `ResolvedClaim` (dtgwg-trust-tasks-tf#370). `attributeId`, `version` and `updatedAt` are OPTIONAL on a resolved entry, and their absence is the whole distinction: it says the value is `inline`, held in one profile with no pool record behind it. Under the old type all three were required, so a conforming agent could not describe such a profile at all — it had to choose between synthesising an `attributeId`, a false claim about where a value lives, and omitting the entry, which returns a profile that appears to present less than it does. No source change was needed. `personaProfileGet` returns the generated response type, and the console's `ResolvedProfile` was already written against the corrected shape — it renders "held only here" on `claim.attributeId === undefined`, a branch the old type made unreachable by construction. So the test keys on the generated schema, not on this library's behaviour: it asserts `resolved.items` is `#/$defs/ResolvedClaim` and that the three pool members are absent from its `required`. Checked against 0.16.11, where both assertions fail. Asserting the console's rendering instead would have passed against either version, which is the shape VTI#1258 got wrong. The surface itself did not move: the same 226 URIs at vta-sdk 0.33.0 as at 0.32.3, 24 of them `persona/*`, all 24 implemented here. VTI's breaking ACL change in that window (#1279) narrows what an entry may do without adding a task or a schema member — capabilities travel in `ext` as `org.openvtc.capabilities`, which this library does not yet set, and which the surface check cannot see.
1 parent 3ab25d3 commit a741be5

7 files changed

Lines changed: 82 additions & 10 deletions

File tree

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@
2828
"esbuild": "^0.28.1"
2929
},
3030
"dependencies": {
31-
"@openvtc/trust-tasks": "^0.16.8"
31+
"@openvtc/trust-tasks": "^0.17.1"
3232
}
3333
}

packages/core/CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,29 @@ For history before this file, see `git log` on `packages/core`.
88

99
## [Unreleased]
1010

11+
### Changed
12+
13+
- **`@openvtc/trust-tasks` 0.16.11 -> 0.17.1.** Carries the persona family's
14+
two projection fixes. The one that reaches a caller is
15+
`persona/profile/get`'s `resolved` array, now typed `ResolvedClaim` rather
16+
than the pool `Attribute` (dtgwg-trust-tasks-tf#370): `attributeId`,
17+
`version` and `updatedAt` are OPTIONAL on a resolved entry, and their
18+
absence is what says the value is `inline` — held in one profile with no
19+
pool record behind it. Under the old type all three were required, so a
20+
conforming agent could not describe such a profile at all, and the console's
21+
"held only here" branch was unreachable by construction. No source change
22+
was needed: `personaProfileGet` returns the generated response type, and the
23+
console was already written against the corrected shape.
24+
`tests/admin.persona.mjs` now pins it, keyed on the generated schema
25+
rather than on this library's behaviour, so a downgrade fails rather than silently
26+
restoring a branch nothing can reach.
27+
- **`task-surface.json` resynced to vta-sdk 0.33.0** (was 0.32.3). The surface
28+
did not move — the same 226 task URIs, 24 of them `persona/*`, all 24
29+
implemented here. VTI's breaking ACL change in that window
30+
(verifiable-trust-infrastructure#1279) narrows what an entry may do without
31+
adding a task or a schema member: an entry's capabilities travel in `ext` as
32+
`org.openvtc.capabilities`, which this library does not yet set.
33+
1134
## [0.7.0] - 2026-09-03
1235

1336
### Migration

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
"dependencies": {
125125
"@cfworker/json-schema": "^4.1.1",
126126
"@noble/curves": "^2.4.0",
127-
"@openvtc/trust-tasks": "^0.16.11",
127+
"@openvtc/trust-tasks": "^0.17.1",
128128
"@openvtc/vti-didcomm-js": "^0.7.0",
129129
"@openvtc/vti-tsp-js": "^0.2.0",
130130
"@scure/base": "^2.2.0",

packages/core/task-surface.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$comment": "Generated by scripts/sync-task-surface.mjs from a vta-sdk checkout. Do not hand-edit: re-run the script. Checked by tests/task-surface.mjs.",
33
"source": {
44
"crate": "vta-sdk",
5-
"version": "0.32.3",
5+
"version": "0.33.0",
66
"scanned": "vta-sdk/src/**/*.rs"
77
},
88
"tasks": [

packages/core/tests/admin.persona.mjs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,45 @@ test("resolve is opt-in on profile/get", async () => {
270270
await personaProfileGet(resolved, { ...PARTIES, profileId: "01P", resolve: true });
271271
assert.deepEqual(resolved.sent[0].envelope.payload, { profileId: "01P", resolve: true });
272272
});
273+
274+
test("a resolved profile entry is typed as a projection, not as a pool record", async () => {
275+
// Keys on the generated schema rather than on this library's behaviour.
276+
//
277+
// The distinction matters because the console renders an `inline` claim —
278+
// "held only here" — by testing `claim.attributeId === undefined`, and until
279+
// `@openvtc/trust-tasks` 0.17.0 the response typed `resolved` as the pool
280+
// `Attribute`, whose `attributeId`, `version` and `updatedAt` are all
281+
// REQUIRED. That branch was unreachable by construction: the schema said the
282+
// member is always there, so a conforming agent could not describe a profile
283+
// holding an inline value at all (dtgwg-trust-tasks-tf#370).
284+
//
285+
// A test asserting the console's own rendering would have passed against
286+
// either version, which is the shape VTI#1258 got wrong — it asserted
287+
// behaviour this side controls instead of the constraint it was waiting on.
288+
// So this asserts the constraint: the three pool members are optional here,
289+
// and a downgrade of the dependency fails rather than silently restoring a
290+
// branch nothing can reach.
291+
const { RESPONSE_PAYLOAD_SCHEMA } = await import(
292+
"@openvtc/trust-tasks/persona/profile/get/1.0/payload"
293+
);
294+
295+
const response = RESPONSE_PAYLOAD_SCHEMA.$defs.Response;
296+
const items = response.properties.resolved.items;
297+
assert.equal(
298+
items.$ref,
299+
"#/$defs/ResolvedClaim",
300+
"`resolved` must project a ResolvedClaim; the pool Attribute cannot describe an inline entry",
301+
);
302+
303+
const claim = RESPONSE_PAYLOAD_SCHEMA.$defs.ResolvedClaim;
304+
for (const member of ["attributeId", "version", "updatedAt"]) {
305+
assert.ok(
306+
claim.properties[member],
307+
`ResolvedClaim should still carry ${member} — its presence is what says the value is pooled`,
308+
);
309+
assert.ok(
310+
!claim.required.includes(member),
311+
`${member} must be OPTIONAL on ResolvedClaim: an inline value has no pool record to have one`,
312+
);
313+
}
314+
});

packages/core/tests/task-surface.mjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,15 @@ test("coverage against the agent's surface is recorded, not discovered", () => {
178178
[...REFERENCED.keys()].map(family).filter((f) => canonicalFamilies.has(f)),
179179
);
180180

181-
// 161 of 178 as of vta-sdk 0.32.3. It was 130 until the specced-but-
182-
// unimplemented gap was closed in one pass: `trust-task-discovery/0.1`,
181+
// 187 of 207 as of vta-sdk 0.33.0. The steps below are in the order they
182+
// happened. The 0.32.3 -> 0.33.0 resync moved no task: the surface is the
183+
// same 226 URIs, and VTI's breaking ACL change in that window
184+
// (OpenVTC/verifiable-trust-infrastructure#1279) narrows what an entry may
185+
// do without adding a task or a schema member — an entry's capabilities
186+
// travel in `ext` as `org.openvtc.capabilities`, which this check cannot
187+
// see and this library does not yet set.
188+
//
189+
// It was 130 until the specced-but-unimplemented gap was closed in one pass: `trust-task-discovery/0.1`,
183190
// `acl/update/0.1`, `vta/webvh/servers/retire-orphan/0.1`,
184191
// `vtc/members/removal-notice/0.1`, `vta/app-state/*` (6), `vta/services/*`
185192
// (8), `vta/credentials/{issue,revoke}/0.1`, and

0 commit comments

Comments
 (0)