Skip to content

explorer: a verifying lens over the witness network (explorer.auths.dev) - #30

Open
bordumb wants to merge 16 commits into
plan/witness-usability-contractsfrom
explorer/network-explorer
Open

explorer: a verifying lens over the witness network (explorer.auths.dev)#30
bordumb wants to merge 16 commits into
plan/witness-usability-contractsfrom
explorer/network-explorer

Conversation

@bordumb

@bordumb bordumb commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Builds the Network Explorer from docs/plans/network/explorer_plan.md — a new apps/explorer deployed at explorer.auths.dev, a sigstore-search-style lens that verifies everything it displays in the browser.

Trust story (D3)

The explorer's server is transport, never a verdict source. It mirrors a witness's refs/auths/* and serves raw bytes; the WASM verifier recomputes every SAID, chain, and receipt quorum in your browser before anything renders as valid. A compromised explorer can omit, never forge — the same property the node has.

What's here

  • X1 — scaffold mirroring apps/market; shared @auths/witnesses package (auths.dev/network and the explorer read one source; apps/web re-points via thin shims); server resolve routes (roster proxy + git-mirror KEL read); browser verifier bridge vendored from a --target web build of crates/auths-verifier.
  • X2 — home/search, member KEL (timeline + verifier-computed key state), anchors (+ duplicity evidence), evidence drop-zone (client-side only, no upload).
  • X3 — auths.dev/network → explorer links; "fetched Xs ago" freshness stamps; browser-direct live-tip check (lights up once witnesses ship CORS); any conformant witness via ?witness=URL.

Verification

  • bun run typecheck and bun run --filter @auths/explorer build both green; apps/web still builds after the shim.
  • Verdict chips validated against @auths-dev/sdk conformance/verdicts.json at build time; a verifier fence (eslint + check-explorer.mjs) keeps the WASM glue behind the one bridge.
  • Full loop verified against live network.auths.dev: readKelJson bytes → validateKelJson → recomputed key state (seq matches tip).

Dependency

The server git-object KEL path needs @auths-dev/sdk0.1.16 (readKelJson), added in the companion auths PR. Until it ships the explorer feature-detects and degrades honestly (that one route returns a clear 501; the rest works). Bump the @auths-dev/sdk pin to 0.1.16 once published.

Follow-ups filed

🤖 Generated with Claude Code

bordumb added 3 commits July 20, 2026 15:26
Stop the market presenting an unanchored, self-signed earnings number as verified fact.

- Never serve a bare cumulative_cents as fact: a pure witnessedView() shaper serves
  seller_claimed_cumulative_cents + unwitnessed:true unless the attestation is
  witness-anchored; the listing tile shows a dash / "seller-claimed, unwitnessed" until
  anchor_tier==='witness'; the "every cent re-derives" copy is scoped to what is witnessed.
- resolveVerifiedAnchor() extracted, stays fail-closed; the `check.anchor &&` guard is
  preserved so on the current SDK (0.1.12, no anchor field) it degrades to first-seen and
  lights up automatically once the anchor/freshness SDK ships. SDK pin kept at 0.1.12.
- computeLiveness() replaces the live_proven_at latch: set on first growth, kept while
  growing, CLEARED when the window goes flat; stamps last_growth_at (new migration); the
  list API now emits dormant + last_growth_at.
- listingStatus() precedence reducer replaces five independent badge conditionals — a
  failing re-check always wins, so "verified" can never render beside "stale".
- integration pane: endpointCommand() hardened so a bare uninstallable downstream renders
  an install hint instead of dead-stopping the buyer; test-mode output honestly labeled as
  a recorded fixture; the good url-transport interpolation kept.
- pending_verification / dashboard surface the daily 06:00 UTC probe schedule.
- Tests: new vitest + happy-dom harness (apps/market/tests) — a forged unanchored aggregate
  is not surfaced as verified; stale flips dormant / clears the latch; the witness tier
  requires a real anchor.tier; the list API carries dormancy; the badge reducer never
  returns verified+stale.

User steps: bump @auths-dev/sdk 0.1.12 -> 0.1.13 after the SDK release (consuming code already
reads anchor/freshness defensively); install the new test devDeps; apply the migration;
publish @auths-dev/receipts-server + repoint the first-party listing (cross-repo).
Spec: product-findings/remediation/EPIC-5.md. Not fully built locally — GitHub CI is the gate.

Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Anchor-Seq: 13
Make the flagship "verify without trust" command runnable and paste-clean, and close the
dead-end CTAs. (The paste-integrity CI lint lives in the auths repo — a separate commit.)

- verify/trust/landing: the copy button and the shown lines now render from one source
  (demo-commands.ts) via <BashLines>, using `npx -y @auths-dev/mcp verify-spend ...` with real
  demo DIDs — no more the un-installed `auths-mcp-gateway` binary and no more <agent>/<root>
  placeholders shipped inside the copy button. The illustrative one-liners are fixed too.
- /trust gains a "Download the demo bundle" button + a one-paste verify-spend so a skeptic
  verifies with zero setup (bundle path is a placeholder; the real signed tarball is produced
  from the auths gateway lab at release — documented in public/demo/README.md, no fake shipped).
- Home CTAs repointed: "Read the quickstart" -> docs.auths.dev/mcp/quickstart; "How the audit
  works" -> docs.auths.dev/mcp/concepts/receipts (were the bare GitHub repo).
- /network cloud tiers get a "Notify me at launch" CTA (mailto network@auths.dev, gated on the
  Epic 7 MX fix); /verify gets a closing forward CTA; the /network witness copy button now copies
  all four displayed lines (was one).
- Tests: apps/web vitest suite — copy strings are placeholder-free, start with npx -y
  @auths-dev/mcp, name no gateway binary, interpolate real DIDs; CTA/mailto/hero-headline locks.

Cross-repo: generating the real demo-bundle.tgz + the site-verify e2e live in the auths repo.
Spec: product-findings/remediation/EPIC-6.md. Not fully built locally — GitHub CI is the gate.
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Anchor-Seq: 13
security-remediation: market trust logic + marketing-site correctness
@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
auths-market Ready Ready Preview, Comment Jul 22, 2026 9:02pm
auths-website Ready Ready Preview, Comment Jul 22, 2026 9:02pm

@bordumb
bordumb force-pushed the explorer/network-explorer branch from cdc9b61 to 0c3e32b Compare July 21, 2026 09:56
@bordumb
bordumb changed the base branch from main to plan/witness-usability-contracts July 21, 2026 09:59
@bordumb
bordumb force-pushed the explorer/network-explorer branch from 0c3e32b to 922047e Compare July 21, 2026 10:42
@bordumb
bordumb force-pushed the explorer/network-explorer branch from 922047e to bcc7006 Compare July 21, 2026 10:56
@bordumb
bordumb force-pushed the explorer/network-explorer branch from bcc7006 to f8e7226 Compare July 21, 2026 11:55
@bordumb
bordumb force-pushed the explorer/network-explorer branch from f8e7226 to 58dce5e Compare July 21, 2026 12:08
@bordumb
bordumb force-pushed the explorer/network-explorer branch from 58dce5e to 623dd7c Compare July 21, 2026 14:59
claude-release and others added 5 commits July 21, 2026 17:09
A new `apps/explorer` app — the sigstore-search analog for the Auths witness
network, per docs/plans/network/explorer_plan.md. Its server is transport,
never a verdict source: it mirrors a witness's refs/auths/* and serves raw
bytes; the WASM verifier recomputes every SAID, chain, and receipt quorum in
the browser before anything renders as valid. A compromised explorer can omit,
never forge — the same property the node has.

What landed:
- X1 scaffold mirroring apps/market (Next 16, ledger-ui, SDK pinned), a shared
  @auths/witnesses package (auths.dev/network and the explorer read one source;
  apps/web re-points via thin shims), server resolve routes (roster proxy +
  git-mirror KEL read, feature-detecting @auths-dev/sdk readKelJson and
  degrading honestly on older SDKs), and a browser verifier bridge vendored from
  a `--target web` build of crates/auths-verifier.
- X2 pages: home/search, member KEL (timeline + verifier-computed key state),
  anchors (+ duplicity evidence surfaced prominently), and an evidence
  drop-zone that verifies presentations/packs entirely client-side (no upload).
- X3 hardening: auths.dev/network rows link to the explorer; every mirror
  carries a "fetched Xs ago" stamp and renders stale honestly; browser-direct
  live-tip check lights up once witnesses ship CORS; any conformant witness
  works by ?witness=URL — the federation, not the node, is the product.

Verdict vocabulary is validated against @auths-dev/sdk conformance/verdicts.json
at build time; a verifier fence (eslint + check-explorer.mjs) keeps the WASM
glue funnelled through the one bridge. Full loop verified against live
network.auths.dev: readKelJson bytes → validateKelJson → recomputed key state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
…d time

Wire scripts/check-explorer.mjs into the build script so the verdict-manifest
assertion (and the WASM-present + verifier-fence guards) run on every build —
the same 'validate verdict vocabulary at build time' guarantee apps/web gets by
importing its verdicts module into the page graph (plan X2.5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
… path)

0.1.16 is the first SDK exporting readKelJson, so the git-object member-KEL
route is now live rather than degrading to 501. Bumps both the package.json pin
and the ensure-sdk-binding vendoring VERSION in lockstep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
…twork

Explorer home: drop the pointless 'full directory' link (the table is the
directory); move the offline command block out of the evidence teaser into the
/evidence page; rewrite 'Why you can distrust this page' in plain language
(WebAssembly pushed deeper, no protocol jargon up front); rename the GitHub link
to 'See source on GitHub'; add 'The cloud network' section (moved from
auths.dev/network). Repoint every docs link to the real, live witness-network
pages (the /mcp/... paths 404'd).

auths.dev/network is removed — the verifying explorer is the network surface now.
Its 'What witnesses solve' content already lives in the docs; /network redirects
to explorer.auths.dev; the shared footer, site nav, and sitemap follow. The
witness-directory data still lives in @auths/witnesses (unchanged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
…as-a-seller doc

Now that the onboarding page is on docs main (auths-docs#6), link the seller
action to it directly instead of the get-listed substitute.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
claude-release and others added 2 commits July 21, 2026 17:09
…ork retired)

Comment/description tidy-up flagged by the operator review — the shared witness
directory is no longer consumed by auths.dev/network (removed), only the
explorer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
…oof resolution

Root-cause fix for the auths-w1 'Unknown witness' / 'standing up' bug (it had
url:null because AUTHS_W1_URL was never set on the deploy — an invisible env-var
hack). Now:
- first-party witness URLs are hardcoded in the checked-in directory (one
  reviewable source of truth), with a load-time guard that throws if any
  first-party entry has a null URL — the hidden-env class of drift can't return.
- resolveWitness treats a ?witness= URL as authoritative for where to fetch and
  matches it against the directory for display, so a node browsed via its own
  URL always resolves — even if the directory is stale or the node was renamed.

Pairs with the node status page passing ?witness=<self-url> (auths repo), so a
node is browsable by its own URL regardless of directory membership.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
Browse a node at /node/<name-or-host> (was /w/…): a bare directory name for a
listed node, a host for anyone else, and ?witness= shrinks to a rare escape
hatch for odd ports/schemes. Sub-routes spell out too: /member/<prefix>,
/anchor/<seed>, /api/node/…. The resolver now accepts a bare host segment
(their-node.example → https://their-node.example) and still matches a listed
host back to its curated name — so a node's own "browse me" link is
rename-/move-proof. Full model: docs/plans/network/url_intuition.md.

Directory: the two genuinely-distinct first-party nodes — auths-network
(lhr, its own fly host, NOT network.auths.dev which becomes the explorer front
door) and auths-network-2 (iad, full roles incl. registry). Roster-less node
pages degrade gracefully (search-by-prefix, honest copy), never a bare
"unavailable". Offline-parity examples fetch from the witness host, not the
soon-to-be-explorer network.auths.dev.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
The looksLikeHost helper was added but never called — a bare host segment
(/node/auths-network-2.fly.dev, the form every status page's "browse me" link
emits) fell through to asHttpsUrl(segment), which throws with no scheme, so the
page rendered "Unknown witness". Route the segment through looksLikeHost →
https://<host>, and match a resolved host back to the directory so a listed
node keeps its curated name. Verified live: /node/<host> now resolves for both
first-party nodes and for stranger hosts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
Checklist reflects the deployed reality (two distinct nodes, /node/ scheme,
status pages, auths-w1 retired); §8 step 4 (network.auths.dev DNS → explorer)
is the sole remaining, gated beat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
Drop the jargon a first-time visitor can't parse. The hero and the site-wide
meta description no longer say "recomputes every SAID, replays every chain,
checks every receipt quorum" — they say the explorer pulls an identity's
records and re-checks them in your browser before anything shows as verified.

Directory note: fix the stale "?witness=https://…" (that's now a rare escape
hatch, not the way in) and drop "stranger's" — you reach any node directly at
/node/<address>.

Evidence page: lead with just "evidence pack" (was "a presentation or an
evidence pack", two undefined terms) across the intro, drop-zone placeholder,
metadata, and CLI parity note. The verifier still recognizes and labels a
presentation correctly once one is actually dropped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFugwwLVfYMGPwoP7fJKDJ
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
bordumb added 2 commits July 22, 2026 21:58
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Anchor-Seq: 13
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Anchor-Seq: 13
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