From 5322b5c0442b23c4867f54a95aa43e3e63aed1f0 Mon Sep 17 00:00:00 2001 From: kzoeps Date: Wed, 1 Apr 2026 13:47:26 +0600 Subject: [PATCH 1/3] feat: add copy raw and view raw for docs pages --- components/CopyRawButton.js | 63 ++++ components/Layout.js | 2 + lib/generate-raw-pages.js | 45 +++ package.json | 4 +- .../raw/architecture/account-and-identity.md | 102 +++++ .../architecture/data-flow-and-lifecycle.md | 229 +++++++++++ public/raw/architecture/epds.md | 196 ++++++++++ .../architecture/indexers-and-discovery.md | 22 ++ public/raw/architecture/overview.md | 40 ++ .../architecture/portability-and-scaling.md | 22 ++ public/raw/core-concepts/cel-work-scopes.md | 224 +++++++++++ .../raw/core-concepts/certified-identity.md | 70 ++++ public/raw/core-concepts/common-use-cases.md | 49 +++ .../core-concepts/funding-and-value-flow.md | 108 ++++++ .../hypercerts-core-data-model.md | 106 ++++++ .../raw/core-concepts/what-is-hypercerts.md | 69 ++++ public/raw/core-concepts/why-at-protocol.md | 38 ++ .../raw/ecosystem/why-we-need-hypercerts.md | 180 +++++++++ .../getting-started/building-on-hypercerts.md | 123 ++++++ public/raw/getting-started/quickstart.md | 354 ++++++++++++++++++ .../getting-started/testing-and-deployment.md | 164 ++++++++ .../working-with-evaluations.md | 87 +++++ public/raw/index.md | 34 ++ public/raw/lexicons/certified-lexicons.md | 17 + .../certified-lexicons/badge-award.md | 16 + .../certified-lexicons/badge-definition.md | 16 + .../certified-lexicons/badge-response.md | 16 + .../lexicons/certified-lexicons/location.md | 14 + .../lexicons/certified-lexicons/profile.md | 12 + .../certified-lexicons/shared-defs.md | 14 + public/raw/lexicons/hypercerts-lexicons.md | 20 + .../hypercerts-lexicons/acknowledgement.md | 55 +++ .../hypercerts-lexicons/activity-claim.md | 16 + .../hypercerts-lexicons/attachment.md | 14 + .../hypercerts-lexicons/collection.md | 14 + .../hypercerts-lexicons/contribution.md | 85 +++++ .../hypercerts-lexicons/evaluation.md | 14 + .../hypercerts-lexicons/funding-receipt.md | 16 + .../hypercerts-lexicons/measurement.md | 14 + .../lexicons/hypercerts-lexicons/rights.md | 12 + .../raw/lexicons/introduction-to-lexicons.md | 18 + public/raw/reference/faq.md | 49 +++ public/raw/reference/glossary.md | 68 ++++ public/raw/roadmap.md | 343 +++++++++++++++++ public/raw/tools/hyperboards.md | 85 +++++ public/raw/tools/hypercerts-cli.md | 149 ++++++++ public/raw/tools/hyperindex.md | 109 ++++++ public/raw/tools/scaffold.md | 297 +++++++++++++++ styles/globals.css | 41 ++ 49 files changed, 3853 insertions(+), 2 deletions(-) create mode 100644 components/CopyRawButton.js create mode 100644 lib/generate-raw-pages.js create mode 100644 public/raw/architecture/account-and-identity.md create mode 100644 public/raw/architecture/data-flow-and-lifecycle.md create mode 100644 public/raw/architecture/epds.md create mode 100644 public/raw/architecture/indexers-and-discovery.md create mode 100644 public/raw/architecture/overview.md create mode 100644 public/raw/architecture/portability-and-scaling.md create mode 100644 public/raw/core-concepts/cel-work-scopes.md create mode 100644 public/raw/core-concepts/certified-identity.md create mode 100644 public/raw/core-concepts/common-use-cases.md create mode 100644 public/raw/core-concepts/funding-and-value-flow.md create mode 100644 public/raw/core-concepts/hypercerts-core-data-model.md create mode 100644 public/raw/core-concepts/what-is-hypercerts.md create mode 100644 public/raw/core-concepts/why-at-protocol.md create mode 100644 public/raw/ecosystem/why-we-need-hypercerts.md create mode 100644 public/raw/getting-started/building-on-hypercerts.md create mode 100644 public/raw/getting-started/quickstart.md create mode 100644 public/raw/getting-started/testing-and-deployment.md create mode 100644 public/raw/getting-started/working-with-evaluations.md create mode 100644 public/raw/index.md create mode 100644 public/raw/lexicons/certified-lexicons.md create mode 100644 public/raw/lexicons/certified-lexicons/badge-award.md create mode 100644 public/raw/lexicons/certified-lexicons/badge-definition.md create mode 100644 public/raw/lexicons/certified-lexicons/badge-response.md create mode 100644 public/raw/lexicons/certified-lexicons/location.md create mode 100644 public/raw/lexicons/certified-lexicons/profile.md create mode 100644 public/raw/lexicons/certified-lexicons/shared-defs.md create mode 100644 public/raw/lexicons/hypercerts-lexicons.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/acknowledgement.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/activity-claim.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/attachment.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/collection.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/contribution.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/evaluation.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/funding-receipt.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/measurement.md create mode 100644 public/raw/lexicons/hypercerts-lexicons/rights.md create mode 100644 public/raw/lexicons/introduction-to-lexicons.md create mode 100644 public/raw/reference/faq.md create mode 100644 public/raw/reference/glossary.md create mode 100644 public/raw/roadmap.md create mode 100644 public/raw/tools/hyperboards.md create mode 100644 public/raw/tools/hypercerts-cli.md create mode 100644 public/raw/tools/hyperindex.md create mode 100644 public/raw/tools/scaffold.md diff --git a/components/CopyRawButton.js b/components/CopyRawButton.js new file mode 100644 index 0000000..a494e98 --- /dev/null +++ b/components/CopyRawButton.js @@ -0,0 +1,63 @@ +import { useState } from 'react'; +import { useRouter } from 'next/router'; + +function getRawUrl(currentPath) { + if (currentPath === '/') return '/raw/index.md'; + return `/raw${currentPath}.md`; +} + +export function CopyRawButton() { + const [copied, setCopied] = useState(false); + const [copyError, setCopyError] = useState(false); + const router = useRouter(); + const currentPath = router.asPath.split('#')[0].split('?')[0] || '/'; + const rawUrl = getRawUrl(currentPath); + + const handleCopy = async () => { + try { + const response = await fetch(rawUrl); + if (!response.ok) throw new Error('Failed to load raw markdown'); + + const raw = await response.text(); + + try { + await navigator.clipboard.writeText(raw); + } catch { + const textarea = document.createElement('textarea'); + textarea.value = raw; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand('copy'); + document.body.removeChild(textarea); + } + + setCopyError(false); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch { + setCopyError(true); + setCopied(false); + setTimeout(() => setCopyError(false), 2000); + } + }; + + return ( +
+ + + View raw + +
+ ); +} diff --git a/components/Layout.js b/components/Layout.js index 5bd3855..366b25a 100644 --- a/components/Layout.js +++ b/components/Layout.js @@ -9,6 +9,7 @@ import { LastUpdated } from './LastUpdated'; import { Breadcrumbs } from './Breadcrumbs'; import { ThemeToggle } from './ThemeToggle'; import { SearchDialog } from './SearchDialog'; +import { CopyRawButton } from './CopyRawButton'; const SITE_URL = 'https://docs.hypercerts.org'; const SITE_NAME = 'Hypercerts Documentation'; @@ -192,6 +193,7 @@ export default function Layout({ children, frontmatter }) {
+ {frontmatter && }
{children}
diff --git a/lib/generate-raw-pages.js b/lib/generate-raw-pages.js new file mode 100644 index 0000000..8125c8a --- /dev/null +++ b/lib/generate-raw-pages.js @@ -0,0 +1,45 @@ +const { + readdirSync, + statSync, + readFileSync, + writeFileSync, + rmSync, + mkdirSync, +} = require('fs'); +const { dirname, join, relative } = require('path'); + +const PAGES_DIR = join(__dirname, '..', 'pages'); +const OUTPUT_DIR = join(__dirname, '..', 'public', 'raw'); + +function walkDir(dir) { + const results = []; + for (const entry of readdirSync(dir)) { + const full = join(dir, entry); + if (statSync(full).isDirectory()) { + results.push(...walkDir(full)); + } else if (full.endsWith('.md')) { + results.push(full); + } + } + return results; +} + +function getRawOutputPath(filePath) { + const rel = relative(PAGES_DIR, filePath).replace(/\.md$/, ''); + const route = rel === 'index' ? '/index' : `/${rel.replace(/\/index$/, '')}`; + const outputRel = route === '/index' ? 'index.md' : `${route.slice(1)}.md`; + return join(OUTPUT_DIR, outputRel); +} + +rmSync(OUTPUT_DIR, { recursive: true, force: true }); +mkdirSync(OUTPUT_DIR, { recursive: true }); + +const files = walkDir(PAGES_DIR); + +for (const file of files) { + const outputPath = getRawOutputPath(file); + mkdirSync(dirname(outputPath), { recursive: true }); + writeFileSync(outputPath, readFileSync(file, 'utf-8')); +} + +console.log(`Generated raw markdown files for ${files.length} pages`); diff --git a/package.json b/package.json index d48e8d2..da60b12 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "private": true, "description": "Hypercerts Protocol Documentation", "scripts": { - "dev": "node lib/generate-search-index.js && node lib/generate-last-updated.js && node lib/generate-sitemap.js && next dev --webpack", - "build": "node lib/generate-search-index.js && node lib/generate-last-updated.js && node lib/generate-sitemap.js && next build --webpack", + "dev": "node lib/generate-search-index.js && node lib/generate-last-updated.js && node lib/generate-sitemap.js && node lib/generate-raw-pages.js && next dev --webpack", + "build": "node lib/generate-search-index.js && node lib/generate-last-updated.js && node lib/generate-sitemap.js && node lib/generate-raw-pages.js && next build --webpack", "start": "next start" }, "dependencies": { diff --git a/public/raw/architecture/account-and-identity.md b/public/raw/architecture/account-and-identity.md new file mode 100644 index 0000000..7101f02 --- /dev/null +++ b/public/raw/architecture/account-and-identity.md @@ -0,0 +1,102 @@ +--- +title: Account & Identity Setup +description: Understand your identity, configure custom domains, and manage credentials. +--- + +# Account & Identity Setup + +If you followed the [Quickstart](/getting-started/quickstart), you already have an account. This page explains what that account gives you and how to configure it — custom domain handles for organizations, app passwords for scripts, shared repositories for teams, and account recovery. + +--- + +## Create an account + +Sign up at [certified.app](https://certified.app/). You'll get: + +- **Low-friction sign-in** — Sign in with just your email and a code. No passwords or protocol knowledge required. +- **A DID** — Your permanent, portable identifier (e.g., `did:plc:z72i7hdynmk6r22z27h6tvur`). It never changes, even if you switch servers or handles. +- **A Repository** — Your own collection on the certified PDS, where your hypercerts, evaluations, and other records are stored. You own this data and you can migrate it between servers. +- **An (embedded) wallet** — Add your existing EVM wallet or get a new one. +- **Ecosystem access** — Your identity works across every Hypercerts application. + +### Why Certified? + +The Hypercerts Protocol is built on AT Protocol — the same decentralized data layer that powers Bluesky. But most Hypercerts users are not Bluesky users. They are researchers, land stewards, open-source maintainers, funders, and evaluators. Asking them to "sign in with Bluesky" to use a funding platform would be confusing — it ties a funding tool to a social media brand. This is no knock on Bluesky — it's a great platform, just not the right entry point for a funding tool. + +Certified is a neutral identity provider that isn't tied to any single application. You create an account and immediately have an identity that works across the entire ecosystem — no knowledge of Bluesky, ATProto, or decentralized protocols required. + +{% callout type="note" %} +Hypercerts is fully interoperable with the AT Protocol ecosystem. If you already have a Bluesky account or any other ATProto identity, log in with your existing handle (e.g., `alice.bsky.social`) and use all Hypercerts applications — no additional account needed. +{% /callout %} + +--- + +## Your DID + +Your DID is your permanent identity. It looks like `did:plc:z72i7hdynmk6r22z27h6tvur` and is resolved via the [PLC directory](https://plc.directory), which maps it to your current PDS, public keys, and handle. + +Every record you create carries your DID as the author. If you change PDS providers, your DID stays the same — other applications continue to recognize you and your data migrates with you. + +--- + +## Handles (your public username) and domain verification + +Handles are not needed to log in to the Hypercerts ecosystem, but every user has one. They serve as human-readable names for publicly addressing others and for interacting with other applications in the AT Protocol ecosystem that haven't implemented email-based login with Certified. Your handle is a human-readable name like `alice.certified.app`. Unlike your DID, your handle can change — it's a pointer to your DID, not your identity itself. + +**Organizations should use custom domain handles.** A handle like `numpy.org` proves organizational identity — anyone can verify that the DID behind `numpy.org` is controlled by whoever controls the domain. + +To set up a custom handle, add a DNS TXT record or host a file at `https://your-domain.com/.well-known/atproto-did`. See the [AT Protocol handle documentation](https://atproto.com/specs/handle) for details. + +{% callout type="note" %} +If you sign up using your email on certified.app you will initially be given a random handle like `1lasdk.certified.app`. You can change your handle by going to your profile settings and clicking on "Change handle" on [certified.app](https://certified.app). +{% /callout %} +--- + +## Organization accounts + +For teams with multiple contributors, create a dedicated organizational account on a PDS. The organization gets its own DID and repository. Team members can write to the organization's repository using app passwords or OAuth scoped to the organizational account. This is useful for open-source projects, research labs, and organizations where many people contribute to the same body of work. + +{% callout type="note" %} +To set up an organizational account, create an account at [certified.app](https://certified.app) with the organization's email. Use a [custom domain handle](#handles-your-public-username-and-domain-verification) (e.g., `numpy.org`) to prove organizational identity. +{% /callout %} + +--- + +## Authentication + +### OAuth (for applications) + +Applications authenticate users via AT Protocol OAuth. The AT Protocol client libraries handle the full OAuth flow — authorization, token management, and session restoration. Users authorize your app through their PDS and never share credentials with your application. See the [Quickstart](/getting-started/quickstart) for the authentication setup. + +### OAuth (for ePDS) +The ePDS (extended PDS) adds email/passwordless login on top of the standard PDS, without modifying the underlying AT Protocol PDS code. When a user authenticates, the ePDS Auth Service handles the OTP flow and then issues a standard AT Protocol authorization code back to your app. + +You can integrate ePDS with [`@atproto/oauth-client-node`](https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-client-node). If your app already has an email field, start OAuth normally and add `login_hint=` to the authorization URL before redirecting the user. If your app just has a sign-in button, redirect the user normally and let ePDS collect the email itself. You can also optionally add `epds_handle_mode` to the authorization URL to control how new users get handles. + +{% callout type="note" %} +See [ePDS (extended PDS)](/architecture/epds) for integration examples, handle mode configuration, and client metadata options. A ready-made skill that implements the full ePDS OAuth flow is available at `.agents/skills/epds-login/SKILL.md` in the [ePDS repository](https://github.com/hypercerts-org/ePDS). +{% /callout %} + + +### App passwords (for scripts and CLI) + +For scripts, CLI tools, and server-side automation, use app passwords instead of your main password. App passwords are scoped credentials that can be revoked independently. + +Create one in your account settings at [certified.app](https://certified.app). Give it a descriptive name (e.g., "CI/CD pipeline" or "Local development"). If a credential is compromised, revoke just that app password — your main account stays secure. The [Hypercerts CLI](/tools/hypercerts-cli) uses app passwords for authentication. + +{% callout type="warning" %} +Never commit app passwords to version control. Use environment variables or a secrets manager. +{% /callout %} + +--- + +## The app.certified namespace + +Beyond identity, Certified contributes shared data schemas to the AT Protocol ecosystem. You'll see `app.certified.*` in some lexicon names — for example, [`app.certified.location`](/lexicons/certified-lexicons/location) defines how geographic locations are represented. These are general-purpose schemas available to any application on AT Protocol, not just Hypercerts. + +--- + +## Next steps + +- [Quickstart](/getting-started/quickstart) — build a complete hypercert with contributions, attachments, and measurements +- [Working with Evaluations](/getting-started/working-with-evaluations) — create evaluations of other people's work diff --git a/public/raw/architecture/data-flow-and-lifecycle.md b/public/raw/architecture/data-flow-and-lifecycle.md new file mode 100644 index 0000000..cfddd93 --- /dev/null +++ b/public/raw/architecture/data-flow-and-lifecycle.md @@ -0,0 +1,229 @@ +--- +title: Data Flow & Lifecycle +description: How a hypercert moves from creation through evaluation to funding. +--- + +# Data Flow & Lifecycle + +A hypercert flows through six stages from creation to ongoing accumulation of attachments and funding. + +## The Lifecycle of a Hypercert + +Every hypercert follows a similar path through the system, though the timeline and participants vary. + +**Creation** happens when a contributor writes an activity claim to their Personal Data Server. The claim gets a unique identifier and becomes part of the contributor's repository. + +**Enrichment** adds supporting data. Contribution records link collaborators. Attachment records attach proof of work. Measurement records provide quantitative data. Rights records define the terms of the claim. Collection records group claims into projects. These can live on the same server or different servers. + +**Evaluation** brings third-party assessment. Evaluators create evaluation records on their own servers that reference the original claim. Multiple evaluators can independently assess the same work. Evaluations accumulate over time. + +**Discovery** makes the hypercert findable. Relays aggregate records from many servers. Indexers build searchable databases. Platforms query indexers to surface hypercerts to users. + +**Funding** connects funders to the claim. Funding receipts (`org.hypercerts.funding.receipt`) record who funded what, how much, and when — this works today on AT Protocol. Optionally, the claim can be frozen and anchored on-chain for tokenized funding. The on-chain tokenization layer is [planned but not yet implemented](/core-concepts/funding-and-value-flow). + +**Accumulation** continues indefinitely. More evaluations arrive. Additional attachments get attached. The data layer continues evolving. + +``` +Creation → Enrichment → Evaluation → Discovery → Funding → Accumulation + ↓ ↓ ↓ ↓ ↓ ↓ + PDS PDS Other PDS Indexer On-chain* Ongoing +``` + +*On-chain layer is planned. See [Funding & Value Flow](/core-concepts/funding-and-value-flow). + +## Stage 1: Creation + +A hypercert begins when a contributor creates an activity claim on their PDS. + +The contributor writes an `org.hypercerts.claim.activity` record. This record includes fields like `workScope`, `startDate`, `endDate`, and `contributors`. The PDS validates the record against the lexicon schema. + +The record receives a unique AT-URI. The format is `at://did:plc:abc123/org.hypercerts.claim.activity/tid` where `did:plc:abc123` is the contributor's DID and `tid` is a timestamp-based identifier. + +The PDS signs the record and includes it in the contributor's repository. The signature proves the contributor created this record at this time. The repository is a Merkle tree that provides tamper-evidence. + +The relay picks up the new record. Within seconds, the record is available to downstream consumers. Indexers can now discover and process it. + +``` +Contributor → PDS → Relay → Indexers + ↓ + (signed record) + at://did:plc:alice/org.hypercerts.claim.activity/3k7 +``` + +## Stage 2: Enrichment + +Supporting data gets attached through additional records that reference the activity claim. + +#### Contribution Records + +Contributors are embedded in the activity claim's `contributors` array. For richer profiles, separate `org.hypercerts.claim.contributorInformation` and `org.hypercerts.claim.contribution` records can be created and referenced. Contributions can be created by the original contributor or by collaborators on their own servers. + +#### Attachment Records + +`org.hypercerts.claim.attachment` records attach supporting documentation. Attachments can be URLs, file uploads, or structured data. Each attachment record includes a strong reference to the claim it supports. + +#### Measurement Records + +`org.hypercerts.claim.measurement` records provide quantitative data. A measurement specifies what was measured, the value, the unit, and the methodology. Multiple measurements can track different metrics. + +#### Rights Records + +`org.hypercerts.claim.rights` records define the rights associated with a hypercert — for example, public display rights, attribution licenses, or transferability terms. The activity claim references a rights record via a strong reference. Rights are defined using a name, type, and description, with an optional attached legal document. + +#### Location Records + +`app.certified.location` records anchor work geographically. A location record can specify a point, a region, or multiple areas. This enables geographic filtering and regional funding mechanisms. + +#### Collection Records + +`org.hypercerts.collection` records group multiple activity claims into a project or portfolio. Each collection has weighted items (strong references to activity claims or other collections), supporting recursive nesting. A collection with `type="project"` represents a multi-year project composed of individual activity claims. + +#### Funding Receipts + +`org.hypercerts.funding.receipt` records track funding events. A receipt records who funded which activity, how much, through which payment rail, and when. Receipts reference the activity claim they fund. See [Funding & Value Flow](/core-concepts/funding-and-value-flow) for details. + +#### Cross-Server References + +These records can live on different PDS instances. A contributor on PDS-A can create an activity claim. A collaborator on PDS-B can create a contribution record that references it. A collaborator on PDS-C can create an attachment. Strong references ensure the connections are tamper-evident. + +``` +PDS-A (Alice) PDS-B (Bob) PDS-C (Carol) +───────────── ─────────── ───────────── +activity claim contribution record attachment record +at://did:alice/... at://did:bob/... at://did:carol/... + subject: at://did:alice/... subject: at://did:alice/... +``` + +## Stage 3: Evaluation + +Third parties assess the work by creating evaluation records on their own servers. + +An evaluator creates an `org.hypercerts.claim.evaluation` record on their PDS. The evaluation includes a `subject` field with a strong reference to the activity claim. Strong references include both the AT-URI and the CID (content hash), ensuring the evaluation references a specific version of the claim. + +The evaluation record includes the evaluator's assessment. This can be a score, a category, structured feedback, or a link to a detailed report. The lexicon allows flexible evaluation formats. + +Multiple evaluators can independently assess the same claim. Each evaluation is a separate record on the evaluator's server. There's no central registry or coordination required. + +Evaluations accumulate over time. A claim created in January might receive its first evaluation in March, another in June, and more years later. Evaluations are never "final" — new assessments can always arrive. + +The evaluator's reputation matters. Applications can weight evaluations based on the evaluator's DID, their history, or their credentials. The protocol doesn't enforce any particular trust model. + +``` +Activity Claim (Alice's PDS) +at://did:alice/org.hypercerts.claim.activity/3k7 + ↑ ↑ ↑ + │ │ │ + Evaluation 1 Evaluation 2 Evaluation 3 + (Eve's PDS) (Frank's PDS) (Grace's PDS) +``` + +## Stage 4: Discovery & Indexing + +Relays and indexers make hypercerts findable across the network. + +#### Relays + +Relays aggregate records from many PDS instances. When a user writes a new record, the relay picks it up and adds it to the firehose. Relays provide a complete stream of network activity. + +#### Indexers (App Views) + +Indexers read from relays and build queryable databases. An indexer might filter for hypercerts-related records, resolve references between claims and evaluations, and compute derived data like total evaluation scores. + +Different indexers can build different views. One indexer might focus on climate-related hypercerts. Another might specialize in open-source contributions. A third might aggregate all evaluations from trusted evaluators. + +#### Platform Queries + +Applications query indexers to surface hypercerts to users. A funding platform might query for "all hypercerts in the climate category with at least two evaluations." A dashboard might query for "all hypercerts created by this DID." + +Indexers expose APIs that applications consume. The protocol doesn't mandate a specific API format, but common patterns include GraphQL and REST endpoints. + +#### The Discovery Flow + +A typical discovery flow: a user creates a claim → the relay picks it up → indexers process it and update their databases → applications query indexers → users discover the claim on platforms. + +``` +Many PDS Instances + ↓ + Relay (firehose) + ↓ + Indexers (filtered views) + ↓ + Applications (queries) + ↓ + Users +``` + +## Stage 5: Funding & Ownership (Planned) + +The on-chain funding layer is not yet implemented. The planned design: before a hypercert can be funded, its ATProto records are frozen and the snapshot is anchored on-chain. This ensures funders know exactly what they are paying for — the cert's contents cannot change after freezing. + +For the full planned design — including anchoring, tokenization, funding mechanisms, and funding readiness patterns — see [Funding & Value Flow](/core-concepts/funding-and-value-flow). + +## Stage 6: Accumulation + +The hypercert continues evolving after funding. + +#### Ongoing Evaluations + +New evaluations arrive over time. A hypercert funded in 2024 might receive evaluations in 2025, 2026, and beyond. Each evaluation is a new record on the evaluator's PDS. + +Indexers pick up new evaluations and update their databases. Applications can show the evolving assessment history. Funders can see how perceptions of the work change over time. + +#### Additional Attachments + +Contributors can attach more supporting documentation as outcomes become clear. A research project might add published papers. A climate initiative might add measurement data showing carbon reduction. + +Attachment records reference the original activity claim. The claim itself doesn't change — attachments accumulate around it. + +#### Long-Term Value + +The separation of data and ownership enables long-term value accumulation. A hypercert's reputation can grow as evaluations accumulate. The data remains portable and accessible regardless of future ownership changes. + +``` +Time → +───────────────────────────────────────────────────────── +Creation Evaluation 1 Discovery Evaluation 2 Attachment Evaluation 3 + ↓ ↓ ↓ ↓ ↓ ↓ + PDS PDS-Eva1 Indexer PDS-Eva2 PDS PDS-Eva3 +``` + +## Cross-PDS References + +Records on different servers reference each other through strong references. + +A strong reference includes both the AT-URI and the CID (content hash). The URI identifies the record. The CID ensures the reference points to a specific version. + +```json +{ + "subject": { + "uri": "at://did:plc:alice/org.hypercerts.claim.activity/3k7", + "cid": "bafyreib2rxk3rh6kzwq7..." + } +} +``` + +If the referenced record changes, the CID won't match. This makes references tamper-evident. An evaluation that references version 1 of a claim won't silently point to version 2. + +Applications can verify references by fetching the record and computing its CID. If the CID matches, the reference is valid. If not, the record was modified after the reference was created. + +This enables trust across servers. A record on PDS-A can safely reference a record on PDS-B. The reference is verifiable without trusting either server. + +## What This Flow Enables + +The lifecycle supports use cases that span time, servers, and participants. + +**Retroactive funding** works because creation and funding are separate stages. A contributor can create a claim in January, accumulate attachments and evaluations through the year, and receive funding in December. The data layer preserves the full history. + +**Cross-platform collaboration** works because enrichment happens across servers. A contributor on Platform A can work with a collaborator on Platform B. Their contribution records reference the same activity claim. Indexers aggregate both records. + +**Independent evaluation** works because evaluators control their own data. An evaluator doesn't need permission from the contributor or any platform. They create a record on their server that references the claim. Applications can discover and display it. + +**Evolving reputation** works because accumulation is ongoing. A hypercert's value isn't fixed at creation. Evaluations arrive over time. Attachments accumulate. The full history is queryable. + +## Next Steps + +For the overall architecture and how layers connect, see [Architecture Overview](/architecture/overview). + +For details on specific record types and their schemas, see [Introduction to Lexicons](/lexicons/introduction-to-lexicons). + +For a practical walkthrough of creating a hypercert, see [Quickstart](/getting-started/quickstart). diff --git a/public/raw/architecture/epds.md b/public/raw/architecture/epds.md new file mode 100644 index 0000000..6c00da9 --- /dev/null +++ b/public/raw/architecture/epds.md @@ -0,0 +1,196 @@ +--- +title: ePDS (extended PDS) +description: How the ePDS adds email/OTP login on top of AT Protocol without changing the standard OAuth flow for apps. +--- + +# ePDS (extended PDS) + +The ePDS adds email-based, passwordless sign-in on top of a standard AT Protocol PDS. Users enter their email, receive a one-time code, and end up with a normal AT Protocol session tied to a DID. + +Certified hosts an ePDS instance at [certified.one](https://certified.one). + +For applications, the important part is that ePDS still finishes by issuing a standard AT Protocol authorization code. In practice, this means you can integrate it with [`@atproto/oauth-client-node`](https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-client-node). + +## System overview + +```text +Client App + -> starts AT Protocol OAuth against the PDS + +PDS Core + -> remains the OAuth issuer and token endpoint + -> advertises the Auth Service as the authorization endpoint + +Auth Service + -> collects the user's email or OTP + -> verifies the user + -> returns control to PDS Core via signed callback + +PDS Core + -> issues a normal authorization code + +Client App + -> exchanges the code for tokens +``` + +The PDS remains the OAuth issuer and token endpoint. The main difference is that the authorization step happens on the ePDS Auth Service, which handles the email and OTP flow before returning control to the PDS. + +## Integrating with `@atproto/oauth-client-node` + +ePDS works with the standard AT Protocol OAuth client libraries. The main ePDS-specific behavior is how you shape the authorization URL before redirecting the user. + +### Flow 1: your app collects the email + +In Flow 1, your app has its own email field. Start OAuth normally, then add `login_hint=` to the authorization URL before redirecting the user. + +```ts +import { NodeOAuthClient } from '@atproto/oauth-client-node' + +const oauthClient = new NodeOAuthClient({ + clientMetadata: { + client_id: 'https://yourapp.example.com/client-metadata.json', + client_name: 'Your App', + client_uri: 'https://yourapp.example.com', + redirect_uris: ['https://yourapp.example.com/api/oauth/callback'], + scope: 'atproto transition:generic', + grant_types: ['authorization_code', 'refresh_token'], + response_types: ['code'], + token_endpoint_auth_method: 'none', + dpop_bound_access_tokens: true, + }, + stateStore, + sessionStore, +}) + +const url = await oauthClient.authorize('alice.certified.app', { + scope: 'atproto transition:generic', +}) + +// ePDS-specific customization happens here. +const authUrl = new URL(url) +authUrl.searchParams.set('login_hint', email) +authUrl.searchParams.set('epds_handle_mode', 'picker-with-random') + +return authUrl.toString() +``` + +{% callout type="warning" %} +Do not put an email address into the PAR body as `login_hint`. For ePDS, add `login_hint` to the authorization URL instead. +{% /callout %} + +With `login_hint` set, the user lands directly on the OTP entry step instead of first seeing an email form on ePDS. + +### Flow 2: ePDS collects the email + +In Flow 2, your app just shows a "Sign in" button. Start OAuth normally and redirect the user to the authorization URL without `login_hint`. + +```ts +import { NodeOAuthClient } from '@atproto/oauth-client-node' + +const oauthClient = new NodeOAuthClient({ + clientMetadata: { + client_id: 'https://yourapp.example.com/client-metadata.json', + client_name: 'Your App', + client_uri: 'https://yourapp.example.com', + redirect_uris: ['https://yourapp.example.com/api/oauth/callback'], + scope: 'atproto transition:generic', + grant_types: ['authorization_code', 'refresh_token'], + response_types: ['code'], + token_endpoint_auth_method: 'none', + dpop_bound_access_tokens: true, + }, + stateStore, + sessionStore, +}) + +const url = await oauthClient.authorize('alice.certified.app', { + scope: 'atproto transition:generic', +}) + +const authUrl = new URL(url) +authUrl.searchParams.set('epds_handle_mode', 'picker') + +return authUrl.toString() +``` + +Without `login_hint`, ePDS renders its own email form and takes the user through the rest of the OTP flow. + +### Callback handling + +Callback handling stays standard. Once the user finishes on ePDS, your callback handler receives a normal authorization code and hands it back to `oauth-client-node`. + +```ts +const result = await oauthClient.callback(params) + +const session = result.session +const did = session.did +``` + +## Handle modes + +Handle mode controls what happens when a brand new user needs a handle during signup. + +| Mode | Behavior | +|------|----------| +| `picker-with-random` | Show the handle picker with a "Generate random" option. | +| `picker` | Show the handle picker without a random option. | +| `random` | Skip the picker and assign a random handle automatically. | + +Handle mode is resolved in this order: + +1. `epds_handle_mode` query param on the authorization URL +2. `epds_handle_mode` in client metadata +3. The ePDS instance default (`EPDS_DEFAULT_HANDLE_MODE`) + +This only affects new account creation. Existing users keep their current handle and skip this step. + +## Client metadata + +Your client metadata file is a public JSON document served over HTTPS. Its URL is also your `client_id`. + +### Bare-bones example + +```json +{ + "client_id": "https://yourapp.example.com/client-metadata.json", + "client_name": "Your App", + "client_uri": "https://yourapp.example.com", + "redirect_uris": ["https://yourapp.example.com/api/oauth/callback"], + "scope": "atproto transition:generic", + "grant_types": ["authorization_code", "refresh_token"], + "response_types": ["code"], + "token_endpoint_auth_method": "none", + "dpop_bound_access_tokens": true +} +``` + +### Full config example + +```json +{ + "client_id": "https://yourapp.example.com/client-metadata.json", + "client_name": "Your App", + "client_uri": "https://yourapp.example.com", + "logo_uri": "https://yourapp.example.com/logo.png", + "redirect_uris": ["https://yourapp.example.com/api/oauth/callback"], + "scope": "atproto transition:generic", + "grant_types": ["authorization_code", "refresh_token"], + "response_types": ["code"], + "token_endpoint_auth_method": "none", + "dpop_bound_access_tokens": true, + "brand_color": "#0f172a", + "background_color": "#ffffff", + "email_template_uri": "https://yourapp.example.com/email-template.html", + "email_subject_template": "{{code}} - Your {{app_name}} code", + "epds_handle_mode": "picker-with-random" +} +``` + +The extra branding fields customize the hosted login and email experience. `epds_handle_mode` sets your preferred handle mode for new users unless you override it on the authorization URL. + +## Further reading + +- [Account & Identity Setup](/architecture/account-and-identity) +- [Scaffold Starter App](/tools/scaffold) +- [ePDS repository](https://github.com/hypercerts-org/ePDS) +- Install the ePDS agent skill with `npx skills add hypercerts-org/ePDS --skill epds-login` diff --git a/public/raw/architecture/indexers-and-discovery.md b/public/raw/architecture/indexers-and-discovery.md new file mode 100644 index 0000000..825a7b2 --- /dev/null +++ b/public/raw/architecture/indexers-and-discovery.md @@ -0,0 +1,22 @@ +--- +title: Indexers & Discovery +description: How indexers make hypercerts findable across the network. +--- + +# {% $markdoc.frontmatter.title %} + +## Why indexers? + +ATProto is federated — data is distributed across multiple PDSs. To discover records, you need something that crawls the network and aggregates data into a queryable database. + +That's what indexers do: they subscribe to the firehose (a real-time stream of repository commits), fetch and parse records according to their lexicons, and expose the results via APIs for searching, filtering, and aggregation. + +## Hyperindex + +[Hyperindex](https://github.com/hypercerts-org/hyperindex) is a reference indexer for the Hypercerts ecosystem. It listens to the network via [Jetstream](https://github.com/bluesky-social/jetstream), stores matching records in a database, and automatically generates a [GraphQL](https://graphql.org/) API for querying them. + +Multiple indexers are running across the ecosystem — see [Hyperscan Indexers](https://www.hyperscan.dev/indexers) for a live list with health status. + +You can also run your own instance and register custom lexicons alongside the standard `org.hypercerts.*` ones. See the [Hyperindex repository](https://github.com/hypercerts-org/hyperindex) for setup instructions. + +For how indexers fit into the protocol stack, see [Data Flow & Lifecycle](/architecture/data-flow-and-lifecycle#stage-4-discovery--indexing). diff --git a/public/raw/architecture/overview.md b/public/raw/architecture/overview.md new file mode 100644 index 0000000..0527342 --- /dev/null +++ b/public/raw/architecture/overview.md @@ -0,0 +1,40 @@ +--- +title: Architecture Overview +description: How the Hypercerts Protocol stack fits together. +--- + +# Architecture Overview + +The Hypercerts Protocol is built on [AT Protocol](https://atproto.com/docs) — the same decentralized data layer that powers Bluesky. Users own their data, applications are interoperable, and records are cryptographically signed. + +## Three Layers + +![The Hypercerts Stack](/images/architecture-stack.svg) + +**Data.** All hypercert records — activity claims, contributions, attachments, evaluations, measurements — live on AT Protocol. Each user's data is stored on a Personal Data Server (PDS) they control. Shared schemas called [lexicons](/lexicons/introduction-to-lexicons) define the structure of every record type, so any application can read any record. Users can switch PDS providers without losing data. See [Account & Identity](/architecture/account-and-identity) and [Portability & Data Access](/architecture/portability-and-scaling). + +**Applications.** Funding platforms, dashboards, and evaluation tools read from and write to the data layer. They query [indexers](/architecture/indexers-and-discovery) that aggregate records from across the network into searchable databases. Different indexers can build different views of the same underlying data. + +**Ownership (planned).** On-chain anchoring for funding and tokenization is not yet implemented. The intended design freezes a hypercert's ATProto records and anchors them on-chain before funding — so funders know exactly what they're paying for. See [Funding & Value Flow](/core-concepts/funding-and-value-flow). + +## How Data Flows + +A user writes a record to their PDS. The PDS signs it and adds it to the user's repository. A relay picks up the new record and streams it to indexers. Indexers update their databases. Applications query indexers to display the data. + +![Data flow through ATProto](/images/architecture-dataflow.svg) + +For the full lifecycle — creation, enrichment, evaluation, discovery, funding, and accumulation — see [Data Flow & Lifecycle](/architecture/data-flow-and-lifecycle). + +## Why It's Trustworthy + +Every PDS repository is a Merkle tree signed by the user's DID key — any third-party tampering is detectable because the signature won't match. When one record references another (e.g., an evaluation pointing to an activity claim), the reference includes a content hash, so you can tell if the target was modified after the reference was created. DIDs resolve via the [PLC directory](https://plc.directory) to a public key, so signatures are independently verifiable. + +This means: Alice creates a hypercert and her PDS signs it. Bob evaluates it, referencing Alice's record by URI and content hash. Anyone can verify Alice authored the claim, Bob authored the evaluation, and Bob evaluated the exact version Alice published. + +## Why This Architecture + +**Why not fully on-chain?** Storing rich data on-chain is expensive — a single activity claim with attachments could cost hundreds of dollars in gas. On-chain works for ownership state, not for the full data layer. + +**Why not fully off-chain?** Funding requires immutability. Without on-chain anchoring, there's no way to guarantee that what a funder evaluated is what they end up funding. + +**Why ATProto?** Persistent DIDs, shared schemas, user-controlled data, and a growing ecosystem. IPFS has no identity layer or schemas. Ceramic has similar goals but a smaller ecosystem. Bluesky demonstrates ATProto scales to millions of users. See [Why AT Protocol?](/core-concepts/why-at-protocol). diff --git a/public/raw/architecture/portability-and-scaling.md b/public/raw/architecture/portability-and-scaling.md new file mode 100644 index 0000000..f90d95d --- /dev/null +++ b/public/raw/architecture/portability-and-scaling.md @@ -0,0 +1,22 @@ +--- +title: Portability & Data Access +description: How ATProto enables data migration, app switching, and transparent data access. +--- + +# {% $markdoc.frontmatter.title %} + +## Public by default + +ATProto records are public by default. Anyone can read your activity claims, evaluations, and contributions. This is intentional — impact work benefits from transparency and discoverability. + +## Switching PDSs + +Users can migrate their entire repository to a new PDS without breaking references. Export from the old PDS, import to the new one, and update your DID document to point to the new URL. Applications automatically follow. + +This works because AT-URIs use DIDs, not server addresses — so all existing references remain valid after migration. See the [ATProto account migration guide](https://atproto.com/guides/account-migration) for the full process. + +## Interoperable data + +Because data is stored on PDSs, not in application databases, users can switch apps without losing data. A claim created in App A is immediately readable by App B. Evaluations, attachments, and measurements created in different apps all reference the same underlying claims. + +This is fundamentally different from traditional platforms, where switching apps means starting over. diff --git a/public/raw/core-concepts/cel-work-scopes.md b/public/raw/core-concepts/cel-work-scopes.md new file mode 100644 index 0000000..5df2b91 --- /dev/null +++ b/public/raw/core-concepts/cel-work-scopes.md @@ -0,0 +1,224 @@ +--- +title: CEL Work Scopes +description: How CEL (Common Expression Language) makes hypercert work scopes machine-readable, composable, and queryable. +--- + +# CEL Work Scopes + +Hypercert work scopes describe what work was done. A CEL expression alongside the human-readable work scope makes hypercerts machine-verifiable, composable, and queryable. + +[CEL (Common Expression Language)](https://github.com/google/cel-spec) is an open-source expression language built by Google for evaluating conditions in distributed systems. It's used by Kubernetes, Firebase, and Google Cloud IAM. + +## Why structured scopes matter + +A community in coastal Kenya mints a hypercert for "mangrove restoration and environmental education." A collective in Uganda creates one for "agroforestry with beekeeping." A drone operator in the Amazon documents "biodiversity monitoring in the Negro River region." These are all legible to a person reading them one at a time. They're invisible to any system trying to connect funders to relevant work at scale. + +As the Hypercerts Protocol grows on ATProto — with actions, evaluations, and evidence living as persistent, portable records — the richer the network becomes, the harder it is to find, compare, validate, and compose claims when the most important field is unstructured text. + +## Architecture: two layers + +The design uses two complementary layers: + +1. **Vocabulary layer** — `workScopeTag` records define what each tag *means* (e.g., what `mangrove_restoration` refers to, its description, hierarchy, and links to external ontologies). +2. **Composition layer** — `celExpression` objects compose those tags into evaluable logic on activity records (e.g., "this work includes mangrove restoration AND environmental education, AND is in Kenya"). + +```text +workScopeTag records (vocabulary) + ├── mangrove_restoration + ├── environmental_education + ├── fishpond_management + └── ecotourism + + ↓ referenced by + +celExpression (composition) + expression: scope.hasAll(['mangrove_restoration', 'environmental_education']) + && scope.hasAny(['fishpond_management', 'ecotourism']) + && location.country == 'KE' + usedTags: [strongRef → mangrove_restoration, strongRef → environmental_education, ...] + + ↓ embedded in + +activity.workScope (union) + → celExpression (structured, machine-evaluable) + → workScopeString (simple free-form fallback) +``` + +The vocabulary layer tells you what a tag means. The composition layer tells you what logic applies to a specific hypercert. The `workScopeString` fallback supports simple free-form scopes. + +## Lexicon schemas + +### `org.hypercerts.ontology.celExpression` + +A CEL expression object embedded inline in the `activity.workScope` union. It's intentionally an `object` type (not a `record`) so it can be embedded directly without requiring a separate collection. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `expression` | `string` | Yes | A CEL expression encoding the work scope conditions. Max 10,000 characters. | +| `usedTags` | `strongRef[]` | Yes | Strong references to `workScopeTag` records used in the expression. Enables fast indexing by AT-URI and provides referential integrity. Max 100 entries. | +| `version` | `string` | Yes | CEL context schema version. Known values: `v1`. Open enum — new versions can be added non-breakingly. | +| `createdAt` | `datetime` | Yes | Client-declared timestamp when this expression was originally created. | + +### `org.hypercerts.ontology.workScopeTag` + +A reusable scope atom — the building block of the vocabulary. Each record represents a single concept like `mangrove_restoration` or `biodiversity_monitoring`. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `key` | `string` | Yes | Lowercase, underscore-separated machine-readable key (e.g., `mangrove_restoration`). Used as the canonical identifier in CEL expressions. | +| `label` | `string` | Yes | Human-readable display name. | +| `kind` | `string` | No | Category type. Known values: `topic`, `language`, `domain`, `method`, `tag`. | +| `description` | `string` | No | Longer explanation of the scope. | +| `parent` | `strongRef` | No | Reference to a parent `workScopeTag` for taxonomy/hierarchy support. | +| `status` | `string` | No | Lifecycle status. Known values: `proposed`, `accepted`, `deprecated`. Communities propose tags, curators accept them, deprecated tags point to replacements. | +| `supersededBy` | `strongRef` | No | When status is `deprecated`, points to the replacement `workScopeTag`. | +| `aliases` | `string[]` | No | Alternative names or identifiers for this scope. | +| `sameAs` | `uri[]` | No | Links to equivalent concepts in external ontologies (e.g., Wikidata QIDs, ENVO terms, SDG targets). | +| `externalReference` | `uri \| blob` | No | External reference as a URI or blob. | +| `createdAt` | `datetime` | Yes | Client-declared timestamp when this record was originally created. | + +### `activity.workScope` union + +The `workScope` field on `org.hypercerts.claim.activity` accepts two variants: + +- **`celExpression`** — a structured, machine-evaluable scope (described above). +- **`workScopeString`** — a simple free-form string for cases where a CEL expression isn't needed. + +## Examples + +### Mangrove restoration in coastal Kenya + +```json +{ + "$type": "org.hypercerts.claim.activity", + "title": "Tsunza Mangrove Restoration & Education", + "workScope": { + "$type": "org.hypercerts.ontology.celExpression", + "expression": "scope.hasAll(['mangrove_restoration', 'environmental_education']) && scope.hasAny(['fishpond_management', 'ecotourism']) && location.country == 'KE'", + "usedTags": [ + { "uri": "at://did:plc:curator/org.hypercerts.ontology.workScopeTag/mangrove_restoration", "cid": "..." }, + { "uri": "at://did:plc:curator/org.hypercerts.ontology.workScopeTag/environmental_education", "cid": "..." }, + { "uri": "at://did:plc:curator/org.hypercerts.ontology.workScopeTag/fishpond_management", "cid": "..." }, + { "uri": "at://did:plc:curator/org.hypercerts.ontology.workScopeTag/ecotourism", "cid": "..." } + ], + "version": "v1", + "createdAt": "2025-07-22T10:00:00Z" + }, + "startDate": "2024-06-01T00:00:00Z", + "endDate": "2025-12-31T23:59:59Z" +} +``` + +### Agroforestry in Uganda + +```json +{ + "workScope": { + "$type": "org.hypercerts.ontology.celExpression", + "expression": "scope.hasAll(['agroforestry', 'tree_planting', 'beekeeping']) && location.country == 'UG'", + "usedTags": [ + { "uri": "at://did:plc:curator/org.hypercerts.ontology.workScopeTag/agroforestry", "cid": "..." }, + { "uri": "at://did:plc:curator/org.hypercerts.ontology.workScopeTag/tree_planting", "cid": "..." }, + { "uri": "at://did:plc:curator/org.hypercerts.ontology.workScopeTag/beekeeping", "cid": "..." } + ], + "version": "v1", + "createdAt": "2025-06-15T08:00:00Z" + } +} +``` + +## What CEL unlocks + +### Funder matching + +Funders can define their criteria as CEL expressions and the appview matches them against existing hypercerts: + +```cel +// "All mangrove work in East Africa" +scope.has("mangrove_restoration") && location.country in ["KE", "TZ", "MZ", "MG"] +``` + +### Evaluation matching + +An auditor who verified mangrove survival rates can express applicability as a CEL condition, and the appview automatically matches it to relevant hypercerts: + +```cel +scope.has("mangrove_restoration") + && location.country == "KE" + && time.end >= timestamp("2025-01-01T00:00:00Z") +``` + +### Overlap detection + +When someone mints a new hypercert, CEL can check whether the claimed work scope overlaps with existing claims: + +```cel +existing.scope.overlaps(new.scope) + && existing.time.start < new.time.end + && new.time.start < existing.time.end + && existing.location.region == new.location.region +``` + +### Measurement-based queries + +Because CEL can access linked measurement records, funders can write queries that go beyond tags: + +```cel +// "Agroforestry that planted 500+ verified trees" +scope.has("agroforestry") + && measurements.exists(m, m.metric == "trees_planted" && m.value >= 500) +``` + +## CEL context schema (v1) + +Every CEL expression evaluates against a typed context. Each variable maps to data already present in the activity record and its linked records. + +| Variable | Type | Source | Description | +|----------|------|--------|-------------| +| `scope` | `ScopeSet` | `usedTags` on the CEL expression | The set of `workScopeTag` keys | +| `location` | `Location` | Linked location records | Geo context | +| `time` | `TimeRange` | `startDate` / `endDate` on activity | Work time range | +| `contributors` | `list(Contributor)` | Contributors on activity | Contributor DIDs and roles | +| `measurements` | `list(Measurement)` | Linked measurement records | Measurement data | +| `evidence` | `list(Evidence)` | Linked attachment records | Evidence / attachments | + +### Custom functions on `ScopeSet` + +| Function | Signature | Semantics | +|----------|-----------|-----------| +| `has` | `ScopeSet.has(string) → bool` | True if label key is present | +| `hasAll` | `ScopeSet.hasAll(list(string)) → bool` | True if every key is present | +| `hasAny` | `ScopeSet.hasAny(list(string)) → bool` | True if at least one is present | +| `overlaps` | `ScopeSet.overlaps(ScopeSet) → bool` | True if the two sets share any key | + +## Starter tag vocabulary + +`workScopeTag` records are published as ATProto records that anyone can reference via strong references. [Certified](https://certified.ink) publishes curated tag sets for specific domains. Here's an example for regenerative work: + +| Domain | Example tags | +|--------|-------------| +| Agroforestry | `agroforestry`, `shade_trees`, `coffee_cultivation`, `beekeeping` | +| Forest conservation | `forest_protection`, `reforestation`, `tree_planting` | +| Marine / coastal | `mangrove_restoration`, `fishpond_management`, `coral_reef` | +| Biodiversity monitoring | `biodiversity_data_collection`, `drone_imagery`, `bioacoustics`, `edna` | +| Carbon / climate | `carbon_sequestration`, `emissions_reduction`, `soil_carbon` | +| Community livelihoods | `community_data_income`, `ecotourism`, `artisanal_crafts` | +| Education & capacity | `environmental_education`, `capacity_building`, `workshops` | + +Anyone can create `workScopeTag` records for other domains. Communities don't write CEL by hand — the vocabulary powers a visual builder, and the structured expression gets generated behind the scenes. + +## Where CEL lives in the stack + +CEL doesn't need to run onchain. The evaluation layer belongs alongside the ATProto infrastructure: + +| Layer | What lives here | +|-------|----------------| +| **ATProto records** | `workScopeTag` records define the vocabulary. Activity records carry the human-readable scope + CEL expression. | +| **Appview / indexer** | CEL parsing and evaluation (using `cel-go`, `cel-rust`, or `cel-js`). Handles validation, querying, overlap detection, evaluation matching. | +| **Client UI** | A scope builder that helps communities construct valid CEL from the `workScopeTag` vocabulary — no code writing required. | + +## Further reading + +- [CEL specification](https://github.com/google/cel-spec) +- [Core Data Model](/core-concepts/hypercerts-core-data-model) — how records connect +- [Activity Claim lexicon](/lexicons/hypercerts-lexicons/activity-claim) — the `workScope` field in context diff --git a/public/raw/core-concepts/certified-identity.md b/public/raw/core-concepts/certified-identity.md new file mode 100644 index 0000000..1ff6f18 --- /dev/null +++ b/public/raw/core-concepts/certified-identity.md @@ -0,0 +1,70 @@ +--- +title: Certified Identity +description: How identity works in the Hypercerts ecosystem — DIDs, signing, portability, and wallet linkage. +--- + +# Certified Identity + +Every hypercert record has an author. Every evaluation carries a signature. Every funding receipt traces back to a DID. Identity is a core primitive of the protocol — it determines who owns records, who can be trusted, and who receives funding. + +## Identity in the Hypercerts Protocol + +The Hypercerts Protocol uses AT Protocol's identity system. Every participant — whether an individual contributor, an evaluator, or an organization — is identified by a **DID (Decentralized Identifier)**. + +A DID like `did:plc:z72i7hdynmk6r22z27h6tvur` is: + +- **Permanent** — it never changes, even if you switch servers or handles +- **Portable** — your records, reputation, and history follow your DID across platforms +- **Cryptographically verifiable** — every record you create is signed by your DID's key pair, and anyone can verify the signature + +Your DID resolves via the [PLC directory](https://plc.directory) to a DID document containing your current PDS, public signing keys, and handle. + +## How identity connects to the protocol + +| Layer | How identity is used | +|-------|---------------------| +| **Data** | Every record (activity claims, evaluations, measurements) carries the author's DID. The PDS signs records into a Merkle tree, making authorship tamper-evident. | +| **Trust** | Evaluators build reputation tied to their DID. Applications can weight evaluations based on the evaluator's history and credentials. | +| **Funding** | Funding receipts link funder DIDs to the work they support. Wallet linkage (work-in-progress) connects DIDs to onchain addresses for payment flows and tokenization. | +| **Portability** | Switching PDS providers doesn't change your DID. Your entire history — claims, evaluations, contributions — migrates with you. | + +## Certified: the reference identity provider + +[Certified](https://certified.app) is the identity provider built for the Hypercerts ecosystem. It provisions the full identity stack in a single sign-up: + +- **A DID** — your permanent identifier +- **A PDS** — your Personal Data Server, where records are stored +- **Low-friction sign-in** — email and code, no passwords or protocol knowledge required + +Certified exists because most Hypercerts users are not Bluesky users. Researchers, land stewards, open-source maintainers, and funders need an entry point that doesn't require knowledge of ATProto or decentralized protocols. Certified provides that — a neutral identity provider that isn't tied to any single application. + +### Handles (your public username) + +Handles are not needed to log in to the Hypercerts ecosystem, but every user has one. They serve as human-readable names for publicly addressing others and for interacting with other applications in the AT Protocol ecosystem that haven't implemented email-based login with Certified. Your handle (e.g., `alice.certified.app`) is human-readable but not permanent — it's a pointer to your DID. Organizations can use **custom domain handles** (e.g., `numpy.org`) to prove organizational identity through DNS verification. + +For setup details, see [Account & Identity Setup](/architecture/account-and-identity). + +## Compatible with Bluesky and other AT Protocol accounts + +{% callout type="note" %} +Hypercerts is fully interoperable with the AT Protocol ecosystem. If you already have a Bluesky account or any other ATProto identity, you can log in with your existing handle (e.g., `alice.bsky.social`) and use all Hypercerts applications — no additional account needed. +{% /callout %} + +## Wallet linkage + +To receive onchain funding, a DID needs to be linked to an onchain wallet address. This is handled by [**IdentityLink**](https://identitylink.vercel.app/) — a cryptographic attestation system that binds a DID to one or more onchain addresses via a signed proof stored in your PDS. For the Ethereum ecosystem this looks like: + +1. Authenticates the user via ATProto OAuth +2. Connects an EVM wallet (EOA, Smart Wallet, or Safe) +3. Signs an EIP-712 typed message proving ownership +4. Stores the attestation in the user's PDS + +The attestation is self-sovereign (stored in your PDS, not a central database) and verifiable by anyone. See the [Roadmap](/roadmap) for current IdentityLink status. + +## Next steps + +- [Account & Identity Setup](/architecture/account-and-identity) — create an account, configure custom domains, manage app passwords, and set up organization accounts +- [Architecture Overview](/architecture/overview) — how identity fits into the protocol stack +- [Quickstart](/getting-started/quickstart) — create your first hypercert + +Next: [Why AT Protocol?](/core-concepts/why-at-protocol) — how identity and records stay portable across apps. diff --git a/public/raw/core-concepts/common-use-cases.md b/public/raw/core-concepts/common-use-cases.md new file mode 100644 index 0000000..7d69700 --- /dev/null +++ b/public/raw/core-concepts/common-use-cases.md @@ -0,0 +1,49 @@ +--- +title: Common Use Cases +description: See how hypercerts work for different types of contributions. +--- + +# Common Use Cases + +Hypercerts work for any kind of impact work. This page shows four common scenarios and how they map to the hypercerts data model. + +## Open-source software maintenance + +A team maintains a widely-used library. They create a hypercert covering a year of maintenance — bug fixes, documentation updates, and community support. + +```typescript +const result = await agent.com.atproto.repo.createRecord({ + repo: agent.session.did, + collection: "org.hypercerts.claim.activity", + record: { + title: "Library maintenance, 2025", + shortDescription: "Ongoing maintenance of an open-source library", + description: "Fixed 47 bugs, reviewed 120 pull requests, updated documentation, and provided community support on Discord.", + workScope: { allOf: ["Software Development", "Open Source"] }, + startDate: "2025-01-01T00:00:00Z", + endDate: "2025-12-31T23:59:59Z", + $type: "org.hypercerts.claim.activity", + createdAt: new Date().toISOString(), + }, +}); +``` + +The team then attaches links to the repository, release notes, and commit history. Contribution records identify who did what — core developers, documentation leads, community managers. Organizations that depend on the library can fund this work retroactively. + +## Regenerative land stewardship + +A conservation group restores degraded forest over several years. The activity claim covers the full project timeline (2020–2025) with work scopes like "Ecosystem Restoration" and "Biodiversity Conservation". + +Measurement records track hectares restored, native species planted, and carbon sequestration estimates. Location records anchor the work geographically. Attachments include satellite imagery, biodiversity surveys, and field reports. Climate funders can review the full record before deciding to support the next phase. + +## Scientific research + +A research team completes a multi-year study and wants to document the effort with clear contributor roles. The activity claim describes the research and its outputs, with contribution records identifying the principal investigator, postdocs, and graduate students along with their relative contributions. + +Attachments link to published papers (via DOI), lab notebooks, and experimental protocols. Evaluation records capture peer review outcomes. Research foundations or industry partners interested in the field can fund the work. + +## Community event organization + +A group runs regular workshops teaching practical skills to underrepresented communities. They want to document their educational impact. The activity claim covers the full year of workshops with work scopes like "Education" and "Community Building". + +Measurement records track total attendees, completion rates, and outcomes. Contribution records identify instructors, venue hosts, and curriculum developers. Attachments include workshop materials and participant feedback. Organizations with community programs can review the record and decide to fund future sessions. diff --git a/public/raw/core-concepts/funding-and-value-flow.md b/public/raw/core-concepts/funding-and-value-flow.md new file mode 100644 index 0000000..8edfc92 --- /dev/null +++ b/public/raw/core-concepts/funding-and-value-flow.md @@ -0,0 +1,108 @@ +--- +title: "Funding & Value Flow" +description: How hypercerts track the funding of activities. +--- + +# Funding & Value Flow + +{% callout type="note" %} +Funding is under active development. +{% /callout %} + +Hypercerts track the funding of activities without prescribing how funds flow — any payment method and any funding mechanism works. + +What hypercerts add is a structured, verifiable record of who funded what. + +## Hypercerts work with any funding mechanism + +Funding can be **prospective** (before work begins) or **retroactive** (after outcomes are demonstrated). Different mechanisms suit different contexts, for example: + +| Mechanism | Description | +|-----------|-------------| +| **Grant funding** | Funders award grants to support planned activities | +| **Milestone-based funding** | Funds are released as work reaches defined milestones | +| **Prize competitions** | Awards for achieving specific outcomes | +| **Quadratic funding** | Small donations amplified through matching pools | +| **Sale of impact certificates** | Funders purchase certificates representing completed work | +| **Auction of impact certificates** | Competitive bidding on verified impact claims | + +Multiple mechanisms can coexist for the same activity — a project might receive a grant prospectively and sell impact certificates retroactively. Hypercerts tracks this accurately without double counting: every funding receipt references the specific activity claim it funds, making it possible to compute total funding per claim across all receipts. + +## Tracking funding + +{% callout type="note" %} +Funding tracking is in active development. Receipts and acknowledgements exist today. +{% /callout %} + +Hypercerts separate the *tracking* of funding from the *flow* of funds. Any existing payment infrastructure can work with hypercerts — the protocol simply records the fact that funding happened. + +The protocol tracks funding through the `org.hypercerts.funding.receipt` record. A funding receipt records who funded which activity, how much, and when — creating a verifiable funding trail. The receipt references the activity claim it funds, linking the funding record to the work it supports. + +Funding receipts are typically created by a **facilitator** — a payment processor, grant platform, funding app, or other intermediary that processes the payment and creates the receipt. The facilitator acts as a neutral third party, giving the receipt more credibility than a self-reported claim. + +| Scenario | Facilitator | Verification | +|----------|-------------|--------------| +| **Onchain funding** | A funding app verifies the transaction and creates the receipt, linking the transaction hash and chain ID | Verifiable onchain | +| **Card / bank transfer** | A payment processor settles the payment and creates the receipt | Trust in the processor | +| **Grant platform** | The grant platform records the award and creates the receipt on behalf of the funder | Trust in the platform | + +The funder or the contributor can then create an **acknowledgement** — a counter-signature confirming the receipt's accuracy — to strengthen its credibility. + +The protocol does not enforce that projects or funders disclose their funding — creating a receipt is voluntary. Funders can also choose to remain anonymous in the public record; a receipt can track a contribution without revealing the funder's identity. + +## Tokenization + +{% callout type="note" %} +Tokenization is under active development. This section describes the planned architecture. +{% /callout %} + +A hypercert can optionally be wrapped in an onchain token. This gives funders a programmable proof of their contribution. Tokenization is an optional wrapper around a claim snapshot; the canonical record remains the AT Protocol data. + +When locking is available, a claim can be frozen before tokenization. This gives funders a stronger guarantee — the claim they reviewed is exactly the claim they funded, and it cannot change after the fact. + +| Property | Detail | +|----------|--------| +| **Token standards** | ERC-20, ERC-1155, or custom — different standards on different chains | +| **Transferability** | Ranges from non-transferable recognition to fully transferable certificates | +| **Single-wrap constraint** | Every claim can only be wrapped in a token once, preventing double counting | +| **Rights** | Optional definition of the rights of the owners, set in the hypercert's `org.hypercerts.claim.rights` record | + +Tokenization enables programmable funding — smart contract logic can enforce distribution rules, matching formulas, and other mechanisms that would be difficult to coordinate offchain. + +## Example: from creation to funding + +There are many different flows that can be represented with hypercerts. Below is one example that follows a hypercert from creation to funding. + +### Stage 1 — Creation and evaluation + +Alice plants 500 trees in a reforestation project and creates an activity claim with measurements and attachments. Bob, an environmental auditor, evaluates the claim from his own PDS. See [Quickstart](/getting-started/quickstart) for a walkthrough. + +### Stage 2 — Funding + +Carol, a climate funder, reviews Alice's claim and Bob's evaluation. She decides to fund Alice's work through her organization's grant platform. The payment facilitator processes the payment and creates a funding receipt, recording Carol's contribution and referencing Alice's activity claim. + +| Record | Owner | +|--------|-------| +| Funding receipt | Payment facilitator | +| Acknowledgement | Alice or Carol | + +Either party can then create an acknowledgement — a counter-signature confirming the receipt's accuracy — to strengthen its credibility. + +### Stage 3 — Locking + +{% callout type="note" %} +Locking is planned but not yet implemented. +{% /callout %} + +Alice locks the claim, freezing it so its contents can't change. This gives future funders a guarantee — the claim they review is exactly the claim they'll be funding. + +### Stage 4 — Retroactive funding + +Two years later, Eve assesses the health of Alice's trees and publishes a positive evaluation. Grace, a climate funder focused on proven outcomes, sees the original claim, both evaluations, and Carol's earlier funding. She funds the project retroactively with a new funding receipt referencing the same activity claim. + + +## See also + +- [Architecture Overview](/architecture/overview) — how the full protocol stack fits together +- [Data Flow & Lifecycle](/architecture/data-flow-and-lifecycle) — how a hypercert moves through the system + diff --git a/public/raw/core-concepts/hypercerts-core-data-model.md b/public/raw/core-concepts/hypercerts-core-data-model.md new file mode 100644 index 0000000..f748b13 --- /dev/null +++ b/public/raw/core-concepts/hypercerts-core-data-model.md @@ -0,0 +1,106 @@ +--- +title: Core Data Model +description: The data model behind hypercerts — record types, dimensions, and how they connect. +--- + +# Core Data Model + +A hypercert is an [activity claim](/lexicons/hypercerts-lexicons/activity-claim) with linked records that describe work done. The activity claim is the anchor — contributions, attachments, measurements, and evaluations reference it to add context. + +This page explains what records exist, what they contain, and how they connect. + +## The core record: activity claim + +Every hypercert starts with an **activity claim** — the central record that answers four questions: + +| Dimension | Question | Example | +|-----------|----------|---------| +| **Contributors** | Who is doing (or did) the work? | Alice, Bob | +| **Work scope** | What are they doing (or what did they do)? | Documentation, Reforestation | +| **Time of work** | When is it happening (or when did it happen)? | January – March 2026 | +| **Location** | Where is it taking (or did it take) place? | Coastal Kenya | + +The activity claim gets a permanent AT-URI like `at://did:plc:alice123/org.hypercerts.claim.activity/3k7`. + +## Additional details + +The activity claim has a `contributors` array. Each entry is a contributor object with three fields: + +- **`contributorIdentity`** — either an inline identity object (`#contributorIdentity`, containing an `identity` DID string) or a strong reference to an `org.hypercerts.claim.contributorInformation` record with a full social profile +- **`contributionWeight`** — an optional relative weight string (e.g. `"1"`, `"0.5"`) +- **`contributionDetails`** — either an inline role object (`#contributorRole`, containing a `role` string) or a strong reference to an `org.hypercerts.claim.contribution` record with structured contribution data + +Simple cases use inline objects directly in the activity claim. Richer profiles use separate records that the contributor or project lead creates independently. + +| Record type | What it adds | Who creates it | Lexicon | +|-------------|-------------|----------------|---------| +| **Contributor Information** | Social profile, image, display name | The contributor or project lead | `org.hypercerts.claim.contributorInformation` | +| **Contribution** | Structured role and contribution data | The contributor or project lead | `org.hypercerts.claim.contribution` | + +## Records that attach to a hypercert + +Other records link to the activity claim to add context. Again, each is a separate record with its own AT-URI – they reference the activity claim, not the other way around. + +The following diagram shows record types and how they reference the activity claim. Records can be created by different people and live in different repositories. + +{% figure src="/images/hypercert-erd.svg" alt="Hypercert record relationships" /%} + +The diagram includes a **token** entity — tokenization (anchoring a hypercert onchain) is not yet implemented. + +| Record type | What it adds | Who creates it | Lexicon | +|-------------|-------------|----------------|---------| +| **Attachment** | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | `org.hypercerts.claim.attachment` | +| **Measurement** | Quantitative data — "12 pages written", "50 tons CO₂ reduced" | E.g. a third-party measurer or the project (self-reported) | `org.hypercerts.claim.measurement` | +| **Evaluation** | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | `org.hypercerts.claim.evaluation` | + +### Additional notes + +- Records don't have to be created together. Users can create a measurement first and link it to an activity claim later. +- A record can also be linked to multiple other records, e.g. a measurement in a bioregion is linked to multiple activity claims. +- An evaluator creates an evaluation from their own account — it references an activity claim but lives in their personal data server. + +This means a hypercert grows over time – it is a living record. The core claim stays the same, but attachments, measurements, and evaluations accumulate around it. + +## Grouping hypercerts + +Hypercerts can be grouped into **collections**. A multi-year project might have one hypercert per year, with a collection representing the full project. But collections are flexible — anyone can create one for any purpose. Someone might curate a personal collection of hypercerts they find interesting, or an organization might group all their hypercerts together. A hypercert can belong to many collections. + +| Record type | What it adds | Who creates it | Lexicon | +|-------------|-------------|----------------|---------| +| **Collection** | Groups activity claims and/or other collections into a project or portfolio. Supports recursive nesting. | E.g. the project organizer | `org.hypercerts.collection` | + +## How records connect + +Records reference each other using [strong references](/reference/glossary#strong-reference) — if a referenced record is modified after the reference was created, the change is detectable. + +```text +Activity Claim (the core record) +├── contributors[0] +│ ├── contributorIdentity: {identity: "did:plc:alice..."} (inline #contributorIdentity or ref to ContributorInformation) +│ ├── contributionWeight: "1" +│ └── contributionDetails: {role: "Lead author"} (inline #contributorRole or ref to Contribution) +├── contributors[1] +│ ├── contributorIdentity: → ContributorInformation record (Bob) +│ └── contributionDetails: → Contribution record (Technical reviewer, Jan-Mar) +├── Attachment: GitHub repository link +├── Measurement: 12 pages written +├── Measurement: 8,500 words +└── Evaluation: "High-quality documentation" (by Carol) +``` + + + +## Mutability + +Activity claims and their linked records are currently immutable once created. Record versioning and edit history will be supported in a future release, along with the ability to lock a hypercert at a specific version for funding. + + +## What happens next + +Once you understand the data model, you're ready to build: + +- **[Quickstart](/getting-started/quickstart)** — create your first activity claim +- **[Quickstart](/getting-started/quickstart)** — build a complete hypercert with all record types +- **[Lexicon reference](/lexicons/hypercerts-lexicons)** — field-by-field schema for every record type + +Next: [Certified Identity](/core-concepts/certified-identity) — who authors records and how signatures work. diff --git a/public/raw/core-concepts/what-is-hypercerts.md b/public/raw/core-concepts/what-is-hypercerts.md new file mode 100644 index 0000000..354e984 --- /dev/null +++ b/public/raw/core-concepts/what-is-hypercerts.md @@ -0,0 +1,69 @@ +--- +title: What are Hypercerts? +description: Living digital records of impact that help you track, share, and get recognized for the work you do. +--- + +# What are Hypercerts? + +A hypercert is a living record of impact work — a verifiable claim that grows as the creator and others add measurements, evaluations, and supporting evidence. + +Think of it like this: you do meaningful work — restoring a forest, maintaining open-source software, running a community program, publishing research. A hypercert captures that work in a structured, verifiable record. Over time, the creator and others enrich it with measurements and evaluations — making it more trustworthy and more useful for recognition and funding. + +## The structure of a hypercert + +At its core, a hypercert answers four questions: + +- **Who** is doing (or did) the work? +- **What** are they doing (or what did they do)? +- **When** is it happening (or when did it happen)? +- **Where** did it happen? (physical or digital) + +That's the starting point. From there, the record grows as people add more context: + +- **Attachments** — photos, links, datasets, documents, or descriptions that substantiate the work +- **Measurements** — quantitative indicators that make the impact concrete ("142 issues resolved", "50 hectares restored"), which can be outputs or outcomes depending on the domain +- **Evaluations** — independent qualitative or quantitative assessments from domain experts, community members, beneficiaries, etc. +- **Contributions** — additional information about who was involved and what they contributed +- **Rights** — what rights are attached to the hypercert (e.g. public display) + + + +## What a hypercert is not + +- **Not a grant application** — it records work that has been done or is in progress, not a request for funding +- **Not a token** — it's a data record, though onchain tokenization for funding is planned +- **Not a single document** — it’s a collection of linked records that can grow over time + +## How people use them + +**If you're doing the work**, you create a hypercert to make your contributions visible. Instead of writing reports that sit in a folder, you publish a verifiable record that any platform can display and build on. + +**If you're evaluating work**, you add your assessment to someone else's hypercert. Your evaluation lives on your own data server linking to their work. You build up reputation over time based on your assessments. + +**If you're funding work**, you can see the full picture before deciding: the original claim, the attachments behind it, and what independent evaluators think. Funding decisions can be based on verifiable records — not just narratives, wordy applications, and guessing. + +**If you're building a platform**, you can read and write hypercerts using shared schemas. A funding platform, a project dashboard, and an evaluation tool can all work with the same data. + +## An example + +Say a team runs a coastal reforestation project. They create a hypercert: + +> **Coastal mangrove restoration, 2025** +> +> 50 hectares restored over 12 months (the activity claim). Satellite imagery confirms canopy coverage. An independent ecologist evaluates the work as "high-quality restoration with strong community engagement." + +The activity claim is the starting record. Over the following months, the team adds measurement data as new satellite imagery comes in. An independent evaluator reviews the project and attaches their assessment. A funder browsing the ecosystem sees the full picture — the claim, the evidence, and the evaluation — and decides to support the next phase. + +## Why it's built this way + +Hypercerts are designed to live beyond any single platform. +This is why we built hypercerts on [AT Protocol](/core-concepts/why-at-protocol), a decentralized data layer that also powers Bluesky. This gives hypercerts some important properties: + +- **You own your data.** Your hypercerts live on your [Personal Data Server (PDS)](/architecture/overview) or on a hosted PDS of your choice, not on a single platform. +- **It's portable.** You can move your data to a different server anytime. No lock-in. +- **It's verifiable.** Every record is cryptographically signed. Anyone can check that it hasn't been tampered with. +- **It works everywhere.** Any app that speaks the Hypercerts protocol can read and display your records. Learn more in the [Architecture Overview](/architecture/overview). + +## Next step + +To see the records that make this work, read the [Core Data Model](/core-concepts/hypercerts-core-data-model). diff --git a/public/raw/core-concepts/why-at-protocol.md b/public/raw/core-concepts/why-at-protocol.md new file mode 100644 index 0000000..ababbe1 --- /dev/null +++ b/public/raw/core-concepts/why-at-protocol.md @@ -0,0 +1,38 @@ +--- +title: Why AT Protocol? +description: Why the Hypercerts Protocol is built on AT Protocol. +--- + +# Why AT Protocol? + +The Hypercerts Protocol is built on [AT Protocol](https://atproto.com/docs) — the same open protocol for decentralized data that powers Bluesky. + +In Hypercerts v0.1, every hypercert was an on-chain token — publishing one required a wallet, gas fees, and a blockchain transaction. This created friction for the contributors, researchers, and organizations the protocol is designed to serve. By moving the data layer to ATProto, creating a hypercert requires no wallet, no gas, and no transaction fees. On-chain anchoring is reserved for where it actually matters: funding and settlement. + +ATProto gives hypercerts three properties that matter for impact funding: portable data, shared schemas, and a trust graph rooted in cryptographic identity. + +## Portable, user-controlled data + +Contributions must outlive any single platform. + +Hypercert records are stored in signed user repositories hosted on Personal Data Servers (PDS). Each repository is cryptographically tied to a user's DID — not to the server hosting it. Contributors, evaluators, and funders choose where their data lives: on Hypercerts Foundation infrastructure, on third-party providers, or self-hosted. They can migrate at any time without losing records or needing anyone's permission. + +Applications are views over user-owned data — not gatekeepers of it. See [Portability & Data Access](/architecture/portability-and-scaling). + +## Shared schemas across applications + +For impact funding to work across applications, a contribution recorded in one app must be evaluable in another and fundable in a third — without bespoke integrations. + +ATProto enables this through [lexicons](/lexicons/introduction-to-lexicons): shared, namespaced schemas that define how records are structured. Because lexicons are open, any app can create compatible records and any app can read them. No bilateral API integrations required. + +Records reference each other via AT-URIs, forming a traversable graph: an evaluation references an activity claim, a funding receipt references both the claim and the funder. This graph is what indexers crawl to build queryable views. See [Indexers & Discovery](/architecture/indexers-and-discovery). + +## A decentralized trust graph + +ATProto provides persistent, portable identities via Decentralized Identifiers (DIDs). Every record carries its author's DID and cryptographic signature. Over time, these identities accumulate contribution records, evaluations, endorsements, and funding decisions — forming a durable impact trust graph that persists across platforms. + +Trust becomes computable across the ecosystem — not siloed within individual platforms. A funder can trace who evaluated a project, what else those evaluators have assessed, and how their past judgments correlated with outcomes. Because all records are signed and publicly indexable, trust models can be independently implemented, compared, and audited. + +## Data layer + ownership layer + +The design principle: keep rich, evolving contribution data off-chain (ATProto) and use on-chain systems only where immutability and settlement matter. ATProto handles the data layer — claims, attachments, evaluations, trust signals. On-chain anchoring and tokenization handle the funding layer — immutable snapshots, programmable funding, and settlement mechanisms. See [Architecture Overview](/architecture/overview) for how the layers fit together. diff --git a/public/raw/ecosystem/why-we-need-hypercerts.md b/public/raw/ecosystem/why-we-need-hypercerts.md new file mode 100644 index 0000000..cfe177a --- /dev/null +++ b/public/raw/ecosystem/why-we-need-hypercerts.md @@ -0,0 +1,180 @@ +--- +title: "Why We Need Hypercerts" +description: Recognizing and rewarding value creators. +--- + +# Why We Need Hypercerts + +## The Problem + +#### A Simple Observation + +Let's start with a simple observation: lots of the work that benefits us the most is funded the least. + +* We underfund digital public goods. +* We underfund the regenerative land projects that protect ecosystems and communities. +* We underfund high-risk, high-potential research that sits between academia and commercialization. +* We underfund investigative journalism and community-run events. + +In short: our economic system fails to recognize and reward what we collectively value. + +Because the people doing this work don't receive enough recognition or support, too few talented people pursue it, too few resources flow into it — and we end up far worse off than we could be. + +#### Why This Happens: We Confuse Price with Value + +Markets are extraordinary information systems. They take millions of individual decisions — what we buy, what we ignore, what we're willing to pay for — and compress them into a single signal: price. + +Price works beautifully for private goods: food, tools, cars, software services, consumer technology. These are things you buy for yourself, based on your individual preferences. + +But price fails systematically when it comes to collective goods. + +* If a forest is healthy, everyone benefits. +* If scientific knowledge increases, everyone benefits. +* If investigative journalism holds power accountable, everyone benefits. + +But because these benefits are shared, the willingness to pay for them isn't concentrated in any one person. And when benefits are diffuse, markets often go blind. Price easily sees private value, but it struggles to see collective value. + +Often, governments have been the approach we solve this. And in many cases, they still do: public education, healthcare systems, basic research funding, environmental regulation. + +But the systems we rely on today were built for a world that was: slower, simpler, more centralized, less data-rich, and far less interconnected. They were not designed for global supply chains, digital ecosystems, environmental instability, decentralized science, or community-run movements. + +And so we're left with a structural mismatch: + +* Markets don't recognize collective value well. +* Governments struggle to keep up with the pace and complexity of today's world. + +## The Shift We Need: Value Recognition Networks + +If our existing institutions struggle to recognize and reward collective value, we need systems that can. + +Not replacements for markets. Not replacements for governments. But a new layer that complements both — systems designed specifically to make collective value visible. + +We call these value recognition networks. + +Value recognition networks are systems built to do three things: + +1. Identify the work that contributes to a shared goal +2. Evaluate that work using data, expertise, and community insight +3. Recognize and fund the people and organizations doing it + +Until recently, building such systems would have been impractical: too much information to collect, too many evaluators to coordinate, too many data sources to integrate. But the technological foundations have changed. We now have the tools to make value recognition networks feasible. + +This also makes our contribution possible: The Hypercerts Protocol. + +Hypercerts provide a simple, interoperable way to structure claims about who did what, when, and where — and to attach the evidence and evaluations needed to make those claims meaningful. This evidence layer turns hypercerts from impact claims into impact certificates that can be held by both financial and non-financial contributors. + +With Hypercerts, we can begin building value recognition networks in practice. So what exactly are Hypercerts, and how do they work? + +## Hypercerts: A Common Language for Contributions + +#### What They Are + +At its core, a hypercert is a structured digital record of a contribution: who did what, when, and where. + +You can think of it as a small, standardized piece of information that captures a specific unit of work. A hypercert can represent: + +* a contribution to an open-source repository +* a regenerative land activity on a defined plot +* a research milestone in a scientific project +* a community event or educational program +* any action that creates positive impact + +Each hypercert links this claim with whatever attachments or context is available: documentation, measurements, expert assessments, community input, or other data that helps evaluate the contribution. + +Hypercerts don't judge whether something is valuable. They don't impose a single metric or worldview. They simply make contributions legible – to people, organizations, communities, and increasingly, AI systems. + +Once contributions are legible, many different actors can use the same underlying information to evaluate work, coordinate funding, reward contributors, and build trust. Hypercerts turn impact from something abstract and dispersed into something structured, portable, and usable across platforms. + +In short: a hypercert is a common language for describing contributions — a building block that other systems can rely on. + +#### What They Contain + +For hypercerts to support many funding mechanisms and evaluation models, each one needs a clear, consistent internal structure. + +A hypercert typically includes: + +1. Contribution Metadata: A structured description of who did what, when, and where. This anchors the contribution in time, space, and authorship. +2. Attachments: Links to documentation, measurements, reports, data, or other materials that help others understand and verify what happened. +3. Evaluations: Assessments from domain experts, peers, communities, or automated systems. These are not embedded inside the hypercert, but referenced — and they accumulate over time. +4. Attribution and Ownership: A record of who holds which share of the contribution, allowing both contributors and funders to prove their role in creating the result. + +This structure provides a standardized container that many different actors can build on. With clear components, hypercerts become the common language from which richer systems — funding platforms, evaluations, trust models, and AI agents — can emerge. + +## What Hypercerts Unlock + +With this foundation in place, hypercerts unlock a range of new possibilities — from funding mechanisms to evaluation systems and incentive models. + +#### 1. Collective Funding Mechanisms + +Because hypercerts are portable and interoperable, projects can raise resources in whatever way suits them: selling hypercerts directly on their own website, joining crowdfunding or retrofunding platforms, validating milestones or bounties, or using entirely new mechanism designs. + +Hypercerts do not dictate how funding works — they provide the shared structure that all these mechanisms can rely on. This shared structure makes it easy for builders to create new platforms without reinventing impact data, and it allows multiple funders to coordinate and pool resources around the same contributions. Different funders can support the same project through their own mechanisms while still operating on a common, verifiable foundation. + +Each impact domain can therefore develop funding approaches tailored to its specific needs — regenerative land projects, scientific research, open-source software, and community organizing all require different designs — while remaining fully interoperable through hypercerts. + +#### 2. Proof of Contributions + +Hypercert ownership gives funders and contributors a way to prove their role in creating impact: they hold a percentage of the resulting contribution, not just a record of how much money they spent. This moves recognition beyond inputs. Funding one project versus another can lead to vastly different outcomes, and hypercerts make this difference visible. + +This ability to demonstrate contribution matters to many stakeholders — employees who care about what their company stands for, industry groups coordinating voluntary standards, regulators assessing corporate claims, and even citizens evaluating whether governments allocate public resources effectively. When the value of a hypercert depends on demonstrated outcomes, all of these groups gain a clearer picture of whether resources were used well. + +This also means funders must care about the quality of the evaluations attached to the hypercerts they buy or reward. Poorly evaluated certificates may lose value later, making rigorous assessment in their own best interest. + +#### 3. Evaluations Become Essential + +These dynamics also reshape incentives for evaluators. Evaluators become central to the ecosystem, because their assessments directly influence how credible and valuable a hypercert becomes. They can be rewarded for adding meaningful insight — not for producing redundant or superficial reviews. For example, a fourth evaluation that simply repeats what three others already concluded adds little value; a fourth evaluation that challenges the earlier ones and ultimately proves correct is highly informative. Hypercert systems can reward this kind of insight directly. + +As a result, new business models for evaluators can emerge — from domain experts working independently, to community-driven review networks, to AI-assisted evaluators that help synthesize evidence and highlight inconsistencies. Evaluation becomes a meaningful, rewarded contribution in its own right, strengthening the quality of information across the entire ecosystem. + +#### 4. Fast Decisions, Iterative Feedback: How the System Improves Itself + +When the challenge is to fund many projects repeatedly at scale, as with regenerative land projects, funding decisions need to be fast. Contributors shouldn't be slowed down by heavy applications, or long decision cycles. Hypercerts make this possible: they provide enough structure for funders or automated systems to make quick, lightweight decisions without placing extra burden on projects. + +But fast decision-making alone isn't enough — it must be paired with a slower, deeper feedback loop that evaluates how good those decisions were. Over time, more evidence and more evaluations accumulate around each hypercert. This allows the ecosystem to assess which decisions were effective, which evaluators were accurate, and which mechanisms worked best. + +These two layers reinforce each other: + +* Fast loops enable projects to move forward without friction. +* Slow loops refine the system, improving future decisions. + +Together, they create a self-improving funding environment where learning compounds over time — without ever placing unnecessary load on the people doing the work. + +#### 5. Why AI Makes This Critical + +These incentive shifts become even more important as AI transforms fundraising and grantmaking. Today, most projects already use AI to write applications. Soon, most projects will have AI agents handling fundraising, and funders will use AI to filter and select proposals. In this world, every project will present a convincing narrative. Narrative advantage disappears. What remains meaningful is verifiable data: structured contributions, linked evidence, and transparent evaluation histories. Hypercerts provide exactly that substrate. + +Ultimately, the goal is simple: projects should be able to focus on doing impactful work, not on navigating complex application processes. When their contributions are captured clearly through hypercerts, the resources and recognition can flow to the people doing the work — without the administrative burden that holds so many back today. + +## Who Buys Hypercerts? + +The question that naturally arises is: who will actually buy hypercerts? In practice, several different groups already have strong reasons to do so, each for their own purpose. + +As they adopt hypercerts, many of them will need new decision-making processes and shared frameworks for allocating resources. Together, these emerging processes form what we can think of as collective funding institutions — new structures for deciding how we support work that benefits many. + +#### 1. Philanthropists and Foundations Who Want to Support Impact Directly + +Philanthropists, foundations, and mission-driven organizations buy hypercerts because they want their resources to create as much impact as possible. They aim to support effective work rather than persuasive narratives. Hypercerts give them a credible way to see which projects actually delivered outcomes, whether they are funding work prospectively by buying hypercerts or milestone commitments, or retroactively by rewarding projects whose value has already been demonstrated. + +Hypercerts also allow these funders to build a coherent, data-rich impact portfolio. Because every hypercert follows the same structure and can incorporate evaluations, evidence, and trust signals from many different sources, funders can analyze their portfolio across domains, compare results more consistently, and allocate resources toward the areas where they see the strongest demonstrated value. + +#### 2. Organizations That Need to Demonstrate Impact + +Companies, NGOs, research institutions, and philanthropic funds often need verifiable evidence of the outcomes they support — whether for employees, customers, partners, industry bodies, or regulators. Hypercerts provide portable, auditable proof of contributions across domains such as open-source software, scientific research, regenerative land stewardship, or community programs. They strengthen reporting, support compliance, and offer a consistent way to demonstrate responsibility and effectiveness. + +#### 3. Communities That Coordinate Funding Together + +Crowdfunding groups, DAOs, community funds, and citizen coalitions buy hypercerts to express collective priorities. Hypercerts give these communities a transparent, durable record of what they chose to support, enabling clear accountability and shared decision-making. Because hypercerts are open and portable, communities can coordinate funding without depending on a centralized platform or intermediary. + +#### 4. National and Local Governments That Prove How Public Resources Were Used + +Governments also have strong reasons to buy or hold hypercerts. They fund significant amounts of public-value work — from environmental restoration to digital infrastructure, scientific initiatives, and social programs. Hypercerts give governments a verifiable way to show how public resources were used and what outcomes were achieved. This supports transparency, improves procurement and grant making, strengthens performance-based budgeting, and gives citizens a clearer understanding of government effectiveness. + +## Where We're Headed + +We're building toward a world where: + +* Projects are less burdened — they can focus on doing impactful work instead of navigating complex applications and reporting cycles. +* Funders have better information — with structured contributions, evidence, and evaluations that support faster, more confident decisions. +* Evaluators are recognized and rewarded — with clear incentives and sustainable business models for producing high-quality assessments. + +This is the foundation for value recognition networks: systems that make collective value legible and reward the people who create it. diff --git a/public/raw/getting-started/building-on-hypercerts.md b/public/raw/getting-started/building-on-hypercerts.md new file mode 100644 index 0000000..62a7dc9 --- /dev/null +++ b/public/raw/getting-started/building-on-hypercerts.md @@ -0,0 +1,123 @@ +--- +title: Building on Hypercerts +description: A guide for platforms and tools that want to integrate the Hypercerts Protocol. +--- + +# {% $markdoc.frontmatter.title %} + +The Hypercerts Protocol is designed for third-party platforms, tools, and services to build on. + +## Who This Is For + +This guide is for: + +- **Funding platform developers** building crowdfunding, retroactive funding, or milestone-based payout systems +- **Evaluation service providers** creating tools for domain experts to assess impact +- **Dashboard and explorer builders** aggregating and visualizing hypercert data across the ecosystem +- **Impact portfolio managers** tracking funded contributions and their outcomes +- **AI and automation developers** building agents that create measurements, flag inconsistencies, or assist evaluators + +## What You Can Build + +### Funding Platforms + +Create platforms that use hypercerts to structure contributions and distribute funding. Examples include: + +- Retroactive funding rounds where evaluators assess completed work +- Milestone-based grant systems that release funds as work progresses +- Crowdfunding campaigns where backers receive fractional rights to impact claims +- Quadratic funding mechanisms that allocate matching pools based on community support + +### Evaluation Tools + +Build services that help domain experts create structured, verifiable evaluations: + +- Peer review systems for scientific contributions +- Impact assessment frameworks for climate projects +- Code quality analysis for open source software +- Educational outcome measurement for learning programs + +```javascript +// Example: Create an evaluation +const evaluation = await agent.com.atproto.repo.createRecord({ + repo: agent.session.did, + collection: "org.hypercerts.context.evaluation", + record: { + subject: { uri: claimUri, cid: claimCid }, + evaluators: [{ did: "did:plc:ragtjsm2j2vknwkz3zp4oxrd" }], + summary: "Scientific rigor and reproducibility assessment", + $type: "org.hypercerts.context.evaluation", + createdAt: new Date().toISOString(), + }, +}); +``` + +### Dashboards & Explorers + +Aggregate and display hypercerts across the ecosystem: + +- Portfolio views showing all claims by a contributor +- Leaderboards ranking projects by evaluation scores +- Impact maps visualizing geographic distribution of work +- Timeline views tracking contribution history + +Read-only integrations require only an indexer connection — no PDS needed. + +### Impact Portfolios + +Help funders track their contributions: + +- Aggregate all hypercerts a funder has supported +- Monitor evaluation updates for funded work +- Calculate portfolio-level impact metrics +- Generate reports for stakeholders + +### Automated Agents + +Build AI systems that participate in the ecosystem: + +- Measurement bots that extract metrics from attachments +- Consistency checkers that flag suspicious claims +- Evaluation assistants that help experts assess work +- Discovery agents that match funders with relevant projects + +## Running an Indexer + +To query hypercerts efficiently, run your own indexer: + +1. **Subscribe to the relay firehose** for hypercert lexicon records +2. **Parse and validate** incoming records against lexicon schemas +3. **Store in a queryable database** (PostgreSQL, MongoDB, etc.) +4. **Expose an API** for your application to query + +For relay subscription details, see the [ATProto documentation](https://atproto.com/specs/event-stream). + +## Interoperability Principles + +The ecosystem works because platforms follow shared conventions: + +### Use Standard Lexicons + +Use the standard `org.hypercerts.*` and `app.certified.*` lexicons for data that fits them — this is what makes your data interoperable across the ecosystem. Default indexers subscribe to these namespaces, so records using standard lexicons are automatically discoverable. If you need additional fields to extend the standard lexicons, create a [sidecar record](https://atproto.com/guides/lexicon-style-guide#design-patterns) that references the standard record via a strong reference. Since sidecars are likely application-specific, default indexers won't see them unless explicitly configured to index your namespace. + +You're also free to create new lexicons for use cases that don't fit the original schemas — ATProto is designed for this. + +### Use Strong References + +Always include CID when referencing records. The CID is a content hash of the record at the time you referenced it — if the record is later modified, the CID won't match, making tampering detectable. + +```javascript +// Good: includes CID +{ uri: "at://did:plc:abc/org.hypercerts.claim.activity/123", cid: "bafyreiabc..." } + +// Bad: URI only (no tamper-evidence) +{ uri: "at://did:plc:abc/org.hypercerts.claim.activity/123" } +``` + + +## Next Steps + +- Read the [Lexicons reference](/lexicons/introduction-to-lexicons) to understand the data model +- Explore the [Architecture overview](/architecture/overview) to see how components fit together +- Try the [Quickstart](/getting-started/quickstart) to create your first hypercert +- Join the community to discuss your integration plans diff --git a/public/raw/getting-started/quickstart.md b/public/raw/getting-started/quickstart.md new file mode 100644 index 0000000..9a4176e --- /dev/null +++ b/public/raw/getting-started/quickstart.md @@ -0,0 +1,354 @@ +--- +title: Quickstart +description: Create your first hypercert in under 5 minutes. +--- + +# Quickstart + +Create your first hypercert. This guide uses TypeScript and Node.js v20+. + +## Create an account + +[Sign up at certified.app](https://certified.app). This gives you an AT Protocol identity and a PDS where your data is stored. (Already have a Bluesky or other ATProto account? That works too.) + +## Install dependencies + +```bash +pnpm add @atproto/oauth-client-node @atproto/jwk-jose @atproto/api +``` + +{% callout type="info" %} +Building a React app? Use `@atproto/oauth-client-browser` instead, alongside `@tanstack/react-query` for data fetching and caching. +{% /callout %} + +## Authenticate + +Authentication uses AT Protocol OAuth. Your app needs a client metadata document hosted at a public URL: + +```typescript +import { NodeOAuthClient } from "@atproto/oauth-client-node"; +import { JoseKey } from "@atproto/jwk-jose"; +import { Agent } from "@atproto/api"; + +const client = new NodeOAuthClient({ + clientMetadata: { + client_id: "https://your-app.example.com/client-metadata.json", + client_name: "My App", + client_uri: "https://your-app.example.com", + redirect_uris: ["https://your-app.example.com/callback"], + grant_types: ["authorization_code", "refresh_token"], + scope: "atproto transition:generic", + response_types: ["code"], + application_type: "web", + token_endpoint_auth_method: "private_key_jwt", + token_endpoint_auth_signing_alg: "RS256", + dpop_bound_access_tokens: true, + jwks_uri: "https://your-app.example.com/jwks.json", + }, + keyset: await Promise.all([ + JoseKey.fromImportable(process.env.PRIVATE_KEY_1, "key1"), + JoseKey.fromImportable(process.env.PRIVATE_KEY_2, "key2"), + JoseKey.fromImportable(process.env.PRIVATE_KEY_3, "key3"), + ]), + stateStore: { /* ... your state store implementation */ }, + sessionStore: { /* ... your session store implementation */ }, +}); + +// Redirect the user to their PDS to authorize +const url = await client.authorize("alice.certified.app"); + +// After the user approves, exchange the callback params for a session +const { session } = await client.callback(new URLSearchParams(callbackQuery)); + +// Wrap the session in an Agent to make authenticated calls +const agent = new Agent(session); +``` + +See the [AT Protocol OAuth documentation](https://atproto.com/specs/oauth) for full details on client metadata, session storage, and keyset configuration. For further info on how to set up OAuth you can check out [AT Protos node.js implementation tutorial](https://atproto.com/guides/oauth-cli-tutorial) or the [scaffold app](/tools/scaffold). + +## Create your first hypercert + +The activity claim is the core record — it describes what work was done, when, and in what scope. Here's how each field maps to the [activity lexicon](/lexicons/hypercerts-lexicons/activity-claim): + +- **Contributors** are embedded directly in the activity claim as a `contributors` array. Each entry has a `contributorIdentity` (inline DID string, or a strong reference to a [`contributorInformation`](/lexicons/hypercerts-lexicons/contributor-information) record), an optional `contributionWeight`, and an optional `contributionDetails` (inline role string, or a strong reference to an [`org.hypercerts.claim.contribution`](/lexicons/hypercerts-lexicons/contribution) record for richer detail). +- **Work scopes** can be a simple free-form string (`{ scope: "Documentation" }`) or a structured [CEL expression](/core-concepts/work-scopes) for machine-evaluable queries across the network. +- **Time** is expressed as `startDate` and `endDate` in ISO 8601 format. +- **Locations** are separate [`app.certified.location`](/lexicons/certified-lexicons/location) records referenced from the activity claim. They support coordinates, GeoJSON, and other formats. + +```typescript +const result = await agent.com.atproto.repo.createRecord({ + repo: agent.did, + collection: "org.hypercerts.claim.activity", + record: { + $type: "org.hypercerts.claim.activity", + title: "NumPy documentation maintenance, Q1 2026", + shortDescription: "Updated API docs and fixed 15 broken examples.", + description: "Created 12 new documentation pages covering quickstart, use cases, evaluations, and architecture. Migrated from GitBook to a custom Next.js + Markdoc site.", + workScope: { + $type: "org.hypercerts.claim.activity#workScopeString", + scope: "Documentation", + }, + startDate: "2026-01-01T00:00:00Z", + endDate: "2026-03-31T23:59:59Z", + createdAt: new Date().toISOString(), + }, +}); + +console.log(result.data.uri); +// → at://did:plc:abc123/org.hypercerts.claim.activity/3k2j4h5g6f7d8s9a + +console.log(result.data.cid); +// → bafyreiabc123... +``` + +Each AT-URI is a permanent, globally unique identifier. Other records (evaluations, attachments, measurements) reference your hypercert using its URI. The CID is a content hash that makes references tamper-evident. Save both — you'll need them to link other records to this hypercert. See the [Activity Claim lexicon](/lexicons/hypercerts-lexicons/activity-claim) for the complete schema. + +## Add contributions + +Contributors are embedded directly in the activity claim's `contributors` array. Each entry uses inline identity and role objects: + +```typescript +const result = await agent.com.atproto.repo.createRecord({ + repo: agent.did, + collection: "org.hypercerts.claim.activity", + record: { + $type: "org.hypercerts.claim.activity", + title: "NumPy documentation maintenance, Q1 2026", + shortDescription: "Updated API docs and fixed 15 broken examples.", + workScope: { + $type: "org.hypercerts.claim.activity#workScopeString", + scope: "Documentation", + }, + startDate: "2026-01-01T00:00:00Z", + endDate: "2026-03-31T23:59:59Z", + contributors: [ + { + contributorIdentity: { + $type: "org.hypercerts.claim.activity#contributorIdentity", + identity: "did:plc:alice123", + }, + contributionWeight: "70", + contributionDetails: { + $type: "org.hypercerts.claim.activity#contributorRole", + role: "Lead author", + }, + }, + { + contributorIdentity: { + $type: "org.hypercerts.claim.activity#contributorIdentity", + identity: "did:plc:bob456", + }, + contributionWeight: "30", + contributionDetails: { + $type: "org.hypercerts.claim.activity#contributorRole", + role: "Technical reviewer", + }, + }, + ], + createdAt: new Date().toISOString(), + }, +}); +``` + +Each contributor entry has: +- `contributorIdentity` — inline `#contributorIdentity` with a DID string, or a strong reference to an `org.hypercerts.claim.contributorInformation` record +- `contributionWeight` — relative weight as a string (weights don't need to sum to 100) +- `contributionDetails` — inline `#contributorRole` with a role string, or a strong reference to an `org.hypercerts.claim.contribution` record for richer detail + +## Attach supporting documentation + +Attachments link supporting documents, reports, or URLs to any record. Create an attachment record that references the hypercert: + +```typescript +await agent.com.atproto.repo.createRecord({ + repo: agent.did, + collection: "org.hypercerts.context.attachment", + record: { + $type: "org.hypercerts.context.attachment", + subjects: [{ uri: result.data.uri, cid: result.data.cid }], + title: "Documentation site repository", + shortDescription: "Source code and content for the Hypercerts Protocol documentation.", + content: [ + { + $type: "org.hypercerts.defs#uri", + uri: "https://github.com/hypercerts-org/hypercerts-atproto-documentation", + }, + ], + createdAt: new Date().toISOString(), + }, +}); +``` + +The `subjects` field is an array of strong references (AT-URI + CID). The `content` field is an array of `org.hypercerts.defs#uri` objects (for URLs) or `org.hypercerts.defs#smallBlob` objects (for file uploads). You can create multiple attachment records — one for the repo, one for the deployed site, one for a methodology document, etc. + +## Add a measurement + +Measurements record quantitative data about the work. Create a measurement record that references the hypercert: + +```typescript +await agent.com.atproto.repo.createRecord({ + repo: agent.did, + collection: "org.hypercerts.context.measurement", + record: { + $type: "org.hypercerts.context.measurement", + subjects: [{ uri: result.data.uri, cid: result.data.cid }], + metric: "Documentation pages written", + value: "12", + unit: "pages", + startDate: "2026-01-01T00:00:00Z", + endDate: "2026-03-31T23:59:59Z", + methodType: "manual-count", + createdAt: new Date().toISOString(), + }, +}); +``` + +Required fields are `metric`, `value`, and `unit`. The `subjects` array links the measurement to your hypercert via strong references. You can attach multiple measurements to the same hypercert — one per metric. + +## Add an evaluation + +Evaluations are third-party assessments of the work. They reference the hypercert via a single `subject` strong reference and are typically created by someone other than the hypercert author: + +```typescript +await agent.com.atproto.repo.createRecord({ + repo: agent.did, + collection: "org.hypercerts.context.evaluation", + record: { + $type: "org.hypercerts.context.evaluation", + subject: { uri: result.data.uri, cid: result.data.cid }, + evaluators: [{ did: "did:plc:ragtjsm2j2vknwkz3zp4oxrd" }], + summary: "High-quality documentation with clear examples and thorough coverage.", + score: { min: 1, max: 5, value: 4 }, + content: [ + { + $type: "org.hypercerts.defs#uri", + uri: "https://example.com/evaluation-report.pdf", + }, + ], + createdAt: new Date().toISOString(), + }, +}); +``` + +Required fields are `evaluators`, `summary`, and `createdAt`. Unlike attachments and measurements, `subject` is a single strong reference (not an array). The optional `score` object takes integer `min`, `max`, and `value` fields. + +## What you've built + +Your hypercert now has a complete structure: + +```text +Activity Claim (the core record) +├── contributors[] (embedded) +│ ├── Alice — identity: did:plc:alice123, weight: 70, role: Lead author +│ └── Bob — identity: did:plc:bob456, weight: 30, role: Technical reviewer +├── Attachment: GitHub repository link ← strong reference (AT-URI + CID) +├── Measurement: 12 pages written ← strong reference (AT-URI + CID) +└── Evaluation: "High-quality documentation" (by Carol) ← strong reference (AT-URI + CID) +``` + +Contributors live inside the activity claim record itself. External records — attachments, measurements, evaluations — link to the activity claim via **strong references** (AT-URI + CID). The CID is a content hash: if the referenced record changes, the hash won't match, making the entire structure tamper-evident. + +This is the same pattern described in the [Core Data Model](/core-concepts/hypercerts-core-data-model#how-records-connect). As the hypercert grows over time, third parties can add measurements, evaluations, and more attachments — each as a separate record referencing your activity claim. + +## Create via the Scaffold App + +If you don't want to write code, the [Scaffold app](https://hypercerts-scaffold.vercel.app) lets you create a full hypercert through a guided wizard. Visit [hypercerts-scaffold.vercel.app](https://hypercerts-scaffold.vercel.app) to get started. + +### Step 1 — Sign in + +Enter your ATProto handle (e.g. `yourname.certified.app` or `yourname.bsky.social`) on the sign-in screen. You'll be redirected to your PDS to authorize the app. Once you approve, you'll land on the home screen with your DID and display name visible. + +![Scaffold sign-in screen showing handle input field](/images/scaffold/sign-in.png) +*Enter your ATProto handle to authenticate via OAuth.* + +### Step 2 — Basic info + +Click **"Create a new hypercert"** on the home screen (or go directly to [hypercerts-scaffold.vercel.app/hypercerts/create](https://hypercerts-scaffold.vercel.app/hypercerts/create)). This opens a multi-step wizard. The first step collects the core fields that form the `org.hypercerts.claim.activity` record on your PDS. + +![Hypercert creation form showing title, description, work scope, and date fields](/images/scaffold/create-cert.png) +*Step 1: Define the basic claim — what work was done, when, and in what scope.* + +| Field | Description | +|---|---| +| **Title** | A specific name for this piece of work. Be verbose — a project may have many hypercerts over time. Max 256 characters. Example: `NumPy documentation maintenance, Q1 2026`. | +| **Short description** | A 1–3 sentence summary suitable for card previews and list views. Max 300 characters. | +| **Description** | A longer narrative of what was done, by whom, and how. Supports rich text. Max 3,000 characters. | +| **Work scope** | One or more tags that precisely define what work is included. Multiple tags are conjunctive — e.g. `Trees` + `Germany` means only tree-planting in Germany. Leave empty for an unconstrained scope. | +| **Start date** | When the work began (ISO 8601). | +| **End date** | When the work ended (ISO 8601). | +| **Cover image** | An optional image for the hypercert card — URL or file upload. | +| **Rights Information** | Required information about the rights to this hypercert | +| **Contributors** *(optional)* | The people or organizations that did the work. Each contributor has an identity (DID or name), an optional relative weight, and an optional role description. You can add multiple contributors here or leave this empty. | + +### Step 3 — Add attachments + +Attach supporting documentation that backs up the claim — reports, URLs, files, or other references. Each attachment becomes an `org.hypercerts.context.attachment` record linked to your hypercert. + +![Evidence form for attaching supporting documentation](/images/scaffold/add-evidence.png) +*Step 2: Attach supporting documentation to back up the claim.* + +| Field | Description | +|---|---| +| **Title** | A label for this attachment. Max 256 characters. Example: `GitHub repository`. | +| **Attachment type** | The kind of attachment: `report`, `audit`, `evidence`, `testimonial`, `methodology`, etc. Max 64 characters. | +| **Short description** | A brief summary of what this attachment contains. Max 300 characters. | +| **Detailed description** | A detailed summary of what this attachment contains. (optional) | +| **Content** | One or more URLs or file uploads that make up the attachment. Max 100 items. | + +### Step 4 — Add location *(optional)* + +Optionally anchor the work geographically. This creates an `app.certified.location` record referenced from your hypercert. + +![Location form for adding geographic context](/images/scaffold/add-location.png) +*Step 3: Add location data to anchor the work geographically.* + +| Field | Description | +|---|---| +| **Name** | A human-readable place name. Example: `Amazon Basin, Brazil`. Max 100 characters. | +| **Location type** | The format of the location data: `coordinate-decimal`, `geojson`, `address`, `h3`, `geohash`, `wkt`, etc. | +| **Location Data** | The location data in the chosen format. Example for `coordinate-decimal`: `-3.47, -62.21`. | +| **Location Description** | Optional context about the location. Max 500 characters. | + +### Step 5 — Add measurements *(optional)* + +Add quantitative data that makes the impact concrete — metrics, values, units, and measurement methods. Each entry becomes an `org.hypercerts.context.measurement` record. + +![Measurement form for adding quantitative impact data](/images/scaffold/add-measurement.png) +*Step 4: Add measurements to quantify the impact.* + +| Field | Description | +|---|---| +| **Metric** | What is being measured. Example: `pages written`, `CO₂e avoided`, `users reached`. Max 500 characters. | +| **Value** | The measured numeric value. Example: `12`. | +| **Unit** | The unit of measurement. Example: `pages`, `kg CO₂e`, `hectares`, `count`. Max 50 characters. | +| **Start / end date** | The period during which this measurement was taken. | +| **Method type** | A short identifier for how it was measured. Example: `automated-count`, `manual-survey`. Max 30 characters. | +| **Method URI** | A link to the methodology documentation or standard protocol. | + +### Step 6 — Add evaluations *(optional)* + +Add third-party assessments of the work. Evaluations are authored by evaluators and can reference measurements. Each entry becomes an `org.hypercerts.context.evaluation` record. + +![Evaluation form for adding third-party assessments](/images/scaffold/add-evaluation.png) +*Step 5: Add evaluations from third-party assessors.* + +| Field | Description | +|---|---| +| **Evaluators** | DIDs or handles of the users who contributed to this evaluation | +| **Summary** | A brief written assessment of the work. Max 1,000 characters. Example: `High-quality documentation with clear examples and thorough coverage.` | +| **Score** *(optional)* | A numeric score on a defined scale. Set a minimum, maximum, and value — e.g. min 1, max 5, value 4. | +| **Content** *(optional)* | Links to detailed evaluation reports or methodology documents — URLs or file uploads. | +| **Measurement** *(optional)* | URI to the measurement tied to this evaluation. It can also be a normal URL. | + +### Step 7 — Done + +Your hypercert is now created and stored on your PDS. The completion screen shows the finalized record — copy the AT-URI to reference it from other records (attachments, measurements, evaluations) or to share it. + +![Completion screen showing the finished hypercert](/images/scaffold/finalized-cert.png) +*The hypercert is created and stored on your PDS.* + +For full details on the Scaffold app — including self-hosting, environment setup, and extending the codebase — see the [Scaffold app documentation](/tools/scaffold). + +## Next steps + +Third parties can now [evaluate your hypercert](/getting-started/working-with-evaluations) by creating evaluation records and measurements on their own PDS. diff --git a/public/raw/getting-started/testing-and-deployment.md b/public/raw/getting-started/testing-and-deployment.md new file mode 100644 index 0000000..abe9efc --- /dev/null +++ b/public/raw/getting-started/testing-and-deployment.md @@ -0,0 +1,164 @@ +--- +title: Testing & Deployment +description: Test your integration, understand record constraints, and go live with confidence. +--- + +# Testing & Deployment + +This page covers how to test your Hypercerts integration locally, the validation rules and constraints your records must satisfy, privacy considerations, and a checklist for going live. + +--- + +## Local development + +### Set up a test PDS + +Run a local PDS to avoid polluting production data. Self-host a test instance using the [ATProto PDS distribution](https://github.com/bluesky-social/pds) and follow the [ATProto self-hosting guide](https://atproto.com/guides/self-hosting). + +Point your ATProto client to the local instance instead of production: + +```typescript +import { AtpAgent } from "@atproto/api"; + +const agent = new AtpAgent({ service: "http://localhost:2583" }); // Local PDS +await agent.login({ + identifier: "test-user.test", + password: "test-password", +}); +``` + +### Use test identities + +Create dedicated test accounts — never use production identities for testing. When running a local PDS, you can create accounts with any handle. Each test identity gets its own DID and repository, isolating test data from production. + +### Create and verify a test record + +Create a record using the same `createRecord` call from the [Quickstart](/getting-started/quickstart), then read it back to confirm it was stored correctly. The returned CID is a content hash — if the record changes, the CID changes, which is how you verify data integrity. + +### Clean up test data + +Delete test records when you're done to keep your repository clean: + +```typescript +const uri = new URL(result.data.uri); +const rkey = uri.pathname.split("/").pop(); +await agent.com.atproto.repo.deleteRecord({ + repo: agent.session.did, + collection: "org.hypercerts.claim.activity", + rkey, +}); +``` + +Deletion removes the record from your PDS. Cached copies may persist in indexers temporarily. + +--- + +## Record constraints + +The PDS itself is schema-agnostic — it will accept any record with a valid `$type`. Validation against lexicon schemas happens downstream: indexers and app views ignore or reject malformed records, and client libraries may validate before submission. To ensure your records are indexed and usable across the ecosystem, they should conform to the lexicon schemas. + +### Required fields + +Every record type has required fields defined in its lexicon. Records missing required fields will be accepted by the PDS but ignored by indexers. See the [lexicon reference](/lexicons/hypercerts-lexicons) for required fields per record type. + +### Datetime format + +All datetime fields must use ISO 8601 format (e.g., `2026-01-15T00:00:00Z`). + +### Strong references + +When one record references another (e.g., an evaluation referencing an activity claim), the reference must include both the AT-URI and the CID. The CID is a content hash — if the referenced record is later modified, the CID won't match, making tampering detectable. If you need the current CID, fetch the record with `getRecord` before creating the reference. + +### String and array limits + +Lexicon schemas define maximum lengths for strings (in bytes and Unicode grapheme clusters) and arrays. Check the [lexicon reference](/lexicons/hypercerts-lexicons) for specific limits on each field. + +### Blob uploads + +Blobs (images, documents, attachment files) are uploaded to the PDS separately from records. Size limits depend on the PDS implementation — check your PDS documentation for exact values. + +{% callout type="note" %} +If your attachment files are too large for blob upload, store them externally (e.g., on IPFS or a public URL) and reference them by URI in the attachment record. +{% /callout %} + +### Common issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Missing required field | Record omits a field the lexicon marks as required | Include all required fields — see the [lexicon reference](/lexicons/hypercerts-lexicons) | +| Invalid datetime | Datetime not in ISO 8601 format | Use format: `2026-01-15T00:00:00Z` | +| Invalid strong reference | Reference missing `uri` or `cid` | Include both fields — fetch the latest CID if needed | +| String too long | String exceeds `maxLength` or `maxGraphemes` | Truncate or validate before submission | +| Array too long | Array exceeds `maxLength` | Reduce array size | +| Blob too large | File exceeds PDS size limit | Compress, split, or use external storage with a URI | + +--- + +## Rate limits + +PDS implementations impose rate limits on API requests. Specific limits vary by PDS — check your provider's documentation. If you hit a rate limit, retry with exponential backoff. + +--- + +## Privacy + +### Records are public by default + +{% callout type="warning" %} +All ATProto records are public. Anyone can read records from any PDS. Never store sensitive personal data in hypercert records. +{% /callout %} + +**Include in records:** +- Public work descriptions (e.g., "Planted 500 trees in Borneo") +- Aggregated impact metrics (e.g., "Reduced CO₂ by 50 tons") +- Public contributor identities (DIDs, handles) +- Links to public attachments (URLs, IPFS CIDs) + +**Keep off-protocol:** +- Personal contact information (email, phone, address) +- Proprietary methodologies or trade secrets +- Participant consent forms or private agreements +- Raw data containing PII (personally identifiable information) + +Store sensitive data in a private database and reference it by ID if needed. + +### Deletion and GDPR + +You can delete records from your PDS at any time. However: + +- Indexers (like Hyperindex) may cache records and take time to update +- Other users may have already fetched and stored copies +- The deletion event itself is visible in your repository history + +If you accidentally publish PII, delete the record immediately and contact indexer operators to request cache purging. + +--- + +## Authentication in production + +Use OAuth for production applications. OAuth lets users authorize your app without sharing credentials. See the [Quickstart](/getting-started/quickstart) for the authentication setup and the [ATProto OAuth spec](https://atproto.com/specs/oauth) for the full protocol details. + +Instead of using generic [transitional](https://atproto.com/specs/oauth#authorization-scopes) permission scopes like `transition:generic` use [granular scopes](https://atproto.com/specs/permission) as much as possible. Example: `repo:org.hypercerts.claim.activity?action=create&action=update`. + +--- + +## Going live checklist + +Before deploying to production: + +- [ ] **Tested record creation and retrieval** — Created and read back at least one hypercert successfully in a test environment. +- [ ] **Validated records against lexicon schemas** — All required fields present, datetimes in ISO 8601, strong references include both URI and CID. +- [ ] **Verified your DID and handle** — Confirmed your DID resolves correctly and your handle matches your intended identity. +- [ ] **Stored credentials securely** — No secrets in source code. Environment variables or secret management in production. +- [ ] **Reviewed records for accidental PII** — No sensitive personal data in any record fields. +- [ ] **Tested cross-PDS references** — If your app references records from other PDSs or repositories, verified those references resolve correctly. +- [ ] **Implemented error handling** — Your app handles validation errors, rate limits, and network failures gracefully. + +--- + +## See also + +- [Quickstart](/getting-started/quickstart) — create your first hypercert +- [Lexicon reference](/lexicons/hypercerts-lexicons) — field definitions and constraints for each record type +- [Architecture Overview](/architecture/overview) — how the protocol stack fits together, including the security model +- [Data Flow & Lifecycle](/architecture/data-flow-and-lifecycle) — how records move through the system diff --git a/public/raw/getting-started/working-with-evaluations.md b/public/raw/getting-started/working-with-evaluations.md new file mode 100644 index 0000000..613a777 --- /dev/null +++ b/public/raw/getting-started/working-with-evaluations.md @@ -0,0 +1,87 @@ +--- +title: Working with Evaluations +description: Learn how to evaluate hypercerts and build trust in the ecosystem. +--- + +# Working with Evaluations + +Evaluations are third-party assessments of hypercerts and other claims. They live on the evaluator's own PDS, not embedded in the original claim, and accumulate over time as different actors provide their perspectives. + +## Create an evaluation + +```typescript +import { AtpAgent } from "@atproto/api"; + +const agent = new AtpAgent({ service: "https://bsky.social" }); +await agent.login({ + identifier: "evaluator.certified.app", + password: "your-app-password", +}); + +// Create an evaluation of an activity claim +const evaluation = await agent.com.atproto.repo.createRecord({ + repo: agent.session.did, + collection: "org.hypercerts.claim.evaluation", + record: { + subject: { + uri: "at://did:plc:xyz789/org.hypercerts.claim.activity/3k2j4h5g6f7d8s9a", + cid: "bafyreiabc123...", + }, + evaluators: ["did:plc:evaluator123"], + summary: "Verified documentation updates. All 15 examples tested and working. High quality contribution with clear impact on developer experience.", + $type: "org.hypercerts.claim.evaluation", + createdAt: new Date().toISOString(), + }, +}); + +console.log(evaluation.data.uri); +``` + +The `subject` is a strong reference (AT-URI + CID) to the claim being evaluated. The `evaluators` array contains DIDs of those conducting the assessment. + +## Add measurements + +Measurements provide quantitative data that supports your evaluation: + +```typescript +const measurement = await agent.com.atproto.repo.createRecord({ + repo: agent.session.did, + collection: "org.hypercerts.claim.measurement", + record: { + subject: { + uri: "at://did:plc:xyz789/org.hypercerts.claim.activity/3k2j4h5g6f7d8s9a", + cid: "bafyreiabc123...", + }, + metric: "Documentation page views", + unit: "views", + value: "12500", + measurers: ["did:plc:evaluator123"], + methodType: "analytics", + methodURI: "https://example.com/analytics-methodology", + evidenceURI: ["https://example.com/analytics-report.pdf"], + comment: "Page view data collected over the first 30 days after publication.", + $type: "org.hypercerts.claim.measurement", + createdAt: new Date().toISOString(), + }, +}); +``` + +The `subject` field is a strong reference (AT-URI + CID) to the claim being measured. + +You can then reference this measurement in an evaluation's `measurements` array (an array of strong references) to link quantitative data to your assessment. + +## Evaluation patterns + +**Expert review:** Domain experts assess technical quality, methodology, and impact. Their DID becomes a portable credential — other projects can discover and trust evaluations from recognized experts. + +**Community assessment:** Multiple stakeholders provide independent evaluations. The diversity of evaluator DIDs creates a richer signal than any single assessment. + +**Automated evaluation:** Scripts and bots can publish evaluations based on API metrics, external data sources, or other programmatic checks. The evaluator DID identifies the automation system and its operator. + +## Trust and reputation + +Every evaluation is signed by its creator's DID, creating accountability. Unlike anonymous reviews, evaluators build portable reputation across the ecosystem. A DID with a history of rigorous, accurate evaluations becomes a trusted signal. Projects can filter evaluations by evaluator identity, weight them differently, or build custom trust graphs based on their values and domain expertise. + +{% callout type="note" %} +Evaluations are append-only. You can't delete someone else's evaluation of your work, and they can't delete yours. This creates a permanent, multi-perspective record of how claims are assessed over time. +{% /callout %} diff --git a/public/raw/index.md b/public/raw/index.md new file mode 100644 index 0000000..ead08ea --- /dev/null +++ b/public/raw/index.md @@ -0,0 +1,34 @@ +--- +title: Hypercerts Documentation +description: Documentation for the Hypercerts Protocol — structured, verifiable records of impact work built on AT Protocol. +--- + +# Hypercerts Protocol + +A hypercert is a structured, verifiable record of impact work — it captures who contributed, what they did, over what time period, and in what scope, along with measurements and supporting evidence. It's a living impact certificate — as evaluations, measurements, and new contributions are added, the record grows richer over time. + +## Get started + +{% card-grid %} +{% card-link title="Quickstart" href="/getting-started/quickstart" icon="" %} +Create your first hypercert in under 5 minutes +{% /card-link %} +{% card-link title="Building on Hypercerts" href="/getting-started/building-on-hypercerts" icon="" %} +Integration patterns for platforms and tools +{% /card-link %} +{% /card-grid %} + +## Core concepts + +{% card-grid %} +{% card-link title="What are Hypercerts?" href="/core-concepts/what-is-hypercerts" icon="" %} +The record structure and why it's built on ATProto +{% /card-link %} +{% card-link title="Core Data Model" href="/core-concepts/hypercerts-core-data-model" icon="" %} +Record types, dimensions, and how they connect +{% /card-link %} +{% card-link title="Why AT Protocol?" href="/core-concepts/why-at-protocol" icon="" %} +Why the protocol is built on AT Protocol +{% /card-link %} +{% /card-grid %} + diff --git a/public/raw/lexicons/certified-lexicons.md b/public/raw/lexicons/certified-lexicons.md new file mode 100644 index 0000000..35a58c1 --- /dev/null +++ b/public/raw/lexicons/certified-lexicons.md @@ -0,0 +1,17 @@ +--- +title: Certified Lexicons +description: Lexicon reference for Certified identity records — profiles, locations, and badges. +--- + +# Certified Lexicons + +These lexicons live in the `app.certified` namespace. They provide shared data structures for identity, profiles, badges, and location — building blocks that other, more specialized lexicons can reference. + +| Lexicon | NSID | Description | +|---------|------|-------------| +| **[Shared Definitions](/lexicons/certified-lexicons/shared-defs)** | `app.certified.defs` | Common type definitions: the `did` type | +| **[Location](/lexicons/certified-lexicons/location)** | `app.certified.location` | Geographic location representation using the Astral Location Protocol | +| **[Profile](/lexicons/certified-lexicons/profile)** | `app.certified.actor.profile` | Account profile with display name, description, avatar, and banner | +| **[Badge Definition](/lexicons/certified-lexicons/badge-definition)** | `app.certified.badge.definition` | Defines a badge type with title, icon, and optional issuer allowlist | +| **[Badge Award](/lexicons/certified-lexicons/badge-award)** | `app.certified.badge.award` | Awards a badge to a user, project, or activity claim | +| **[Badge Response](/lexicons/certified-lexicons/badge-response)** | `app.certified.badge.response` | Recipient accepts or rejects a badge award | diff --git a/public/raw/lexicons/certified-lexicons/badge-award.md b/public/raw/lexicons/certified-lexicons/badge-award.md new file mode 100644 index 0000000..f29ce85 --- /dev/null +++ b/public/raw/lexicons/certified-lexicons/badge-award.md @@ -0,0 +1,16 @@ +--- +title: Badge Award +description: Lexicon reference for the Badge Award record type in Certified. +--- + +# Badge Award + +`app.certified.badge.award` + +Awards a badge to a user, project, or activity claim. Each award references a badge definition and a subject — either an account DID (for user badges) or a strong reference to a specific record like an activity claim (for project or work badges). + +Badge awards can include an optional note explaining why the badge was given. This creates a public record of recognition that can be verified by anyone. + +Recipients can respond to badge awards using the badge response lexicon, allowing them to accept or reject badges and assign relative weights to accepted badges. This enables consent-based recognition where recipients have control over what badges appear on their profile. + +For the full schema, see [`app.certified.badge.award`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/app/certified/badge/award.json) in the lexicon repo. diff --git a/public/raw/lexicons/certified-lexicons/badge-definition.md b/public/raw/lexicons/certified-lexicons/badge-definition.md new file mode 100644 index 0000000..0a90dc6 --- /dev/null +++ b/public/raw/lexicons/certified-lexicons/badge-definition.md @@ -0,0 +1,16 @@ +--- +title: Badge Definition +description: Lexicon reference for the Badge Definition record type in Certified. +--- + +# Badge Definition + +`app.certified.badge.definition` + +Defines a badge that can be awarded to users, projects, or activity claims. Each badge definition includes a title, description, icon, and badge type (like endorsement, participation, or affiliation). + +Badge definitions can optionally specify an allowlist of DIDs that are permitted to issue the badge. If no allowlist is provided, anyone can create badge awards using this definition. This enables both open badges (where anyone can award them) and restricted badges (where only specific issuers are authorized). + +Once created, a badge definition can be referenced by multiple badge award records. This separation allows the badge's visual identity and meaning to be defined once and reused many times. + +For the full schema, see [`app.certified.badge.definition`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/app/certified/badge/definition.json) in the lexicon repo. diff --git a/public/raw/lexicons/certified-lexicons/badge-response.md b/public/raw/lexicons/certified-lexicons/badge-response.md new file mode 100644 index 0000000..cf427f3 --- /dev/null +++ b/public/raw/lexicons/certified-lexicons/badge-response.md @@ -0,0 +1,16 @@ +--- +title: Badge Response +description: Lexicon reference for the Badge Response record type in Certified. +--- + +# Badge Response + +`app.certified.badge.response` + +A recipient's response to a badge award. Recipients can accept or reject badges, and can optionally assign a relative weight to accepted badges to indicate their importance or relevance. + +Badge responses are created in the recipient's own repository, making them independently verifiable. This enables consent-based recognition — rather than assuming that receiving a badge implies acceptance, responses make consent explicit. + +The weight field allows recipients to curate their badge display, emphasizing badges they consider most significant. Applications can use these weights to determine how prominently to display different badges on a user's profile. + +For the full schema, see [`app.certified.badge.response`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/app/certified/badge/response.json) in the lexicon repo. diff --git a/public/raw/lexicons/certified-lexicons/location.md b/public/raw/lexicons/certified-lexicons/location.md new file mode 100644 index 0000000..18bd437 --- /dev/null +++ b/public/raw/lexicons/certified-lexicons/location.md @@ -0,0 +1,14 @@ +--- +title: Location +description: Lexicon reference for the Location record type in Certified. +--- + +# Location + +`app.certified.location` + +A location record implementing the [Astral Location Protocol](https://spec.decentralizedgeo.org/) — a standardized framework for creating, sharing, and verifying location information in decentralized systems. This lexicon is the ATProto implementation of that spec. + +Locations can be represented in multiple formats: decimal coordinates, GeoJSON, H3 indices, geohashes, etc. Each record includes a Spatial Reference System (SRS) URI so coordinate values are unambiguous. See the [location type registry](https://spec.decentralizedgeo.org/specification/location-types/#location-type-registry) for the full list of supported formats. + +For the full schema, see [`app.certified.location`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/app/certified/location.json) in the lexicon repo. diff --git a/public/raw/lexicons/certified-lexicons/profile.md b/public/raw/lexicons/certified-lexicons/profile.md new file mode 100644 index 0000000..23de427 --- /dev/null +++ b/public/raw/lexicons/certified-lexicons/profile.md @@ -0,0 +1,12 @@ +--- +title: Profile +description: Lexicon reference for the Profile record type in Certified. +--- + +# Profile + +`app.certified.actor.profile` + +A user profile in the Certified ecosystem. This is a singleton record — each account has exactly one, stored with the key `self`. Includes display name, avatar, banner image, description, website URL, and pronouns. + +For the full schema, see [`app.certified.actor.profile`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/app/certified/actor/profile.json) in the lexicon repo. diff --git a/public/raw/lexicons/certified-lexicons/shared-defs.md b/public/raw/lexicons/certified-lexicons/shared-defs.md new file mode 100644 index 0000000..0ea0823 --- /dev/null +++ b/public/raw/lexicons/certified-lexicons/shared-defs.md @@ -0,0 +1,14 @@ +--- +title: Shared Definitions +description: Reusable type definitions shared across Certified lexicons. +--- + +# Shared Definitions + +`app.certified.defs` + +Common type definitions used across the certified ecosystem. Currently defines the `did` type, which represents a Decentralized Identifier. + +The `did` type is used throughout the certified and hypercerts lexicons to reference accounts and actors. It ensures consistent formatting and validation of DIDs across all record types. + +For the full schema, see [`app.certified.defs`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/app/certified/defs.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons.md b/public/raw/lexicons/hypercerts-lexicons.md new file mode 100644 index 0000000..1d0a84b --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons.md @@ -0,0 +1,20 @@ +--- +title: Hypercerts Lexicons +description: Lexicon reference for Hypercerts record types — activity claims, contributions, evaluations, and more. +--- + +# Hypercerts Lexicons + +These lexicons define the record types for tracking impact work in the `org.hypercerts` namespace. The **activity claim** is the central record — all other types attach to it. + +| Lexicon | NSID | Description | +|---------|------|-------------| +| **[Activity Claim](/lexicons/hypercerts-lexicons/activity-claim)** | `org.hypercerts.claim.activity` | The core hypercert record — who did what, when, where | +| **[Contribution](/lexicons/hypercerts-lexicons/contribution)** | `org.hypercerts.claim.contributorInformation`
`org.hypercerts.claim.contribution` | Contributor identity and contribution details (two lexicons) | +| **[Attachment](/lexicons/hypercerts-lexicons/attachment)** | `org.hypercerts.context.attachment` | Supporting documentation — URLs, files, IPFS links | +| **[Measurement](/lexicons/hypercerts-lexicons/measurement)** | `org.hypercerts.context.measurement` | Quantitative data attached to a claim | +| **[Evaluation](/lexicons/hypercerts-lexicons/evaluation)** | `org.hypercerts.context.evaluation` | Third-party assessment of a claim | +| **[Collection](/lexicons/hypercerts-lexicons/collection)** | `org.hypercerts.collection` | Groups activity claims and/or other collections into a project | +| **[Rights](/lexicons/hypercerts-lexicons/rights)** | `org.hypercerts.claim.rights` | Rights associated with a hypercert | +| **[Funding Receipt](/lexicons/hypercerts-lexicons/funding-receipt)** | `org.hypercerts.funding.receipt` | Records a funding payment from one party to another | +| **[Acknowledgement](/lexicons/hypercerts-lexicons/acknowledgement)** | `org.hypercerts.context.acknowledgement` | Acceptance or rejection of a relationship | diff --git a/public/raw/lexicons/hypercerts-lexicons/acknowledgement.md b/public/raw/lexicons/hypercerts-lexicons/acknowledgement.md new file mode 100644 index 0000000..adae159 --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/acknowledgement.md @@ -0,0 +1,55 @@ +--- +title: Acknowledgement +description: Lexicon reference for the Acknowledgement record type in Hypercerts. +--- + +# Acknowledgement + +`org.hypercerts.context.acknowledgement` + +## Definition + +An acknowledgement is a record expressing acceptance or rejection of a relationship. For example, a contributor might acknowledge their inclusion in an activity claim, or a funder might confirm a funding receipt. + +Acknowledgements are created in the acknowledging actor's own repository, making them independently verifiable. Each acknowledgement references the record being acknowledged, specifies whether it's accepted or rejected, and can include an optional note explaining the decision. + +This enables consent-based relationships in the hypercerts ecosystem. Rather than assuming that being listed as a contributor or funder implies agreement, acknowledgements make consent explicit and auditable. They also enable dispute resolution — if someone is incorrectly listed, they can create a rejection acknowledgement. + +## Use case: contributor acknowledges inclusion in an activity + +Alice creates an activity claim about her research project and lists Einstein as a contributor. Einstein needs to confirm he actually participated — otherwise anyone could claim he worked on their project. + +1. Alice creates an `org.hypercerts.claim.activity` record on her PDS, listing Einstein in the `contributors` array +2. Einstein sees he's been listed (via an indexer or notification) +3. Einstein creates an `org.hypercerts.context.acknowledgement` on **his own PDS** with: + - `subject` → strong reference to Alice's activity claim + - `acknowledged` → `true` + - `comment` → `"Confirming my role as theoretical physics advisor"` + +If Einstein never actually contributed, he'd set `acknowledged` to `false` instead — creating a visible rejection that indexers and applications can surface. No more claiming Einstein co-authored your term paper. + +## Use case: funder confirms a funding receipt + +A grant platform creates a funding receipt recording that Funder X contributed $5,000 to a project. Funder X wants to confirm the receipt is accurate. + +1. The platform creates an `org.hypercerts.funding.receipt` record +2. Funder X creates an `org.hypercerts.context.acknowledgement` on their own PDS with: + - `subject` → strong reference to the funding receipt + - `acknowledged` → `true` + - `comment` → `"Confirmed — payment processed via our grants program"` + +If the amount or details were wrong, the funder sets `acknowledged` to `false` with a comment explaining the discrepancy. + +## Use case: rejecting an evaluation + +A project lead disagrees with an evaluation of their work and wants to flag it. + +1. An evaluator creates an `org.hypercerts.context.evaluation` referencing the project's activity claim +2. The project lead creates an acknowledgement with: + - `subject` → strong reference to the evaluation + - `acknowledged` → `false` + - `comment` → `"This evaluation references outdated data — see our updated measurements"` + +The rejection doesn't delete the evaluation — it creates a counter-signal that applications can use to present both sides. + +For the full schema, see [`org.hypercerts.context.acknowledgement`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/context/acknowledgement.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/activity-claim.md b/public/raw/lexicons/hypercerts-lexicons/activity-claim.md new file mode 100644 index 0000000..bd91558 --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/activity-claim.md @@ -0,0 +1,16 @@ +--- +title: Activity Claim +description: Lexicon reference for the Activity Claim record type — the core record of a hypercert. +--- + +# Activity Claim + +`org.hypercerts.claim.activity` + +The activity claim is the core hypercert record — the anchor point for all impact tracking. It represents a durable, referenceable statement that a clearly bounded piece of work is planned, ongoing, or completed. + +An activity claim defines work using four core dimensions: who performed it, what was done, when it happened, and where it took place. By making work precisely scoped and inspectable, activity claims become stable reference points that others can build on. Contributions, attachments, measurements, evaluations, and funding receipts all reference back to an activity claim. + +The activity claim supports rich descriptions with text formatting, cover images, contributor lists with weights and roles, work scope definitions, time ranges, location references, and rights declarations. It's designed to be flexible enough to represent everything from open-source software maintenance to forest stewardship to research projects. + +For the full schema, see [`org.hypercerts.claim.activity`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/claim/activity.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/attachment.md b/public/raw/lexicons/hypercerts-lexicons/attachment.md new file mode 100644 index 0000000..290d67a --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/attachment.md @@ -0,0 +1,14 @@ +--- +title: Attachment +description: Lexicon reference for the Attachment record type in Hypercerts. +--- + +# Attachment + +`org.hypercerts.context.attachment` + +An attachment links supporting documentation to one or more existing records. It can reference files, documents, external URIs, or IPFS content, and can attach to any record type via strong references. + +Attachments are useful for providing evidence, documentation, or additional context for hypercerts. For example, you might attach a research paper to an activity claim, link a GitHub repository to a software project, or include photos documenting environmental work. Each attachment includes a title, optional description, the URI or content reference, and an array of strong references to the records it supports. + +For the full schema, see [`org.hypercerts.context.attachment`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/context/attachment.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/collection.md b/public/raw/lexicons/hypercerts-lexicons/collection.md new file mode 100644 index 0000000..13a08af --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/collection.md @@ -0,0 +1,14 @@ +--- +title: Collection +description: Lexicon reference for the Collection record type in Hypercerts. +--- + +# Collection + +`org.hypercerts.collection` + +A collection groups activity claims into a named set. A single hypercert can belong to multiple collections at the same time — for example, one collection representing a multi-year reforestation program, another curating a funder's portfolio, and a personal "favorites" list. Collections make it easy to organize and surface hypercerts in different contexts without duplicating data. + +Each collection has a title, description, and an array of strong references to the claims it contains. + +For the full schema, see [`org.hypercerts.collection`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/collection.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/contribution.md b/public/raw/lexicons/hypercerts-lexicons/contribution.md new file mode 100644 index 0000000..1198825 --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/contribution.md @@ -0,0 +1,85 @@ +--- +title: Contribution +description: Lexicon reference for the Contribution record type in Hypercerts. +--- + +# Contribution + +This page covers two related lexicons that work together to represent contributors and their contributions. + +## Contributor Information + +`org.hypercerts.claim.contributorInformation` + +Stores identity information for a contributor: display name, identifier (like a GitHub username or email), and an optional profile image. This record can be created once and referenced from multiple activity claims, making it easy to maintain consistent contributor identity across projects. + +A contributor doesn't need a full `contributorInformation` record. The activity claim's `contributors` array accepts either a strong reference to a `contributorInformation` record or an inline identity string (typically a DID). Use the inline form for simple cases; use the record when you want a reusable profile with a display name and image. + +For the full schema, see [`org.hypercerts.claim.contributorInformation`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/claim/contributorInformation.json) in the lexicon repo. + +## Contribution + +`org.hypercerts.claim.contribution` + +Stores details about a specific contribution, including the contributor's role, a description of what they did, and the timeframe of their work. Like contributor identity, contribution details can be provided inline (as a role string) or as a strong reference to a separate record. + +The activity claim's `contributors` array also supports contribution weights to indicate relative effort or impact. + +## Choosing contribution weights + +Weights are always proportional. The protocol stores them as strings and does not enforce any particular calculation method. How you arrive at the numbers is up to you. The following are just examples — pick whatever approach fits your project, or invent your own. + +### Equal split + +Every contributor gets weight `"1"`. Works well for collaborative work where contributions are hard to separate, or small teams where everyone contributed roughly equally. + +Example: 4 contributors each with `contributionWeight: "1"` + +### Role-based multipliers + +Assign a base multiplier per role: + +| Role | Weight | +|------|--------| +| Lead/Creator | 6 | +| Core contributor | 4 | +| Reviewer/Advisor | 2 | +| Minor contributor | 1 | + +Example: Lead author `"6"`, two core contributors `"4"` each, one reviewer `"2"`, one minor contributor `"1"` + +### Activity-based (git signals) + +Derive weights from repository data: commits, lines changed, PRs merged, issues closed. + +Caveat: biased toward code-heavy contributions; does not capture design, coordination, or review work well. + +Example: Alice (450 commits) `"45"`, Bob (350 commits) `"35"`, Carol (200 commits) `"20"` + +### Peer assessment + +Each contributor receives a fixed budget of points (e.g. 100) to distribute among peers (not themselves). Final weight = total points received. + +Caveat: requires active participation from all contributors. + +Example: After a round, Alice receives 140 points → `"140"`, Bob receives 90 → `"90"`, Carol receives 70 → `"70"` + +### Outcome-based + +Weight by measurable deliverables: features shipped, milestones hit, KPIs moved. + +Caveat: hardest to quantify fairly; risk of rewarding easily-measured work over important-but-hard-to-measure work. + +Example: Alice delivered 3 milestones → `"3"`, Bob delivered 1 → `"1"` + +### Composite + +Combine multiple signals — for example, mix role-based multipliers with peer assessment scores. Weight each signal by how much it should matter, then add them up. + +Example: A team weights roles at 40% and peer scores at 60%. Alice (lead, peer score 140) gets `"57"`, Bob (core, peer score 90) gets `"55"`, Carol (core, peer score 70) gets `"43"`. + +{% callout type="note" %} +Weights are stored as strings and do not need to sum to any particular value. These examples all produce relative values — what matters is the ratio between contributors, not the absolute numbers. +{% /callout %} + +For the full schema, see [`org.hypercerts.claim.contribution`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/claim/contribution.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/evaluation.md b/public/raw/lexicons/hypercerts-lexicons/evaluation.md new file mode 100644 index 0000000..b0b4ddc --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/evaluation.md @@ -0,0 +1,14 @@ +--- +title: Evaluation +description: Lexicon reference for the Evaluation record type in Hypercerts. +--- + +# Evaluation + +`org.hypercerts.context.evaluation` + +An evaluation is a structured assessment of a hypercert or other record. Third parties — auditors, peer reviewers, grant programs — use evaluations to assess whether claimed work actually happened and had the stated impact. It includes the evaluator's DID, a summary of their assessment, an optional numeric score, and can reference measurements that informed the evaluation. + +An evaluation can reference multiple records (for example, assessing a collection and all its constituent claims), and can cite specific measurements as evidence. This creates a traceable chain from raw data through measurements to final assessments. + +For the full schema, see [`org.hypercerts.context.evaluation`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/context/evaluation.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/funding-receipt.md b/public/raw/lexicons/hypercerts-lexicons/funding-receipt.md new file mode 100644 index 0000000..07f2da6 --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/funding-receipt.md @@ -0,0 +1,16 @@ +--- +title: Funding Receipt +description: Lexicon reference for the Funding Receipt record type in Hypercerts. +--- + +# Funding Receipt + +`org.hypercerts.funding.receipt` + +A funding receipt records a funding payment from one party to another. It's typically created by a facilitator or funding platform, but can be created by either the funder or recipient. + +Each receipt includes the funder's DID, the recipient's DID, the amount and currency, the payment rail used (like bank transfer, crypto, or grant platform), and an optional transaction ID for verification. Receipts can reference the activity claims or collections they fund, creating a traceable link from funding to impact work. + +Funding receipts enable transparent funding tracking and make it possible to see who funded what work. They're designed to be simple and flexible enough to represent everything from traditional grants to crypto payments to in-kind contributions. + +For the full schema, see [`org.hypercerts.funding.receipt`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/funding/receipt.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/measurement.md b/public/raw/lexicons/hypercerts-lexicons/measurement.md new file mode 100644 index 0000000..db47a1e --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/measurement.md @@ -0,0 +1,14 @@ +--- +title: Measurement +description: Lexicon reference for the Measurement record type in Hypercerts. +--- + +# Measurement + +`org.hypercerts.context.measurement` + +A measurement records a single quantitative data point related to a hypercert or other record. It captures what was measured (the metric), the unit of measurement, the measured value, and when the measurement was taken. + +Measurements support methodology traceability through optional fields for method type, method URI (linking to a detailed methodology), and evidence URIs (linking to raw data or supporting documentation). This makes measurements auditable and reproducible. + +For the full schema, see [`org.hypercerts.context.measurement`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/context/measurement.json) in the lexicon repo. diff --git a/public/raw/lexicons/hypercerts-lexicons/rights.md b/public/raw/lexicons/hypercerts-lexicons/rights.md new file mode 100644 index 0000000..e73c074 --- /dev/null +++ b/public/raw/lexicons/hypercerts-lexicons/rights.md @@ -0,0 +1,12 @@ +--- +title: Rights +description: Lexicon reference for the Rights record type in Hypercerts. +--- + +# Rights + +`org.hypercerts.claim.rights` + +Describes the rights associated with a hypercert — whether it can be sold, transferred, and under what conditions. Rights are defined as a separate record and referenced from an activity claim, so the same rights definition can be reused across multiple claims. + +For the full schema, see [`org.hypercerts.claim.rights`](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/lexicons/org/hypercerts/claim/rights.json) in the lexicon repo. diff --git a/public/raw/lexicons/introduction-to-lexicons.md b/public/raw/lexicons/introduction-to-lexicons.md new file mode 100644 index 0000000..dfa621f --- /dev/null +++ b/public/raw/lexicons/introduction-to-lexicons.md @@ -0,0 +1,18 @@ +--- +title: Introduction to Lexicons +description: Understand lexicons — the shared schemas that define record types in the Hypercerts Protocol. +--- + +# Introduction to Lexicons + +## What is a lexicon? + +An ATProto lexicon is essentially a schema or template that defines what data can be stored and how it should be structured. Think of it like a form with specific fields - it tells you what information is required, what's optional, and what format each piece of data should follow. + +## Lexicon Categories + +All lexicons follow the principle that "everything is a claim" - whether it's a hypercert, a measurement, or an attachment, each represents a verifiable assertion stored on the ATProto network. This creates a composable system where claims can reference and build upon each other while maintaining clear data structures and relationships. + +[**Certified Lexicons**](certified-lexicons/) provide foundational building blocks that can be shared across multiple protocols. These include common data types, standardized location references, profiles, badges, and other universal concepts that extend beyond hypercerts alone. + +[**Hypercerts Lexicons**](hypercerts-lexicons/) contain the core claim types specific to impact tracking. These lexicons define how to structure and relate different types of impact claims. The central record is the activity claim (the hypercert itself), which lives in the `org.hypercerts.claim` namespace. Supporting records like measurements, attachments, evaluations, and acknowledgements live in the `org.hypercerts.context` namespace, enabling anyone to add context to existing claims. diff --git a/public/raw/reference/faq.md b/public/raw/reference/faq.md new file mode 100644 index 0000000..b3c5021 --- /dev/null +++ b/public/raw/reference/faq.md @@ -0,0 +1,49 @@ +--- +title: FAQ +description: Common questions about building with Hypercerts. +--- + +# FAQ + +--- + +#### What is a hypercert? + +A structured digital record of a contribution — who did what, when, where, and with what supporting documentation. You create one by writing an `org.hypercerts.claim.activity` record to your PDS. See the [Quickstart](/getting-started/quickstart). + +#### How is this different from the previous (EVM-based) Hypercerts? + +The new protocol stores data on AT Protocol instead of purely on-chain. This gives you richer schemas, data portability, and lower costs. On-chain anchoring for funding is [planned](/core-concepts/funding-and-value-flow) but not yet implemented. + +#### Do I need a blockchain wallet? + +Not to create or evaluate hypercerts — you only need an account on [certified.app](https://certified.app) or any ATProto provider. A wallet will be needed for on-chain funding once the [tokenization layer](/core-concepts/funding-and-value-flow) is built. + +#### Can I use my Bluesky account? + +Yes. Bluesky accounts are ATProto accounts. Your existing DID and identity work with Hypercerts out of the box. + +#### Is my data public? + +Yes. All records are public by default. Do not store sensitive personal information in hypercert records. See the privacy section in [Testing & Deployment](/getting-started/testing-and-deployment) for guidance on what to include and what to keep off-protocol. + +#### Can I delete a hypercert? + +You can delete records from your account. However, cached copies may persist in indexers temporarily. Once data is published, treat it as potentially permanent. + +#### Who can evaluate my hypercert? + +Anyone with an ATProto account. Evaluations are separate records created by the evaluator, linked to your hypercert via a strong reference. You don't control who evaluates your work. See [Working with Evaluations](/getting-started/working-with-evaluations). + +#### How do I query hypercerts across the network? + +Use the [Hyperindex](/tools/hyperindex) GraphQL API at `https://api.hi.gainforest.app/graphql`. It indexes all hypercert records across the network and supports filtering, search, and real-time subscriptions. + +#### How do I fund a hypercert? + +The on-chain funding layer is not yet implemented. The planned design freezes records before funding to ensure funders know exactly what they are paying for. See [Funding & Value Flow](/core-concepts/funding-and-value-flow). + +#### Where do I get help? + +- [GitHub](https://github.com/hypercerts-org) — source code, issues, and discussions +- [Roadmap](/roadmap) — what's being built and what's next diff --git a/public/raw/reference/glossary.md b/public/raw/reference/glossary.md new file mode 100644 index 0000000..3f45892 --- /dev/null +++ b/public/raw/reference/glossary.md @@ -0,0 +1,68 @@ +--- +title: Glossary +description: Key terms used in the Hypercerts documentation. +--- + +# Glossary + +--- + +#### Hypercert + +A structured digital record of a contribution: who did what, when, where, and with what evidence. The core primitive of the protocol. Technically, a hypercert is an activity claim record with linked contributions, attachments, measurements, and evaluations. + +#### Activity claim + +The central record in the hypercerts data model. Describes the work that was done, when, and in what scope. + +#### AT-URI + +The permanent, globally unique identifier for a record. Looks like `at://did:plc:abc123/org.hypercerts.claim.activity/3k7`. You'll see these in every API response — they're how records reference each other. + +#### DID (Decentralized Identifier) + +A permanent identifier for a user or organization. Looks like `did:plc:abc123xyz`. You get one when you create an account on [certified.app](https://certified.app) or [Bluesky](https://bsky.app). Your DID never changes, even if you switch servers or handles. Every record you create carries your DID as the author. + +#### Strong reference + +A reference to another record that includes both the AT-URI and a content hash (CID). Used when one record points to another (e.g., an evaluation referencing an activity claim). The CID makes the reference tamper-evident — if the target record changes, the hash won't match. + +#### Evaluation + +A third-party assessment of a hypercert. Created on the evaluator's own account, not the original author's. + +#### Attachment + +Supporting documentation linked to one or more records — a URL, uploaded file, or IPFS link. + +#### Measurement + +A quantitative observation attached to a hypercert (e.g., "12 pages written", "50 tons CO₂ reduced"). + +#### Contribution + +Who contributed to a hypercert. Can be as simple as a DID string, or a richer record with display name, image, role, and timeframe. + +#### Collection + +A named group of hypercerts and/or other collections, with an optional weight per item. Each collection has a `type` (e.g., "favorites", "project") so the same hypercert can appear in different collections for different purposes. + +#### Lexicon + +A versioned schema that defines the structure of a record type. Lexicons enable interoperability — any app that knows the schema can read the record. See [Introduction to Lexicons](/lexicons/introduction-to-lexicons). + +#### Work scope + +The "what" dimension of a hypercert — what work is being claimed. Can be a simple free-text string or a structured [CEL expression](https://github.com/google/cel-spec) for machine-evaluable scopes. See [Work Scopes](/core-concepts/work-scopes). + +#### Hyperindex + +A reference indexer that indexes hypercert records across the network and exposes them via a GraphQL API. Other indexers exist — see [Indexers & Discovery](/architecture/indexers-and-discovery). + +#### PDS (Personal Data Server) + +The server where your records are stored. You interact with it through the ATProto API — you don't need to manage it directly. You can use the Hypercerts Foundation's PDS, Bluesky's, or self-host one. Records are portable between PDS instances. + +#### Certified + +The identity provider for the Hypercerts ecosystem. We built Certified to give the ecosystem a unified entry point — one account that works across all Hypercerts applications. When you sign up at [certified.app](https://certified.app), you get a DID, a PDS, and an embedded wallet. See [Account & Identity Setup](/architecture/account-and-identity). diff --git a/public/raw/roadmap.md b/public/raw/roadmap.md new file mode 100644 index 0000000..ac9de81 --- /dev/null +++ b/public/raw/roadmap.md @@ -0,0 +1,343 @@ +--- +title: Roadmap +description: Development priorities, infrastructure components, and phased delivery plan for Hypercerts v0.2. +--- + +# Roadmap + +This page outlines the infrastructure components, build priorities, and phased delivery plan for Hypercerts v0.2 — a decentralized system for tracking, evaluating, and funding impactful work on the open internet. + +{% callout type="note" %} +This roadmap reflects the current plan and is subject to change as we gather feedback from real users and contributors. Status labels indicate where each component stands today. +{% /callout %} + +--- + +## Infrastructure overview + +The Hypercerts infrastructure divides into six functional areas. Each area has a different ownership model: + +| Color | Meaning | +|-------|---------| +| 🔵 Blue | Hypercerts Infrastructure — core protocol components this roadmap covers | +| 🟢 Green | Hypercerts Collective Infrastructure — community-governed components | +| ⬜ Grey | Third-party Infrastructure — leverage existing services, don't rebuild | + +--- + +## Build priorities + +| Component | Priority | Status | Owner | +|-----------|----------|--------|-------| +| Lexicons | 🔴 Critical | Active | Hypercerts Foundation | +| Hyperindex AppView | 🔴 Critical | Active | GainForest → Foundation | +| IdentityLink | 🟠 High | Live | GainForest → Foundation | +| EVM Indexer | 🟠 High | Planned | TBD | +| Evaluators | 🟠 High | Active | Hypercerts Collective | +| Hypercerts Labeller | 🟠 High | Active | Hypercerts Collective | +| AI-Ready Docs | 🟠 High | In Progress | All | +| StorageLink | 🟡 Medium | Planned | TBD | +| Hypercerts PDS | ⚪ Low | Optional | — | +| Hypercerts Relayer / Firehose / Jetstream | ⚪ Low | Future | — | + +--- + +## Lexicons 🔵 + +### Lexicons + +**Priority:** 🔴 Critical · **Status:** Active · **Owner:** Hypercerts Foundation + +Lexicons are the schema definitions that specify the structure of all Hypercerts records on ATProto. They are the "contracts" that define how data is structured, validated, and referenced across the network. Without standardized schemas, interoperability between applications would be impossible. + +**`app.certified.*` — Certified application lexicons** + +| Lexicon | Purpose | +|---------|---------| +| `app.certified.badge.definition` | Badge type definitions | +| `app.certified.badge.award` | Badge awards to users | +| `app.certified.location` | Georeferenced location data | +| `app.certified.link.*` | Identity attestations (DID to EVM) | + +**`org.hypercerts.*` — Hypercerts protocol lexicons** + +| Lexicon | Purpose | +|---------|---------| +| `org.hypercerts.claim.activity` | Core hypercert records tracking impact work | +| `org.hypercerts.claim.evaluation` | Evaluations of activities by third parties | +| `org.hypercerts.claim.measurement` | Quantitative data attached to claims | +| `org.hypercerts.collection` | Projects/portfolios grouping multiple activities | +| `org.hypercerts.claim.attachment` | Attachments, reports, documentation | +| `org.hypercerts.funding.receipt` | Funding flow records | + +{% callout type="note" %} +**Migration:** `org.impactindexer.link.attestation` will migrate to `app.certified.link.*`. +{% /callout %} + +**Resources:** +- Repository: [github.com/hypercerts-org/hypercerts-lexicon](https://github.com/hypercerts-org/hypercerts-lexicon) +- Documentation: [impactindexer.org/lexicon](https://impactindexer.org/lexicon) + +--- + +## Data layer + +### Hypercerts PDS + +**Priority:** ⚪ Low · **Status:** Optional + +Personal Data Servers operated by the Hypercerts ecosystem that host user repositories containing hypercert records. + +**Why we're not prioritizing this:** Users can use any ATProto PDS (Bluesky's, self-hosted, community-operated). The data layer is solved. However, dedicated Hypercerts PDSs could eventually provide guaranteed uptime for impact-critical data, support for larger blobs, federation across multiple servers, and organizational sovereignty. + +| PDS | Type | Example users | +|-----|------|---------------| +| `pds.bsky.app` | Third-party (Bluesky) | General users | +| `pds1.certified.app` | Optional Hypercerts | climateai.org, daviddao.org, hyperboards.org | +| `pds2.certified.app` | Optional Hypercerts | Additional users | + +--- + +## Network & streaming layers + +### Current approach ⬜ + +We subscribe to Bluesky's relay and filter for `org.hypercerts.*` and `app.certified.*` collections. Bluesky's Jetstream provides filtered JSON streams by collection. This is sufficient for current needs. + +### Future options 🔵 + +**Priority:** ⚪ Low · **Status:** Future + +If needed later, dedicated Hypercerts infrastructure could include: + +- **Hypercerts Relayer** — Aggregation service that crawls PDSs hosting hypercert records, validates cryptographic signatures, and provides a unified event stream. +- **Hypercerts Firehose** — WebSocket endpoint providing real-time stream of all hypercert-related commits in CBOR format. +- **Hypercerts Jetstream** — Filtered, JSON-formatted stream allowing consumers to subscribe only to specific collections with reduced bandwidth and lower resource requirements. + +{% callout type="note" %} +These are not needed today. Bluesky's relay (`bsky.network`) and Jetstream handle this. We will revisit if the network outgrows third-party infrastructure. +{% /callout %} + +--- + +## Moderation layer 🟢 + +Community-governed evaluation and labeling infrastructure, managed by the Hypercerts Collective. + +### Evaluators + +**Priority:** 🟠 High · **Status:** Active · **Owner:** Hypercerts Collective + +Services producing structured evaluations for hypercert records. Types include AI-powered evaluators (automated analysis), human expert panels (domain expertise), and hybrid approaches (AI-assisted human review). + +**Lexicons:** `org.hypercerts.claim.evaluation`, `app.gainforest.evaluator.*` + +### Hypercerts Labeller + +**Priority:** 🟠 High · **Status:** Active · **Owner:** Hypercerts Collective + +Lightweight annotations using ATProto's labeler pattern. Use cases include quality indicators, verification status, category tags, and warning labels. + +--- + +## Application layer + +### Hyperindex AppView 🔵 + +**Priority:** 🔴 Critical · **Status:** Active · **Owner:** GainForest → Foundation + +The primary AppView server that indexes hypercert records and exposes them via a GraphQL API. Name origin: **Hyper**sphere **Go** **AT**Proto AppView. + +**Why it matters:** Raw ATProto data is distributed across PDSs. The AppView consumes the Firehose/Jetstream, builds queryable indexes, hydrates records with context, provides search and aggregation, and serves the `app.certified.*` and `org.hypercerts.*` API endpoints. + +**Technical details:** + +| Feature | Detail | +|---------|--------| +| API | GraphQL (HTTP + WebSocket subscriptions) | +| Schema | Dynamically generated from uploaded lexicons | +| Pagination | Relay-style cursor pagination | +| Real-time | WebSocket subscriptions for new records | +| Search | Full-text search across hypercert content | + +**Endpoints:** +- GraphQL: `hyperindex.certified.app/graphql` +- GraphiQL: `hyperindex.certified.app/graphiql` + +### Frontends 🟢 + +Applications built on the infrastructure, governed by the Hypercerts Collective: + +| Frontend | Purpose | Status | +|----------|---------|--------| +| **Ma Earth** | Regenerative land funding, community onboarding | Active | +| **hyperboards.org** | Hypercert visualization and management | Active | +| **Other frontends** | Third-party applications | Ecosystem | + +**How records flow:** + +1. User creates a hypercert record via a frontend (Ma Earth, hyperboards.org, etc.) +2. Frontend writes the record to the user's PDS +3. PDS syncs to the network via the relay +4. Hyperindex indexes the record +5. Record becomes available for queries and evaluations + +--- + +## Bridge layer 🔵 + +### IdentityLink + +**Priority:** 🟠 High · **Status:** Live + +A system for linking ATProto DIDs to Ethereum/EVM wallet addresses via cryptographic attestations. This enables contributors to receive onchain payments, verification that a DID controls a specific address, integration with onchain attestation layers (EAS), and cross-chain identity resolution. + +**Flow:** + +``` +1. User authenticates with ATProto via OAuth +2. User connects EVM wallet +3. User signs EIP-712 typed message +4. Attestation stored in user's PDS +5. Anyone can verify cryptographically +``` + +**Properties:** + +- **Self-sovereign** — Attestations in user's PDS, not a central database +- **Cryptographic** — EIP-712 signatures verifiable by anyone +- **Wallet-agnostic** — EOAs, Coinbase Smart Wallet, Safe, ERC-1271 + +**Live:** [identitylink.vercel.app](https://identitylink.vercel.app) + +{% callout type="note" %} +**Migration:** Lexicon migrating from `org.impactindexer.link.attestation` to `app.certified.link.*`. +{% /callout %} + +### StorageLink + +**Priority:** 🟡 Medium · **Status:** Planned + +A service that creates immutable backups of hypercert records on decentralized storage (Filecoin/IPFS). ATProto repositories are mutable — records can be updated or deleted. For high-stakes impact claims, immutable archival provides permanence, verifiability, and compliance with funding mechanisms that require immutable records. + +``` +User's PDS record → StorageLink → Filecoin Cloud (immutable backup) +``` + +### EVM Indexer + +**Priority:** 🟠 High · **Status:** Planned + +An indexer that tracks onchain events related to Hypercerts (token mints, transfers, funding distributions). Creates a unified view across ATProto records and blockchain state — indexing tokenization events, tracking funding flows, and enabling queries like "show all funded activities for this project." + +``` +Blockchain events → EVM Indexer → Hyperindex (unified view) +``` + +--- + +## AI agent readiness + +**Priority:** 🟠 High + +Most applications will be built via AI coding assistants. Infrastructure must be AI-native. + +**Requirements by component:** + +| Component | Requirements | +|-----------|-------------| +| Lexicons | Complete field descriptions, clear constraints, examples, consistent patterns | +| AppView | GraphQL introspection, complete schema docs, consistent queries | +| Docs | OpenAPI/JSON Schema, `AGENTS.md` files, copy-pasteable examples | + +**Action items:** + +| Action | Priority | Status | +|--------|----------|--------| +| Add OpenAPI spec for Hyperindex | High | Todo | +| Create `AGENTS.md` in repos | High | Todo | +| Ensure all lexicon fields have descriptions | High | In Progress | +| Publish example workflows | Medium | Todo | +| Create MCP (Model Context Protocol) server | Medium | Todo | + +--- + +## Governance: the Hypercerts Collective + +**Priority:** 🟠 High + +Open governance body for the ATProto impact ecosystem. Coordinates decisions about shared infrastructure (🟢 green components). + +**Repository:** [tangled.org/gainforest.earth/hypercollective](https://tangled.org/gainforest.earth/hypercollective) + +**What the Hypercerts Collective governs:** + +- Evaluators +- Hypercerts Labeller +- Frontend applications (Ma Earth, hyperboards.org) +- Lexicon standards adoption + +### Lexicon Indexing Requests (LIRs) + +Formal proposals to add lexicons to Hyperindex's indexing. The community decides what becomes shared infrastructure. + +| LIR | Description | Status | +|-----|-------------|--------| +| LIR-0001 | GainForest Lexicons (Darwin Core, Evaluator, Organization) | Approved | +| LIR-0002 | Impact Indexer Review System (comments, likes) | Approved | +| LIR-0003 | Hypercerts Lexicons (claims, funding, badges, locations) | Approved | + +### Infrastructure transitions + +| Component | Current owner | Future owner | +|-----------|--------------|--------------| +| Hyperindex AppView | GainForest | Foundation + Community | +| IdentityLink | GainForest | Foundation + Community | +| Impact Indexer | GainForest | Foundation + Community | +| Lexicon Repos | Various | Hypercerts Collective coordination | + +--- + +## Development phases + +### Phase 1: Make it work (current) + +- End-to-end staging tests: create activity → evaluate → fund → distribute +- Integration tests across AppView → IdentityLink → EVM +- Basic functionality before optimization + +### Phase 2: Make it right (next) + +- Deploy to real users (Ma Earth, GainForest, community) +- Gather feedback on pain points and missing features +- Iterate on lexicon design based on actual usage +- Improve developer experience based on feedback + +### Phase 3: Make it fast (future) + +- Performance optimization based on real usage patterns +- Caching strategies for AppView +- Query optimization +- Only after validation and stability + +--- + +## Next steps + +1. **Finalize Lexicon v1.0** — Lock core schemas for `org.hypercerts.claim.*` to enable stable application development +2. **Productionize Hyperindex** — Harden for production traffic, add caching, improve query performance +3. **AI documentation sprint** — OpenAPI spec, `AGENTS.md` files, copy-pasteable examples +4. **IdentityLink integration** — Complete EIP-712 attestation flow with certified.app frontend +5. **Infrastructure transitions** — Begin handoff to Foundation stewardship + +--- + +## Links & resources + +| Resource | URL | +|----------|-----| +| Lexicon Documentation | [impactindexer.org/lexicon](https://impactindexer.org/lexicon) | +| Hyperindex API | [hyperindex.certified.app/graphql](https://hyperindex.certified.app/graphql) | +| IdentityLink | [identitylink.vercel.app](https://identitylink.vercel.app) | +| Governance Repo | [tangled.org/gainforest.earth/hypercollective](https://tangled.org/gainforest.earth/hypercollective) | +| Hypercerts Foundation | [hypercerts.org](https://hypercerts.org) | diff --git a/public/raw/tools/hyperboards.md b/public/raw/tools/hyperboards.md new file mode 100644 index 0000000..d8a846d --- /dev/null +++ b/public/raw/tools/hyperboards.md @@ -0,0 +1,85 @@ +--- +title: Hyperboards +description: Visual contributor boards on ATProto — see who built what, beautifully. +--- + +# Hyperboards + +Hyperboards creates visual contributor boards backed by ATProto data. Build a board from your hypercerts, customize the layout, and embed it anywhere. + +Live at [hyperboards.org](https://hyperboards.org). Source: [github.com/hypercerts-org/hyperboards](https://github.com/hypercerts-org/hyperboards). + +## What it does + +Hyperboards turns hypercert data into shareable, embeddable visualizations. Each board is a treemap layout that shows contributors, their roles, and relative weights at a glance. + +- **Treemap layouts** — contributors are displayed as proportionally sized tiles, making contribution weights immediately visible +- **Drag-to-resize editing** — adjust contributor tile sizes interactively to reflect their relative contributions +- **Embeddable** — drop a board into any website with a simple iframe +- **ATProto-native** — board data comes directly from signed ATProto records, not a separate database + +## How it works + +1. **Sign in** with your ATProto handle (e.g. `yourname.certified.app` or `yourname.bsky.social`) +2. **Create a board** from the dashboard — select one or more hypercerts to visualize +3. **Customize** the treemap layout by dragging and resizing contributor tiles +4. **Share** the board URL or embed it on your website via iframe + +Because boards pull data from ATProto repositories, the contributor information is cryptographically signed and publicly verifiable. Anyone can inspect the underlying records and confirm who contributed to a hypercert. + +## How weights become tile sizes + +Hyperboards normalizes contributor weights into proportional tile areas using this formula: + +``` +tileArea = contributorWeight / sumOfAllWeights +``` + +For example, if three contributors have weights `"70"`, `"20"`, and `"10"`: + +| Contributor | Weight | Calculation | Tile Area | +|-------------|--------|-------------|-----------| +| Alice | 70 | 70 / 100 | 70% | +| Bob | 20 | 20 / 100 | 20% | +| Carol | 10 | 10 / 100 | 10% | + +D3 recomputes tile positions from the weights on every render. + +**Missing or invalid weights:** Contributors without a `contributionWeight` default to a weight of 1. There are two fallback layers: (1) if `contributionWeight` is undefined or null, the string `"1"` is used; (2) if the string cannot be parsed as a number (e.g. empty string), the number `1` is used. Contributors are never excluded — they always appear on the board with at least a weight of 1. + +**Drag-to-resize behavior:** When you drag to resize tiles in the editor, this directly updates the `contributionWeight` stored in the contributor's ATProto activity record on their PDS. There is no separate layout layer — the weight IS the layout. Weights are rounded to one decimal place on save. + +**Choosing weights for visual clarity:** For boards with many contributors, using percentage-style weights (summing to 100) makes the visual proportions intuitive. For boards with few contributors, simple multipliers (like `"3"`, `"2"`, `"1"`) work well. + +For methods to calculate contributor weights, see [Choosing contribution weights](/lexicons/hypercerts-lexicons/contribution#choosing-contribution-weights). + +## Embedding + +Add a board to any website: + +```html + +``` + +Replace `BOARD_ID` with your board's identifier from the dashboard. + +## Use cases + +**Project pages** — Embed a board on your project website to showcase your team. The treemap makes it easy to see who contributed and how much. + +**Funding transparency** — Show funders exactly who their contributions support. Contributors are displayed with verifiable ATProto-backed attribution. + +**Impact portfolios** — Contributors can link to boards as portable proof of their work. Because the underlying records are signed, the attribution is credible across platforms. + +**Recognition** — Publicly acknowledge contributors in a visual, shareable format that is not locked into any single platform. + +## See also + +- [Quickstart](/getting-started/quickstart) — build a hypercert with contributors that Hyperboards can display +- [Core Data Model](/core-concepts/hypercerts-core-data-model) — understand the record types behind a board +- [Scaffold Starter App](/tools/scaffold) — another example of building on ATProto with the Hypercerts protocol diff --git a/public/raw/tools/hypercerts-cli.md b/public/raw/tools/hypercerts-cli.md new file mode 100644 index 0000000..10322bb --- /dev/null +++ b/public/raw/tools/hypercerts-cli.md @@ -0,0 +1,149 @@ +--- +title: Hypercerts CLI +description: A Go command-line tool for managing hypercerts on ATProto. +--- + +# Hypercerts CLI + +The Hypercerts CLI (`hc`) is a command-line tool for managing hypercerts on ATProto. You can use it to: + +- Create, read, update, and delete all Hypercerts record types (activities, measurements, evaluations, attachments, and more) +- Authenticate with any ATProto PDS +- Run interactively with a terminal UI or non-interactively with flags for CI/CD +- Resolve identities and inspect any record on the network + +Built using Go on [bluesky-social/indigo](https://github.com/bluesky-social/indigo) with interactive forms powered by [Charm](https://charm.sh) libraries. Source: [github.com/GainForest/hypercerts-cli](https://github.com/GainForest/hypercerts-cli). + +## Install + +Choose one of three installation methods: + +1. **Quick install** (recommended): + +```bash +curl -sSL https://raw.githubusercontent.com/GainForest/hypercerts-cli/main/install.sh | bash +``` + +2. **Go install** (requires Go 1.23+): + +```bash +go install github.com/GainForest/hypercerts-cli/cmd/hc@v0.1.1 +``` + +3. **Build from source**: + +```bash +git clone https://github.com/GainForest/hypercerts-cli +cd hypercerts-cli +make build +``` + +## Authenticate + +Log in with your ATProto handle and app password: + +```bash +hc account login -u yourhandle.certified.app -p your-app-password +``` + +Check your session status: + +```bash +hc account status +``` + +Log out: + +```bash +hc account logout +``` + +For CI/CD, set `HYPER_USERNAME`, `HYPER_PASSWORD`, and optionally `ATP_PDS_HOST` as environment variables. + +## Core commands + +All record types follow the same CRUD pattern. Here's the full workflow using activities as the primary example: + +```bash +# Create interactively (launches TUI form) +hc activity create + +# Create with flags +hc activity create \ + --title "Rainforest Carbon Study" \ + --description "12-month carbon sequestration measurement" \ + --start-date 2025-01-01 \ + --end-date 2025-12-31 + +# List +hc activity ls +hc activity ls --json + +# Get details +hc activity get + +# Edit +hc activity edit --title "Updated Title" + +# Delete (cascades to linked measurements and attachments) +hc activity delete -f +``` + +{% callout type="note" %} +Deleting an activity also removes all linked measurements and attachments. Use the `-f` flag to skip confirmation. +{% /callout %} + +## All record types + +Every record type supports `create`, `ls`, `get`, `edit`, `delete` with the same flag patterns shown above. + +| Command | Record Type | Alias | +|---------|------------|-------| +| `hc activity` | `org.hypercerts.claim.activity` | — | +| `hc measurement` | `org.hypercerts.context.measurement` | `hc meas` | +| `hc location` | `app.certified.location` | `hc loc` | +| `hc attachment` | `org.hypercerts.context.attachment` | `hc attach` | +| `hc rights` | `org.hypercerts.claim.rights` | — | +| `hc evaluation` | `org.hypercerts.context.evaluation` | `hc eval` | +| `hc collection` | `org.hypercerts.collection` | `hc coll` | +| `hc contributor` | `org.hypercerts.claim.contributorInformation` | `hc contrib` | +| `hc funding` | `org.hypercerts.funding.receipt` | `hc fund` | +| `hc workscope` | `org.hypercerts.workscope.tag` | `hc ws` | + +{% callout type="note" %} +The CLI is currently being updated to reflect the latest lexicon namespaces shown above. This migration is currently ongoing. +{% /callout %} + +## Generic operations + +Inspect any record on the network using AT-URIs: + +```bash +hc get at://did:plc:xxx/org.hypercerts.claim.activity/rkey +``` + +List all records for a user: + +```bash +hc ls handle.example.com +``` + +List records filtered by collection: + +```bash +hc ls handle.example.com --collection org.hypercerts.claim.activity +``` + +Resolve a handle to a DID: + +```bash +hc resolve handle.example.com +``` + +## Interactive UI + +When you run commands without flags, the CLI launches interactive forms with keyboard navigation, live preview cards during activity creation, multi-select for bulk deletes, and select-or-create patterns when linking records. + +{% callout type="note" %} +The interactive UI requires a terminal that supports ANSI escape codes. For CI/CD environments, always use flags to run commands non-interactively. +{% /callout %} diff --git a/public/raw/tools/hyperindex.md b/public/raw/tools/hyperindex.md new file mode 100644 index 0000000..3f7c36e --- /dev/null +++ b/public/raw/tools/hyperindex.md @@ -0,0 +1,109 @@ +--- +title: Hyperindex +description: A Go ATProto indexer that indexes hypercert records and exposes them via GraphQL. +--- + +# Hyperindex + +Hyperindex (`hi`) is a Go AT Protocol AppView server that indexes records and exposes them via GraphQL. Use it to: + +- Index all hypercert-related records from the ATProto network in real time +- Query indexed data through a typed GraphQL API +- Backfill historical records from any user or the entire network +- Run your own indexer for full control over data availability and query performance + +Built in Go on [bluesky-social/indigo](https://github.com/bluesky-social/indigo). Source: [github.com/hypercerts-org/hyperindex](https://github.com/hypercerts-org/hyperindex). + +## How it works + +Hyperindex connects to the AT Protocol network via Jetstream (a real-time event stream). It watches for records matching your configured lexicons, parses them, and stores them in a queryable database (SQLite or PostgreSQL). It then exposes a GraphQL API for querying the indexed data. + +``` +Jetstream ──→ Consumer ──→ Records DB ──→ GraphQL API + │ + Activity Log ──→ Admin Dashboard + +Backfill Worker ──→ AT Protocol Relay ──→ Records DB +``` + +## Quick start + +```bash +git clone https://github.com/hypercerts-org/hyperindex.git +cd hyperindex +cp .env.example .env +go run ./cmd/hyperindex +``` + +Open [http://localhost:8080/graphiql/admin](http://localhost:8080/graphiql/admin) to access the admin interface. + +## Register lexicons + +Lexicons define the AT Protocol record types you want to index. Register them via the Admin GraphQL API at `/graphiql/admin`: + +```graphql +mutation { + uploadLexicons(files: [...]) # Upload lexicon JSON files +} +``` + +Or place lexicon JSON files in a directory and set the `LEXICON_DIR` environment variable. + +For hypercerts, you would register the `org.hypercerts.claim.*` lexicons — see [Introduction to Lexicons](/lexicons/introduction-to-lexicons) for the full list. + +## Query via GraphQL + +Access your indexed data at `/graphql`: + +```graphql +# Query records by collection +query { + records(collection: "org.hypercerts.claim.activity") { + edges { + node { + uri + did + value + } + } + } +} + +# With typed queries (when lexicon schemas are loaded) +query { + orgHypercertsClaimActivity(first: 10) { + edges { + node { + uri + workScope + startDate + createdAt + } + } + } +} +``` + +## Endpoints + +| Endpoint | Description | +|---|---| +| `/graphql` | Public GraphQL API | +| `/graphql/ws` | GraphQL subscriptions (WebSocket) | +| `/admin/graphql` | Admin GraphQL API | +| `/graphiql` | GraphQL playground (public API) | +| `/graphiql/admin` | GraphQL playground (admin API) | +| `/health` | Health check | +| `/stats` | Server statistics | + +## Running with Docker + +```bash +docker compose up --build +``` + +## Learn more + +- [GitHub repository](https://github.com/hypercerts-org/hyperindex) — source code, issues, and documentation +- [Indexers & Discovery](/architecture/indexers-and-discovery) — how indexers fit into the Hypercerts architecture +- [Building on Hypercerts](/getting-started/building-on-hypercerts) — integration patterns for platforms and tools diff --git a/public/raw/tools/scaffold.md b/public/raw/tools/scaffold.md new file mode 100644 index 0000000..4e813ba --- /dev/null +++ b/public/raw/tools/scaffold.md @@ -0,0 +1,297 @@ +--- +title: Scaffold Starter App +description: A Next.js starter app for building on ATProto with the Hypercerts protocol. +--- + +# Scaffold Starter App + +The Hypercerts Scaffold is a working Next.js app that demonstrates how to build on ATProto with the Hypercerts protocol. It handles OAuth authentication, profile management, and the full hypercert creation workflow — from basic claims through attachments, locations, measurements, and evaluations. + +Live at [hypercerts-scaffold.vercel.app](https://hypercerts-scaffold.vercel.app). Source: [github.com/hypercerts-org/hypercerts-scaffold-atproto](https://github.com/hypercerts-org/hypercerts-scaffold-atproto). + +The repo is also indexed on [deepwiki](https://deepwiki.com/hypercerts-org/hypercerts-scaffold-atproto) if you want to dive deeper into the docs and setup. + +## Tech Stack + +| Category | Technology | +|----------|------------| +| Framework | Next.js 16 (App Router), React 19, TypeScript | +| Styling | Tailwind CSS 4, shadcn/ui (Radix primitives) | +| State Management | TanStack React Query v5 | +| Auth / Protocol | AT Protocol OAuth, `@atproto/oauth-client-node` | +| Infrastructure | Redis (session + OAuth state storage) | + +## What the app does + +### Sign in with ATProto + +Enter your handle (e.g. `yourname.certified.app` or `yourname.bsky.social`) and the app redirects you to your PDS for OAuth authorization. Once approved, you're signed in with a session tied to your DID. + +Alternatively, the sign-in dialog has an **Email** tab (visible when `NEXT_PUBLIC_EPDS_URL` is configured). Entering your email authenticates via the ePDS — if no account is registered with that email, the ePDS creates one for you automatically. + +![Scaffold sign-in screen showing handle input field](/images/scaffold/sign-in.png) +*The sign-in screen. Enter your ATProto handle to authenticate via OAuth.* + +### Home screen + +After signing in, the home screen shows your active session — your DID, display name, and handle. From here you can create a new hypercert or view your existing ones. + +![Scaffold home screen showing session info and action buttons](/images/scaffold/homepage.png) +*The authenticated home screen with session details and quick actions.* + +### Create a hypercert + +The creation flow is a 5-step wizard with a sidebar stepper that tracks your progress: + +**Step 1 — Basic info.** Title, description, work scope tags, start and end dates, and an optional cover image. This creates the core `org.hypercerts.claim.activity` record on your PDS. + +![Hypercert creation form showing title, description, work scope, and date fields](/images/scaffold/create-cert.png) +*Step 1: Define the basic claim — what work was done, when, and in what scope.* + +**Step 2 — Attachments.** Attach supporting documentation — URLs, files, or descriptions that back up the claim. + +![Evidence form for attaching supporting documentation](/images/scaffold/add-evidence.png) +*Step 2: Attach supporting documentation to back up the claim.* + +**Step 3 — Location.** Add geographic context to the work — where it happened. + +![Location form for adding geographic context](/images/scaffold/add-location.png) +*Step 3: Add location data to anchor the work geographically.* + +**Step 4 — Measurements.** Add quantitative data — metrics, values, and measurement methods that make the impact concrete. + +![Measurement form for adding quantitative impact data](/images/scaffold/add-measurement.png) +*Step 4: Add measurements to quantify the impact.* + +**Step 5 — Evaluations.** Add third-party assessments of the work. + +![Evaluation form for adding third-party assessments](/images/scaffold/add-evaluation.png) +*Step 5: Add evaluations from third-party assessors.* + +**Step 6 — Done.** Review the completed hypercert and create another or view your collection. + +![Completion screen showing the finished hypercert](/images/scaffold/finalized-cert.png) +*Step 6: The hypercert is created and stored on your PDS.* + +### Browse your hypercerts + +The hypercerts page shows all your claims in a card grid. Each card displays the title, description, creation date, work scope tags, and cover image. Click any card to view its full details. + +![Grid of hypercert cards showing titles, descriptions, and work scope tags](/images/scaffold/view-hypercerts.png) +*Your hypercerts displayed as cards with metadata and work scope tags.* + +### Edit your profile + +The profile page lets you update your Certified profile — display name, bio, pronouns, website, avatar, and banner image. Changes are written directly to your PDS. + +![Profile editing form with display name, bio, and avatar fields](/images/scaffold/profile.png) +*Edit your Certified profile. Changes are stored on your PDS.* + +## Environment variables + +| Variable | Description | +|----------|-------------| +| `NEXT_PUBLIC_BASE_URL` | App URL (`http://127.0.0.1:3000` for local) | +| `ATPROTO_JWK_PRIVATE` | OAuth private key (generate with `pnpm run generate-jwk`) | +| `REDIS_HOST` | Redis hostname | +| `REDIS_PORT` | Redis port | +| `REDIS_PASSWORD` | Redis password | +| `NEXT_PUBLIC_PDS_URL` | PDS URL (e.g. `https://pds-eu-west4.test.certified.app`) | +| `NEXT_PUBLIC_EPDS_URL` | ePDS URL (e.g. `https://epds1.test.certified.app`) (optional; required only for email/passwordless login) | + +{% callout type="note" %} +Redis is the default session store, but you can use any persistent storage (Supabase, Postgres, DynamoDB, etc.). You just need to implement the `NodeSavedStateStore` and `NodeSavedSessionStore` interfaces from `@atproto/oauth-client-node`. See `lib/redis-state-store.ts` for the reference implementation. +{% /callout %} + +## Run it locally + +1. Clone and install: +```bash +git clone https://github.com/hypercerts-org/hypercerts-scaffold-atproto +cd hypercerts-scaffold-atproto +pnpm install +``` + +2. Configure environment: +```bash +cp .env.example .env.local +pnpm run generate-jwk >> .env.local +``` + +3. Start Redis (for session storage): +```bash +docker run -d -p 6379:6379 redis:alpine +``` + +4. Run the dev server: +```bash +pnpm run dev +``` + +Open `http://127.0.0.1:3000`. Requires Node.js 20+ and pnpm. + +> **Note:** Use `127.0.0.1` not `localhost` for local development. ATProto OAuth requires IP-based loopback addresses per RFC 8252. The app auto-redirects, but your `.env.local` must use `127.0.0.1`. + +## Architecture + +### OAuth Flow + +The scaffold implements ATProto OAuth with DPoP-bound tokens. The flow involves four parties: the **Browser**, the **Scaffold Server** (Next.js), the **Authorization Server** (user's PDS), and **Redis** (session storage). + +![Sequence diagram showing the ATProto OAuth flow between Browser, Scaffold Server, Auth Server (PDS), and Redis](/images/scaffold/oauth-flow.png) +*The ATProto OAuth flow — from login initiation through session creation and subsequent request authentication.* + +**1–3 — Login initiation.** The browser sends the user's handle to `POST /api/oauth/login`. The server resolves the handle to a DID, discovers their PDS, and generates an authorization URL. Temporary OAuth state is stored in Redis (`oauth-state:`, 10-minute TTL) to prevent CSRF. + +**4–6 — Authorization.** The browser redirects to the PDS where the user grants consent. The PDS redirects back to `/api/oauth/callback` with an authorization code. + +**7–9 — Session creation.** The server exchanges the code for a DPoP-bound session via the OAuth client's `callback()` method. The session (tokens, refresh token, DID) is persisted to Redis (`session:`, no TTL) and a `user-did` httpOnly cookie is set in the browser. + +**10–12 — Session restore.** On subsequent requests, the server reads the `user-did` cookie and calls `oauthClient.restore(did)` to load the session from Redis, auto-refreshing expired tokens. This call is wrapped in React's `cache()` so multiple server components in the same render only hit Redis once. + +**Logout.** `GET /api/oauth/logout` revokes tokens with the PDS, deletes the Redis session, and clears the cookie. + +**Discovery endpoints.** Before any of this works, the PDS needs to discover the app's identity. Two endpoints handle this: + +- `/client-metadata.json` (`app/client-metadata.json/route.ts`) — serves RFC 7591 client metadata: `client_id`, redirect URIs, scopes, and DPoP configuration. +- `/jwks.json` (`app/jwks.json/route.ts`) — serves the public half of the app's ES256 key pair (from `ATPROTO_JWK_PRIVATE`). The PDS uses this to verify client assertion JWTs. + +### Local Loopback Development + +ATProto OAuth requires loopback clients to use `127.0.0.1` rather than `localhost`, per RFC 8252 Section 7.3. This prevents DNS rebinding attacks and means local development operates differently from production in two ways: + +**`client_id` format.** In production, the `client_id` is the URL of the client metadata document (`https://yourdomain.com/client-metadata.json`). In local development, ATProto uses a special loopback format: `http://localhost?scope=...&redirect_uri=...`. The `lib/config.ts` module auto-detects which format to use based on whether the base URL resolves to a loopback address. + +**Automatic redirect.** The app includes a proxy (`proxy.ts`) that issues a 307 redirect from `localhost` to `127.0.0.1` for any incoming request. + +> **Note:** Your `.env.local` must set `NEXT_PUBLIC_BASE_URL=http://127.0.0.1:3000`. Using `localhost` will cause the configuration validator in `lib/config.ts` to throw an error at startup. + +### Server-Side Data Boundary + +All data fetching happens server-side. The ATProto session lives in Redis, accessed via an httpOnly cookie — there is no browser-side session. Client components never talk to the PDS directly. + +The app exposes server-side logic to client components through two patterns: **API Routes** (`app/api/`) for operations that need FormData like file uploads, and **Server Actions** (`lib/create-actions.ts`) for simpler operations called directly without an HTTP round-trip. Client components use TanStack React Query hooks (in `queries/`) to call both. + +Server component pages like `app/hypercerts/page.tsx` and `app/hypercerts/[hypercertUri]/page.tsx` skip this entirely — they call the ATProto client directly on the server and pass fetched data as props to client components. + +### Constellation Backlinks + +ATProto has no built-in reverse lookup — given a hypercert URI, there is no native way to find which attachments, evaluations, or measurements reference it. The scaffold uses [Constellation](https://constellation.microcosm.blue), an external backlinks service, to solve this. + +Constellation indexes ATProto records and returns all records that reference a given subject URI. The scaffold queries three source paths: + +- Attachments: `org.hypercerts.claim.attachment:subjects[com.atproto.repo.strongRef].uri` +- Evaluations: `org.hypercerts.claim.evaluation:subject.uri` +- Measurements: `org.hypercerts.claim.measurement:subject.uri` + +The query hooks follow a two-step pattern: fetch backlink URIs from Constellation, then fetch each record's full data via Server Actions. This split is necessary because Constellation returns record identifiers, not record contents. + +## Project structure +``` +hypercerts-scaffold/ +├── app/ +│ ├── layout.tsx # Root layout (server component, wraps providers) +│ ├── page.tsx # Landing page (server component) +│ ├── loading.tsx # Root loading state +│ ├── robots.ts # Robots meta +│ ├── sitemap.ts # Sitemap generation +│ ├── client-metadata.json/ +│ │ └── route.ts # OAuth client metadata endpoint (RFC 7591) +│ ├── jwks.json/ +│ │ └── route.ts # JWKS public key endpoint for OAuth +│ ├── api/ +│ │ ├── oauth/ +│ │ │ ├── login/route.ts # POST — initiate OAuth login (handle) +│ │ │ ├── callback/route.ts # GET — OAuth callback, sets session +│ │ │ ├── logout/route.ts # GET — revoke session, clear cookie +│ │ │ └── epds/ +│ │ │ ├── login/route.ts # POST — initiate ePDS email login (PAR + PKCE) +│ │ │ └── callback/route.ts # GET — ePDS token exchange +│ │ ├── certs/ +│ │ │ ├── route.ts # POST — create hypercert +│ │ │ ├── add-location/route.ts # POST — attach location to hypercert +│ │ │ └── add-attachment/route.ts # POST — attach evidence/files +│ │ └── profile/ +│ │ ├── update/route.ts # POST — update Certified profile +│ │ └── bsky/update/route.ts # POST — update Bluesky profile +│ ├── hypercerts/ +│ │ ├── page.tsx # List all hypercerts (server component) +│ │ ├── loading.tsx +│ │ ├── create/ +│ │ │ ├── page.tsx # Multi-step creation wizard +│ │ │ └── layout.tsx +│ │ └── [hypercertUri]/ +│ │ ├── page.tsx # Hypercert detail view (server component) +│ │ ├── loading.tsx +│ │ ├── edit/page.tsx # Edit hypercert +│ │ └── add/[type]/page.tsx # Add evidence/evaluation/measurement/etc. +│ ├── profile/ +│ │ ├── page.tsx # Certified profile editor +│ │ └── loading.tsx +│ └── bsky-profile/page.tsx # Bluesky profile editor +│ +├── lib/ +│ ├── config.ts # Centralized config, env validation, URL detection +│ ├── hypercerts-sdk.ts # NodeOAuthClient initialization + Redis stores +│ ├── atproto-session.ts # Session restore helpers (server-only, cached) +│ ├── atproto-writes.ts # StrongRef resolution, location creation, blob upload +│ ├── atproto-branding.ts # OAuth page CSS/logo branding +│ ├── epds-config.ts # Derives ePDS OAuth endpoints from NEXT_PUBLIC_EPDS_URL +│ ├── epds-helpers.ts # PKCE + DPoP utilities for ePDS flow +│ ├── repo-context.ts # getRepoContext() — authenticated Agent + DID context +│ ├── redis.ts # Redis client singleton (server-only) +│ ├── redis-state-store.ts # Redis-backed OAuth state + session stores +│ ├── create-actions.ts # Server Actions ("use server") +│ ├── record-validation.ts # Generic lexicon record validation +│ ├── blob-utils.ts # Blob/image URL resolution (server-only) +│ ├── contribution-helpers.ts # Contributor/contribution utilities +│ ├── types.ts # Core TypeScript types +│ ├── utils.ts # Shared utilities (cn, validators) +│ └── api/ # Client-side API layer +│ ├── client.ts # Base fetch wrappers (JSON, FormData) +│ ├── auth.ts # Auth API functions +│ ├── hypercerts.ts # Hypercert API functions +│ ├── profile.ts # Profile API functions +│ ├── bsky-profile.ts # Bluesky profile API functions +│ ├── types.ts # Shared API types +│ ├── query-keys.ts # Centralized TanStack Query key factory +│ └── external/ +│ ├── bluesky.ts # Bluesky public API (search, profiles) +│ └── constellation.ts # Constellation backlinks API +│ +├── providers/ +│ ├── AllProviders.tsx # QueryClientProvider (client component) +│ ├── AuthErrorToast.tsx # Auth error toast notifications +│ └── SignedInProvider.tsx # Auth gate + Navbar (server component) +│ +├── queries/ # TanStack Query hooks (all client-side) +│ ├── use-active-profile-query.tsx +│ ├── auth/ # Login/logout mutations +│ ├── hypercerts/ # Create, edit, delete, attach queries/mutations +│ ├── profile/ # Profile update mutations +│ └── external/ # Bluesky search, Constellation queries +│ +├── components/ +│ ├── ui/ # shadcn/ui primitives +│ ├── navbar.tsx # Top navigation +│ ├── login-dialog.tsx # Login form (handle + email tab toggle) +│ ├── hypercerts-create-form.tsx # Create wizard wrapper +│ ├── hypercerts-edit-form.tsx # Edit hypercert form +│ ├── evidence-form.tsx # Evidence step +│ ├── locations-form.tsx # Location step +│ ├── measurement-form.tsx # Measurement step +│ ├── evaluation-form.tsx # Evaluation step +│ ├── contributions-form.tsx # Contributors step +│ ├── hypercert-detail-view.tsx # Detail page client component +│ ├── hypercert-*-section.tsx # Collapsible detail sections (evidence, evaluations, etc.) +│ ├── delete-confirm-dialog.tsx # Delete confirmation +│ ├── profile-form.tsx # Certified profile form +│ └── bsky-profile-form.tsx # Bluesky profile form +│ +├── scripts/ +│ └── generate-jwk.mjs # JWK key pair generator (ES256) +│ +└── vendor/ # Packed dependency tarballs (pre-release) +``` + +`app/` contains pages (server components by default) and API routes. `lib/` is split: top-level files are server-only, while `lib/api/` is the client-side fetch layer that browser code calls. `providers/` has one server component (`SignedInProvider`, which handles the auth gate and renders the Navbar) and one client component (`AllProviders`, which sets up the TanStack Query client). `queries/` is entirely client-side TanStack Query hooks. `components/` is entirely client-side React components. \ No newline at end of file diff --git a/styles/globals.css b/styles/globals.css index 5b2ed49..dfd7902 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -977,6 +977,47 @@ a.sidebar-link-active:hover { } /* ===== Last Updated ===== */ +.page-tools { + display: flex; + align-items: center; + gap: var(--space-3); + margin-bottom: var(--space-6); +} + +.page-tools-button, +.page-tools-link { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 32px; + padding: 0 var(--space-3); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + background: var(--color-bg-subtle); + color: var(--color-text-secondary); + font-size: 0.8125rem; + font-weight: 500; + text-decoration: none; + transition: border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast); +} + +.page-tools-button { + cursor: pointer; +} + +.page-tools-button:hover, +.page-tools-link:hover { + border-color: var(--color-link); + color: var(--color-link); + text-decoration: none; +} + +.page-tools-button:focus-visible, +.page-tools-link:focus-visible { + outline: none; + box-shadow: var(--focus-ring); +} + .last-updated { margin-top: var(--space-12); padding-top: var(--space-4); From d812d55d7a5bd7e8130025e40956da9cacc2451b Mon Sep 17 00:00:00 2001 From: kzoeps Date: Wed, 1 Apr 2026 19:28:36 +0600 Subject: [PATCH 2/3] update docs for lexicon usage (coderabbit comment) --- lib/generate-raw-pages.js | 4 +- lib/lastUpdated.json | 8 +- pages/architecture/data-flow-and-lifecycle.md | 6 +- pages/core-concepts/cel-work-scopes.md | 2 +- pages/core-concepts/certified-identity.md | 4 +- pages/core-concepts/funding-and-value-flow.md | 5 +- .../hypercerts-core-data-model.md | 8 +- .../working-with-evaluations.md | 8 +- pages/reference/faq.md | 20 ++--- pages/roadmap.md | 6 +- pages/tools/hyperboards.md | 2 +- pages/tools/hyperindex.md | 2 +- pages/tools/scaffold.md | 10 +-- .../architecture/data-flow-and-lifecycle.md | 6 +- public/raw/core-concepts/cel-work-scopes.md | 2 +- .../raw/core-concepts/certified-identity.md | 4 +- .../core-concepts/funding-and-value-flow.md | 5 +- .../hypercerts-core-data-model.md | 8 +- .../working-with-evaluations.md | 8 +- public/raw/reference/faq.md | 20 ++--- public/raw/roadmap.md | 6 +- public/raw/tools/hyperboards.md | 2 +- public/raw/tools/hyperindex.md | 2 +- public/raw/tools/scaffold.md | 10 +-- public/search-index.json | 19 +++- public/sitemap.xml | 88 +++++++++---------- 26 files changed, 138 insertions(+), 127 deletions(-) diff --git a/lib/generate-raw-pages.js b/lib/generate-raw-pages.js index 8125c8a..bda1cbc 100644 --- a/lib/generate-raw-pages.js +++ b/lib/generate-raw-pages.js @@ -25,7 +25,9 @@ function walkDir(dir) { } function getRawOutputPath(filePath) { - const rel = relative(PAGES_DIR, filePath).replace(/\.md$/, ''); + const rel = relative(PAGES_DIR, filePath) + .replace(/\.md$/, '') + .replace(/\\/g, '/'); const route = rel === 'index' ? '/index' : `/${rel.replace(/\/index$/, '')}`; const outputRel = route === '/index' ? 'index.md' : `${route.slice(1)}.md`; return join(OUTPUT_DIR, outputRel); diff --git a/lib/lastUpdated.json b/lib/lastUpdated.json index ffda5b9..514a474 100644 --- a/lib/lastUpdated.json +++ b/lib/lastUpdated.json @@ -1,6 +1,6 @@ { "/architecture/account-and-identity": "2026-04-01T13:47:13+06:00", - "/architecture/data-flow-and-lifecycle": "2026-03-05T20:17:36+06:00", + "/architecture/data-flow-and-lifecycle": "2026-04-01T19:28:36+06:00", "/architecture/epds": "2026-04-01T13:47:13+06:00", "/architecture/indexers-and-discovery": "2026-03-05T04:01:13+08:00", "/architecture/overview": "2026-03-05T20:46:24+08:00", @@ -9,14 +9,14 @@ "/core-concepts/certified-identity": "2026-03-14T20:43:33-07:00", "/core-concepts/common-use-cases": "2026-03-05T12:52:26+08:00", "/core-concepts/funding-and-value-flow": "2026-03-05T17:11:22+06:00", - "/core-concepts/hypercerts-core-data-model": "2026-03-05T20:17:43+06:00", + "/core-concepts/hypercerts-core-data-model": "2026-04-01T19:28:36+06:00", "/core-concepts/what-is-hypercerts": "2026-03-05T03:40:14+08:00", "/core-concepts/why-at-protocol": "2026-03-05T21:06:04+08:00", "/ecosystem/why-we-need-hypercerts": "2026-02-20T12:49:43+01:00", "/getting-started/building-on-hypercerts": "2026-03-06T22:56:46+08:00", "/getting-started/quickstart": "2026-03-14T20:43:33-07:00", "/getting-started/testing-and-deployment": "2026-03-05T14:36:55+06:00", - "/getting-started/working-with-evaluations": "2026-03-06T22:56:46+08:00", + "/getting-started/working-with-evaluations": "2026-04-01T19:28:36+06:00", "/": "2026-03-24T12:56:03-07:00", "/lexicons/certified-lexicons/badge-award": "2026-03-24T12:56:03-07:00", "/lexicons/certified-lexicons/badge-definition": "2026-03-24T12:56:03-07:00", @@ -42,5 +42,5 @@ "/tools/hyperboards": "2026-03-09T15:56:42+08:00", "/tools/hypercerts-cli": "2026-03-05T12:30:00+06:00", "/tools/hyperindex": "2026-02-20T19:42:03+08:00", - "/tools/scaffold": "2026-03-05T15:58:36+06:00" + "/tools/scaffold": "2026-04-01T19:28:36+06:00" } diff --git a/pages/architecture/data-flow-and-lifecycle.md b/pages/architecture/data-flow-and-lifecycle.md index cfddd93..4ef428b 100644 --- a/pages/architecture/data-flow-and-lifecycle.md +++ b/pages/architecture/data-flow-and-lifecycle.md @@ -60,11 +60,11 @@ Contributors are embedded in the activity claim's `contributors` array. For rich #### Attachment Records -`org.hypercerts.claim.attachment` records attach supporting documentation. Attachments can be URLs, file uploads, or structured data. Each attachment record includes a strong reference to the claim it supports. +`org.hypercerts.context.attachment` records attach supporting documentation. Attachments can be URLs, file uploads, or structured data. Each attachment record includes a strong reference to the claim it supports. #### Measurement Records -`org.hypercerts.claim.measurement` records provide quantitative data. A measurement specifies what was measured, the value, the unit, and the methodology. Multiple measurements can track different metrics. +`org.hypercerts.context.measurement` records provide quantitative data. A measurement specifies what was measured, the value, the unit, and the methodology. Multiple measurements can track different metrics. #### Rights Records @@ -98,7 +98,7 @@ at://did:alice/... at://did:bob/... at://did:carol/ Third parties assess the work by creating evaluation records on their own servers. -An evaluator creates an `org.hypercerts.claim.evaluation` record on their PDS. The evaluation includes a `subject` field with a strong reference to the activity claim. Strong references include both the AT-URI and the CID (content hash), ensuring the evaluation references a specific version of the claim. +An evaluator creates an `org.hypercerts.context.evaluation` record on their PDS. The evaluation includes a `subject` field with a strong reference to the activity claim. Strong references include both the AT-URI and the CID (content hash), ensuring the evaluation references a specific version of the claim. The evaluation record includes the evaluator's assessment. This can be a score, a category, structured feedback, or a link to a detailed report. The lexicon allows flexible evaluation formats. diff --git a/pages/core-concepts/cel-work-scopes.md b/pages/core-concepts/cel-work-scopes.md index 5df2b91..b58d649 100644 --- a/pages/core-concepts/cel-work-scopes.md +++ b/pages/core-concepts/cel-work-scopes.md @@ -193,7 +193,7 @@ Every CEL expression evaluates against a typed context. Each variable maps to da ## Starter tag vocabulary -`workScopeTag` records are published as ATProto records that anyone can reference via strong references. [Certified](https://certified.ink) publishes curated tag sets for specific domains. Here's an example for regenerative work: +`workScopeTag` records are published as ATProto records that anyone can reference via strong references. [Certified](https://certified.app) publishes curated tag sets for specific domains. Here's an example for regenerative work: | Domain | Example tags | |--------|-------------| diff --git a/pages/core-concepts/certified-identity.md b/pages/core-concepts/certified-identity.md index 1ff6f18..9d7d31a 100644 --- a/pages/core-concepts/certified-identity.md +++ b/pages/core-concepts/certified-identity.md @@ -25,7 +25,7 @@ Your DID resolves via the [PLC directory](https://plc.directory) to a DID docume |-------|---------------------| | **Data** | Every record (activity claims, evaluations, measurements) carries the author's DID. The PDS signs records into a Merkle tree, making authorship tamper-evident. | | **Trust** | Evaluators build reputation tied to their DID. Applications can weight evaluations based on the evaluator's history and credentials. | -| **Funding** | Funding receipts link funder DIDs to the work they support. Wallet linkage (work-in-progress) connects DIDs to onchain addresses for payment flows and tokenization. | +| **Funding** | Funding receipts link funder DIDs to the work they support. Wallet linkage (work-in-progress) connects DIDs to on-chain addresses for payment flows and tokenization. | | **Portability** | Switching PDS providers doesn't change your DID. Your entire history — claims, evaluations, contributions — migrates with you. | ## Certified: the reference identity provider @@ -52,7 +52,7 @@ Hypercerts is fully interoperable with the AT Protocol ecosystem. If you already ## Wallet linkage -To receive onchain funding, a DID needs to be linked to an onchain wallet address. This is handled by [**IdentityLink**](https://identitylink.vercel.app/) — a cryptographic attestation system that binds a DID to one or more onchain addresses via a signed proof stored in your PDS. For the Ethereum ecosystem this looks like: +To receive on-chain funding, a DID needs to be linked to an on-chain wallet address. This is handled by [**IdentityLink**](https://identitylink.vercel.app/) — a cryptographic attestation system that binds a DID to one or more on-chain addresses via a signed proof stored in your PDS. For the Ethereum ecosystem this looks like: 1. Authenticates the user via ATProto OAuth 2. Connects an EVM wallet (EOA, Smart Wallet, or Safe) diff --git a/pages/core-concepts/funding-and-value-flow.md b/pages/core-concepts/funding-and-value-flow.md index 8edfc92..07a1df4 100644 --- a/pages/core-concepts/funding-and-value-flow.md +++ b/pages/core-concepts/funding-and-value-flow.md @@ -42,7 +42,7 @@ Funding receipts are typically created by a **facilitator** — a payment proces | Scenario | Facilitator | Verification | |----------|-------------|--------------| -| **Onchain funding** | A funding app verifies the transaction and creates the receipt, linking the transaction hash and chain ID | Verifiable onchain | +| **On-chain funding** | A funding app verifies the transaction and creates the receipt, linking the transaction hash and chain ID | Verifiable on-chain | | **Card / bank transfer** | A payment processor settles the payment and creates the receipt | Trust in the processor | | **Grant platform** | The grant platform records the award and creates the receipt on behalf of the funder | Trust in the platform | @@ -56,7 +56,7 @@ The protocol does not enforce that projects or funders disclose their funding Tokenization is under active development. This section describes the planned architecture. {% /callout %} -A hypercert can optionally be wrapped in an onchain token. This gives funders a programmable proof of their contribution. Tokenization is an optional wrapper around a claim snapshot; the canonical record remains the AT Protocol data. +A hypercert can optionally be wrapped in an on-chain token. This gives funders a programmable proof of their contribution. Tokenization is an optional wrapper around a claim snapshot; the canonical record remains the AT Protocol data. When locking is available, a claim can be frozen before tokenization. This gives funders a stronger guarantee — the claim they reviewed is exactly the claim they funded, and it cannot change after the fact. @@ -105,4 +105,3 @@ Two years later, Eve assesses the health of Alice's trees and publishes a positi - [Architecture Overview](/architecture/overview) — how the full protocol stack fits together - [Data Flow & Lifecycle](/architecture/data-flow-and-lifecycle) — how a hypercert moves through the system - diff --git a/pages/core-concepts/hypercerts-core-data-model.md b/pages/core-concepts/hypercerts-core-data-model.md index f748b13..2d2e6bc 100644 --- a/pages/core-concepts/hypercerts-core-data-model.md +++ b/pages/core-concepts/hypercerts-core-data-model.md @@ -45,13 +45,13 @@ The following diagram shows record types and how they reference the activity cla {% figure src="/images/hypercert-erd.svg" alt="Hypercert record relationships" /%} -The diagram includes a **token** entity — tokenization (anchoring a hypercert onchain) is not yet implemented. +The diagram includes a **token** entity — tokenization (anchoring a hypercert on-chain) is not yet implemented. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| -| **Attachment** | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | `org.hypercerts.claim.attachment` | -| **Measurement** | Quantitative data — "12 pages written", "50 tons CO₂ reduced" | E.g. a third-party measurer or the project (self-reported) | `org.hypercerts.claim.measurement` | -| **Evaluation** | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | `org.hypercerts.claim.evaluation` | +| **Attachment** | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | `org.hypercerts.context.attachment` | +| **Measurement** | Quantitative data — "12 pages written", "50 tons CO₂ reduced" | E.g. a third-party measurer or the project (self-reported) | `org.hypercerts.context.measurement` | +| **Evaluation** | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | `org.hypercerts.context.evaluation` | ### Additional notes diff --git a/pages/getting-started/working-with-evaluations.md b/pages/getting-started/working-with-evaluations.md index 613a777..f29fd57 100644 --- a/pages/getting-started/working-with-evaluations.md +++ b/pages/getting-started/working-with-evaluations.md @@ -21,7 +21,7 @@ await agent.login({ // Create an evaluation of an activity claim const evaluation = await agent.com.atproto.repo.createRecord({ repo: agent.session.did, - collection: "org.hypercerts.claim.evaluation", + collection: "org.hypercerts.context.evaluation", record: { subject: { uri: "at://did:plc:xyz789/org.hypercerts.claim.activity/3k2j4h5g6f7d8s9a", @@ -29,7 +29,7 @@ const evaluation = await agent.com.atproto.repo.createRecord({ }, evaluators: ["did:plc:evaluator123"], summary: "Verified documentation updates. All 15 examples tested and working. High quality contribution with clear impact on developer experience.", - $type: "org.hypercerts.claim.evaluation", + $type: "org.hypercerts.context.evaluation", createdAt: new Date().toISOString(), }, }); @@ -46,7 +46,7 @@ Measurements provide quantitative data that supports your evaluation: ```typescript const measurement = await agent.com.atproto.repo.createRecord({ repo: agent.session.did, - collection: "org.hypercerts.claim.measurement", + collection: "org.hypercerts.context.measurement", record: { subject: { uri: "at://did:plc:xyz789/org.hypercerts.claim.activity/3k2j4h5g6f7d8s9a", @@ -60,7 +60,7 @@ const measurement = await agent.com.atproto.repo.createRecord({ methodURI: "https://example.com/analytics-methodology", evidenceURI: ["https://example.com/analytics-report.pdf"], comment: "Page view data collected over the first 30 days after publication.", - $type: "org.hypercerts.claim.measurement", + $type: "org.hypercerts.context.measurement", createdAt: new Date().toISOString(), }, }); diff --git a/pages/reference/faq.md b/pages/reference/faq.md index b3c5021..c499451 100644 --- a/pages/reference/faq.md +++ b/pages/reference/faq.md @@ -7,43 +7,43 @@ description: Common questions about building with Hypercerts. --- -#### What is a hypercert? +## What is a hypercert? A structured digital record of a contribution — who did what, when, where, and with what supporting documentation. You create one by writing an `org.hypercerts.claim.activity` record to your PDS. See the [Quickstart](/getting-started/quickstart). -#### How is this different from the previous (EVM-based) Hypercerts? +## How is this different from the previous (EVM-based) Hypercerts? The new protocol stores data on AT Protocol instead of purely on-chain. This gives you richer schemas, data portability, and lower costs. On-chain anchoring for funding is [planned](/core-concepts/funding-and-value-flow) but not yet implemented. -#### Do I need a blockchain wallet? +## Do I need a blockchain wallet? Not to create or evaluate hypercerts — you only need an account on [certified.app](https://certified.app) or any ATProto provider. A wallet will be needed for on-chain funding once the [tokenization layer](/core-concepts/funding-and-value-flow) is built. -#### Can I use my Bluesky account? +## Can I use my Bluesky account? Yes. Bluesky accounts are ATProto accounts. Your existing DID and identity work with Hypercerts out of the box. -#### Is my data public? +## Is my data public? Yes. All records are public by default. Do not store sensitive personal information in hypercert records. See the privacy section in [Testing & Deployment](/getting-started/testing-and-deployment) for guidance on what to include and what to keep off-protocol. -#### Can I delete a hypercert? +## Can I delete a hypercert? You can delete records from your account. However, cached copies may persist in indexers temporarily. Once data is published, treat it as potentially permanent. -#### Who can evaluate my hypercert? +## Who can evaluate my hypercert? Anyone with an ATProto account. Evaluations are separate records created by the evaluator, linked to your hypercert via a strong reference. You don't control who evaluates your work. See [Working with Evaluations](/getting-started/working-with-evaluations). -#### How do I query hypercerts across the network? +## How do I query hypercerts across the network? Use the [Hyperindex](/tools/hyperindex) GraphQL API at `https://api.hi.gainforest.app/graphql`. It indexes all hypercert records across the network and supports filtering, search, and real-time subscriptions. -#### How do I fund a hypercert? +## How do I fund a hypercert? The on-chain funding layer is not yet implemented. The planned design freezes records before funding to ensure funders know exactly what they are paying for. See [Funding & Value Flow](/core-concepts/funding-and-value-flow). -#### Where do I get help? +## Where do I get help? - [GitHub](https://github.com/hypercerts-org) — source code, issues, and discussions - [Roadmap](/roadmap) — what's being built and what's next diff --git a/pages/roadmap.md b/pages/roadmap.md index ac9de81..6958a93 100644 --- a/pages/roadmap.md +++ b/pages/roadmap.md @@ -194,7 +194,7 @@ A system for linking ATProto DIDs to Ethereum/EVM wallet addresses via cryptogra **Flow:** -``` +```text 1. User authenticates with ATProto via OAuth 2. User connects EVM wallet 3. User signs EIP-712 typed message @@ -220,7 +220,7 @@ A system for linking ATProto DIDs to Ethereum/EVM wallet addresses via cryptogra A service that creates immutable backups of hypercert records on decentralized storage (Filecoin/IPFS). ATProto repositories are mutable — records can be updated or deleted. For high-stakes impact claims, immutable archival provides permanence, verifiability, and compliance with funding mechanisms that require immutable records. -``` +```text User's PDS record → StorageLink → Filecoin Cloud (immutable backup) ``` @@ -230,7 +230,7 @@ User's PDS record → StorageLink → Filecoin Cloud (immutable backup) An indexer that tracks onchain events related to Hypercerts (token mints, transfers, funding distributions). Creates a unified view across ATProto records and blockchain state — indexing tokenization events, tracking funding flows, and enabling queries like "show all funded activities for this project." -``` +```text Blockchain events → EVM Indexer → Hyperindex (unified view) ``` diff --git a/pages/tools/hyperboards.md b/pages/tools/hyperboards.md index d8a846d..7ecd006 100644 --- a/pages/tools/hyperboards.md +++ b/pages/tools/hyperboards.md @@ -31,7 +31,7 @@ Because boards pull data from ATProto repositories, the contributor information Hyperboards normalizes contributor weights into proportional tile areas using this formula: -``` +```text tileArea = contributorWeight / sumOfAllWeights ``` diff --git a/pages/tools/hyperindex.md b/pages/tools/hyperindex.md index 3f7c36e..b0bf0a9 100644 --- a/pages/tools/hyperindex.md +++ b/pages/tools/hyperindex.md @@ -18,7 +18,7 @@ Built in Go on [bluesky-social/indigo](https://github.com/bluesky-social/indigo) Hyperindex connects to the AT Protocol network via Jetstream (a real-time event stream). It watches for records matching your configured lexicons, parses them, and stores them in a queryable database (SQLite or PostgreSQL). It then exposes a GraphQL API for querying the indexed data. -``` +```text Jetstream ──→ Consumer ──→ Records DB ──→ GraphQL API │ Activity Log ──→ Admin Dashboard diff --git a/pages/tools/scaffold.md b/pages/tools/scaffold.md index 4e813ba..433a69c 100644 --- a/pages/tools/scaffold.md +++ b/pages/tools/scaffold.md @@ -180,14 +180,14 @@ ATProto has no built-in reverse lookup — given a hypercert URI, there is no na Constellation indexes ATProto records and returns all records that reference a given subject URI. The scaffold queries three source paths: -- Attachments: `org.hypercerts.claim.attachment:subjects[com.atproto.repo.strongRef].uri` -- Evaluations: `org.hypercerts.claim.evaluation:subject.uri` -- Measurements: `org.hypercerts.claim.measurement:subject.uri` +- Attachments: `org.hypercerts.context.attachment:subjects[com.atproto.repo.strongRef].uri` +- Evaluations: `org.hypercerts.context.evaluation:subject.uri` +- Measurements: `org.hypercerts.context.measurement:subject.uri` The query hooks follow a two-step pattern: fetch backlink URIs from Constellation, then fetch each record's full data via Server Actions. This split is necessary because Constellation returns record identifiers, not record contents. ## Project structure -``` +```text hypercerts-scaffold/ ├── app/ │ ├── layout.tsx # Root layout (server component, wraps providers) @@ -294,4 +294,4 @@ hypercerts-scaffold/ └── vendor/ # Packed dependency tarballs (pre-release) ``` -`app/` contains pages (server components by default) and API routes. `lib/` is split: top-level files are server-only, while `lib/api/` is the client-side fetch layer that browser code calls. `providers/` has one server component (`SignedInProvider`, which handles the auth gate and renders the Navbar) and one client component (`AllProviders`, which sets up the TanStack Query client). `queries/` is entirely client-side TanStack Query hooks. `components/` is entirely client-side React components. \ No newline at end of file +`app/` contains pages (server components by default) and API routes. `lib/` is split: top-level files are server-only, while `lib/api/` is the client-side fetch layer that browser code calls. `providers/` has one server component (`SignedInProvider`, which handles the auth gate and renders the Navbar) and one client component (`AllProviders`, which sets up the TanStack Query client). `queries/` is entirely client-side TanStack Query hooks. `components/` is entirely client-side React components. diff --git a/public/raw/architecture/data-flow-and-lifecycle.md b/public/raw/architecture/data-flow-and-lifecycle.md index cfddd93..4ef428b 100644 --- a/public/raw/architecture/data-flow-and-lifecycle.md +++ b/public/raw/architecture/data-flow-and-lifecycle.md @@ -60,11 +60,11 @@ Contributors are embedded in the activity claim's `contributors` array. For rich #### Attachment Records -`org.hypercerts.claim.attachment` records attach supporting documentation. Attachments can be URLs, file uploads, or structured data. Each attachment record includes a strong reference to the claim it supports. +`org.hypercerts.context.attachment` records attach supporting documentation. Attachments can be URLs, file uploads, or structured data. Each attachment record includes a strong reference to the claim it supports. #### Measurement Records -`org.hypercerts.claim.measurement` records provide quantitative data. A measurement specifies what was measured, the value, the unit, and the methodology. Multiple measurements can track different metrics. +`org.hypercerts.context.measurement` records provide quantitative data. A measurement specifies what was measured, the value, the unit, and the methodology. Multiple measurements can track different metrics. #### Rights Records @@ -98,7 +98,7 @@ at://did:alice/... at://did:bob/... at://did:carol/ Third parties assess the work by creating evaluation records on their own servers. -An evaluator creates an `org.hypercerts.claim.evaluation` record on their PDS. The evaluation includes a `subject` field with a strong reference to the activity claim. Strong references include both the AT-URI and the CID (content hash), ensuring the evaluation references a specific version of the claim. +An evaluator creates an `org.hypercerts.context.evaluation` record on their PDS. The evaluation includes a `subject` field with a strong reference to the activity claim. Strong references include both the AT-URI and the CID (content hash), ensuring the evaluation references a specific version of the claim. The evaluation record includes the evaluator's assessment. This can be a score, a category, structured feedback, or a link to a detailed report. The lexicon allows flexible evaluation formats. diff --git a/public/raw/core-concepts/cel-work-scopes.md b/public/raw/core-concepts/cel-work-scopes.md index 5df2b91..b58d649 100644 --- a/public/raw/core-concepts/cel-work-scopes.md +++ b/public/raw/core-concepts/cel-work-scopes.md @@ -193,7 +193,7 @@ Every CEL expression evaluates against a typed context. Each variable maps to da ## Starter tag vocabulary -`workScopeTag` records are published as ATProto records that anyone can reference via strong references. [Certified](https://certified.ink) publishes curated tag sets for specific domains. Here's an example for regenerative work: +`workScopeTag` records are published as ATProto records that anyone can reference via strong references. [Certified](https://certified.app) publishes curated tag sets for specific domains. Here's an example for regenerative work: | Domain | Example tags | |--------|-------------| diff --git a/public/raw/core-concepts/certified-identity.md b/public/raw/core-concepts/certified-identity.md index 1ff6f18..9d7d31a 100644 --- a/public/raw/core-concepts/certified-identity.md +++ b/public/raw/core-concepts/certified-identity.md @@ -25,7 +25,7 @@ Your DID resolves via the [PLC directory](https://plc.directory) to a DID docume |-------|---------------------| | **Data** | Every record (activity claims, evaluations, measurements) carries the author's DID. The PDS signs records into a Merkle tree, making authorship tamper-evident. | | **Trust** | Evaluators build reputation tied to their DID. Applications can weight evaluations based on the evaluator's history and credentials. | -| **Funding** | Funding receipts link funder DIDs to the work they support. Wallet linkage (work-in-progress) connects DIDs to onchain addresses for payment flows and tokenization. | +| **Funding** | Funding receipts link funder DIDs to the work they support. Wallet linkage (work-in-progress) connects DIDs to on-chain addresses for payment flows and tokenization. | | **Portability** | Switching PDS providers doesn't change your DID. Your entire history — claims, evaluations, contributions — migrates with you. | ## Certified: the reference identity provider @@ -52,7 +52,7 @@ Hypercerts is fully interoperable with the AT Protocol ecosystem. If you already ## Wallet linkage -To receive onchain funding, a DID needs to be linked to an onchain wallet address. This is handled by [**IdentityLink**](https://identitylink.vercel.app/) — a cryptographic attestation system that binds a DID to one or more onchain addresses via a signed proof stored in your PDS. For the Ethereum ecosystem this looks like: +To receive on-chain funding, a DID needs to be linked to an on-chain wallet address. This is handled by [**IdentityLink**](https://identitylink.vercel.app/) — a cryptographic attestation system that binds a DID to one or more on-chain addresses via a signed proof stored in your PDS. For the Ethereum ecosystem this looks like: 1. Authenticates the user via ATProto OAuth 2. Connects an EVM wallet (EOA, Smart Wallet, or Safe) diff --git a/public/raw/core-concepts/funding-and-value-flow.md b/public/raw/core-concepts/funding-and-value-flow.md index 8edfc92..07a1df4 100644 --- a/public/raw/core-concepts/funding-and-value-flow.md +++ b/public/raw/core-concepts/funding-and-value-flow.md @@ -42,7 +42,7 @@ Funding receipts are typically created by a **facilitator** — a payment proces | Scenario | Facilitator | Verification | |----------|-------------|--------------| -| **Onchain funding** | A funding app verifies the transaction and creates the receipt, linking the transaction hash and chain ID | Verifiable onchain | +| **On-chain funding** | A funding app verifies the transaction and creates the receipt, linking the transaction hash and chain ID | Verifiable on-chain | | **Card / bank transfer** | A payment processor settles the payment and creates the receipt | Trust in the processor | | **Grant platform** | The grant platform records the award and creates the receipt on behalf of the funder | Trust in the platform | @@ -56,7 +56,7 @@ The protocol does not enforce that projects or funders disclose their funding Tokenization is under active development. This section describes the planned architecture. {% /callout %} -A hypercert can optionally be wrapped in an onchain token. This gives funders a programmable proof of their contribution. Tokenization is an optional wrapper around a claim snapshot; the canonical record remains the AT Protocol data. +A hypercert can optionally be wrapped in an on-chain token. This gives funders a programmable proof of their contribution. Tokenization is an optional wrapper around a claim snapshot; the canonical record remains the AT Protocol data. When locking is available, a claim can be frozen before tokenization. This gives funders a stronger guarantee — the claim they reviewed is exactly the claim they funded, and it cannot change after the fact. @@ -105,4 +105,3 @@ Two years later, Eve assesses the health of Alice's trees and publishes a positi - [Architecture Overview](/architecture/overview) — how the full protocol stack fits together - [Data Flow & Lifecycle](/architecture/data-flow-and-lifecycle) — how a hypercert moves through the system - diff --git a/public/raw/core-concepts/hypercerts-core-data-model.md b/public/raw/core-concepts/hypercerts-core-data-model.md index f748b13..2d2e6bc 100644 --- a/public/raw/core-concepts/hypercerts-core-data-model.md +++ b/public/raw/core-concepts/hypercerts-core-data-model.md @@ -45,13 +45,13 @@ The following diagram shows record types and how they reference the activity cla {% figure src="/images/hypercert-erd.svg" alt="Hypercert record relationships" /%} -The diagram includes a **token** entity — tokenization (anchoring a hypercert onchain) is not yet implemented. +The diagram includes a **token** entity — tokenization (anchoring a hypercert on-chain) is not yet implemented. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| -| **Attachment** | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | `org.hypercerts.claim.attachment` | -| **Measurement** | Quantitative data — "12 pages written", "50 tons CO₂ reduced" | E.g. a third-party measurer or the project (self-reported) | `org.hypercerts.claim.measurement` | -| **Evaluation** | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | `org.hypercerts.claim.evaluation` | +| **Attachment** | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | `org.hypercerts.context.attachment` | +| **Measurement** | Quantitative data — "12 pages written", "50 tons CO₂ reduced" | E.g. a third-party measurer or the project (self-reported) | `org.hypercerts.context.measurement` | +| **Evaluation** | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | `org.hypercerts.context.evaluation` | ### Additional notes diff --git a/public/raw/getting-started/working-with-evaluations.md b/public/raw/getting-started/working-with-evaluations.md index 613a777..f29fd57 100644 --- a/public/raw/getting-started/working-with-evaluations.md +++ b/public/raw/getting-started/working-with-evaluations.md @@ -21,7 +21,7 @@ await agent.login({ // Create an evaluation of an activity claim const evaluation = await agent.com.atproto.repo.createRecord({ repo: agent.session.did, - collection: "org.hypercerts.claim.evaluation", + collection: "org.hypercerts.context.evaluation", record: { subject: { uri: "at://did:plc:xyz789/org.hypercerts.claim.activity/3k2j4h5g6f7d8s9a", @@ -29,7 +29,7 @@ const evaluation = await agent.com.atproto.repo.createRecord({ }, evaluators: ["did:plc:evaluator123"], summary: "Verified documentation updates. All 15 examples tested and working. High quality contribution with clear impact on developer experience.", - $type: "org.hypercerts.claim.evaluation", + $type: "org.hypercerts.context.evaluation", createdAt: new Date().toISOString(), }, }); @@ -46,7 +46,7 @@ Measurements provide quantitative data that supports your evaluation: ```typescript const measurement = await agent.com.atproto.repo.createRecord({ repo: agent.session.did, - collection: "org.hypercerts.claim.measurement", + collection: "org.hypercerts.context.measurement", record: { subject: { uri: "at://did:plc:xyz789/org.hypercerts.claim.activity/3k2j4h5g6f7d8s9a", @@ -60,7 +60,7 @@ const measurement = await agent.com.atproto.repo.createRecord({ methodURI: "https://example.com/analytics-methodology", evidenceURI: ["https://example.com/analytics-report.pdf"], comment: "Page view data collected over the first 30 days after publication.", - $type: "org.hypercerts.claim.measurement", + $type: "org.hypercerts.context.measurement", createdAt: new Date().toISOString(), }, }); diff --git a/public/raw/reference/faq.md b/public/raw/reference/faq.md index b3c5021..c499451 100644 --- a/public/raw/reference/faq.md +++ b/public/raw/reference/faq.md @@ -7,43 +7,43 @@ description: Common questions about building with Hypercerts. --- -#### What is a hypercert? +## What is a hypercert? A structured digital record of a contribution — who did what, when, where, and with what supporting documentation. You create one by writing an `org.hypercerts.claim.activity` record to your PDS. See the [Quickstart](/getting-started/quickstart). -#### How is this different from the previous (EVM-based) Hypercerts? +## How is this different from the previous (EVM-based) Hypercerts? The new protocol stores data on AT Protocol instead of purely on-chain. This gives you richer schemas, data portability, and lower costs. On-chain anchoring for funding is [planned](/core-concepts/funding-and-value-flow) but not yet implemented. -#### Do I need a blockchain wallet? +## Do I need a blockchain wallet? Not to create or evaluate hypercerts — you only need an account on [certified.app](https://certified.app) or any ATProto provider. A wallet will be needed for on-chain funding once the [tokenization layer](/core-concepts/funding-and-value-flow) is built. -#### Can I use my Bluesky account? +## Can I use my Bluesky account? Yes. Bluesky accounts are ATProto accounts. Your existing DID and identity work with Hypercerts out of the box. -#### Is my data public? +## Is my data public? Yes. All records are public by default. Do not store sensitive personal information in hypercert records. See the privacy section in [Testing & Deployment](/getting-started/testing-and-deployment) for guidance on what to include and what to keep off-protocol. -#### Can I delete a hypercert? +## Can I delete a hypercert? You can delete records from your account. However, cached copies may persist in indexers temporarily. Once data is published, treat it as potentially permanent. -#### Who can evaluate my hypercert? +## Who can evaluate my hypercert? Anyone with an ATProto account. Evaluations are separate records created by the evaluator, linked to your hypercert via a strong reference. You don't control who evaluates your work. See [Working with Evaluations](/getting-started/working-with-evaluations). -#### How do I query hypercerts across the network? +## How do I query hypercerts across the network? Use the [Hyperindex](/tools/hyperindex) GraphQL API at `https://api.hi.gainforest.app/graphql`. It indexes all hypercert records across the network and supports filtering, search, and real-time subscriptions. -#### How do I fund a hypercert? +## How do I fund a hypercert? The on-chain funding layer is not yet implemented. The planned design freezes records before funding to ensure funders know exactly what they are paying for. See [Funding & Value Flow](/core-concepts/funding-and-value-flow). -#### Where do I get help? +## Where do I get help? - [GitHub](https://github.com/hypercerts-org) — source code, issues, and discussions - [Roadmap](/roadmap) — what's being built and what's next diff --git a/public/raw/roadmap.md b/public/raw/roadmap.md index ac9de81..6958a93 100644 --- a/public/raw/roadmap.md +++ b/public/raw/roadmap.md @@ -194,7 +194,7 @@ A system for linking ATProto DIDs to Ethereum/EVM wallet addresses via cryptogra **Flow:** -``` +```text 1. User authenticates with ATProto via OAuth 2. User connects EVM wallet 3. User signs EIP-712 typed message @@ -220,7 +220,7 @@ A system for linking ATProto DIDs to Ethereum/EVM wallet addresses via cryptogra A service that creates immutable backups of hypercert records on decentralized storage (Filecoin/IPFS). ATProto repositories are mutable — records can be updated or deleted. For high-stakes impact claims, immutable archival provides permanence, verifiability, and compliance with funding mechanisms that require immutable records. -``` +```text User's PDS record → StorageLink → Filecoin Cloud (immutable backup) ``` @@ -230,7 +230,7 @@ User's PDS record → StorageLink → Filecoin Cloud (immutable backup) An indexer that tracks onchain events related to Hypercerts (token mints, transfers, funding distributions). Creates a unified view across ATProto records and blockchain state — indexing tokenization events, tracking funding flows, and enabling queries like "show all funded activities for this project." -``` +```text Blockchain events → EVM Indexer → Hyperindex (unified view) ``` diff --git a/public/raw/tools/hyperboards.md b/public/raw/tools/hyperboards.md index d8a846d..7ecd006 100644 --- a/public/raw/tools/hyperboards.md +++ b/public/raw/tools/hyperboards.md @@ -31,7 +31,7 @@ Because boards pull data from ATProto repositories, the contributor information Hyperboards normalizes contributor weights into proportional tile areas using this formula: -``` +```text tileArea = contributorWeight / sumOfAllWeights ``` diff --git a/public/raw/tools/hyperindex.md b/public/raw/tools/hyperindex.md index 3f7c36e..b0bf0a9 100644 --- a/public/raw/tools/hyperindex.md +++ b/public/raw/tools/hyperindex.md @@ -18,7 +18,7 @@ Built in Go on [bluesky-social/indigo](https://github.com/bluesky-social/indigo) Hyperindex connects to the AT Protocol network via Jetstream (a real-time event stream). It watches for records matching your configured lexicons, parses them, and stores them in a queryable database (SQLite or PostgreSQL). It then exposes a GraphQL API for querying the indexed data. -``` +```text Jetstream ──→ Consumer ──→ Records DB ──→ GraphQL API │ Activity Log ──→ Admin Dashboard diff --git a/public/raw/tools/scaffold.md b/public/raw/tools/scaffold.md index 4e813ba..433a69c 100644 --- a/public/raw/tools/scaffold.md +++ b/public/raw/tools/scaffold.md @@ -180,14 +180,14 @@ ATProto has no built-in reverse lookup — given a hypercert URI, there is no na Constellation indexes ATProto records and returns all records that reference a given subject URI. The scaffold queries three source paths: -- Attachments: `org.hypercerts.claim.attachment:subjects[com.atproto.repo.strongRef].uri` -- Evaluations: `org.hypercerts.claim.evaluation:subject.uri` -- Measurements: `org.hypercerts.claim.measurement:subject.uri` +- Attachments: `org.hypercerts.context.attachment:subjects[com.atproto.repo.strongRef].uri` +- Evaluations: `org.hypercerts.context.evaluation:subject.uri` +- Measurements: `org.hypercerts.context.measurement:subject.uri` The query hooks follow a two-step pattern: fetch backlink URIs from Constellation, then fetch each record's full data via Server Actions. This split is necessary because Constellation returns record identifiers, not record contents. ## Project structure -``` +```text hypercerts-scaffold/ ├── app/ │ ├── layout.tsx # Root layout (server component, wraps providers) @@ -294,4 +294,4 @@ hypercerts-scaffold/ └── vendor/ # Packed dependency tarballs (pre-release) ``` -`app/` contains pages (server components by default) and API routes. `lib/` is split: top-level files are server-only, while `lib/api/` is the client-side fetch layer that browser code calls. `providers/` has one server component (`SignedInProvider`, which handles the auth gate and renders the Navbar) and one client component (`AllProviders`, which sets up the TanStack Query client). `queries/` is entirely client-side TanStack Query hooks. `components/` is entirely client-side React components. \ No newline at end of file +`app/` contains pages (server components by default) and API routes. `lib/` is split: top-level files are server-only, while `lib/api/` is the client-side fetch layer that browser code calls. `providers/` has one server component (`SignedInProvider`, which handles the auth gate and renders the Navbar) and one client component (`AllProviders`, which sets up the TanStack Query client). `queries/` is entirely client-side TanStack Query hooks. `components/` is entirely client-side React components. diff --git a/public/search-index.json b/public/search-index.json index 4e8c351..d4911a5 100644 --- a/public/search-index.json +++ b/public/search-index.json @@ -36,7 +36,7 @@ "What This Flow Enables", "Next Steps" ], - "body": "Data Flow & Lifecycle A hypercert flows through six stages from creation to ongoing accumulation of attachments and funding. The Lifecycle of a Hypercert Every hypercert follows a similar path through the system, though the timeline and participants vary. Creation happens when a contributor writes an activity claim to their Personal Data Server. The claim gets a unique identifier and becomes part of the contributor's repository. Enrichment adds supporting data. Contribution records link collaborators. Attachment records attach proof of work. Measurement records provide quantitative data. Rights records define the terms of the claim. Collection records group claims into projects. These can live on the same server or different servers. Evaluation brings third-party assessment. Evaluators create evaluation records on their own servers that reference the original claim. Multiple evaluators can independently assess the same work. Evaluations accumulate over time. Discovery makes the hypercert findable. Relays aggregate records from many servers. Indexers build searchable databases. Platforms query indexers to surface hypercerts to users. Funding connects funders to the claim. Funding receipts (org.hypercerts.funding.receipt) record who funded what, how much, and when — this works today on AT Protocol. Optionally, the claim can be frozen and anchored on-chain for tokenized funding. The on-chain tokenization layer is planned but not yet implemented. Accumulation continues indefinitely. More evaluations arrive. Additional attachments get attached. The data layer continues evolving. *On-chain layer is planned. See Funding & Value Flow. Stage 1: Creation A hypercert begins when a contributor creates an activity claim on their PDS. The contributor writes an org.hypercerts.claim.activity record. This record includes fields like workScope, startDate, endDate, and contributors. The PDS validates the record against the lexicon schema. The record receives a unique AT-URI. The format is at://did:plc:abc123/org.hypercerts.claim.activity/tid where did:plc:abc123 is the contributor's DID and tid is a timestamp-based identifier. The PDS signs the record and includes it in the contributor's repository. The signature proves the contributor created this record at this time. The repository is a Merkle tree that provides tamper-evidence. The relay picks up the new record. Within seconds, the record is available to downstream consumers. Indexers can now discover and process it. Stage 2: Enrichment Supporting data gets attached through additional records that reference the activity claim. Contribution Records Contributors are embedded in the activity claim's contributors array. For richer profiles, separate org.hypercerts.claim.contributorInformation and org.hypercerts.claim.contribution records can be created and referenced. Contributions can be created by the original contributor or by collaborators on their own servers. Attachment Records org.hypercerts.claim.attachment records attach supporting documentation. Attachments can be URLs, file uploads, or structured data. Each attachment record includes a strong reference to the claim it supports. Measurement Records org.hypercerts.claim.measurement records provide quantitative data. A measurement specifies what was measured, the value, the unit, and the methodology. Multiple measurements can track different metrics. Rights Records org.hypercerts.claim.rights records define the rights associated with a hypercert — for example, public display rights, attribution licenses, or transferability terms. The activity claim references a rights record via a strong reference. Rights are defined using a name, type, and description, with an optional attached legal document. Location Records app.certified.location records anchor work geographically. A location record can specify a point, a region, or multiple areas. This enables geographic filtering and regional funding mechanisms. Collection Records org.hypercerts.collection records group multiple activity claims into a project or portfolio. Each collection has weighted items (strong references to activity claims or other collections), supporting recursive nesting. A collection with type=\"project\" represents a multi-year project composed of individual activity claims. Funding Receipts org.hypercerts.funding.receipt records track funding events. A receipt records who funded which activity, how much, through which payment rail, and when. Receipts reference the activity claim they fund. See Funding & Value Flow for details. Cross-Server References These records can live on different PDS instances. A contributor on PDS-A can create an activity claim. A collaborator on PDS-B can create a contribution record that references it. A collaborator on PDS-C can create an attachment. Strong references ensure the connections are tamper-evident. Stage 3: Evaluation Third parties assess the work by creating evaluation records on their own servers. An evaluator cre" + "body": "Data Flow & Lifecycle A hypercert flows through six stages from creation to ongoing accumulation of attachments and funding. The Lifecycle of a Hypercert Every hypercert follows a similar path through the system, though the timeline and participants vary. Creation happens when a contributor writes an activity claim to their Personal Data Server. The claim gets a unique identifier and becomes part of the contributor's repository. Enrichment adds supporting data. Contribution records link collaborators. Attachment records attach proof of work. Measurement records provide quantitative data. Rights records define the terms of the claim. Collection records group claims into projects. These can live on the same server or different servers. Evaluation brings third-party assessment. Evaluators create evaluation records on their own servers that reference the original claim. Multiple evaluators can independently assess the same work. Evaluations accumulate over time. Discovery makes the hypercert findable. Relays aggregate records from many servers. Indexers build searchable databases. Platforms query indexers to surface hypercerts to users. Funding connects funders to the claim. Funding receipts (org.hypercerts.funding.receipt) record who funded what, how much, and when — this works today on AT Protocol. Optionally, the claim can be frozen and anchored on-chain for tokenized funding. The on-chain tokenization layer is planned but not yet implemented. Accumulation continues indefinitely. More evaluations arrive. Additional attachments get attached. The data layer continues evolving. *On-chain layer is planned. See Funding & Value Flow. Stage 1: Creation A hypercert begins when a contributor creates an activity claim on their PDS. The contributor writes an org.hypercerts.claim.activity record. This record includes fields like workScope, startDate, endDate, and contributors. The PDS validates the record against the lexicon schema. The record receives a unique AT-URI. The format is at://did:plc:abc123/org.hypercerts.claim.activity/tid where did:plc:abc123 is the contributor's DID and tid is a timestamp-based identifier. The PDS signs the record and includes it in the contributor's repository. The signature proves the contributor created this record at this time. The repository is a Merkle tree that provides tamper-evidence. The relay picks up the new record. Within seconds, the record is available to downstream consumers. Indexers can now discover and process it. Stage 2: Enrichment Supporting data gets attached through additional records that reference the activity claim. Contribution Records Contributors are embedded in the activity claim's contributors array. For richer profiles, separate org.hypercerts.claim.contributorInformation and org.hypercerts.claim.contribution records can be created and referenced. Contributions can be created by the original contributor or by collaborators on their own servers. Attachment Records org.hypercerts.context.attachment records attach supporting documentation. Attachments can be URLs, file uploads, or structured data. Each attachment record includes a strong reference to the claim it supports. Measurement Records org.hypercerts.context.measurement records provide quantitative data. A measurement specifies what was measured, the value, the unit, and the methodology. Multiple measurements can track different metrics. Rights Records org.hypercerts.claim.rights records define the rights associated with a hypercert — for example, public display rights, attribution licenses, or transferability terms. The activity claim references a rights record via a strong reference. Rights are defined using a name, type, and description, with an optional attached legal document. Location Records app.certified.location records anchor work geographically. A location record can specify a point, a region, or multiple areas. This enables geographic filtering and regional funding mechanisms. Collection Records org.hypercerts.collection records group multiple activity claims into a project or portfolio. Each collection has weighted items (strong references to activity claims or other collections), supporting recursive nesting. A collection with type=\"project\" represents a multi-year project composed of individual activity claims. Funding Receipts org.hypercerts.funding.receipt records track funding events. A receipt records who funded which activity, how much, through which payment rail, and when. Receipts reference the activity claim they fund. See Funding & Value Flow for details. Cross-Server References These records can live on different PDS instances. A contributor on PDS-A can create an activity claim. A collaborator on PDS-B can create a contribution record that references it. A collaborator on PDS-C can create an attachment. Strong references ensure the connections are tamper-evident. Stage 3: Evaluation Third parties assess the work by creating evaluation records on their own servers. An evaluator" }, { "path": "/architecture/epds", @@ -166,7 +166,7 @@ "Stage 4 — Retroactive funding", "See also" ], - "body": "Funding & Value Flow Funding is under active development. Hypercerts track the funding of activities without prescribing how funds flow — any payment method and any funding mechanism works. What hypercerts add is a structured, verifiable record of who funded what. Hypercerts work with any funding mechanism Funding can be prospective (before work begins) or retroactive (after outcomes are demonstrated). Different mechanisms suit different contexts, for example: | Mechanism | Description | |-----------|-------------| | Grant funding | Funders award grants to support planned activities | | Milestone-based funding | Funds are released as work reaches defined milestones | | Prize competitions | Awards for achieving specific outcomes | | Quadratic funding | Small donations amplified through matching pools | | Sale of impact certificates | Funders purchase certificates representing completed work | | Auction of impact certificates | Competitive bidding on verified impact claims | Multiple mechanisms can coexist for the same activity — a project might receive a grant prospectively and sell impact certificates retroactively. Hypercerts tracks this accurately without double counting: every funding receipt references the specific activity claim it funds, making it possible to compute total funding per claim across all receipts. Tracking funding Funding tracking is in active development. Receipts and acknowledgements exist today. Hypercerts separate the tracking of funding from the flow of funds. Any existing payment infrastructure can work with hypercerts — the protocol simply records the fact that funding happened. The protocol tracks funding through the org.hypercerts.funding.receipt record. A funding receipt records who funded which activity, how much, and when — creating a verifiable funding trail. The receipt references the activity claim it funds, linking the funding record to the work it supports. Funding receipts are typically created by a facilitator — a payment processor, grant platform, funding app, or other intermediary that processes the payment and creates the receipt. The facilitator acts as a neutral third party, giving the receipt more credibility than a self-reported claim. | Scenario | Facilitator | Verification | |----------|-------------|--------------| | Onchain funding | A funding app verifies the transaction and creates the receipt, linking the transaction hash and chain ID | Verifiable onchain | | Card / bank transfer | A payment processor settles the payment and creates the receipt | Trust in the processor | | Grant platform | The grant platform records the award and creates the receipt on behalf of the funder | Trust in the platform | The funder or the contributor can then create an acknowledgement — a counter-signature confirming the receipt's accuracy — to strengthen its credibility. The protocol does not enforce that projects or funders disclose their funding — creating a receipt is voluntary. Funders can also choose to remain anonymous in the public record; a receipt can track a contribution without revealing the funder's identity. Tokenization Tokenization is under active development. This section describes the planned architecture. A hypercert can optionally be wrapped in an onchain token. This gives funders a programmable proof of their contribution. Tokenization is an optional wrapper around a claim snapshot; the canonical record remains the AT Protocol data. When locking is available, a claim can be frozen before tokenization. This gives funders a stronger guarantee — the claim they reviewed is exactly the claim they funded, and it cannot change after the fact. | Property | Detail | |----------|--------| | Token standards | ERC-20, ERC-1155, or custom — different standards on different chains | | Transferability | Ranges from non-transferable recognition to fully transferable certificates | | Single-wrap constraint | Every claim can only be wrapped in a token once, preventing double counting | | Rights | Optional definition of the rights of the owners, set in the hypercert's org.hypercerts.claim.rights record | Tokenization enables programmable funding — smart contract logic can enforce distribution rules, matching formulas, and other mechanisms that would be difficult to coordinate offchain. Example: from creation to funding There are many different flows that can be represented with hypercerts. Below is one example that follows a hypercert from creation to funding. Stage 1 — Creation and evaluation Alice plants 500 trees in a reforestation project and creates an activity claim with measurements and attachments. Bob, an environmental auditor, evaluates the claim from his own PDS. See Quickstart for a walkthrough. Stage 2 — Funding Carol, a climate funder, reviews Alice's claim and Bob's evaluation. She decides to fund Alice's work through her organization's grant platform. The payment facilitator processes the payment and creates a funding receipt, recording Carol's contribution an" + "body": "Funding & Value Flow Funding is under active development. Hypercerts track the funding of activities without prescribing how funds flow — any payment method and any funding mechanism works. What hypercerts add is a structured, verifiable record of who funded what. Hypercerts work with any funding mechanism Funding can be prospective (before work begins) or retroactive (after outcomes are demonstrated). Different mechanisms suit different contexts, for example: | Mechanism | Description | |-----------|-------------| | Grant funding | Funders award grants to support planned activities | | Milestone-based funding | Funds are released as work reaches defined milestones | | Prize competitions | Awards for achieving specific outcomes | | Quadratic funding | Small donations amplified through matching pools | | Sale of impact certificates | Funders purchase certificates representing completed work | | Auction of impact certificates | Competitive bidding on verified impact claims | Multiple mechanisms can coexist for the same activity — a project might receive a grant prospectively and sell impact certificates retroactively. Hypercerts tracks this accurately without double counting: every funding receipt references the specific activity claim it funds, making it possible to compute total funding per claim across all receipts. Tracking funding Funding tracking is in active development. Receipts and acknowledgements exist today. Hypercerts separate the tracking of funding from the flow of funds. Any existing payment infrastructure can work with hypercerts — the protocol simply records the fact that funding happened. The protocol tracks funding through the org.hypercerts.funding.receipt record. A funding receipt records who funded which activity, how much, and when — creating a verifiable funding trail. The receipt references the activity claim it funds, linking the funding record to the work it supports. Funding receipts are typically created by a facilitator — a payment processor, grant platform, funding app, or other intermediary that processes the payment and creates the receipt. The facilitator acts as a neutral third party, giving the receipt more credibility than a self-reported claim. | Scenario | Facilitator | Verification | |----------|-------------|--------------| | On-chain funding | A funding app verifies the transaction and creates the receipt, linking the transaction hash and chain ID | Verifiable on-chain | | Card / bank transfer | A payment processor settles the payment and creates the receipt | Trust in the processor | | Grant platform | The grant platform records the award and creates the receipt on behalf of the funder | Trust in the platform | The funder or the contributor can then create an acknowledgement — a counter-signature confirming the receipt's accuracy — to strengthen its credibility. The protocol does not enforce that projects or funders disclose their funding — creating a receipt is voluntary. Funders can also choose to remain anonymous in the public record; a receipt can track a contribution without revealing the funder's identity. Tokenization Tokenization is under active development. This section describes the planned architecture. A hypercert can optionally be wrapped in an on-chain token. This gives funders a programmable proof of their contribution. Tokenization is an optional wrapper around a claim snapshot; the canonical record remains the AT Protocol data. When locking is available, a claim can be frozen before tokenization. This gives funders a stronger guarantee — the claim they reviewed is exactly the claim they funded, and it cannot change after the fact. | Property | Detail | |----------|--------| | Token standards | ERC-20, ERC-1155, or custom — different standards on different chains | | Transferability | Ranges from non-transferable recognition to fully transferable certificates | | Single-wrap constraint | Every claim can only be wrapped in a token once, preventing double counting | | Rights | Optional definition of the rights of the owners, set in the hypercert's org.hypercerts.claim.rights record | Tokenization enables programmable funding — smart contract logic can enforce distribution rules, matching formulas, and other mechanisms that would be difficult to coordinate offchain. Example: from creation to funding There are many different flows that can be represented with hypercerts. Below is one example that follows a hypercert from creation to funding. Stage 1 — Creation and evaluation Alice plants 500 trees in a reforestation project and creates an activity claim with measurements and attachments. Bob, an environmental auditor, evaluates the claim from his own PDS. See Quickstart for a walkthrough. Stage 2 — Funding Carol, a climate funder, reviews Alice's claim and Bob's evaluation. She decides to fund Alice's work through her organization's grant platform. The payment facilitator processes the payment and creates a funding receipt, recording Carol's contribution" }, { "path": "/core-concepts/hypercerts-core-data-model", @@ -183,7 +183,7 @@ "Mutability", "What happens next" ], - "body": "Core Data Model A hypercert is an activity claim with linked records that describe work done. The activity claim is the anchor — contributions, attachments, measurements, and evaluations reference it to add context. This page explains what records exist, what they contain, and how they connect. The core record: activity claim Every hypercert starts with an activity claim — the central record that answers four questions: | Dimension | Question | Example | |-----------|----------|---------| | Contributors | Who is doing (or did) the work? | Alice, Bob | | Work scope | What are they doing (or what did they do)? | Documentation, Reforestation | | Time of work | When is it happening (or when did it happen)? | January – March 2026 | | Location | Where is it taking (or did it take) place? | Coastal Kenya | The activity claim gets a permanent AT-URI like at://did:plc:alice123/org.hypercerts.claim.activity/3k7. Additional details The activity claim has a contributors array. Each entry is a contributor object with three fields: - contributorIdentity — either an inline identity object (#contributorIdentity, containing an identity DID string) or a strong reference to an org.hypercerts.claim.contributorInformation record with a full social profile - contributionWeight — an optional relative weight string (e.g. \"1\", \"0.5\") - contributionDetails — either an inline role object (#contributorRole, containing a role string) or a strong reference to an org.hypercerts.claim.contribution record with structured contribution data Simple cases use inline objects directly in the activity claim. Richer profiles use separate records that the contributor or project lead creates independently. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Contributor Information | Social profile, image, display name | The contributor or project lead | org.hypercerts.claim.contributorInformation | | Contribution | Structured role and contribution data | The contributor or project lead | org.hypercerts.claim.contribution | Records that attach to a hypercert Other records link to the activity claim to add context. Again, each is a separate record with its own AT-URI – they reference the activity claim, not the other way around. The following diagram shows record types and how they reference the activity claim. Records can be created by different people and live in different repositories. The diagram includes a token entity — tokenization (anchoring a hypercert onchain) is not yet implemented. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Attachment | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | org.hypercerts.claim.attachment | | Measurement | Quantitative data — \"12 pages written\", \"50 tons CO₂ reduced\" | E.g. a third-party measurer or the project (self-reported) | org.hypercerts.claim.measurement | | Evaluation | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | org.hypercerts.claim.evaluation | Additional notes - Records don't have to be created together. Users can create a measurement first and link it to an activity claim later. - A record can also be linked to multiple other records, e.g. a measurement in a bioregion is linked to multiple activity claims. - An evaluator creates an evaluation from their own account — it references an activity claim but lives in their personal data server. This means a hypercert grows over time – it is a living record. The core claim stays the same, but attachments, measurements, and evaluations accumulate around it. Grouping hypercerts Hypercerts can be grouped into collections. A multi-year project might have one hypercert per year, with a collection representing the full project. But collections are flexible — anyone can create one for any purpose. Someone might curate a personal collection of hypercerts they find interesting, or an organization might group all their hypercerts together. A hypercert can belong to many collections. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Collection | Groups activity claims and/or other collections into a project or portfolio. Supports recursive nesting. | E.g. the project organizer | org.hypercerts.collection | How records connect Records reference each other using strong references — if a referenced record is modified after the reference was created, the change is detectable. Mutability Activity claims and their linked records are currently immutable once created. Record versioning and edit history will be supported in a future release, along with the ability to lock a hypercert at a specific version for funding. What happens next Once you understand the data model, you're ready to build: - Quickstart — create " + "body": "Core Data Model A hypercert is an activity claim with linked records that describe work done. The activity claim is the anchor — contributions, attachments, measurements, and evaluations reference it to add context. This page explains what records exist, what they contain, and how they connect. The core record: activity claim Every hypercert starts with an activity claim — the central record that answers four questions: | Dimension | Question | Example | |-----------|----------|---------| | Contributors | Who is doing (or did) the work? | Alice, Bob | | Work scope | What are they doing (or what did they do)? | Documentation, Reforestation | | Time of work | When is it happening (or when did it happen)? | January – March 2026 | | Location | Where is it taking (or did it take) place? | Coastal Kenya | The activity claim gets a permanent AT-URI like at://did:plc:alice123/org.hypercerts.claim.activity/3k7. Additional details The activity claim has a contributors array. Each entry is a contributor object with three fields: - contributorIdentity — either an inline identity object (#contributorIdentity, containing an identity DID string) or a strong reference to an org.hypercerts.claim.contributorInformation record with a full social profile - contributionWeight — an optional relative weight string (e.g. \"1\", \"0.5\") - contributionDetails — either an inline role object (#contributorRole, containing a role string) or a strong reference to an org.hypercerts.claim.contribution record with structured contribution data Simple cases use inline objects directly in the activity claim. Richer profiles use separate records that the contributor or project lead creates independently. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Contributor Information | Social profile, image, display name | The contributor or project lead | org.hypercerts.claim.contributorInformation | | Contribution | Structured role and contribution data | The contributor or project lead | org.hypercerts.claim.contribution | Records that attach to a hypercert Other records link to the activity claim to add context. Again, each is a separate record with its own AT-URI – they reference the activity claim, not the other way around. The following diagram shows record types and how they reference the activity claim. Records can be created by different people and live in different repositories. The diagram includes a token entity — tokenization (anchoring a hypercert onchain) is not yet implemented. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Attachment | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | org.hypercerts.context.attachment | | Measurement | Quantitative data — \"12 pages written\", \"50 tons CO₂ reduced\" | E.g. a third-party measurer or the project (self-reported) | org.hypercerts.context.measurement | | Evaluation | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | org.hypercerts.context.evaluation | Additional notes - Records don't have to be created together. Users can create a measurement first and link it to an activity claim later. - A record can also be linked to multiple other records, e.g. a measurement in a bioregion is linked to multiple activity claims. - An evaluator creates an evaluation from their own account — it references an activity claim but lives in their personal data server. This means a hypercert grows over time – it is a living record. The core claim stays the same, but attachments, measurements, and evaluations accumulate around it. Grouping hypercerts Hypercerts can be grouped into collections. A multi-year project might have one hypercert per year, with a collection representing the full project. But collections are flexible — anyone can create one for any purpose. Someone might curate a personal collection of hypercerts they find interesting, or an organization might group all their hypercerts together. A hypercert can belong to many collections. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Collection | Groups activity claims and/or other collections into a project or portfolio. Supports recursive nesting. | E.g. the project organizer | org.hypercerts.collection | How records connect Records reference each other using strong references — if a referenced record is modified after the reference was created, the change is detectable. Mutability Activity claims and their linked records are currently immutable once created. Record versioning and edit history will be supported in a future release, along with the ability to lock a hypercert at a specific version for funding. What happens next Once you understand the data model, you're ready to build: - Quickstart — c" }, { "path": "/core-concepts/what-is-hypercerts", @@ -495,7 +495,18 @@ "title": "FAQ", "description": "Common questions about building with Hypercerts.", "section": "Reference", - "headings": [], + "headings": [ + "What is a hypercert?", + "How is this different from the previous (EVM-based) Hypercerts?", + "Do I need a blockchain wallet?", + "Can I use my Bluesky account?", + "Is my data public?", + "Can I delete a hypercert?", + "Who can evaluate my hypercert?", + "How do I query hypercerts across the network?", + "How do I fund a hypercert?", + "Where do I get help?" + ], "body": "FAQ --- What is a hypercert? A structured digital record of a contribution — who did what, when, where, and with what supporting documentation. You create one by writing an org.hypercerts.claim.activity record to your PDS. See the Quickstart. How is this different from the previous (EVM-based) Hypercerts? The new protocol stores data on AT Protocol instead of purely on-chain. This gives you richer schemas, data portability, and lower costs. On-chain anchoring for funding is planned but not yet implemented. Do I need a blockchain wallet? Not to create or evaluate hypercerts — you only need an account on certified.app or any ATProto provider. A wallet will be needed for on-chain funding once the tokenization layer is built. Can I use my Bluesky account? Yes. Bluesky accounts are ATProto accounts. Your existing DID and identity work with Hypercerts out of the box. Is my data public? Yes. All records are public by default. Do not store sensitive personal information in hypercert records. See the privacy section in Testing & Deployment for guidance on what to include and what to keep off-protocol. Can I delete a hypercert? You can delete records from your account. However, cached copies may persist in indexers temporarily. Once data is published, treat it as potentially permanent. Who can evaluate my hypercert? Anyone with an ATProto account. Evaluations are separate records created by the evaluator, linked to your hypercert via a strong reference. You don't control who evaluates your work. See Working with Evaluations. How do I query hypercerts across the network? Use the Hyperindex GraphQL API at https://api.hi.gainforest.app/graphql. It indexes all hypercert records across the network and supports filtering, search, and real-time subscriptions. How do I fund a hypercert? The on-chain funding layer is not yet implemented. The planned design freezes records before funding to ensure funders know exactly what they are paying for. See Funding & Value Flow. Where do I get help? - GitHub — source code, issues, and discussions - Roadmap — what's being built and what's next" }, { diff --git a/public/sitemap.xml b/public/sitemap.xml index f0a39d4..873c881 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -2,222 +2,222 @@ https://docs.hypercerts.org/architecture/account-and-identity - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/architecture/data-flow-and-lifecycle - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/architecture/epds - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/architecture/indexers-and-discovery - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/architecture/overview - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/architecture/portability-and-scaling - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/core-concepts/cel-work-scopes - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/core-concepts/certified-identity - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/core-concepts/common-use-cases - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/core-concepts/funding-and-value-flow - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/core-concepts/hypercerts-core-data-model - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/core-concepts/what-is-hypercerts - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/core-concepts/why-at-protocol - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/ecosystem/why-we-need-hypercerts - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/getting-started/building-on-hypercerts - 2026-04-01 + 2026-04-02 0.8 https://docs.hypercerts.org/getting-started/quickstart - 2026-04-01 + 2026-04-02 0.8 https://docs.hypercerts.org/getting-started/testing-and-deployment - 2026-04-01 + 2026-04-02 0.8 https://docs.hypercerts.org/getting-started/working-with-evaluations - 2026-04-01 + 2026-04-02 0.8 https://docs.hypercerts.org/ - 2026-04-01 + 2026-04-02 1.0 https://docs.hypercerts.org/lexicons/certified-lexicons/badge-award - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/certified-lexicons/badge-definition - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/certified-lexicons/badge-response - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/certified-lexicons - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/certified-lexicons/location - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/certified-lexicons/profile - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/certified-lexicons/shared-defs - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/acknowledgement - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/activity-claim - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/attachment - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/collection - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/contribution - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/evaluation - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/funding-receipt - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/measurement - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/hypercerts-lexicons/rights - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/lexicons/introduction-to-lexicons - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/reference/faq - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/reference/glossary - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/roadmap - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/tools/hyperboards - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/tools/hypercerts-cli - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/tools/hyperindex - 2026-04-01 + 2026-04-02 0.6 https://docs.hypercerts.org/tools/scaffold - 2026-04-01 + 2026-04-02 0.6 From 976a2323ef1902fecc4eef93bb0608108bc02e46 Mon Sep 17 00:00:00 2001 From: kzoeps Date: Fri, 3 Apr 2026 01:02:38 +0600 Subject: [PATCH 3/3] beautify copy and view buttons --- components/CopyRawButton.js | 33 ++++++- lib/lastUpdated.json | 14 +-- public/raw/tools/hyperindex.md | 174 +++++++++++++++++++++++++++++++-- public/search-index.json | 22 ++++- styles/globals.css | 16 +++ 5 files changed, 240 insertions(+), 19 deletions(-) diff --git a/components/CopyRawButton.js b/components/CopyRawButton.js index a494e98..b8ec7b3 100644 --- a/components/CopyRawButton.js +++ b/components/CopyRawButton.js @@ -9,11 +9,14 @@ function getRawUrl(currentPath) { export function CopyRawButton() { const [copied, setCopied] = useState(false); const [copyError, setCopyError] = useState(false); + const [isCopying, setIsCopying] = useState(false); const router = useRouter(); const currentPath = router.asPath.split('#')[0].split('?')[0] || '/'; const rawUrl = getRawUrl(currentPath); const handleCopy = async () => { + setIsCopying(true); + try { const response = await fetch(rawUrl); if (!response.ok) throw new Error('Failed to load raw markdown'); @@ -38,6 +41,8 @@ export function CopyRawButton() { setCopyError(true); setCopied(false); setTimeout(() => setCopyError(false), 2000); + } finally { + setIsCopying(false); } }; @@ -47,8 +52,20 @@ export function CopyRawButton() { className="page-tools-button" onClick={handleCopy} type="button" + disabled={isCopying} > - {copied ? 'Copied' : copyError ? 'Copy failed' : 'Copy raw'} + + {isCopying ? 'Copying...' : copied ? 'Copied' : copyError ? 'Copy failed' : 'Copy raw'} - View raw + + View raw ); diff --git a/lib/lastUpdated.json b/lib/lastUpdated.json index 514a474..0c910a2 100644 --- a/lib/lastUpdated.json +++ b/lib/lastUpdated.json @@ -5,10 +5,10 @@ "/architecture/indexers-and-discovery": "2026-03-05T04:01:13+08:00", "/architecture/overview": "2026-03-05T20:46:24+08:00", "/architecture/portability-and-scaling": "2026-03-05T13:01:42+08:00", - "/core-concepts/cel-work-scopes": "2026-02-26T16:26:35+01:00", - "/core-concepts/certified-identity": "2026-03-14T20:43:33-07:00", + "/core-concepts/cel-work-scopes": "2026-04-01T19:28:36+06:00", + "/core-concepts/certified-identity": "2026-04-01T19:28:36+06:00", "/core-concepts/common-use-cases": "2026-03-05T12:52:26+08:00", - "/core-concepts/funding-and-value-flow": "2026-03-05T17:11:22+06:00", + "/core-concepts/funding-and-value-flow": "2026-04-01T19:28:36+06:00", "/core-concepts/hypercerts-core-data-model": "2026-04-01T19:28:36+06:00", "/core-concepts/what-is-hypercerts": "2026-03-05T03:40:14+08:00", "/core-concepts/why-at-protocol": "2026-03-05T21:06:04+08:00", @@ -36,11 +36,11 @@ "/lexicons/hypercerts-lexicons/measurement": "2026-03-24T12:56:03-07:00", "/lexicons/hypercerts-lexicons/rights": "2026-03-24T12:56:03-07:00", "/lexicons/introduction-to-lexicons": "2026-03-24T12:56:03-07:00", - "/reference/faq": "2026-03-14T20:43:33-07:00", + "/reference/faq": "2026-04-01T19:28:36+06:00", "/reference/glossary": "2026-03-14T20:43:33-07:00", - "/roadmap": "2026-03-05T20:17:36+06:00", - "/tools/hyperboards": "2026-03-09T15:56:42+08:00", + "/roadmap": "2026-04-01T19:28:36+06:00", + "/tools/hyperboards": "2026-04-01T19:28:36+06:00", "/tools/hypercerts-cli": "2026-03-05T12:30:00+06:00", - "/tools/hyperindex": "2026-02-20T19:42:03+08:00", + "/tools/hyperindex": "2026-04-03T00:18:36+06:00", "/tools/scaffold": "2026-04-01T19:28:36+06:00" } diff --git a/public/raw/tools/hyperindex.md b/public/raw/tools/hyperindex.md index b0bf0a9..d1fffea 100644 --- a/public/raw/tools/hyperindex.md +++ b/public/raw/tools/hyperindex.md @@ -16,16 +16,16 @@ Built in Go on [bluesky-social/indigo](https://github.com/bluesky-social/indigo) ## How it works -Hyperindex connects to the AT Protocol network via Jetstream (a real-time event stream). It watches for records matching your configured lexicons, parses them, and stores them in a queryable database (SQLite or PostgreSQL). It then exposes a GraphQL API for querying the indexed data. +Hyperindex is **Tap-first** (recommended). Tap handles ingestion and Hyperindex consumes Tap events, stores records, and exposes them via GraphQL. ```text -Jetstream ──→ Consumer ──→ Records DB ──→ GraphQL API - │ - Activity Log ──→ Admin Dashboard - -Backfill Worker ──→ AT Protocol Relay ──→ Records DB +ATProto Relay ──→ Tap ──→ Hyperindex Consumer ──→ Records DB ──→ GraphQL API + │ + Activity Log ──→ Admin Dashboard ``` +Jetstream mode still exists as a legacy/non-Tap mode, but Tap is the preferred setup. + ## Quick start ```bash @@ -39,7 +39,10 @@ Open [http://localhost:8080/graphiql/admin](http://localhost:8080/graphiql/admin ## Register lexicons -Lexicons define the AT Protocol record types you want to index. Register them via the Admin GraphQL API at `/graphiql/admin`: +Lexicons define the AT Protocol record types you want to index. You can register them via: + +1. Admin GraphQL API at `/graphiql/admin` +2. Client admin UI at `https:///lexicons` (you must log in with an admin DID) ```graphql mutation { @@ -82,6 +85,22 @@ query { } } } + +# With typed filter queries (title contains "Hypercerts") +query { + orgHypercertsClaimActivity( + first: 10 + where: { title: { contains: "Hypercerts" } } + ) { + edges { + node { + uri + title + createdAt + } + } + } +} ``` ## Endpoints @@ -96,6 +115,147 @@ query { | `/health` | Health check | | `/stats` | Server statistics | +## Deployment configuration + +Use this section when deploying Hyperindex (backend, Tap, and client). It lists the environment variables you should set first for a reliable initial deployment, followed by optional variables for advanced tuning. + +### Baseline deployment variables + +These are the variables you should set first to get a stable deployment running. + +### Hyperindex backend + +| Variable | Example | What it is for | +|---|---|---| +| `HOST` | `0.0.0.0` | Makes the app reachable in container runtime | +| `PORT` | `8080` | App port | +| `DATABASE_URL` | `sqlite:/data/hypergoat.db` | Main indexed-records database | +| `EXTERNAL_BASE_URL` | `https://hyperindex.example.com` | Public backend URL used by frontend/admin flows and GraphiQL links | +| `SECRET_KEY_BASE` | `` | Session/signing secret | +| `ADMIN_DIDS` | `did:plc:...` | DIDs with admin privileges | +| `TRUST_PROXY_HEADERS` | `true` | Trust forwarded auth headers from client proxy | +| `TAP_ENABLED` | `true` | Enables Tap mode | +| `TAP_URL` | `ws://tap.railway.internal:2480` | Tap websocket endpoint | +| `TAP_ADMIN_PASSWORD` | `` | Tap admin auth secret | +| `TAP_DISABLE_ACKS` | `true` or `false` | Controls ACK behavior for Tap consumer; set to `true` if ACK mode causes websocket reconnect/drop loops | + +> `TAP_DISABLE_ACKS` is configured on the **backend/indexer** service. +> **Note on `TAP_DISABLE_ACKS`** +> +> In some deployments, ACK mode (`TAP_DISABLE_ACKS=false`) can cause repeated websocket disconnect loops (for example: `connection reset by peer`, `close 1006`, frequent reconnect backoff). +> If you see that pattern, set `TAP_DISABLE_ACKS=true` on the **Hyperindex backend** to stabilize ingestion first, then investigate Tap resource/config compatibility before re-enabling ACK mode. + +### Tap service + +| Variable | Example | What it is for | +|---|---|---| +| `TAP_DATABASE_URL` | `sqlite:///data/tap.db` | Persists Tap cursor/state | +| `TAP_ADMIN_PASSWORD` | `` | Protects Tap admin routes | +| `TAP_COLLECTION_FILTERS` | `app.gainforest.*,app.certified.*,org.hypercerts.*` | Filters ingested record collections | +| `TAP_SIGNAL_COLLECTION` | `app.certified.actor.profile` | Signal collection for repo discovery | +| `TAP_FULL_NETWORK` | `true` / `false` | Full network tracking toggle | + +> `TAP_FULL_NETWORK=true` enables full-network tracking and triggers a broad historical backfill across discoverable repos. + +### Client (Next.js) + +| Variable | Example | What it is for | +|---|---|---| +| `NEXT_PUBLIC_API_URL` | `https://hyperindex.example.com` | Browser-side URL of your Hyperindex backend | +| `HYPERINDEX_URL` | `https://hyperindex.example.com` | Server-side URL of your Hyperindex backend (used by Next API proxy routes) | +| `PUBLIC_URL` | `https://hyperindex-frontend.example.com` | Client frontend URL used for OAuth client metadata and auth redirects | +| `COOKIE_SECRET` | `` | Session encryption | +| `ATPROTO_JWK_PRIVATE` | `` | Confidential OAuth signing key | + +### Optional variables + +Set these only when needed. + +### Backend +- `ALLOWED_ORIGINS` + +### Tap +- `TAP_FIREHOSE_PARALLELISM` +- `TAP_RESYNC_PARALLELISM` +- `TAP_OUTBOX_PARALLELISM` +- `TAP_MAX_DB_CONNS` +- `TAP_OUTBOX_CAPACITY` +- `TAP_NO_REPLAY` +- `TAP_REPO_FETCH_TIMEOUT` + +### Client +- Additional auth/provider-specific settings depending on deployment model + +## Common pitfalls + +- **Wrong variable on wrong service** + - `TAP_COLLECTION_FILTERS`, `TAP_SIGNAL_COLLECTION`, `TAP_FULL_NETWORK` belong to **Tap** + - `TAP_DISABLE_ACKS`, `TAP_ENABLED`, `TAP_URL` belong to **Hyperindex backend** + +- **Client works but admin requests fail** + - `HYPERINDEX_URL` is missing on the client deployment + - `NEXT_PUBLIC_API_URL` alone is not enough for server-side proxy routes + +- **`admin privileges required` while logged in** + - `TRUST_PROXY_HEADERS` is missing/false + - Logged-in DID is not present in `ADMIN_DIDS` + +- **Trailing slash URL issues** + - `PUBLIC_URL` must **not** include a trailing slash. + - Use: + - `https://hyperindex-frontend.example.com` ✅ + - `https://hyperindex-frontend.example.com/` ❌ + - A trailing slash can cause OAuth client metadata lookup errors (for example: `client_metadata not found`). + +- **Healthcheck confusion** + - Backend healthcheck should be `/health` + - Frontend usually uses `/` unless you explicitly add a `/health` route + +## Deploy on Railway + +### 1) Deploy Hyperindex backend + +1. Create a Railway service from the repository +2. Attach a persistent volume mounted to `/data` +3. Set healthcheck path to `/health` +4. Add backend variables from the baseline list above +5. Deploy + +### 2) Deploy Tap + +1. Create a Railway service from image: + `ghcr.io/bluesky-social/indigo/tap:latest` (or a pinned tag) +2. Attach a persistent volume mounted to `/data` +3. Add Tap variables from the baseline list above +4. Deploy + +### 3) Connect backend to Tap + +Set on backend service: + +- `TAP_ENABLED=true` +- `TAP_URL=ws://:2480` +- `TAP_ADMIN_PASSWORD=` + +Redeploy backend after updating these values. + +### 4) Deploy client (Next.js) + +Deploy client on Railway/Vercel/etc and set: + +- `NEXT_PUBLIC_API_URL=` +- `HYPERINDEX_URL=` +- auth/session vars (`PUBLIC_URL`, `COOKIE_SECRET`, `ATPROTO_JWK_PRIVATE`) as needed + +### Railway-specific DB path notes + +For mounted volumes at `/data`: + +- Backend SQLite: + - `DATABASE_URL=sqlite:/data/hypergoat.db` +- Tap SQLite: + - `TAP_DATABASE_URL=sqlite:///data/tap.db` + ## Running with Docker ```bash diff --git a/public/search-index.json b/public/search-index.json index d4911a5..0c3346e 100644 --- a/public/search-index.json +++ b/public/search-index.json @@ -135,7 +135,7 @@ "Wallet linkage", "Next steps" ], - "body": "Certified Identity Every hypercert record has an author. Every evaluation carries a signature. Every funding receipt traces back to a DID. Identity is a core primitive of the protocol — it determines who owns records, who can be trusted, and who receives funding. Identity in the Hypercerts Protocol The Hypercerts Protocol uses AT Protocol's identity system. Every participant — whether an individual contributor, an evaluator, or an organization — is identified by a DID (Decentralized Identifier). A DID like did:plc:z72i7hdynmk6r22z27h6tvur is: - Permanent — it never changes, even if you switch servers or handles - Portable — your records, reputation, and history follow your DID across platforms - Cryptographically verifiable — every record you create is signed by your DID's key pair, and anyone can verify the signature Your DID resolves via the PLC directory to a DID document containing your current PDS, public signing keys, and handle. How identity connects to the protocol | Layer | How identity is used | |-------|---------------------| | Data | Every record (activity claims, evaluations, measurements) carries the author's DID. The PDS signs records into a Merkle tree, making authorship tamper-evident. | | Trust | Evaluators build reputation tied to their DID. Applications can weight evaluations based on the evaluator's history and credentials. | | Funding | Funding receipts link funder DIDs to the work they support. Wallet linkage (work-in-progress) connects DIDs to onchain addresses for payment flows and tokenization. | | Portability | Switching PDS providers doesn't change your DID. Your entire history — claims, evaluations, contributions — migrates with you. | Certified: the reference identity provider Certified is the identity provider built for the Hypercerts ecosystem. It provisions the full identity stack in a single sign-up: - A DID — your permanent identifier - A PDS — your Personal Data Server, where records are stored - Low-friction sign-in — email and code, no passwords or protocol knowledge required Certified exists because most Hypercerts users are not Bluesky users. Researchers, land stewards, open-source maintainers, and funders need an entry point that doesn't require knowledge of ATProto or decentralized protocols. Certified provides that — a neutral identity provider that isn't tied to any single application. Handles (your public username) Handles are not needed to log in to the Hypercerts ecosystem, but every user has one. They serve as human-readable names for publicly addressing others and for interacting with other applications in the AT Protocol ecosystem that haven't implemented email-based login with Certified. Your handle (e.g., alice.certified.app) is human-readable but not permanent — it's a pointer to your DID. Organizations can use custom domain handles (e.g., numpy.org) to prove organizational identity through DNS verification. For setup details, see Account & Identity Setup. Compatible with Bluesky and other AT Protocol accounts Hypercerts is fully interoperable with the AT Protocol ecosystem. If you already have a Bluesky account or any other ATProto identity, you can log in with your existing handle (e.g., alice.bsky.social) and use all Hypercerts applications — no additional account needed. Wallet linkage To receive onchain funding, a DID needs to be linked to an onchain wallet address. This is handled by IdentityLink — a cryptographic attestation system that binds a DID to one or more onchain addresses via a signed proof stored in your PDS. For the Ethereum ecosystem this looks like: 1. Authenticates the user via ATProto OAuth 2. Connects an EVM wallet (EOA, Smart Wallet, or Safe) 3. Signs an EIP-712 typed message proving ownership 4. Stores the attestation in the user's PDS The attestation is self-sovereign (stored in your PDS, not a central database) and verifiable by anyone. See the Roadmap for current IdentityLink status. Next steps - Account & Identity Setup — create an account, configure custom domains, manage app passwords, and set up organization accounts - Architecture Overview — how identity fits into the protocol stack - Quickstart — create your first hypercert Next: Why AT Protocol? — how identity and records stay portable across apps." + "body": "Certified Identity Every hypercert record has an author. Every evaluation carries a signature. Every funding receipt traces back to a DID. Identity is a core primitive of the protocol — it determines who owns records, who can be trusted, and who receives funding. Identity in the Hypercerts Protocol The Hypercerts Protocol uses AT Protocol's identity system. Every participant — whether an individual contributor, an evaluator, or an organization — is identified by a DID (Decentralized Identifier). A DID like did:plc:z72i7hdynmk6r22z27h6tvur is: - Permanent — it never changes, even if you switch servers or handles - Portable — your records, reputation, and history follow your DID across platforms - Cryptographically verifiable — every record you create is signed by your DID's key pair, and anyone can verify the signature Your DID resolves via the PLC directory to a DID document containing your current PDS, public signing keys, and handle. How identity connects to the protocol | Layer | How identity is used | |-------|---------------------| | Data | Every record (activity claims, evaluations, measurements) carries the author's DID. The PDS signs records into a Merkle tree, making authorship tamper-evident. | | Trust | Evaluators build reputation tied to their DID. Applications can weight evaluations based on the evaluator's history and credentials. | | Funding | Funding receipts link funder DIDs to the work they support. Wallet linkage (work-in-progress) connects DIDs to on-chain addresses for payment flows and tokenization. | | Portability | Switching PDS providers doesn't change your DID. Your entire history — claims, evaluations, contributions — migrates with you. | Certified: the reference identity provider Certified is the identity provider built for the Hypercerts ecosystem. It provisions the full identity stack in a single sign-up: - A DID — your permanent identifier - A PDS — your Personal Data Server, where records are stored - Low-friction sign-in — email and code, no passwords or protocol knowledge required Certified exists because most Hypercerts users are not Bluesky users. Researchers, land stewards, open-source maintainers, and funders need an entry point that doesn't require knowledge of ATProto or decentralized protocols. Certified provides that — a neutral identity provider that isn't tied to any single application. Handles (your public username) Handles are not needed to log in to the Hypercerts ecosystem, but every user has one. They serve as human-readable names for publicly addressing others and for interacting with other applications in the AT Protocol ecosystem that haven't implemented email-based login with Certified. Your handle (e.g., alice.certified.app) is human-readable but not permanent — it's a pointer to your DID. Organizations can use custom domain handles (e.g., numpy.org) to prove organizational identity through DNS verification. For setup details, see Account & Identity Setup. Compatible with Bluesky and other AT Protocol accounts Hypercerts is fully interoperable with the AT Protocol ecosystem. If you already have a Bluesky account or any other ATProto identity, you can log in with your existing handle (e.g., alice.bsky.social) and use all Hypercerts applications — no additional account needed. Wallet linkage To receive on-chain funding, a DID needs to be linked to an on-chain wallet address. This is handled by IdentityLink — a cryptographic attestation system that binds a DID to one or more on-chain addresses via a signed proof stored in your PDS. For the Ethereum ecosystem this looks like: 1. Authenticates the user via ATProto OAuth 2. Connects an EVM wallet (EOA, Smart Wallet, or Safe) 3. Signs an EIP-712 typed message proving ownership 4. Stores the attestation in the user's PDS The attestation is self-sovereign (stored in your PDS, not a central database) and verifiable by anyone. See the Roadmap for current IdentityLink status. Next steps - Account & Identity Setup — create an account, configure custom domains, manage app passwords, and set up organization accounts - Architecture Overview — how identity fits into the protocol stack - Quickstart — create your first hypercert Next: Why AT Protocol? — how identity and records stay portable across apps." }, { "path": "/core-concepts/common-use-cases", @@ -183,7 +183,7 @@ "Mutability", "What happens next" ], - "body": "Core Data Model A hypercert is an activity claim with linked records that describe work done. The activity claim is the anchor — contributions, attachments, measurements, and evaluations reference it to add context. This page explains what records exist, what they contain, and how they connect. The core record: activity claim Every hypercert starts with an activity claim — the central record that answers four questions: | Dimension | Question | Example | |-----------|----------|---------| | Contributors | Who is doing (or did) the work? | Alice, Bob | | Work scope | What are they doing (or what did they do)? | Documentation, Reforestation | | Time of work | When is it happening (or when did it happen)? | January – March 2026 | | Location | Where is it taking (or did it take) place? | Coastal Kenya | The activity claim gets a permanent AT-URI like at://did:plc:alice123/org.hypercerts.claim.activity/3k7. Additional details The activity claim has a contributors array. Each entry is a contributor object with three fields: - contributorIdentity — either an inline identity object (#contributorIdentity, containing an identity DID string) or a strong reference to an org.hypercerts.claim.contributorInformation record with a full social profile - contributionWeight — an optional relative weight string (e.g. \"1\", \"0.5\") - contributionDetails — either an inline role object (#contributorRole, containing a role string) or a strong reference to an org.hypercerts.claim.contribution record with structured contribution data Simple cases use inline objects directly in the activity claim. Richer profiles use separate records that the contributor or project lead creates independently. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Contributor Information | Social profile, image, display name | The contributor or project lead | org.hypercerts.claim.contributorInformation | | Contribution | Structured role and contribution data | The contributor or project lead | org.hypercerts.claim.contribution | Records that attach to a hypercert Other records link to the activity claim to add context. Again, each is a separate record with its own AT-URI – they reference the activity claim, not the other way around. The following diagram shows record types and how they reference the activity claim. Records can be created by different people and live in different repositories. The diagram includes a token entity — tokenization (anchoring a hypercert onchain) is not yet implemented. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Attachment | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | org.hypercerts.context.attachment | | Measurement | Quantitative data — \"12 pages written\", \"50 tons CO₂ reduced\" | E.g. a third-party measurer or the project (self-reported) | org.hypercerts.context.measurement | | Evaluation | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | org.hypercerts.context.evaluation | Additional notes - Records don't have to be created together. Users can create a measurement first and link it to an activity claim later. - A record can also be linked to multiple other records, e.g. a measurement in a bioregion is linked to multiple activity claims. - An evaluator creates an evaluation from their own account — it references an activity claim but lives in their personal data server. This means a hypercert grows over time – it is a living record. The core claim stays the same, but attachments, measurements, and evaluations accumulate around it. Grouping hypercerts Hypercerts can be grouped into collections. A multi-year project might have one hypercert per year, with a collection representing the full project. But collections are flexible — anyone can create one for any purpose. Someone might curate a personal collection of hypercerts they find interesting, or an organization might group all their hypercerts together. A hypercert can belong to many collections. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Collection | Groups activity claims and/or other collections into a project or portfolio. Supports recursive nesting. | E.g. the project organizer | org.hypercerts.collection | How records connect Records reference each other using strong references — if a referenced record is modified after the reference was created, the change is detectable. Mutability Activity claims and their linked records are currently immutable once created. Record versioning and edit history will be supported in a future release, along with the ability to lock a hypercert at a specific version for funding. What happens next Once you understand the data model, you're ready to build: - Quickstart — c" + "body": "Core Data Model A hypercert is an activity claim with linked records that describe work done. The activity claim is the anchor — contributions, attachments, measurements, and evaluations reference it to add context. This page explains what records exist, what they contain, and how they connect. The core record: activity claim Every hypercert starts with an activity claim — the central record that answers four questions: | Dimension | Question | Example | |-----------|----------|---------| | Contributors | Who is doing (or did) the work? | Alice, Bob | | Work scope | What are they doing (or what did they do)? | Documentation, Reforestation | | Time of work | When is it happening (or when did it happen)? | January – March 2026 | | Location | Where is it taking (or did it take) place? | Coastal Kenya | The activity claim gets a permanent AT-URI like at://did:plc:alice123/org.hypercerts.claim.activity/3k7. Additional details The activity claim has a contributors array. Each entry is a contributor object with three fields: - contributorIdentity — either an inline identity object (#contributorIdentity, containing an identity DID string) or a strong reference to an org.hypercerts.claim.contributorInformation record with a full social profile - contributionWeight — an optional relative weight string (e.g. \"1\", \"0.5\") - contributionDetails — either an inline role object (#contributorRole, containing a role string) or a strong reference to an org.hypercerts.claim.contribution record with structured contribution data Simple cases use inline objects directly in the activity claim. Richer profiles use separate records that the contributor or project lead creates independently. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Contributor Information | Social profile, image, display name | The contributor or project lead | org.hypercerts.claim.contributorInformation | | Contribution | Structured role and contribution data | The contributor or project lead | org.hypercerts.claim.contribution | Records that attach to a hypercert Other records link to the activity claim to add context. Again, each is a separate record with its own AT-URI – they reference the activity claim, not the other way around. The following diagram shows record types and how they reference the activity claim. Records can be created by different people and live in different repositories. The diagram includes a token entity — tokenization (anchoring a hypercert on-chain) is not yet implemented. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Attachment | Supporting documentation — URLs, uploaded files, IPFS links. Can link to any record type, not only activity claims. | Anyone with additional data | org.hypercerts.context.attachment | | Measurement | Quantitative data — \"12 pages written\", \"50 tons CO₂ reduced\" | E.g. a third-party measurer or the project (self-reported) | org.hypercerts.context.measurement | | Evaluation | An (independent) assessment of the work | E.g. a third-party evaluator, community members, beneficiaries | org.hypercerts.context.evaluation | Additional notes - Records don't have to be created together. Users can create a measurement first and link it to an activity claim later. - A record can also be linked to multiple other records, e.g. a measurement in a bioregion is linked to multiple activity claims. - An evaluator creates an evaluation from their own account — it references an activity claim but lives in their personal data server. This means a hypercert grows over time – it is a living record. The core claim stays the same, but attachments, measurements, and evaluations accumulate around it. Grouping hypercerts Hypercerts can be grouped into collections. A multi-year project might have one hypercert per year, with a collection representing the full project. But collections are flexible — anyone can create one for any purpose. Someone might curate a personal collection of hypercerts they find interesting, or an organization might group all their hypercerts together. A hypercert can belong to many collections. | Record type | What it adds | Who creates it | Lexicon | |-------------|-------------|----------------|---------| | Collection | Groups activity claims and/or other collections into a project or portfolio. Supports recursive nesting. | E.g. the project organizer | org.hypercerts.collection | How records connect Records reference each other using strong references — if a referenced record is modified after the reference was created, the change is detectable. Mutability Activity claims and their linked records are currently immutable once created. Record versioning and edit history will be supported in a future release, along with the ability to lock a hypercert at a specific version for funding. What happens next Once you understand the data model, you're ready to build: - Quickstart — " }, { "path": "/core-concepts/what-is-hypercerts", @@ -596,10 +596,26 @@ "Register lexicons", "Query via GraphQL", "Endpoints", + "Deployment configuration", + "Baseline deployment variables", + "Hyperindex backend", + "Tap service", + "Client (Next.js)", + "Optional variables", + "Backend", + "Tap", + "Client", + "Common pitfalls", + "Deploy on Railway", + "1) Deploy Hyperindex backend", + "2) Deploy Tap", + "3) Connect backend to Tap", + "4) Deploy client (Next.js)", + "Railway-specific DB path notes", "Running with Docker", "Learn more" ], - "body": "Hyperindex Hyperindex (hi) is a Go AT Protocol AppView server that indexes records and exposes them via GraphQL. Use it to: - Index all hypercert-related records from the ATProto network in real time - Query indexed data through a typed GraphQL API - Backfill historical records from any user or the entire network - Run your own indexer for full control over data availability and query performance Built in Go on bluesky-social/indigo. Source: github.com/hypercerts-org/hyperindex. How it works Hyperindex connects to the AT Protocol network via Jetstream (a real-time event stream). It watches for records matching your configured lexicons, parses them, and stores them in a queryable database (SQLite or PostgreSQL). It then exposes a GraphQL API for querying the indexed data. Quick start Open http://localhost:8080/graphiql/admin to access the admin interface. Register lexicons Lexicons define the AT Protocol record types you want to index. Register them via the Admin GraphQL API at /graphiql/admin: Or place lexicon JSON files in a directory and set the LEXICON_DIR environment variable. For hypercerts, you would register the org.hypercerts.claim.* lexicons — see Introduction to Lexicons for the full list. Query via GraphQL Access your indexed data at /graphql: Endpoints | Endpoint | Description | |---|---| | /graphql | Public GraphQL API | | /graphql/ws | GraphQL subscriptions (WebSocket) | | /admin/graphql | Admin GraphQL API | | /graphiql | GraphQL playground (public API) | | /graphiql/admin | GraphQL playground (admin API) | | /health | Health check | | /stats | Server statistics | Running with Docker Learn more - GitHub repository — source code, issues, and documentation - Indexers & Discovery — how indexers fit into the Hypercerts architecture - Building on Hypercerts — integration patterns for platforms and tools" + "body": "Hyperindex Hyperindex (hi) is a Go AT Protocol AppView server that indexes records and exposes them via GraphQL. Use it to: - Index all hypercert-related records from the ATProto network in real time - Query indexed data through a typed GraphQL API - Backfill historical records from any user or the entire network - Run your own indexer for full control over data availability and query performance Built in Go on bluesky-social/indigo. Source: github.com/hypercerts-org/hyperindex. How it works Hyperindex is Tap-first (recommended). Tap handles ingestion and Hyperindex consumes Tap events, stores records, and exposes them via GraphQL. Jetstream mode still exists as a legacy/non-Tap mode, but Tap is the preferred setup. Quick start Open http://localhost:8080/graphiql/admin to access the admin interface. Register lexicons Lexicons define the AT Protocol record types you want to index. You can register them via: 1. Admin GraphQL API at /graphiql/admin 2. Client admin UI at https:///lexicons (you must log in with an admin DID) Or place lexicon JSON files in a directory and set the LEXICON_DIR environment variable. For hypercerts, you would register the org.hypercerts.claim. lexicons — see Introduction to Lexicons for the full list. Query via GraphQL Access your indexed data at /graphql: Endpoints | Endpoint | Description | |---|---| | /graphql | Public GraphQL API | | /graphql/ws | GraphQL subscriptions (WebSocket) | | /admin/graphql | Admin GraphQL API | | /graphiql | GraphQL playground (public API) | | /graphiql/admin | GraphQL playground (admin API) | | /health | Health check | | /stats | Server statistics | Deployment configuration Use this section when deploying Hyperindex (backend, Tap, and client). It lists the environment variables you should set first for a reliable initial deployment, followed by optional variables for advanced tuning. Baseline deployment variables These are the variables you should set first to get a stable deployment running. Hyperindex backend | Variable | Example | What it is for | |---|---|---| | HOST | 0.0.0.0 | Makes the app reachable in container runtime | | PORT | 8080 | App port | | DATABASE_URL | sqlite:/data/hypergoat.db | Main indexed-records database | | EXTERNAL_BASE_URL | https://hyperindex.example.com | Public backend URL used by frontend/admin flows and GraphiQL links | | SECRET_KEY_BASE | ` | Session/signing secret | | ADMIN_DIDS | did:plc:... | DIDs with admin privileges | | TRUST_PROXY_HEADERS | true | Trust forwarded auth headers from client proxy | | TAP_ENABLED | true | Enables Tap mode | | TAP_URL | ws://tap.railway.internal:2480 | Tap websocket endpoint | | TAP_ADMIN_PASSWORD | | Tap admin auth secret | | TAP_DISABLE_ACKS | true or false | Controls ACK behavior for Tap consumer; set to true if ACK mode causes websocket reconnect/drop loops | > TAP_DISABLE_ACKS is configured on the backend/indexer service. > Note on TAP_DISABLE_ACKS > > In some deployments, ACK mode (TAP_DISABLE_ACKS=false) can cause repeated websocket disconnect loops (for example: connection reset by peer, close 1006, frequent reconnect backoff). > If you see that pattern, set TAP_DISABLE_ACKS=true on the Hyperindex backend to stabilize ingestion first, then investigate Tap resource/config compatibility before re-enabling ACK mode. Tap service | Variable | Example | What it is for | |---|---|---| | TAP_DATABASE_URL | sqlite:///data/tap.db | Persists Tap cursor/state | | TAP_ADMIN_PASSWORD | | Protects Tap admin routes | | TAP_COLLECTION_FILTERS | app.gainforest.,app.certified.,org.hypercerts. | Filters ingested record collections | | TAP_SIGNAL_COLLECTION | app.certified.actor.profile | Signal collection for repo discovery | | TAP_FULL_NETWORK | true / false | Full network tracking toggle | > TAP_FULL_NETWORK=true enables full-network tracking and triggers a broad historical backfill across discoverable repos. Client (Next.js) | Variable | Example | What it is for | |---|---|---| | NEXT_PUBLIC_API_URL | https://hyperindex.example.com | Browser-side URL of your Hyperindex backend | | HYPERINDEX_URL | https://hyperindex.example.com | Server-side URL of your Hyperindex backend (used by Next API proxy routes) | | PUBLIC_URL | https://hyperindex-frontend.example.com | Client frontend URL used for OAuth client metadata and auth redirects | | COOKIE_SECRET | | Session encryption | | ATPROTO_JWK_PRIVATE | | Confidential OAuth signing key | Optional variables Set these only when needed. Backend - ALLOWED_ORIGINS Tap - TAP_FIREHOSE_PARALLELISM - TAP_RESYNC_PARALLELISM - TAP_OUTBOX_PARALLELISM - TAP_MAX_DB_CONNS - TAP_OUTBOX_CAPACITY - TAP_NO_REPLAY - TAP_REPO_FETCH_TIMEOUT Client - Additional auth/provider-specific settings depending on deployment model Common pitfalls - Wrong variable on wrong service - TAP_COLLECTION_FILTERS, TAP_SIGNAL_COLLECTION, TAP_FULL_NETWORK belong to Tap - TAP_DISABLE_ACKS, TAP_ENABLED, TAP_URL belong to Hyperindex backend - Client works but admin requests fail - HYPERINDEX_URL" }, { "path": "/tools/scaffold", diff --git a/styles/globals.css b/styles/globals.css index dfd7902..679d79b 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -980,6 +980,7 @@ a.sidebar-link-active:hover { .page-tools { display: flex; align-items: center; + justify-content: flex-end; gap: var(--space-3); margin-bottom: var(--space-6); } @@ -989,6 +990,7 @@ a.sidebar-link-active:hover { display: inline-flex; align-items: center; justify-content: center; + gap: var(--space-2); min-height: 32px; padding: 0 var(--space-3); border: 1px solid var(--color-border); @@ -1005,6 +1007,15 @@ a.sidebar-link-active:hover { cursor: pointer; } +.page-tools-button:disabled { + opacity: 0.65; + cursor: not-allowed; +} + +.page-tools-icon { + flex-shrink: 0; +} + .page-tools-button:hover, .page-tools-link:hover { border-color: var(--color-link); @@ -1012,6 +1023,11 @@ a.sidebar-link-active:hover { text-decoration: none; } +.page-tools-button:disabled:hover { + border-color: var(--color-border); + color: var(--color-text-secondary); +} + .page-tools-button:focus-visible, .page-tools-link:focus-visible { outline: none;