ust-protocol 1.0.0-rc.2 → 1.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.mjs +15 -5
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -202,9 +202,15 @@ export function verify(doc, opts = {}) {
202
202
  if (doc.sig.pub === undefined) return bad('E-KEY', 'no carried pub (LIGHT)');
203
203
  if (keyId(doc.sig.pub) !== st.id.key_id) return bad('E-SIG', 'key_id != H(ust:keylog, pub)');
204
204
  if (!edVerifyStrict(doc.sig.pub, S, doc.sig.sig)) return bad('E-SIG', 'Ed25519 verify failed');
205
- // step 3 — name authority (HIGH, §12/§14.3): resolved ONLY if the caller supplies genesis+keylog.
206
- const identity = opts.genesis ? resolveAuthority(doc, opts) : { strength: 'self-asserted', status: 'verified' };
207
- if (identity.error) return bad(identity.error, identity.detail); // forked genesis / broken key-log
205
+ // step 3 — name authority (§14.3): HIGH resolves genesis+key-log; else a PINNED key (TOFU, §3.1) if the caller
206
+ // supplies pinnedKeys a key NOT in the pin set is INVALID (that is what pinning means); else self-asserted.
207
+ let identity;
208
+ if (opts.genesis) identity = resolveAuthority(doc, opts);
209
+ else if (opts.pinnedKeys) identity = opts.pinnedKeys.includes(st.id.key_id)
210
+ ? { strength: 'pinned', status: 'verified' }
211
+ : { error: 'E-KEY', detail: 'key_id not in the pinned set (§3.1 TOFU)' };
212
+ else identity = { strength: 'self-asserted', status: 'verified' };
213
+ if (identity.error) return bad(identity.error, identity.detail); // forked genesis / broken key-log / not pinned
208
214
  if (opts.requireAuthoritative && !(identity.strength === 'authoritative' && identity.status === 'verified'))
209
215
  return identity.status === 'unavailable'
210
216
  ? { result: 'INDETERMINATE', reason: 'unavailable', identity, detail: identity.detail } // W1: retry, NOT failure
@@ -236,8 +242,12 @@ export function verify(doc, opts = {}) {
236
242
  // §14.9 attestation: recompute the Merkle root from constituents (⇒ E-ROOT on mismatch).
237
243
  if (st.id.class === 'attestation' && st.provenance?.constituents && st.provenance?.root !== undefined)
238
244
  if (merkleRoot(st.provenance.constituents) !== st.provenance.root) return bad('E-ROOT', 'attestation root mismatch');
239
- return { result: 'VALID', identity, disclosed, sources,
240
- publisher: st.id.domain_shard, ust_id: st.id.ust_id, class: st.id.class, content_hash: ch,
245
+ // §Y3: `domain_shard` is surfaced as `publisher` ONLY at `authoritative` strength; otherwise it is a
246
+ // self-asserted/pinned LABEL `publisher_claimed` so a consumer that never read Y3 cannot over-attribute.
247
+ // (Pinning authenticates the KEY, not the name.)
248
+ const nameField = identity.strength === 'authoritative' ? { publisher: st.id.domain_shard } : { publisher_claimed: st.id.domain_shard };
249
+ return { result: 'VALID', identity, disclosed, sources, ...nameField,
250
+ ust_id: st.id.ust_id, class: st.id.class, content_hash: ch,
241
251
  time: { strength: 'unproven', status: doc.proof ? 'present' : 'none' } };
242
252
  } catch (e) {
243
253
  return bad(e.code || 'E-MALFORMED', e.detail || String(e)); // fail-closed (§14/I10)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ust-protocol",
3
- "version": "1.0.0-rc.2",
3
+ "version": "1.0.0-rc.3",
4
4
  "description": "Universal State Transcript (UST) — the stateless reference base: canonical hashing (JCS), Ed25519 signing, three-tier verification (LIGHT/HIGH/TOP), privacy commitments, chains, and anchoring. Trust infrastructure for machine-readable state.",
5
5
  "author": "THE LAB (https://thelab.md)",
6
6
  "type": "module",