Releases: hypercerts-org/hypercerts-lexicon
v0.11.2
v0.11.1
Patch Changes
-
#196
e66a459Thanks @aspiers! - Fix incorrect NSID reference inorg.hyperboards.boardsubject field description (org.hypercerts.claim.collection→org.hypercerts.collection).Documentation fixes in
README.mdandSCHEMAS.md:- Correct
validate()call signature examples (parameter order and result shape) - Fix relationship diagram arrow directions and missing entries (
link/evm,CERTIFIEDsection) - Fix contributor field name (
avatar→image) - Fix context target descriptions (generalized to
any recordsince subjects use genericstrongRef) - Add missing
$typediscriminators to union member examples
- Correct
v0.11.0
The v0.11.0 release introduces EVM identity linking, stronger type safety across badge and funding schemas, vendored Leaflet lexicons for runtime validation, and a set of schema refinements based on real-world usage from the first month of v0.10.0 adoption. All changes listed below are merged to main and will ship together as a single coordinated release.
npm install @hypercerts-org/lexicon@0.11.0New lexicons
EVM identity linking
app.certified.link.evm
A new record type for creating verifiable links between ATProto identities and EVM wallet addresses. Each record contains a cryptographic proof — currently EIP-712 typed data signatures for EOA wallets — that binds a DID to an Ethereum address onchain.
The proof field is an open union, so future signature methods (ERC-1271, ERC-6492) can be added without breaking existing records.
{
"address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
"proof": {
"$type": "app.certified.link.evm#eip712Proof",
"signature": "0x...",
"message": {
"did": "did:plc:abc123",
"evmAddress": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
"chainId": "1",
"timestamp": "1711929600",
"nonce": "0",
},
},
"createdAt": "2026-04-03T00:00:00.000Z",
}Vendored Leaflet and richtext lexicons
pub.leaflet.* · pub.leaflet.richtext.facet
The package now ships the full set of Leaflet block and richtext facet lexicon JSON files (17 files). Previously, these external schemas were shimmed at the TypeScript type level via @atcute packages, which caused LexiconDefNotFoundError at runtime when validating records with description or facet fields. Vendoring them fixes runtime validation and removes the @atcute/leaflet and @atcute/bluesky dependencies.
This is a packaging change, not a schema change. No record structures are affected.
Breaking changes
This release includes three breaking schema changes. All were identified early enough in adoption that the team decided the long-term gains outweigh the migration cost.
Evaluation scores are now strings
org.hypercerts.context.evaluation
The min, max, and value fields on evaluation scores changed from integer to string. ATProto has no native decimal type, and integer-only scores made use cases like "3.7 out of 5" impossible.
// Before
- { "min": 0, "max": 10, "value": 7 }
+ // After
+ { "min": "0", "max": "10", "value": "7.5" }Who needs to update:
| Consumer | Action |
|---|---|
| Indexers | Change column type from INTEGER to TEXT. Backfill existing records. Update any numeric sorting or filtering logic. |
| AppViews | Parse scores as strings. Use parseFloat() for numeric display where appropriate. |
| Frontend | Handle both numeric strings ("3.7") and potentially non-numeric strings ("A+") in display components. |
Badge references are now strong refs
app.certified.badge.award · app.certified.badge.response
Badge awards and responses now reference their parent records via com.atproto.repo.strongRef instead of plain lexicon refs. Strong references include both a URI and a content hash (CID), pinning the reference to a specific version of the badge definition. This prevents the meaning of an award from drifting if the underlying badge definition is later modified.
// Before
- "badge": "at://did:plc:abc/app.certified.badge.definition/123"
// After
+ "badge": {
+ "uri": "at://did:plc:abc/app.certified.badge.definition/123",
+ "cid": "bafyrei..."
+ }Who needs to update:
| Consumer | Action |
|---|---|
| Indexers | Update parsing to expect { uri, cid } objects instead of plain URI strings for badge and badgeAward fields. |
| AppViews | Update resolution logic. Dereference using both uri and cid for content verification. |
| SDK consumers | Regenerate types. Any code constructing badge awards or responses must supply the full strong ref. |
Funding receipt fields normalized
org.hypercerts.funding.receipt
The from, to, and for fields have been reworked for consistency and stronger type safety.
| Field | Before (v0.10.0) | After |
|---|---|---|
from |
Required, DID ref | Optional, union of #text | app.certified.defs#did | com.atproto.repo.strongRef |
to |
Plain string | Union of #text | app.certified.defs#did | com.atproto.repo.strongRef |
for |
AT-URI string | com.atproto.repo.strongRef (pins to a specific record version) |
The from and to fields were asymmetric — from required an AT Protocol identity while to accepted any string. Now both are three-way unions that accept a free-text string (#text — for display names, wallet addresses, or other identifiers), a DID, or a strong reference. This treats senders and recipients uniformly while preserving the ability to reference non-ATProto participants. from is also optional, properly supporting anonymous funding. for is now a strong ref, ensuring the receipt always points to the exact version of the activity it funded.
// Before
- "from": { "$type": "app.certified.defs#did", "did": "did:plc:sender" },
- "to": "did:plc:recipient",
- "for": "at://did:plc:abc/org.hypercerts.claim.activity/123"
// After — with a DID
+ "from": { "$type": "app.certified.defs#did", "did": "did:plc:sender" },
+ "to": { "$type": "app.certified.defs#did", "did": "did:plc:recipient" },
// After — with a free-text identifier
+ "to": { "$type": "org.hypercerts.funding.receipt#text", "value": "0xAb58...eC9B" },
// After — for field
+ "for": {
+ "uri": "at://did:plc:abc/org.hypercerts.claim.activity/123",
+ "cid": "bafyrei..."
+ }Who needs to update:
| Consumer | Action |
|---|---|
| Indexers | Update parsing for from, to (now unions with $type discriminator — handle all three variants), and for (now { uri, cid }). Allow NULL for from. |
| AppViews | Update resolution logic for all three fields. for requires dereferencing via both URI and CID. Handle #text variants for display. |
| SDK consumers | Regenerate types. Code constructing receipts must supply union-typed to and strong ref for. |
| Frontend | Update forms to construct proper union objects for sender/recipient. Handle #text for non-ATProto participants. Handle missing from for anonymous display. |
Schema changes
A note on "optional" fields: Even new optional fields require attention from indexers and AppViews. If an indexer doesn't store a new field, that data is silently lost for every downstream consumer. The changes below are non-breaking in the strict sense — existing records remain valid — but ignoring them means incomplete data.
Known values
Several free-text string fields now declare knownValues — a set of canonical values that establish interoperability conventions across the ecosystem. Custom values are still permitted. Think of these as Schelling points, not constraints.
| Lexicon | Field | Known values |
|---|---|---|
org.hypercerts.collection |
type |
favorites · project · portfolio · program |
org.hypercerts.context.attachment |
contentType |
report · audit · evidence · testimonial · methodology |
app.certified.badge.definition |
badgeType |
endorsement · verification · participation · certification · affiliation · recognition |
Action: Indexers should index these values for filtering and categorization. AppViews and frontends can use them for dropdowns, search facets, and display grouping. No schema migration required — the underlying field type is still a string.
Badge icon is now optional
app.certified.badge.definition
The icon field moved from required to optional. Not all badges have a visual representation — endorsements, participation records, and text-based certifications can now omit the icon entirely.
Action: Indexers should allow NULL in the icon column. Frontend developers must add a fallback or placeholder when rendering badges without an icon — apps that assume icon is always present will crash or render broken UI.
Contributors array is uncapped
org.hypercerts.claim.activity
Removed the maxLength: 1000 constraint on the contributors array. ATProto records have a natural 1 MB size limit (~2,000–...
v0.10.0
Minor Changes
-
#76
3044e22Thanks @s-adamantine! - Add org.hypercerts.acknowledgement lexicon for bidirectional inclusion links between records across PDS repos -
#141
06fb6b5Thanks @holkexyz! - Add CEL expression support for structured work scopes (org.hypercerts.workscope.cel,org.hypercerts.workscope.tag) -
#106
b03a1f7Thanks @copilot-swe-agent! - Add avatar and banner fields to collection lexicon for visual representation -
#113
c3f9ca2Thanks @holkexyz! - Refactor collection items structure to support optional weights and remove activityWeight from activity schemaBreaking Changes:
- Activity lexicon (
org.hypercerts.claim.activity):- Removed
org.hypercerts.claim.activity#activityWeightdef - Activity records no longer include activity weight information
- Removed
- Collection lexicon (
org.hypercerts.claim.collection):- Changed
org.hypercerts.claim.collection#itemsfrom array of strongRefs to array of item objects - Added
org.hypercerts.claim.collection#itemdef with:itemIdentifier(required): strongRef to an item (activity or collection)itemWeight(optional): positive numeric value stored as string
- Supports recursive collection nesting (items can reference activities or other collections)
- Changed
Migration:
Collection items: Convert from array of strongRefs to array of item objects:
// Before "items": [strongRef1, strongRef2] // After "items": [ { "itemIdentifier": strongRef1, "itemWeight": "1.5" }, { "itemIdentifier": strongRef2 } ]
Activity weights: Migrate existing
org.hypercerts.claim.activity#activityWeightdata to collectionorg.hypercerts.claim.collection#item.itemWeight:// Old (removed from activity) { "activity": { "uri": "...", "cid": "..." }, "weight": "1.5" } // New (in collection items) { "itemIdentifier": { "uri": "...", "cid": "..." }, "itemWeight": "1.5" }
Update collections that reference activities to include weights in
org.hypercerts.claim.collection#item.itemWeight. Weights can be dropped if not needed. - Activity lexicon (
-
#149
9f124ebThanks @daviddao! - Addorg.hyperboards.boardandorg.hyperboards.displayProfilelexicons for hyperboard visual presentation records. -
#123
c623d32Thanks @aspiers! - Addlocationproperty to collections. Collections can now reference a location record directly via strongRef. This replaces the sidecar pattern which was impractical since location records cannot be reused across multiple collections. -
#140
20eb414Thanks @holkexyz! - Add app.certified.actor.organization sidecar record for organization actor profiles with fields for organization type, labeled URLs, location (strongRef), and founded date -
#133
6752cadThanks @Kzoeps! - Add profile lexicon for Hypercert account profiles with support for display name, description, pronouns, website, avatar, banner. -
#78
c55d8a7Thanks @bitbeckers! - Remove org.hypercerts.claim.project lexicon and replace with org.hypercerts.claim.collection.project sidecar. Projects are now represented as collections with an optional project sidecar (same TID) that provides rich-text descriptions, avatars, and cover photos. Avatar and coverPhoto fields moved from base collection to project sidecar. Collections without the project sidecar are simple groupings; collections with it are "projects" with rich documentation. -
#91
0c6da09Thanks @holkexyz! - Add rich text facet support to activity claim descriptionsAdd
shortDescriptionFacetsanddescriptionFacetsfields to the activity lexicon to support rich text annotations (mentions, URLs, hashtags, etc.) in activity claim descriptions. -
#144
fb90134Thanks @holkexyz! - Make items optional in collection schema to allow creating empty collections -
#151
4d5f42fThanks @holkexyz! - Add optionalurlfield toapp.certified.badge.awardfor linking to an external page associated with the badge -
#122
3e3da41Thanks @aspiers! - Drop HELPER_ prefix from workScopeTag constants.HELPER_WORK_SCOPE_TAG_NSID,HELPER_WORK_SCOPE_TAG_LEXICON_JSON, andHELPER_WORK_SCOPE_TAG_LEXICON_DOCare nowWORK_SCOPE_TAG_NSID,WORK_SCOPE_TAG_LEXICON_JSON, andWORK_SCOPE_TAG_LEXICON_DOC. -
#136
062fbdeThanks @copilot-swe-agent! - Expand locationType knownValues to include geojson, h3, geohash, wkt, address, and scaledCoordinates from the Location Protocol spec -
#131
7f42fadThanks @aspiers! - Add inline string format to app.certified.location schema with documentation and examples -
#121
5c33b79Thanks @aspiers! - Fix camelCase export names to use underscores. Generated constants likeCONTRIBUTIONDETAILS_LEXICON_*are nowCONTRIBUTION_DETAILS_LEXICON_*for consistency.Affected exports:
CONTRIBUTION_DETAILS_NSID,CONTRIBUTION_DETAILS_LEXICON_JSON,CONTRIBUTION_DETAILS_LEXICON_DOC(wasCONTRIBUTIONDETAILS_*)CONTRIBUTOR_INFORMATION_NSID,CONTRIBUTOR_INFORMATION_LEXICON_JSON,CONTRIBUTOR_INFORMATION_LEXICON_DOC(wasCONTRIBUTORINFORMATION_*)STRONG_REF_NSID,STRONG_REF_LEXICON_JSON,STRONG_REF_LEXICON_DOC(wasSTRONGREF_*)HELPER_WORK_SCOPE_TAG_NSID,HELPER_WORK_SCOPE_TAG_LEXICON_JSON,HELPER_WORK_SCOPE_TAG_LEXICON_DOC(wasHELPER_WORKSCOPETAG_*)
-
#132
da481e0Thanks @aspiers! - Convert app.certified.defs#did to object typeThe did definition in app.certified.defs has been converted from a primitive
string type to an object type to comply with the ATProto specification
requirement that all union variants must be object or record types.This change was necessary because app.certified.badge.award uses this
definition in a union for the subject property.Breaking changes:
app.certified.defs#did: Now an object withdidstring property (maxLength 256)- Code using this type must now access the
.didproperty instead of using the value directly
-
#132
e134b26Thanks @aspiers! - Convert union string definitions to object types in activity lexiconThe contributorIdentity, contributorRole, an...