Skip to content

[attestations] Add attestations to mvr frontend#243

Draft
mdgeorge4153 wants to merge 51 commits into
mainfrom
mdgeorge/attestation-issued-tab
Draft

[attestations] Add attestations to mvr frontend#243
mdgeorge4153 wants to merge 51 commits into
mainfrom
mdgeorge/attestation-issued-tab

Conversation

@mdgeorge4153

Copy link
Copy Markdown
Collaborator

No description provided.

mdgeorge4153 and others added 20 commits May 28, 2026 16:32
Records the design decisions and build plan for displaying package
attestations (from a curated set of trusted attestor packages) on the
MVR web app, read over JSON-RPC from a localnet-backed simulated network.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- crates/mvr-api/examples/demo_server.rs: ephemeral-Postgres mvr-api that
  seeds name_records/packages/package_infos from the attestation demo's
  demo-ids.json (lifting the test-cluster setup_dummy_data pattern) and
  runs the real run_server, so @demo/subject resolves to the localnet
  package address.
- app: env-driven mainnet RPC + MVR endpoint overrides
  (NEXT_PUBLIC_MAINNET_RPC_URL / NEXT_PUBLIC_MAINNET_MVR_ENDPOINT), unset
  in production; documented in .env.example.
- ATTESTATION-INTEGRATION.md: local run recipe; M0/M1 marked done.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename the override env vars to NEXT_PUBLIC_LOCAL_RPC_URL /
NEXT_PUBLIC_LOCAL_MVR_ENDPOINT and apply them to both networks plus the
experimental/analytics endpoints, so the demo never touches live Sui
infra. Fixes a crash where the analytics call still hit real QA mainnet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- lib/attestations.ts: env-driven config, boxAddress (deriveObjectID),
  Attestation<T> JSON-RPC mapper, trusted-lineage helpers, and the
  ported conventions effectiveness interpreter (active/expires/requires
  with cycle guard).
- useGetAttestations: getOwnedObjects on the per-subject Box, client-side
  trusted-lineage filter + Display-gate, per-attestation effectiveness.
- SinglePackageAttestations tab: grouped by attester, exact inner type,
  effectiveness badge, https report link; count label of effective
  attestations. Registered in the SinglePackage Tabs.
- scripts/write-demo-env.sh: generate app/.env (endpoints + attestation
  config incl. attester lineage) from demo-ids.json.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Rename the package tab to Trust Signals with Attestations as a section;
  split into Vulnerabilities and Audits sections (by polarity), each
  grouped by attester with an initials avatar.
- Tab badge: two pills — effective positive count (check) and effective
  negative count (warning) — as real SVG icons (no more orange-on-orange).
- lib/attestations.ts: isNegative() polarity helper, optional iconUrl on
  TrustedAttestor.
- Doc: pass plan + web-of-trust whitelist and summary-field follow-ups.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- demo_server seeds the subject -> dependency edge (powers the
  Dependencies tab and propagation).
- useGetAttestations: extract fetchTrustedAttestations(); add
  useInheritedVulns() that surfaces a dependency's effective vulns on its
  dependents (negative-polarity dual of `requires`).
- Security tab: Vulnerabilities (one severity-sorted list of own +
  inherited, CVSS band chips, max-severity-colored warning) and Audits
  sections; ineffective collapsed to a compact 'Inactive' line; friendly
  attester names (write-demo-env.sh) + attester avatars; count-pill
  numbers default-colored, icons colored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- demo_server seeds an MVR name for each trusted attester package
  (@demo/audit, @demo/vuln) so they browse to their own page.
- write-demo-env.sh adds mvrName to the trust config (in sync).
- Trust config gains optional mvrName; the Security tab links each
  attester name (on audit cards and disclosure rows) to its MVR page.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Audit cards show the attester's MVR name (from the trust config, no
  extra reverse-resolution roundtrip) rather than the truncated original id.
- Doc: web-of-trust whitelist deferred pending a team discussion on the
  RPC-roundtrip cost of per-attester on-chain lookups.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Disclosure rows show the attester's MVR name in parens (e.g. Example
  Security Scanner (@example-scanner/disclosures)).
- Auditors get distinct MVR namespaces: @example-auditor/audits and
  @example-scanner/disclosures (underscores aren't valid MVR/SuiNS names,
  so hyphenated orgs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Seed a git_infos row for each trusted attester pointing at the
sui-attestation-registry repo's mvr-demo tag, so the auditor MVR pages
render their sample README via MVR's git-backed README fetch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Audit cards: friendly name as a plain label, MVR name as the link.
- Disclosure rows: drop the display name; show the attester avatar + the
  MVR name as a link.
- (Dependency provenance names were already linked.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Replace the package address in displayed types with the attester's
  (linked) MVR name; vuln rows consolidate to avatar + linked
  @org/name::module::Type · in dependency <link>.
- Audit rows show module::Type (no raw address; attester is in the card).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…plorer links

- Cards only show effective attestations, so the 'Active' badge is removed.
- Vulnerability rows' left border is colored by severity band.
- Attestation types show the object id truncated + linked to an explorer,
  e.g. audit::Audit (0x123…567).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Severity left-border uses an arbitrary-value class bound to the CSS var
  (the content palette is text-only, so border-content-* didn't exist).
- The 'N high, M medium' header summary colors each band segment by its
  own severity (not all by the max).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Color severity chips, the per-band header breakdown, and the warning
  icons via inline style bound to the band's CSS var. Tailwind only scans
  .tsx, so classes built in attestations.ts (.ts) were never generated —
  which silently dropped Medium (text-content-warning). Inline styles are
  generation-independent.
- Severity left-border likewise via inline style.
- Move the report/advisory link into the row header next to the headline
  (the description), e.g. 'Heap overflow in the dependency (scanner.example.com ↗)'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the client-side lineage filter with a server-side MatchAny: the
trusted type set is the Attestation<T> for every store type T defined by
a trusted attester's lineage (resolveTrustedTypes via
getNormalizedMoveModulesByPackage, cached). Untrusted attestations are
never returned by the node; the read-time Display-gate still drops
trusted-but-undisplayed types. JSON-RPC only — no GraphQL/indexer.
Verified against localnet (Untrusted excluded server-side).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pass 4: an 'Issued' tab on trusted-attester package pages, listing the
attestations a package has issued (GraphQL objects() reverse query over
the attester's Attestation<T> types, grouped by subject, Display-gated,
with revoked/expired entries shown inactive).

The tab is gated on trusted-attestor whitelist membership — a free
in-memory check (isConfiguredAttestor) — so the reverse query never runs
on non-attester package pages. Repoints the GraphQL endpoint to the local
stack alongside RPC/MVR, and the env generator emits NEXT_PUBLIC_LOCAL_GRAPHQL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The local run recipe and the demo_server example hardcoded a personal path
for demo-ids.json. It's a cross-repo artifact (written by the
attestation-registry repo's run-demo.sh) whose location this repo can't know,
so use a <attestation-registry>/demo-ids.json placeholder instead. Also note
WITH_GRAPHQL=1 in the recipe — the frontend reads need localnet GraphQL on
:9125 (gRPC is the part not needed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New /attestors page listing the configured trusted attestors, each linking
  to its MVR package page; reachable via a "View all trusted attestors" link
  on the Security tab.
- "MVR-trusted attestor" badge in the package header, shown when the package
  is a configured attestor (same isConfiguredAttestor gate as the tab).
- Rename the attester-only "Issued" tab to "Attestations".
- Give the demo attestors real brand icons (public SVGs + iconUrl in the
  generated config) so AttesterAvatar stops falling back to initials; avatar
  is now rounded-md to read as a logo. AttesterAvatar exported + gains an
  lg size so the page and Security tab share one implementation.
- write-demo-env.sh now requires the demo-ids.json path explicitly (first arg
  or ATTESTATION_DEMO_IDS) rather than defaulting to a machine-specific path.

All attestation UI stays demo-only: attestationConfig() is null in production,
so the page is empty, the badge never shows, and the Security-tab link hides.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mvr Ready Ready Preview, Comment Jun 26, 2026 8:08pm

Request Review

The attestation-registry repo reorganized ts/lib into ts/src (SDK) / examples
/ demo. Update the ported-from references (boxes/conventions/queries) in the
attestations read layer and ATTESTATION-INTEGRATION.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tonka User and others added 3 commits June 16, 2026 22:40
Mirror the on-chain box-membership model:
- attestations.ts: `boxAddress(registryPkg, registryId, subject)` keys on
  `BoxKey{subject, revoked:false}`; add `revokedBoxAddress` (revoked:true).
  `isEffective` shrinks to expiry-only; `readActive`/`readRequires`/
  `ConventionsContext` removed.
- useGetAttestations: Trust Signals reads the active box, so revoked
  attestations are absent by construction. The Issued tab reads by type
  across all boxes, so it recovers revocation from ownership — an issued
  attestation is revoked iff its owner is the subject's revoked sink. Drops
  the now-dead `fetchByIdFor`.
- SinglePackageIssued: greys out revoked/expired rows, labelling "(revoked)"
  vs "(expired)".

Verified on localnet: the auditor's Issued tab flags the revoked dependency
audit; the subject's audits stay live.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revoked attestations live in the per-subject revoked sink, so the
active-box reads never see them. Surface them explicitly instead of a
subtle inline grey:

- Issued tab: revoked entries move to their own "Revoked" section at the
  bottom (factored out groupBySubject + SubjectGroup).
- Security page: read the revoked sink (fetchRevokedAttestations /
  useGetRevokedAttestations), sharing a new fetchBoxAttestations core with
  the active-box read, and render a concise "Revoked: ..." list.
- InactiveList gains a `label` ("Inactive" for expired, "Revoked" for the
  sink); DisplayedAttestation now extends a base AttributedAttestation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the attestation frontend positive-only for the MVP and finish the
revocation UX:

- Carve out the negative surface: drop useInheritedVulns/InheritedVuln, the
  VulnerabilitiesSection/VulnRow/severity-chip UI, and isNegative/
  readSeverity/severityBand. Shared MVR features (useMvrDependencies, the
  Dependencies/Dependents/Versions tabs) untouched.
- Security page: warn when a package has no live attestations ("…no active
  attestations published on MVR, it may not have been audited") — covers
  unattested and only-revoked alike — and drop the "View all trusted
  attestors" link (reachable via the attester icon).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match the attestation-repo restructure that renamed the demo's trusted auditor
package to `auditor_a` (a published copy of `examples/auditor`). write-demo-env
keys the friendly name/icon/mvr-name maps on the demo-ids trustedAttestor name,
which is now `auditor_a`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread app/src/lib/attestations.ts Outdated
/** Every package-version id in the attester's lineage. Matching an
* attestation's inner-type package against this set is equivalent to
* resolving that package's original id (the on-chain `attester_of` rule).
* M2 seeds this directly; M3 derives it via GraphQL `packageVersions`. */

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is pretty confusing

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Reworded the comment.

Comment thread app/src/lib/attestations.ts Outdated
registryId: string,
subject: string,
revoked: boolean,
): string {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not familiar with ts, but could we introduce some type aliases so that everything isn't just string?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Done — added SuiAddress/ObjectId aliases and applied them to the config/box/id fields.

Comment thread app/src/lib/attestations.ts Outdated
export interface AttestationInfo {
id: string;
/** Full object type, `…::attestation_registry::Attestation<T>`. */
type: string;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to keep type since it's always {registryPkg}::attestation_registry::Attestation<{innerType}>?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Done — dropped the type field; it's derived from innerType (+ the registry pkg) where needed, and no other consumer used it.


/** The defining (origin) package id of an inner type string. */
export function innerTypePackage(innerType: string): string {
return normalizeSuiAddress(innerType.split("::")[0]!);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a sui SDK that will do some of this stuff for us?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] @mysten/sui already gives us the primitives in use — deriveObjectID + bcs for the box-address derivation, and SuiClient/GraphQL for the reads. The only custom piece is the BoxKey-derivation wrapper mirroring the on-chain derive_address; there's no higher-level SDK for the registry's box layout specifically.

Comment thread app/src/lib/attestations.ts Outdated
* An attestation is effective iff its `expires_at` Display field (if present)
* is still in the future. Revocation is handled upstream by box membership.
*/
export function isEffective(

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should consider removing expiresAt from the MVP, which would remove this logic entirely (take it out of CONVENTIONS.md or leave it in a future extensions section).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC our demo doesn't exercise it, and I don't have any concrete examples in mind of who would want to use it. Feel free to propose some

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Done — removed the expiration feature entirely (isEffective/readExpiresAt + the effective field across lib/hooks/components), matching expires_at → planned-future on the registry side.

Comment thread app/src/hooks/useGetAttestations.ts Outdated
* attesters, with effectiveness. Reads the per-subject Box directly over
* JSON-RPC (no MVR backend).
*
* Spam-resistant (M3): rather than fetch every `Attestation<*>` on the box and

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove things like "M3" from the comments - nobody knows what they mean

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Done — stripped the M1/M2/M3 milestone labels (kept the substantive comment text).

* `revoke` moved out of the active box into the subject's revoked sink. Same
* trusted/Display filter, just against the sink address.
*/
export async function fetchRevokedAttestations(

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if an attestation is unrevoked but expired then it will not show up at all. If we decide to keep the expiration feature, we should show expired attestations (probably add fetchExpiredAttestations). But as I mentioned above, I think we should consider removing expiration.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Resolved by removing expiration — there's no expired-but-unrevoked state anymore; a live attestation (in the active box) is simply live.

Comment thread app/src/hooks/useGetAttestations.ts Outdated
const key = `${cfg.registryPkg}|${[...new Set(lineage.map((id) => normalizeSuiAddress(id)))].join(",")}`;
const cached = trustedTypesCache.get(key);
if (cached) return cached;
const promise = enumerateAttestationTypes(client, lineage, cfg.registryPkg);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could pre-enumerate the attestation types in the config instead of refetching them every time. It might be sensible for the config to list the trusted types anyway so that we can include some attestations and not others. wdyt?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH we lose the automatic upgradability property (an attestor can just add new types and have them appear).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Noted — I lean toward this (pre-enumerate the trusted types in the config: a perf win, and it enables whitelisting specific types, not just attesters). Holding it with the config-sourcing decision, since the config format would change together.

Comment thread app/public/demo-attestors/auditor.svg Outdated

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little uncomfortable having the demo stuff co-mingled with the actual mvr application.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Removed — app/public/demo-attestors/*.svg is gone, so no demo asset ships in the app. Each demo auditor's brand icon now lives with its package in the attestation-registry repo (beside the README the demo already renders: demo/auditor_a/icon.svg, demo/auditor_b/icon.svg), and write-demo-env points iconUrl at the GitHub raw URL (4d7c852). Bonus: iconUrl is now a real external URL, which matches the production shape — a consumer's trust config points at an attester's hosted icon rather than a local path. The other demo-only bits were already segregated: demo_server is a cargo example (not in the shipped binary), write-demo-env is a script, and the integration md is a doc.

// The real `subject -> dependency` edge, so the dependencies endpoint
// returns it (powering both the Dependencies tab and vuln propagation).
{
let mut conn = db.connect().await?;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the approach here is that we're directly pushing the mvr names into the database. This is probably ok, but I wonder what it would look like to go through the mvr registration process for them (i.e. publish the on-chain registrations and then let the indexer pick them up).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CLAUDE] Decided (per your discussion) to keep the direct DB seeding — going through real on-chain mvr registration + indexer pickup isn't worth the extra demo machinery here. Leaving demo_server's approach as-is.

Same swallow as the Issued tab: SinglePackageTrustSignals only checked
isLoading, so a failed forward read would render as "This package version has
no published audits" — a failure disguised as a clean negative. Surface the
query error explicitly, matching the Issued tab.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mdgeorge4153 and others added 2 commits June 26, 2026 00:15
…ions

- Reverse read returns { items, failures }: the per-object getObject re-read
  now counts rejections instead of silently dropping them, and the Issued tab
  shows "N attestations couldn't be loaded" while still rendering the rest.
- Revoked moved out of the inline list into their own de-emphasized section
  (each section independently paginated), so endorsements read distinctly from
  withdrawn ones.
- Each row now leads with the attestation's description (then module::Type +
  date as secondary metadata).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d error

The Security tab's version selector now navigates to /package/<name>/<version>
(preserving the tab) instead of swapping a local list, so the whole page — and
the tab's attestation-count pill, which keys off the resolved version —
reflects the chosen version. Drops the selectedAddress state + re-sync effect.

Also fold the revoked sub-query's error into the surfaced error, so a
revoked-read failure no longer hides behind "no published audits".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The badge was shown for `version === name.version` — the version the page is
resolved to — which only coincided with the newest version because you'd
normally view a package at its latest. Now that the attestation version selector
can navigate to an older version, that conflation mislabeled the viewed (older)
version as "Latest". Tag the actual max version as "Latest", add a separate
"Current" marker for the viewed version when it isn't the latest, and use the
max version for the Versions count heading (same conflation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ector

Replace the version dropdown (which navigated to /package/<name>/<version>) with
all versions listed on the page at once, newest first — each version shows its
own audits / "no published audits" / errors via a VersionAudits sub-component
(one per version, so the per-version reads stay rules-of-hooks-safe). Answers
"which versions are audited?" at a glance and drops the dependency on
per-version page routing. Single-version packages render with no version header.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
"✓ 0" on the latest version is a real signal — this package has no published
audits — so show the pill at zero too, instead of hiding it. (No config gate;
the feature only ships once attesters are configured for prod anyway.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The in-page heading reads "Audits" for now, since audits are the only trust
signal. Once others are integrated, the "Security" tab becomes an h1 with an
"Audits" h2 beneath it. The tab title is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The card special-cased `display.score` (an AuditV2-specific field) as a pill,
coupling the platform UI to one schema. Drop it: the card now surfaces only the
standard presentation conventions (name/description/image_url/link). A
schema-specific field like `score` should be promoted to a documented
convention if it's broadly useful, not inferred by the general UI. Removes the
now-unused ScorePill.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Seed an mvr name (+ README) for each untrustedAttestors entry in demo-ids.json,
so @demo/auditor-b resolves and its page is browsable. It's not added to the
trust config, so the UI hides its Issued tab — the case we want to demo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Issued tab now works for any package, not just configured trusted attesters:
- useIssuedAttestations enumerates the viewed package's own types from its mvr
  version lineage (useGetMvrVersionAddresses) instead of the trust config, so it
  loads for any package. The trust config governs only presentation now.
- The tab stays in the nav for configured attesters only, but is reachable by
  URL (?tab=issued) for any package — SinglePackage splits nav visibility
  (navTabs) from URL-selectability (the full Tabs list); the issued label gets
  `name` so its count can resolve the lineage too.
- SinglePackageIssued shows a prominent "not on your trusted list" warning when
  the package isn't a configured attester.

Safe to show: Attestation<T> is mintable only by T's defining package, so a
package's issued list is genuinely its own claims; the warning is about trust,
not authenticity.

Verified: tsc clean; demo end-to-end — auditor-b (untrusted) issued read returns
its 1 attestation and /package/@demo/auditor-b?tab=issued serves.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give the attestation registry package itself an mvr name (@demo/attestations),
so <registry-pkg> resolves by name in the demo — e.g. as a move-call target like
the auditor packages, matching what the onboarding doc describes. No README
(the package has none; like @demo/subject).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give the demo packages more realistic mvr names: the registry is
@mysten/attestations, and each auditor is its own org (@auditor-a/audit,
@auditor-b/audit) rather than @demo/auditor-x — matching the existing
@example-scanner/disclosures shape. Subject/dependency stay @demo/*.

Kept in sync: auditor_mvr_name (demo_server.rs) and the trusted attester's
mvrName (write-demo-env.sh).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wire the registry name's git_path to packages/attestations so its mvr page shows
the package README (mirrored into the public prototype repo that the demo fetches
READMEs from).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant