trust-tasks-capability-client 0.21.16

Client-side wire helpers for the capability Trust Task families (governance/capability/*, git-trust/*): document builders, envelope parsing, reply classification. Shared by capability producers (community services) and management UIs so the two cannot drift.
Documentation

Client-side wire helpers for the capability Trust Task families — governance/capability/* (enable / disable / list a community capability) and git-trust/* (grant / revoke commit-signing trust).

This crate owns the documents, not a transport: it builds request documents, parses inbound envelope replies, classifies them, and (behind the signing feature) attaches a Data-Integrity proof. Each consumer keeps its own send/receive plumbing but shares this wire layer, so a capability producer (a community service) and a management UI cannot drift on the contract.

Layers

  • Envelope: capability documents travel as the trust-tasks-didcomm binding envelope ([TRUST_TASK_ENVELOPE_TYPE]); [parse_envelope_document] turns an inbound body into (threadId, document).
  • Builders: [build_document] plus the family-specific [build_list_document], [build_toggle_document], [build_git_trust_grant], [build_git_trust_revoke].
  • Replies: [classify_git_trust_reply] (for grant/revoke writers) and [parse_capability_reply] (for governance management UIs).

Retries versus fresh attempts

This crate is a producer, and the producer half of SPEC §7.2 item 11 is §8.4: a retry is a bit-for-bit identical resend. As of trust-tasks-rs 0.12.0 there is a consumer that enforces it — the record is keyed on the document id and compared against the whole document — and the DIDComm and TSP bindings now keep that record by default. So the two ways of sending a request again have become genuinely different operations:

Intent What to send What the consumer does
The first send may not have arrived previous itself, unchanged Absorbs it; returns whatever the first execution determined
Something about the request changed new_attempt(&previous) Treats it as the new document it is
Anything else under a reused id Rejects it with idConflict

"Something about the request changed" is wider than it sounds: a re-stamped issuedAt or a re-signed proof over identical content is already a different document. That is deliberate — §8.4 says a producer that "retries" by re-signing "has not retried", and the whole point of item 11's comparison is that an id alone cannot tell the retry it must absorb from the conflict it must reject.

[build_document] and every builder over it mint a fresh id per call, so a caller that rebuilds is already minting a new attempt. [new_attempt] covers the case where the document has already been built (and possibly signed) and is about to be sent again.

Signing is deliberately not here — it is a thin Data-Integrity call each consumer makes with its own signer (a service reuses its credential signer; a client signs with the persona key), so this crate stays free of any crypto dependency. Sign the built document over its canonical form (the document minus its proof member, eddsa-jcs-2022) and set the proof member.

Versioning

This crate exposes trust-tasks-rs types in its own public API, so a breaking change there breaks this crate's callers even when nothing here changes. cargo-semver-checks cannot catch that: it compares each crate's rustdoc against that crate's own published baseline, and does not track type identity across dependency versions. The crates that share trust-tasks-rs in their public API are therefore released as one compatibility unit with a single shared version — see version_group in release-plz.toml.