Skip to content
View raw

@hypercerts-org/lexicon

1.4.0#

This release adds first-class records for non-agent subjects, together with shared tags for describing features and collections.

Represent non-agent subjects#

The new org.hypercerts.entity.feature record represents a subject that is not a person or organization. Examples include a managed land zone, ecological stratum, participant cohort, or campaign.

A feature can include:

  • a title, description, and general type
  • tags describing the feature
  • optional location records when the subject is spatial
  • external identifiers through sameAs

Collections can now include features alongside activities and nested collections. Existing activity claims continue to reference app.certified.location directly and do not need to change.

Add shared tags to features and collections#

The new org.hypercerts.vocab.tag record lets publishers define tags that features and collections can share.

For example, a land feature could have both a "project site" tag and a "mangrove land cover" tag. Because each tag is published as a record, different features and collections can use the same definition instead of relying on inconsistent free-text values.

A tag can also record:

  • alternative names
  • a link to the equivalent term in another standard
  • whether it has been retired and replaced
  • the more general tags it belongs under

When a feature or collection has several tags, they are all treated as facts about that record. Tags do not express OR, NOT, weighting, or other logic.

Compatibility#

These changes are additive. Existing records remain valid.

Thanks @DjimoSerodio for contributing these changes in #242.

1.3.1#

Patch Changes#

  • #244 8dc6eb3 Thanks @Kzoeps! - Recognize ISO 3166-1 alpha-2 country codes as location values.

1.3.0#

Updates the bundled Leaflet lexicons to match their published schemas.

New Leaflet schemas#

  • Blocks: html, imageGallery, membersOnlyDelimiter, postsList, signup, standardSitePost, and standardSitePublication
  • Theme colors: pub.leaflet.theme.color

Schema updates#

  • Iframes no longer require a URL. They can also specify an aspect ratio or use the deprecated inline HTML field.
  • Images can specify their display width.
  • Linear documents accept the new block types.
  • Rich-text links can use href, and highlighted text can specify an RGB or RGBA color.

Released in #239 by @Kzoeps (d772554).

1.2.0#

Minor Changes#

  • #236 5439b36 Thanks @Ashex! - Add app.certified.graph.entityFollow, a follow record for non-account entities. subject is an open union currently offering only app.certified.defs#recordSubject (a record referenced by AT-URI without a CID, so the follow survives updates to the referenced record); account follows remain in app.certified.graph.follow. The new collection is also added to the app.certified.authWrite permission set so it is grantable alongside the other Certified records.

  • #222 fa1c29a Thanks @aspiers! - Add three permission-set lexicons — org.hypercerts.authWrite, org.hyperboards.authWrite, and app.certified.authWrite — each granting create/update/delete over every record collection in its namespace.

    A permission set lets any AT Protocol app request a whole bundle of repo: scopes with a single include:<nsid> OAuth scope, instead of enumerating each collection by hand. The user's PDS resolves and expands the set during the OAuth grant; the same published set can also be consumed by services (e.g. the Certified group service) when expanding API-key scopes.

    There are three sets rather than one because the spec requires it: a permission set "is limited to expressing permissions that reference resources under the same NSID namespace as the set itself" and "can not address 'sibling groups' or 'parents'". org.hypercerts, org.hyperboards, and app.certified are separate namespace authorities, so they cannot be combined in a single set — an app needing more than one requests each include: scope.

    Permission sets are published as-is (they are the source of truth for what gets published to AT Protocol) but have no TypeScript shape — lex gen-api cannot generate code for permission-set defs. They are therefore excluded from the codegen globs (gen-api/gen-md/gen-ts) and from generated/exports.ts, while still shipping as raw lexicon JSON.

    Collection lists are enumerated explicitly because the spec forbids wildcards inside a permission set; they must be kept in sync as record types are added. See docs/design/permission-sets.md.

    The generated SCHEMAS.md reference now renders permission-set entries (title, detail, and the resource/collections/actions each set grants) instead of leaving them as empty sections.

1.1.0#

Minor Changes#

  • #219 39d7547 Thanks @aspiers! - Add optional cryptographic signature support to all 21 record lexicons.

    Non-breaking: signatures are optional on every record.

    • New app.certified.signature.defs with #list (open union of inline signatures and com.atproto.repo.strongRef references) and #inline (raw ECDSA (r,s) bytes plus a DID verification method reference; signing curve derived from the verification method's multicodec prefix).
    • New app.certified.signature.proof record for remote attestations.
    • Every record lexicon gains an optional signatures property referencing #list.
    • README.md, SCHEMAS.md, and the building-with-hypercerts-lexicons agent skill all gain a "Cryptographic Signatures" section with a worked end-to-end signing example.

    On-the-wire shape, signing procedure, and verification procedure all conform to Nick Gerakines' ATProtocol Attestation Specification (see also the accompanying blog post).

    On app.certified.link.evm the existing EIP-712 proof field (wallet consent) and the new signatures array (record provenance) are complementary and do not conflict.

1.0.0#

Major Changes#

  • #220 dd78ed4 Thanks @s-adamantine! - Promote @hypercerts-org/lexicon to v1.0.0 — first stable release.

    This changeset contributes no schema or type changes of its own; it exists solely to force a major version bump so the package crosses the 0.x → 1.0 line. From v1.0.0 onward, the lexicons, TypeScript types, and generated exports are considered stable for downstream consumers, and the package follows standard SemVer semantics: breaking changes bump the major version, non-breaking additions the minor version, and fixes the patch version. (Prior to v1.0.0, breaking changes were allowed under minor per the SemVer 0.x convention — see .claude/skills/writing-changesets/SKILL.md.)

    Any other changesets pending at the time this one is consumed are folded into the same v1.0.0 release; see the other entries below for those contributions.

Minor Changes#

  • #212 871608f Thanks @Kzoeps! - Increase the free-form activity work scope string limit from 100 to 1,000 graphemes, with a 10,000-byte cap.

    The previous 100-grapheme limit was too tight for simple work scope descriptions: if the relevant terms are around 10–15 characters each, the field only fits roughly 5–6 words. Gainforest hit this limit while implementing the work scope string field and had to move to the CEL-based work scope form earlier than intended.

    Most invalid work scope records were caused by the newer typed shape requiring $type; the length cap only affects two known accounts at the time, so raising it fixes those without changing currently valid claims.

    The string form is the simplest option for producers that do not need CEL's structured, machine-evaluable semantics. Raising the grapheme and byte limits keeps that simple path viable for concise natural-language scopes while CEL remains available for more complex tagging and query logic.

0.13.0#

Minor Changes#

  • #209 8ec051f Thanks @s-adamantine! - Add app.certified.graph.follow lexicon — a social-graph follow record schema-compatible with app.bsky.graph.follow (same tid key, same subject / createdAt / optional via strongRef fields). Exports new GRAPH_FOLLOW_NSID, GRAPH_FOLLOW_LEXICON_JSON, GRAPH_FOLLOW_LEXICON_DOC, and AppCertifiedGraphFollow type namespace.

Patch Changes#

  • #213 80e5b42 Thanks @s-adamantine! - Clarify that knownValues is an open vocabulary, not a closed enum. Adds a "Schema Conventions" section to README.md explaining that custom string values are permitted on any knownValues field (and contrasting with enum, which is closed and validator-enforced). Updates inline descriptions on app.certified.location#locationType, org.hypercerts.workscope.tag#category, and org.hypercerts.workscope.tag#status to explicitly note that values beyond the listed set are permitted — bringing them in line with the existing wording on org.hypercerts.collection#type, org.hypercerts.context.attachment#contentType, and app.certified.badge.definition#badgeType. The locationType description now also explicitly calls out that polygons / multipolygons / featurecollections use the catch-all geojson entry rather than a typed variant. Fixes a misleading line in STRING_CONSTRAINTS.md that conflated knownValues with enum. Documentation-only — no schema or type changes.

0.12.0#

Minor Changes#

  • #174 b1c2096 Thanks @satyam-mishra-pce! - Add optional longDescription and visibility fields to app.certified.actor.organization lexicon. longDescription uses the description union pattern — an inline string for plain text or markdown, an embedded Leaflet linear document for rich-text content, or a strong reference to an existing description record — matching the pattern used on activity, collection, and attachment.

Patch Changes#

  • #208 18abe86 Thanks @s-adamantine! - Sync SKILL.md Organization row with README.md: list foundedDate, longDescription, and visibility in the Certified lexicons overview table so AI agents building on top of app.certified.actor.organization see the full set of documented fields.

0.11.2#

Patch Changes#

  • #205 4af4e8b Thanks @s-adamantine! - Sync vendored pub.leaflet.blocks.image lexicon with upstream, adding the optional fullBleed boolean property

0.11.1#

Patch Changes#

  • #196 e66a459 Thanks @aspiers! - Fix incorrect NSID reference in org.hyperboards.board subject field description (org.hypercerts.claim.collectionorg.hypercerts.collection).

    Documentation fixes in README.md and SCHEMAS.md:

    • Correct validate() call signature examples (parameter order and result shape)
    • Fix relationship diagram arrow directions and missing entries (link/evm, CERTIFIED section)
    • Fix contributor field name (avatarimage)
    • Fix context target descriptions (generalized to any record since subjects use generic strongRef)
    • Add missing $type discriminators to union member examples

0.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.

Terminal
npm install @hypercerts-org/lexicon@0.11.0

New 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.

jsonc
{
  "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.

diff
  // Before
- { "min": 0, "max": 10, "value": 7 }
+ // After
+ { "min": "0", "max": "10", "value": "7.5" }

Who needs to update:

ConsumerAction
IndexersChange column type from INTEGER to TEXT. Backfill existing records. Update any numeric sorting or filtering logic.
AppViewsParse scores as strings. Use parseFloat() for numeric display where appropriate.
FrontendHandle 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.

diff
  // 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:

ConsumerAction
IndexersUpdate parsing to expect { uri, cid } objects instead of plain URI strings for badge and badgeAward fields.
AppViewsUpdate resolution logic. Dereference using both uri and cid for content verification.
SDK consumersRegenerate 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.

FieldBefore (v0.10.0)After
fromRequired, DID refOptional, union of #text | app.certified.defs#did | com.atproto.repo.strongRef
toPlain stringUnion of #text | app.certified.defs#did | com.atproto.repo.strongRef
forAT-URI stringcom.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.

diff
  // 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:

ConsumerAction
IndexersUpdate parsing for from, to (now unions with $type discriminator — handle all three variants), and for (now { uri, cid }). Allow NULL for from.
AppViewsUpdate resolution logic for all three fields. for requires dereferencing via both URI and CID. Handle #text variants for display.
SDK consumersRegenerate types. Code constructing receipts must supply union-typed to and strong ref for.
FrontendUpdate 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.

LexiconFieldKnown values
org.hypercerts.collectiontypefavorites · project · portfolio · program
org.hypercerts.context.attachmentcontentTypereport · audit · evidence · testimonial · methodology
app.certified.badge.definitionbadgeTypeendorsement · 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–4,000 contributors), making the artificial cap unnecessary.

Action: Indexers and AppViews with hardcoded length limits matching the old max should remove them. Frontends should implement pagination or lazy loading for large contributor lists to avoid performance issues.

Rich text on collection short descriptions

org.hypercerts.collection

Added shortDescriptionFacets — an optional array of rich text facets (mentions, URLs, hashtags) that annotate the shortDescription field. This brings collections in line with activity claims, which already supported facets.

Action: Indexers must store the new field when present — without it, rich text annotations (links, mentions) are permanently lost. AppViews should include facets in API responses. Frontends can render rich text using the standard ATProto facet model.


Documentation improvements#

  • Contributor and item defs now have descriptions, improving TypeScript IntelliSense and AI code generation.
  • occurredAt vs createdAt semantics clarified on funding receipts. occurredAt is when the funding happened in the real world; createdAt is when the record was written to the PDS.
  • Stale references in board and measurement lexicon descriptions have been corrected.
  • README rewritten with an ASCII namespace map and structured reference tables.
  • AI agent skill added for downstream developers. Install via npx skills add hypercerts-org/hypercerts-lexicon.

Upgrading#

Terminal
npm install @hypercerts-org/lexicon@0.11.0

The source of truth for lexicon definitions is the NPM package and the published ATProto repository. The main branch on GitHub is a development branch — do not build production applications against it.

After upgrading, regenerate your TypeScript types and run your validation suite against the updated schemas. The package includes all lexicon JSON files and pre-built type definitions.

0.10.0#

Minor Changes#

  • #76 3044e22 Thanks @s-adamantine! - Add org.hypercerts.acknowledgement lexicon for bidirectional inclusion links between records across PDS repos

  • #141 06fb6b5 Thanks @holkexyz! - Add CEL expression support for structured work scopes (org.hypercerts.workscope.cel, org.hypercerts.workscope.tag)

  • #106 b03a1f7 Thanks @copilot-swe-agent! - Add avatar and banner fields to collection lexicon for visual representation

  • #113 c3f9ca2 Thanks @holkexyz! - Refactor collection items structure to support optional weights and remove activityWeight from activity schema

    Breaking Changes:

    • Activity lexicon (org.hypercerts.claim.activity):
      • Removed org.hypercerts.claim.activity#activityWeight def
      • Activity records no longer include activity weight information
    • Collection lexicon (org.hypercerts.claim.collection):
      • Changed org.hypercerts.claim.collection#items from array of strongRefs to array of item objects
      • Added org.hypercerts.claim.collection#item def 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)

    Migration:

    Collection items: Convert from array of strongRefs to array of item objects:

    JSON
    // Before
    "items": [strongRef1, strongRef2]
    
    
    // After
    "items": [
      { "itemIdentifier": strongRef1, "itemWeight": "1.5" },
      { "itemIdentifier": strongRef2 }
    ]
    

    Activity weights: Migrate existing org.hypercerts.claim.activity#activityWeight data to collection org.hypercerts.claim.collection#item.itemWeight:

    JSON
    // 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.

  • #149 9f124eb Thanks @daviddao! - Add org.hyperboards.board and org.hyperboards.displayProfile lexicons for hyperboard visual presentation records.

  • #123 c623d32 Thanks @aspiers! - Add location property 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 20eb414 Thanks @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 6752cad Thanks @Kzoeps! - Add profile lexicon for Hypercert account profiles with support for display name, description, pronouns, website, avatar, banner.

  • #78 c55d8a7 Thanks @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 0c6da09 Thanks @holkexyz! - Add rich text facet support to activity claim descriptions

    Add shortDescriptionFacets and descriptionFacets fields to the activity lexicon to support rich text annotations (mentions, URLs, hashtags, etc.) in activity claim descriptions.

  • #144 fb90134 Thanks @holkexyz! - Make items optional in collection schema to allow creating empty collections

  • #151 4d5f42f Thanks @holkexyz! - Add optional url field to app.certified.badge.award for linking to an external page associated with the badge

  • #122 3e3da41 Thanks @aspiers! - Drop HELPER_ prefix from workScopeTag constants. HELPER_WORK_SCOPE_TAG_NSID, HELPER_WORK_SCOPE_TAG_LEXICON_JSON, and HELPER_WORK_SCOPE_TAG_LEXICON_DOC are now WORK_SCOPE_TAG_NSID, WORK_SCOPE_TAG_LEXICON_JSON, and WORK_SCOPE_TAG_LEXICON_DOC.

  • #136 062fbde Thanks @copilot-swe-agent! - Expand locationType knownValues to include geojson, h3, geohash, wkt, address, and scaledCoordinates from the Location Protocol spec

  • #131 7f42fad Thanks @aspiers! - Add inline string format to app.certified.location schema with documentation and examples

  • #121 5c33b79 Thanks @aspiers! - Fix camelCase export names to use underscores. Generated constants like CONTRIBUTIONDETAILS_LEXICON_* are now CONTRIBUTION_DETAILS_LEXICON_* for consistency.

    Affected exports:

    • CONTRIBUTION_DETAILS_NSID, CONTRIBUTION_DETAILS_LEXICON_JSON, CONTRIBUTION_DETAILS_LEXICON_DOC (was CONTRIBUTIONDETAILS_*)
    • CONTRIBUTOR_INFORMATION_NSID, CONTRIBUTOR_INFORMATION_LEXICON_JSON, CONTRIBUTOR_INFORMATION_LEXICON_DOC (was CONTRIBUTORINFORMATION_*)
    • STRONG_REF_NSID, STRONG_REF_LEXICON_JSON, STRONG_REF_LEXICON_DOC (was STRONGREF_*)
    • HELPER_WORK_SCOPE_TAG_NSID, HELPER_WORK_SCOPE_TAG_LEXICON_JSON, HELPER_WORK_SCOPE_TAG_LEXICON_DOC (was HELPER_WORKSCOPETAG_*)
  • #132 da481e0 Thanks @aspiers! - Convert app.certified.defs#did to object type

    The 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 with did string property (maxLength 256)
    • Code using this type must now access the .did property instead of using the value directly
  • #132 e134b26 Thanks @aspiers! - Convert union string definitions to object types in activity lexicon

    The contributorIdentity, contributorRole, and workScopeString definitions in org.hypercerts.claim.activity have been converted from primitive string types to object types to comply with the ATProto specification requirement that all union variants must be object or record types.

    Additionally, maximum length constraints have been reduced to more reasonable values:

    • contributorIdentity.identity: maxLength 1000, maxGraphemes 100 (previously no limits)
    • contributorRole.role: maxLength 1000, maxGraphemes 100 (previously maxLength 10000, maxGraphemes 1000)
    • workScopeString.scope: maxLength 1000, maxGraphemes 100 (previously maxLength 10000, maxGraphemes 1000)

    Breaking changes:

    • contributorIdentity: Now an object with identity string property
    • contributorRole: Now an object with role string property
    • workScopeString: Now an object with scope string property
    • Reduced maximum lengths may affect existing records with longer values

    This requires updating code that uses these union types to access the nested property instead of using the value directly.

  • #152 2afb6ed Thanks @holkexyz! - Use Leaflet linear documents for rich-text descriptions in activity and attachment lexicons, and make attachment content optional.

  • #161 96bdb6c Thanks @aspiers! - Improved exports structure with semantic collection mappings for extra syntactic sugar.

    Breaking Changes:

    • Renamed ids export to HYPERCERTS_NSIDS_BY_TYPE (maps type namespaces to NSIDs)

    New Features:

    • Added HYPERCERTS_NSIDS object with semantic keys (e.g., ACTIVITY, RIGHTS, CONTRIBUTION)
    • Added HYPERCERTS_LEXICON_JSON object with semantic keys mapping to raw JSON lexicons
    • Added HYPERCERTS_LEXICON_DOC object with semantic keys mapping to typed lexicon documents
    • All three new objects share the same key structure for consistency

    Migration Guide:

    If you were using the ids export (rare):

    TypeScript
    // Before
    import { ids } from "@hypercerts-org/lexicon";
    const nsid = ids.OrgHypercertsClaimActivity;
    
    
    // After
    import { HYPERCERTS_NSIDS_BY_TYPE } from "@hypercerts-org/lexicon";
    const nsid = HYPERCERTS_NSIDS_BY_TYPE.OrgHypercertsClaimActivity;
    

    Most users should use individual NSID constants (unchanged):

    TypeScript
    import { ACTIVITY_NSID, RIGHTS_NSID } from "@hypercerts-org/lexicon";
    

    Or the new semantic mapping:

    TypeScript
    import { HYPERCERTS_NSIDS } from "@hypercerts-org/lexicon";
    const nsid = HYPERCERTS_NSIDS.ACTIVITY; // Same as ACTIVITY_NSID
    
  • #161 6a62c04 Thanks @aspiers! - This release represents the migration of the lexicon package from the SDK monorepo (hypercerts-sdk/packages/lexicon) to a dedicated standalone repository (hypercerts-lexicon). This separation allows for independent versioning and development of the lexicon definitions.

    Major architectural and feature updates compared to the SDK lexicon package include but are not limited to the following:

    New Lexicons:

    • Activity model: org.hypercerts.claim.activity - activity-based hypercert records (replaces single claim model)
    • Project records: org.hypercerts.claim.project - projects that group multiple activities
    • Shared definitions: org.hypercerts.defs - common types (uri, smallBlob, largeBlob, smallImage, largeImage)
    • Badge system: app.certified.badge.definition, app.certified.badge.award, app.certified.badge.response for badge-based endorsements
    • Funding receipts: org.hypercerts.funding.receipt - payment and funding tracking

    Architectural Changes:

    • Claim model: Replaced single org.hypercerts.claim record with activity-based org.hypercerts.claim.activity model
    • Collection model: Collections now reference activities (via activityWeight) instead of claims (via claimItem)
    • Work scope: Activity model uses structured workScope object with label-based conditions (withinAllOf, withinAnyOf, withinNoneOf)
    • Time fields: Activity uses startDate/endDate instead of workTimeFrameFrom/workTimeFrameTo
    • Image references: Activity model references org.hypercerts.defs#smallImage instead of app.certified.defs#uri/smallBlob

    Definition Updates:

    • app.certified.defs now includes did type definition
    • Added org.hypercerts.defs with image and blob type definitions
    • Activity model references project via AT-URI instead of strongRef

    Removed/Replaced:

    • org.hypercerts.claim (replaced by org.hypercerts.claim.activity)
    • Top-level org.hypercerts.collection (replaced by org.hypercerts.claim.collection using activities)
  • #153 57dc44c Thanks @holkexyz! - Improve acknowledgement schema: move to org.hypercerts.context.acknowledgement, generalize descriptions, make context optional, add maxGraphemes to comment.

  • #158 7743aa6 Thanks @holkexyz! - Move collection lexicon from org.hypercerts.claim.collection to org.hypercerts.collection to reflect that collections can contain more than just claims.

  • #154 4c52b2c Thanks @holkexyz! - Move evaluation and attachment lexicons to org.hypercerts.context namespace.

  • #135 806cfbc Thanks @Kzoeps! - Move profile lexicon from app.certified.profile to app.certified.actor.profile namespace, requiring migration of existing profile records

  • #97 ceddab9 Thanks @aspiers! - Move schema documentation tables from README.md to auto-generated SCHEMAS.md to reduce git merge conflicts. The SCHEMAS.md file is now auto-generated from lexicon definitions and included in the distributed package.

  • #102 68011ae Thanks @holkexyz! - Refactor contributions structure in activity lexicon

    Breaking Changes:

    • Activity lexicon (org.hypercerts.claim.activity):
      • Renamed contributions field to contributors
      • Replaced contributions array (array of strongRefs) with new contributors array containing contributor objects
      • Each contributor object (org.hypercerts.claim.activity#contributor) has three fields:
        • contributorIdentity (required): string (DID/identifier) or strongRef to a contributor information record
        • contributionWeight (optional): positive numeric value stored as string
        • contributionDetails (optional): string or strongRef to a contribution details record
      • Added internal defs:
        • #contributor: object type for contributor entries
        • #contributorIdentity: string type for DID/identifier values
        • #contributorRole: string type for contribution details (maxLength 10000, maxGraphemes 1000)

    Migration:

    Convert from array of strongRefs to array of contributor objects:

    JSON
    // Before
    "contributions": [strongRef1, strongRef2]
    
    
    // After
    "contributors": [
      {
        "contributorIdentity": "did:example:123",
        "contributionWeight": "1.5",
        "contributionDetails": "Lead developer"
      },
      {
        "contributorIdentity": strongRefToContributorInfo,
        "contributionDetails": strongRefToContributionDetails
      }
    ]
    
  • #120 b2f7b68 Thanks @holkexyz! - Refactor measurement lexicon schema: convert subject to subjects array, add unit field, date ranges, and locations array

    Breaking Changes:

    • Measurement lexicon (org.hypercerts.context.measurement):
      • Changed subject (single strongRef) to subjects (array of strongRefs, maxLength: 100)
      • Changed required fields: removed measurers from required, added unit as required
      • Added unit field (required, string, maxLength: 50): The unit of the measured value (e.g. kg CO₂e, hectares, %, index score)
      • Added startDate field (optional, datetime): The start date and time when the measurement began
      • Added endDate field (optional, datetime): The end date and time when the measurement ended
      • Changed location (single strongRef) to locations (array of strongRefs, maxLength: 100)
      • Moved measurers from required to optional field
      • Added comment field (optional, string): Short comment suitable for previews and list views
      • Added commentFacets field (optional, array): Rich text annotations for comment (mentions, URLs, hashtags, etc.)
      • Updated field descriptions for metric and value with more detailed examples
  • #67 b51dd76 Thanks @bitbeckers! - Remove bidirectional project-activity link. Activities no longer include a project field reference. Projects continue to reference activities via the activities array, making the relationship unidirectional (project → activities only).

  • #98 43b0431 Thanks @aspiers! - Remove org.hypercerts.claim.collection.project lexicon

  • #155 a59e541 Thanks @holkexyz! - Rename contributionDetails to contribution (org.hypercerts.claim.contribution).

  • #118 8427780 Thanks @holkexyz! - Rename evidence lexicon to attachment and refactor schema structure

    Breaking Changes:

    • Lexicon ID change:
      • org.hypercerts.claim.evidenceorg.hypercerts.claim.attachment
      • All existing evidence records must be migrated to use the new lexicon ID
    • Schema structure changes (org.hypercerts.claim.attachment):
      • Changed subject (single strongRef) to subjects (array of strongRefs, maxLength: 100)
      • Changed content from single union (uri/blob) to array of unions (maxLength: 100)
      • Added contentType field (string, maxLength: 64) to specify attachment type
      • Removed relationType field (previously used to indicate supports/challenges/clarifies)
      • Removed contributors field
      • Removed locations field
      • Added rich text support: shortDescriptionFacets and descriptionFacets (arrays of app.bsky.richtext.facet)
      • Updated required fields: ["title", "content", "createdAt"] (content is now required)
    • Common definitions (org.hypercerts.defs):
      • Added weightedContributor def for contributor references with optional weights
      • Added contributorIdentity def for string-based contributor identification

    Migration:

    Lexicon ID: Update all references from org.hypercerts.claim.evidence to org.hypercerts.claim.attachment.

    Schema migration:

    JSON
    // Before (org.hypercerts.claim.evidence)
    {
      "$type": "org.hypercerts.claim.evidence",
      "subject": { "uri": "...", "cid": "..." },
      "content": { "uri": "https://..." },
      "title": "Evidence Title",
      "relationType": "supports",
      "createdAt": "..."
    }
    
    
    // After (org.hypercerts.claim.attachment)
    {
      "$type": "org.hypercerts.claim.attachment",
      "subjects": [{ "uri": "...", "cid": "..." }],
      "content": [{ "uri": "https://..." }],
      "contentType": "evidence",
      "title": "Evidence Title",
      "createdAt": "..."
    }
    

    Field mapping:

    • subjectsubjects (wrap in array)
    • content (single) → content (array, wrap existing value)
    • relationType → remove (no direct replacement)
    • contributors → remove (no direct replacement)
    • locations → remove (no direct replacement)
  • #156 86f252d Thanks @holkexyz! - Require createdAt in app.certified.actor.profile schema

  • #161 ec91289 Thanks @aspiers! - chore: switch to build via rollup

    Major build system improvements:

    • Build System: Migrated from direct TypeScript to Rollup-based builds
      • Generates proper ESM (dist/index.mjs) and CommonJS (dist/index.cjs) bundles
      • Generates TypeScript declarations (dist/index.d.ts)
      • Includes source maps for debugging
      • Adds /lexicons export for lighter bundle (validation only)
    • Code Generation:
      • Auto-generates generated/exports.ts with clean, organized exports
      • Creates type shims for external lexicons (@atcute/leaflet)
      • All generated code now in generated/ directory (gitignored)
    • Package Exports:
      • Main export: @hypercerts-org/lexicon (full package with types)
      • Lexicons export: @hypercerts-org/lexicon/lexicons (schemas only, smaller bundle)
      • Proper dual package support (ESM + CommonJS)
    • Code Quality:
      • Added ESLint configuration
      • Added TypeScript type-checking to CI
      • Improved build validation workflow
    • Dependencies:
      • Added @atcute/leaflet for external lexicon references
      • Added multiformats as runtime dependency
      • Moved @atproto/lex-cli to devDependencies (build-time only)

    Migration: No breaking changes for existing users. Package structure is improved but import paths remain compatible.

  • #125 771d142 Thanks @s-adamantine! - Simplify workScope to union of strongRef and string

    Breaking Changes:

    • The workScope field in org.hypercerts.claim.activity is now a union of:
      • com.atproto.repo.strongRef: A reference to a work-scope logic record for structured, nested work scope definitions
      • org.hypercerts.claim.activity#workScopeString: A free-form string for simple or legacy scopes
    • Removed from org.hypercerts.defs:
      • workScopeAll (logical AND operator)
      • workScopeAny (logical OR operator)
      • workScopeNot (logical NOT operator)
      • workScopeAtom (atomic scope reference)

    This simplification allows work scope complexity to be managed via referenced records while still supporting simple string-based scopes for straightforward use cases.

  • #47 6a66e4b Thanks @satyam-mishra-pce! - Add support for multiple locations in an activity claim.

  • #103 b5d79da Thanks @s-adamantine! - Align all lexicons with the ATProto Lexicon Style Guide: change badge response enum to knownValues, add maxLength/maxGraphemes to unconstrained string and array fields, fix style checker to skip format-typed fields.

  • #75 95e2ba1 Thanks @s-adamantine! - Unify project and collection schemas into a single org.hypercerts.claim.collection lexicon with type discriminator field to allow collections to be designated as projects. Custom strings are also allowed in type.

    Also make shortDescription field optional in org.hypercerts.claim.collection to match org.hypercerts.claim.project.

    This unification removes org.hypercerts.claim.project, so existing projects should be migrated to collections with type set to project.

  • #80 e8d5a7c Thanks @s-adamantine! - Updated org.hypercerts.claim.collection lexicon:

    • Added optional type field to specify collection type (e.g., 'favorites', 'project')
    • Renamed fields for consistency:
      • collectionTitletitle
      • shortCollectionDescriptionshortDescription
      • collectionDescriptiondescription
    • Changed description from string to Leaflet linear document reference (pub.leaflet.pages.linearDocument#main) to support rich-text descriptions

    Breaking changes:

    • Field names have been renamed (e.g., collectionTitletitle)
    • The description field now expects a reference object instead of a plain string
  • #92 bec8e63 Thanks @s-adamantine! - Update org.hypercerts.claim.contributor lexicon to support individual contributor profiles and roles.

    Breaking Changes:

    • Removed contributors array.
    • Added identifier, displayName, and image fields for individual profiles.
    • Renamed description to contributionDescription.
    • Updated required fields to only include createdAt.

    Also corrected incorrect references to org.hypercerts.claim.contribution across the codebase to use the correct ID org.hypercerts.claim.contributor.

Patch Changes#

  • #118 8427780 Thanks @holkexyz! - Add location property to attachment schema

    New Feature:

    • location field (org.hypercerts.claim.attachment):
      • Added optional location property as a strong reference (com.atproto.repo.strongRef)
      • Allows attachments to associate location metadata directly without using the sidecar pattern
      • The referenced record must conform to the app.certified.location lexicon

    Usage:

    JSON
    {
      "$type": "org.hypercerts.claim.attachment",
      "subjects": [
        {
          "uri": "at://did:plc:.../org.hypercerts.claim.activity/...",
          "cid": "..."
        }
      ],
      "content": [{ "uri": "https://..." }],
      "title": "Field Report",
      "location": {
        "uri": "at://did:plc:.../app.certified.location/abc123",
        "cid": "..."
      },
      "createdAt": "..."
    }
    

    This change aligns with the location property addition to collections (PR #123), providing a consistent pattern for associating location metadata across record types.

  • #161 5a490bf Thanks @aspiers! - Add basic test suite using vitest 4.

  • #77 0d61ff7 Thanks @bitbeckers! - Document ATProto sidecar pattern for collections using app.certified.location. Collections can now have location metadata by creating a location record with the same TID, allowing location updates without changing the collection CID. Updated README with usage example and ERD with sidecar relationship.

  • #161 ece7629 Thanks @aspiers! - Include CHANGELOG.md in package distribution for better user documentation.

  • #74 f845f92 Thanks @aspiers! - Make startDate and endDate optional in activity lexicon

  • #161 913eb06 Thanks @aspiers! - Switch from bundled to individual type declaration files

    Changes:

    • Removed rollup-plugin-dts dependency
    • Switched to native TypeScript declaration generation
    • Type declarations now mirror source structure in dist/types/
    • Individual type files are small (1-3KB each) and lazy-loaded by TypeScript
    • Improves IDE performance by avoiding single 39MB bundled declaration file

    Technical Details:

    The package now generates individual .d.ts files alongside the bundled JavaScript output. This provides better IDE performance as TypeScript can lazy-load type files on demand rather than parsing a massive bundled declaration file upfront.

0.10.0-beta.16#

Minor Changes#

  • #141 06fb6b5 Thanks @holkexyz! - Add CEL expression support for structured work scopes (org.hypercerts.workscope.cel, org.hypercerts.workscope.tag)

  • #149 9f124eb Thanks @daviddao! - Add org.hyperboards.board and org.hyperboards.displayProfile lexicons for hyperboard visual presentation records.

  • #140 20eb414 Thanks @holkexyz! - Add app.certified.actor.organization sidecar record for organization actor profiles with fields for organization type, labeled URLs, location (strongRef), and founded date

  • #144 fb90134 Thanks @holkexyz! - Make items optional in collection schema to allow creating empty collections

  • #151 4d5f42f Thanks @holkexyz! - Add optional url field to app.certified.badge.award for linking to an external page associated with the badge

  • #152 2afb6ed Thanks @holkexyz! - Use Leaflet linear documents for rich-text descriptions in activity and attachment lexicons, and make attachment content optional.

  • #153 57dc44c Thanks @holkexyz! - Improve acknowledgement schema: move to org.hypercerts.context.acknowledgement, generalize descriptions, make context optional, add maxGraphemes to comment.

  • #158 7743aa6 Thanks @holkexyz! - Move collection lexicon from org.hypercerts.claim.collection to org.hypercerts.collection to reflect that collections can contain more than just claims.

  • #154 4c52b2c Thanks @holkexyz! - Move evaluation and attachment lexicons to org.hypercerts.context namespace.

  • #155 a59e541 Thanks @holkexyz! - Rename contributionDetails to contribution (org.hypercerts.claim.contribution).

  • #156 86f252d Thanks @holkexyz! - Require createdAt in app.certified.actor.profile schema

  • #103 b5d79da Thanks @s-adamantine! - Align all lexicons with the ATProto Lexicon Style Guide: change badge response enum to knownValues, add maxLength/maxGraphemes to unconstrained string and array fields, fix style checker to skip format-typed fields.

0.10.0-beta.15#

Minor Changes#

0.10.0-beta.14#

Minor Changes#

  • #133 6752cad Thanks @Kzoeps! - Add profile lexicon for Hypercert account profiles with support for display name, description, pronouns, website, avatar, banner.

  • #132 da481e0 Thanks @aspiers! - Convert app.certified.defs#did to object type

    The 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 with did string property (maxLength 256)
    • Code using this type must now access the .did property instead of using the value directly
  • #132 e134b26 Thanks @aspiers! - Convert union string definitions to object types in activity lexicon

    The contributorIdentity, contributorRole, and workScopeString definitions in org.hypercerts.claim.activity have been converted from primitive string types to object types to comply with the ATProto specification requirement that all union variants must be object or record types.

    Additionally, maximum length constraints have been reduced to more reasonable values:

    • contributorIdentity.identity: maxLength 1000, maxGraphemes 100 (previously no limits)
    • contributorRole.role: maxLength 1000, maxGraphemes 100 (previously maxLength 10000, maxGraphemes 1000)
    • workScopeString.scope: maxLength 1000, maxGraphemes 100 (previously maxLength 10000, maxGraphemes 1000)

    Breaking changes:

    • contributorIdentity: Now an object with identity string property
    • contributorRole: Now an object with role string property
    • workScopeString: Now an object with scope string property
    • Reduced maximum lengths may affect existing records with longer values

    This requires updating code that uses these union types to access the nested property instead of using the value directly.

  • #135 806cfbc Thanks @Kzoeps! - Move profile lexicon from app.certified.profile to app.certified.actor.profile namespace, requiring migration of existing profile records

0.10.0-beta.13#

Minor Changes#

  • #131 7f42fad Thanks @aspiers! - Add inline string format to app.certified.location schema with documentation and examples

  • #118 8427780 Thanks @holkexyz! - Rename evidence lexicon to attachment and refactor schema structure

    Breaking Changes:

    • Lexicon ID change:
      • org.hypercerts.claim.evidenceorg.hypercerts.claim.attachment
      • All existing evidence records must be migrated to use the new lexicon ID
    • Schema structure changes (org.hypercerts.claim.attachment):
      • Changed subject (single strongRef) to subjects (array of strongRefs, maxLength: 100)
      • Changed content from single union (uri/blob) to array of unions (maxLength: 100)
      • Added contentType field (string, maxLength: 64) to specify attachment type
      • Removed relationType field (previously used to indicate supports/challenges/clarifies)
      • Removed contributors field
      • Removed locations field
      • Added rich text support: shortDescriptionFacets and descriptionFacets (arrays of app.bsky.richtext.facet)
      • Updated required fields: ["title", "content", "createdAt"] (content is now required)
    • Common definitions (org.hypercerts.defs):
      • Added weightedContributor def for contributor references with optional weights
      • Added contributorIdentity def for string-based contributor identification

    Migration:

    Lexicon ID: Update all references from org.hypercerts.claim.evidence to org.hypercerts.claim.attachment.

    Schema migration:

    JSON
    // Before (org.hypercerts.claim.evidence)
    {
      "$type": "org.hypercerts.claim.evidence",
      "subject": { "uri": "...", "cid": "..." },
      "content": { "uri": "https://..." },
      "title": "Evidence Title",
      "relationType": "supports",
      "createdAt": "..."
    }
    
    
    // After (org.hypercerts.claim.attachment)
    {
      "$type": "org.hypercerts.claim.attachment",
      "subjects": [{ "uri": "...", "cid": "..." }],
      "content": [{ "uri": "https://..." }],
      "contentType": "evidence",
      "title": "Evidence Title",
      "createdAt": "..."
    }
    

    Field mapping:

    • subjectsubjects (wrap in array)
    • content (single) → content (array, wrap existing value)
    • relationType → remove (no direct replacement)
    • contributors → remove (no direct replacement)
    • locations → remove (no direct replacement)

Patch Changes#

  • #118 8427780 Thanks @holkexyz! - Add location property to attachment schema

    New Feature:

    • location field (org.hypercerts.claim.attachment):
      • Added optional location property as a strong reference (com.atproto.repo.strongRef)
      • Allows attachments to associate location metadata directly without using the sidecar pattern
      • The referenced record must conform to the app.certified.location lexicon

    Usage:

    JSON
    {
      "$type": "org.hypercerts.claim.attachment",
      "subjects": [
        {
          "uri": "at://did:plc:.../org.hypercerts.claim.activity/...",
          "cid": "..."
        }
      ],
      "content": [{ "uri": "https://..." }],
      "title": "Field Report",
      "location": {
        "uri": "at://did:plc:.../app.certified.location/abc123",
        "cid": "..."
      },
      "createdAt": "..."
    }
    

    This change aligns with the location property addition to collections (PR #123), providing a consistent pattern for associating location metadata across record types.

0.10.0-beta.12#

Minor Changes#

  • #120 b2f7b68 Thanks @holkexyz! - Refactor measurement lexicon schema: add unit field, date ranges, and locations array

    Breaking Changes:

    • Measurement lexicon (org.hypercerts.claim.measurement):
      • Changed required fields: removed measurers from required, added unit as required
      • Added unit field (required, string, maxLength: 50): The unit of the measured value (e.g. kg CO₂e, hectares, %, index score)
      • Added startDate field (optional, datetime): The start date and time when the measurement began
      • Added endDate field (optional, datetime): The end date and time when the measurement ended
      • Changed location (single strongRef) to locations (array of strongRefs, maxLength: 100)
      • Moved measurers from required to optional field
      • Added comment field (optional, string): Short comment suitable for previews and list views
      • Added commentFacets field (optional, array): Rich text annotations for comment (mentions, URLs, hashtags, etc.)
      • Updated field descriptions for metric and value with more detailed examples

    Migration:

    Required fields: Update measurement records to include the new required unit field:

    JSON
    // Before
    {
      "$type": "org.hypercerts.claim.measurement",
      "measurers": [...],
      "metric": "CO₂ sequestered",
      "value": "1000",
      "createdAt": "..."
    }
    
    
    // After
    {
      "$type": "org.hypercerts.claim.measurement",
      "metric": "CO₂ sequestered",
      "unit": "kg CO₂e",
      "value": "1000",
      "measurers": [...],  // Now optional
      "createdAt": "..."
    }
    

    Location field: Convert from single location to locations array:

    JSON
    // Before
    {
      "location": { "uri": "...", "cid": "..." }
    }
    
    
    // After
    {
      "locations": [{ "uri": "...", "cid": "..." }]
    }
    

    Date ranges: Optionally add startDate and endDate to specify when measurements were taken.

  • #125 771d142 Thanks @s-adamantine! - Simplify workScope to union of strongRef and string

    Breaking Changes:

    • The workScope field in org.hypercerts.claim.activity is now a union of:
      • com.atproto.repo.strongRef: A reference to a work-scope logic record for structured, nested work scope definitions
      • org.hypercerts.claim.activity#workScopeString: A free-form string for simple or legacy scopes
    • Removed from org.hypercerts.defs:
      • workScopeAll (logical AND operator)
      • workScopeAny (logical OR operator)
      • workScopeNot (logical NOT operator)
      • workScopeAtom (atomic scope reference)

    This simplification allows work scope complexity to be managed via referenced records while still supporting simple string-based scopes for straightforward use cases.

0.10.0-beta.11#

Minor Changes#

  • #123 c623d32 Thanks @aspiers! - Add location property 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.

0.10.0-beta.10#

Minor Changes#

  • #122 3e3da41 Thanks @aspiers! - Drop HELPER_ prefix from workScopeTag constants. HELPER_WORK_SCOPE_TAG_NSID, HELPER_WORK_SCOPE_TAG_LEXICON_JSON, and HELPER_WORK_SCOPE_TAG_LEXICON_DOC are now WORK_SCOPE_TAG_NSID, WORK_SCOPE_TAG_LEXICON_JSON, and WORK_SCOPE_TAG_LEXICON_DOC.

0.10.0-beta.9#

Minor Changes#

  • #121 5c33b79 Thanks @aspiers! - Fix camelCase export names to use underscores. Generated constants like CONTRIBUTIONDETAILS_LEXICON_* are now CONTRIBUTION_DETAILS_LEXICON_* for consistency.

    Affected exports:

    • CONTRIBUTION_DETAILS_NSID, CONTRIBUTION_DETAILS_LEXICON_JSON, CONTRIBUTION_DETAILS_LEXICON_DOC (was CONTRIBUTIONDETAILS_*)
    • CONTRIBUTOR_INFORMATION_NSID, CONTRIBUTOR_INFORMATION_LEXICON_JSON, CONTRIBUTOR_INFORMATION_LEXICON_DOC (was CONTRIBUTORINFORMATION_*)
    • STRONG_REF_NSID, STRONG_REF_LEXICON_JSON, STRONG_REF_LEXICON_DOC (was STRONGREF_*)
    • HELPER_WORK_SCOPE_TAG_NSID, HELPER_WORK_SCOPE_TAG_LEXICON_JSON, HELPER_WORK_SCOPE_TAG_LEXICON_DOC (was HELPER_WORKSCOPETAG_*)

0.10.0-beta.8#

Minor Changes#

  • #107 678de97 Thanks @holkexyz! - Add work scope logic expression system with boolean operators

    New Features:

    • Work scope logic AST (org.hypercerts.defs):
      • Added org.hypercerts.defs#workScopeAll (logical AND): requires all arguments to be satisfied, with recursive union support for nested expressions
      • Added org.hypercerts.defs#workScopeAny (logical OR): requires at least one argument to be satisfied, with recursive union support for nested expressions
      • Added org.hypercerts.defs#workScopeNot (logical NOT): negates an expression, with recursive union support for nested expressions
      • Added org.hypercerts.defs#workScopeAtom: atomic reference to a scope tag record via strongRef
      • All operators support recursive boolean logic expressions through union types in their args/arg properties, allowing nested combinations of workScopeAll, workScopeAny, workScopeNot, and workScopeAtom
    • Work scope tag lexicon (org.hypercerts.helper.workScopeTag):
      • New record type for reusable scope atoms
      • Fields: createdAt, key, label (required), kind, description, parent, aliases, externalReference (optional)
      • Supports taxonomy/hierarchy via parent strongRef
      • Supports external references via URI or blob
    • Activity lexicon (org.hypercerts.claim.activity):
      • Added org.hypercerts.claim.activity#workScope field using a union type that references org.hypercerts.defs#workScopeAll, org.hypercerts.defs#workScopeAny, org.hypercerts.defs#workScopeNot, and org.hypercerts.defs#workScopeAtom
      • Enables complex boolean logic expressions for work scope definitions with recursive nesting support
      • Replaces simple strongRef approach with expressive AST-based system

    Breaking Changes:

    • The workScope field in org.hypercerts.claim.activity now expects a work scope logic expression instead of a simple strongRef. Existing records using the old format will need to be migrated to use the new AST structure.

0.10.0-beta.7#

Minor Changes#

  • #106 b03a1f7 Thanks @copilot-swe-agent! - Add avatar and banner fields to collection lexicon for visual representation

  • #113 c3f9ca2 Thanks @holkexyz! - Refactor collection items structure to support optional weights and remove activityWeight from activity schema

    Breaking Changes:

    • Activity lexicon (org.hypercerts.claim.activity):
      • Removed org.hypercerts.claim.activity#activityWeight def
      • Activity records no longer include activity weight information
    • Collection lexicon (org.hypercerts.claim.collection):
      • Changed org.hypercerts.claim.collection#items from array of strongRefs to array of item objects
      • Added org.hypercerts.claim.collection#item def 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)

    Migration:

    Collection items: Convert from array of strongRefs to array of item objects:

    JSON
    // Before
    "items": [strongRef1, strongRef2]
    
    
    // After
    "items": [
      { "itemIdentifier": strongRef1, "itemWeight": "1.5" },
      { "itemIdentifier": strongRef2 }
    ]
    

    Activity weights: Migrate existing org.hypercerts.claim.activity#activityWeight data to collection org.hypercerts.claim.collection#item.itemWeight:

    JSON
    // 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.

  • #91 0c6da09 Thanks @holkexyz! - Add rich text facet support to activity claim descriptions

    Add shortDescriptionFacets and descriptionFacets fields to the activity lexicon to support rich text annotations (mentions, URLs, hashtags, etc.) in activity claim descriptions.

0.10.0-beta.6#

Minor Changes#

  • #102 68011ae Thanks @holkexyz! - Refactor contributions structure and split contributor lexicon

    Breaking Changes:

    • Activity lexicon (org.hypercerts.claim.activity):
      • Renamed contributions field to contributors
      • Replaced contributions array (array of strongRefs) with new contributors array containing contributor objects
      • Each contributor object has three fields:
        • contributorInformation (required): string (DID/identifier) or strongRef to org.hypercerts.claim.contributorInformation#main
        • weight (optional): positive number (stored as string)
        • contributionDetails (optional): string or strongRef to org.hypercerts.claim.contributionDetails#main
      • Renamed internal contribution object type to contributor
      • Renamed string wrapper defs: contributorInformationStringcontributorIdentity, contributionDetailsStringcontributorRole
      • Updated contributorRole string limits: maxLength 10000, maxGraphemes 1000
    • Contributor lexicon (org.hypercerts.claim.contributor):
      • Split into two separate lexicon files:
        • org.hypercerts.claim.contributorInformation: new lexicon file containing identifier, displayName, image (contributor profile information)
        • org.hypercerts.claim.contributionDetails: new lexicon file containing role, contributionDescription, startDate, endDate (contribution-specific details)
      • The original org.hypercerts.claim.contributor lexicon has been removed

    Existing contributions using the old structure will need to be migrated to the new format.

0.10.0-beta.5#

Minor Changes#

  • #78 c55d8a7 Thanks @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.

  • #93 3276d6e Thanks @bitbeckers! - Change workScope from inline object definition to strongRef in activity lexicon. This breaking change removes the workScope definition (withinAllOf, withinAnyOf, withinNoneOf properties) and changes the workScope property to reference an external record via strongRef, allowing for more flexible work scope definitions.

  • #97 ceddab9 Thanks @aspiers! - Move schema documentation tables from README.md to auto-generated SCHEMAS.md to reduce git merge conflicts. The SCHEMAS.md file is now auto-generated from lexicon definitions and included in the distributed package.

  • #78 cc9d7bf Thanks @bitbeckers! - Refactor collection lexicon to use items array instead of activities. The items array contains plain strongRefs (com.atproto.repo.strongRef) that can reference activities (org.hypercerts.claim.activity) and/or other collections (org.hypercerts.claim.collection), enabling recursive collection nesting. This change removes the activityWeight object structure from the base collection lexicon.

  • #67 b51dd76 Thanks @bitbeckers! - Remove bidirectional project-activity link. Activities no longer include a project field reference. Projects continue to reference activities via the activities array, making the relationship unidirectional (project → activities only).

  • #98 43b0431 Thanks @aspiers! - Remove org.hypercerts.claim.collection.project lexicon

  • #75 95e2ba1 Thanks @s-adamantine! - Unify project and collection schemas into a single org.hypercerts.claim.collection lexicon with type discriminator field to allow collections to be designated as projects. Custom strings are also allowed in type.

    Also make shortDescription field optional in org.hypercerts.claim.collection to match org.hypercerts.claim.project.

    This unification removes org.hypercerts.claim.project, so existing projects should be migrated to collections with type set to project.

  • #80 e8d5a7c Thanks @s-adamantine! - Updated org.hypercerts.claim.collection lexicon:

    • Added optional type field to specify collection type (e.g., 'favorites', 'project')
    • Renamed fields for consistency:
      • collectionTitletitle
      • shortCollectionDescriptionshortDescription
      • collectionDescriptiondescription
    • Changed description from string to Leaflet linear document reference (pub.leaflet.pages.linearDocument#main) to support rich-text descriptions

    Breaking changes:

    • Field names have been renamed (e.g., collectionTitletitle)
    • The description field now expects a reference object instead of a plain string
  • #92 bec8e63 Thanks @s-adamantine! - Update org.hypercerts.claim.contributor lexicon to support individual contributor profiles and roles.

    Breaking Changes:

    • Removed contributors array.
    • Added identifier, displayName, and image fields for individual profiles.
    • Renamed description to contributionDescription.
    • Updated required fields to only include createdAt.

    Also corrected incorrect references to org.hypercerts.claim.contribution across the codebase to use the correct ID org.hypercerts.claim.contributor.

Patch Changes#

  • #77 0d61ff7 Thanks @bitbeckers! - Document ATProto sidecar pattern for collections using app.certified.location. Collections can now have location metadata by creating a location record with the same TID, allowing location updates without changing the collection CID. Updated README with usage example and ERD with sidecar relationship.

  • #74 f845f92 Thanks @aspiers! - Make startDate and endDate optional in activity lexicon

0.10.0-beta.4#

Minor Changes#

0.10.0-beta.3#

Patch Changes#

  • ece7629 Thanks @aspiers! - Include CHANGELOG.md in package distribution for better user documentation.

0.10.0-beta.2#

Patch Changes#

0.10.0-beta.1#

Minor Changes#

  • 96bdb6c Thanks @aspiers! - Improved exports structure with semantic collection mappings for extra syntactic sugar.

    Breaking Changes:

    • Renamed ids export to HYPERCERTS_NSIDS_BY_TYPE (maps type namespaces to NSIDs)

    New Features:

    • Added HYPERCERTS_NSIDS object with semantic keys (e.g., ACTIVITY, RIGHTS, CONTRIBUTION)
    • Added HYPERCERTS_LEXICON_JSON object with semantic keys mapping to raw JSON lexicons
    • Added HYPERCERTS_LEXICON_DOC object with semantic keys mapping to typed lexicon documents
    • All three new objects share the same key structure for consistency

    Migration Guide:

    If you were using the ids export (rare):

    TypeScript
    // Before
    import { ids } from "@hypercerts-org/lexicon";
    const nsid = ids.OrgHypercertsClaimActivity;
    
    
    // After
    import { HYPERCERTS_NSIDS_BY_TYPE } from "@hypercerts-org/lexicon";
    const nsid = HYPERCERTS_NSIDS_BY_TYPE.OrgHypercertsClaimActivity;
    

    Most users should use individual NSID constants (unchanged):

    TypeScript
    import { ACTIVITY_NSID, RIGHTS_NSID } from "@hypercerts-org/lexicon";
    

    Or the new semantic mapping:

    TypeScript
    import { HYPERCERTS_NSIDS } from "@hypercerts-org/lexicon";
    const nsid = HYPERCERTS_NSIDS.ACTIVITY; // Same as ACTIVITY_NSID
    
  • ec91289 Thanks @aspiers! - chore: switch to build via rollup

    Major build system improvements:

    • Build System: Migrated from direct TypeScript to Rollup-based builds
      • Generates proper ESM (dist/index.mjs) and CommonJS (dist/index.cjs) bundles
      • Generates TypeScript declarations (dist/index.d.ts)
      • Includes source maps for debugging
      • Adds /lexicons export for lighter bundle (validation only)
    • Code Generation:
      • Auto-generates generated/exports.ts with clean, organized exports
      • Creates type shims for external lexicons (@atcute/leaflet)
      • All generated code now in generated/ directory (gitignored)
    • Package Exports:
      • Main export: @hypercerts-org/lexicon (full package with types)
      • Lexicons export: @hypercerts-org/lexicon/lexicons (schemas only, smaller bundle)
      • Proper dual package support (ESM + CommonJS)
    • Code Quality:
      • Added ESLint configuration
      • Added TypeScript type-checking to CI
      • Improved build validation workflow
    • Dependencies:
      • Added @atcute/leaflet for external lexicon references
      • Added multiformats as runtime dependency
      • Moved @atproto/lex-cli to devDependencies (build-time only)

    Migration: No breaking changes for existing users. Package structure is improved but import paths remain compatible.

Patch Changes#

  • 913eb06 Thanks @aspiers! - Switch from bundled to individual type declaration files

    Changes:

    • Removed rollup-plugin-dts dependency
    • Switched to native TypeScript declaration generation
    • Type declarations now mirror source structure in dist/types/
    • Individual type files are small (1-3KB each) and lazy-loaded by TypeScript
    • Improves IDE performance by avoiding single 39MB bundled declaration file

    Technical Details:

    The package now generates individual .d.ts files alongside the bundled JavaScript output. This provides better IDE performance as TypeScript can lazy-load type files on demand rather than parsing a massive bundled declaration file upfront.

0.10.0-beta.0#

Minor Changes#

  • 6a62c04 Thanks @aspiers! - This release represents the migration of the lexicon package from the SDK monorepo (hypercerts-sdk/packages/lexicon) to a dedicated standalone repository (hypercerts-lexicon). This separation allows for independent versioning and development of the lexicon definitions.

    Major architectural and feature updates compared to the SDK lexicon package include but are not limited to the following:

    New Lexicons:

    • Activity model: org.hypercerts.claim.activity - activity-based hypercert records (replaces single claim model)
    • Project records: org.hypercerts.claim.project - projects that group multiple activities
    • Shared definitions: org.hypercerts.defs - common types (uri, smallBlob, largeBlob, smallImage, largeImage)
    • Badge system: app.certified.badge.definition, app.certified.badge.award, app.certified.badge.response for badge-based endorsements
    • Funding receipts: org.hypercerts.funding.receipt - payment and funding tracking

    Architectural Changes:

    • Claim model: Replaced single org.hypercerts.claim record with activity-based org.hypercerts.claim.activity model
    • Collection model: Collections now reference activities (via activityWeight) instead of claims (via claimItem)
    • Work scope: Activity model uses structured workScope object with label-based conditions (withinAllOf, withinAnyOf, withinNoneOf)
    • Time fields: Activity uses startDate/endDate instead of workTimeFrameFrom/workTimeFrameTo
    • Image references: Activity model references org.hypercerts.defs#smallImage instead of app.certified.defs#uri/smallBlob

    Definition Updates:

    • app.certified.defs now includes did type definition
    • Added org.hypercerts.defs with image and blob type definitions
    • Activity model references project via AT-URI instead of strongRef

    Removed/Replaced:

    • org.hypercerts.claim (replaced by org.hypercerts.claim.activity)
    • Top-level org.hypercerts.collection (replaced by org.hypercerts.claim.collection using activities)