Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 46 additions & 33 deletions .agents/skills/building-with-hypercerts-lexicons/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ const record = {
};

// Validate before writing
const result = validate(ACTIVITY_NSID, record);
if (!result.valid) throw new Error(JSON.stringify(result.errors));
const result = validate(record, ACTIVITY_NSID, "main");
if (!result.success) throw new Error(String(result.error));

// Write to the network
await agent.api.com.atproto.repo.createRecord({
Expand All @@ -86,9 +86,9 @@ lexicon type on the AT Protocol network.
```typescript
import {
ACTIVITY_NSID,
COLLECTION_NSID,
ATTACHMENT_NSID,
RECEIPT_NSID,
HYPERCERTS_COLLECTION_NSID,
CONTEXT_ATTACHMENT_NSID,
FUNDING_RECEIPT_NSID,
} from "@hypercerts-org/lexicon";
```

Expand Down Expand Up @@ -155,9 +155,9 @@ const doc = HYPERCERTS_LEXICON_DOC.ACTIVITY;
```typescript
import { validate, ACTIVITY_NSID } from "@hypercerts-org/lexicon";

const result = validate(ACTIVITY_NSID, record);
if (!result.valid) {
console.error(result.errors);
const result = validate(record, ACTIVITY_NSID, "main");
if (!result.success) {
console.error(result.error);
}
```

Expand Down Expand Up @@ -198,7 +198,7 @@ if (result.success) {
| --------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Activity** | `org.hypercerts.claim.activity` | The main hypercert record — title, description, contributors, work scope, timeframe, locations, rights |
| **Contribution** | `org.hypercerts.claim.contribution` | Details about a specific contribution: role, description, timeframe |
| **Contributor Information** | `org.hypercerts.claim.contributorInformation` | Identity record: DID or URI identifier, display name, avatar |
| **Contributor Information** | `org.hypercerts.claim.contributorInformation` | Identity record: DID or URI identifier, display name, image |
| **Rights** | `org.hypercerts.claim.rights` | Licensing terms (e.g. "CC BY-SA 4.0") attached to an activity |

### Collections
Expand Down Expand Up @@ -243,7 +243,7 @@ if (result.success) {
| **Location** | `app.certified.location` | Geographic reference via [Location Protocol](https://spec.decentralizedgeo.org) |
| **Profile** | `app.certified.actor.profile` | User profile: display name, bio, avatar, banner |
| **Organization** | `app.certified.actor.organization` | Organization metadata: legal structure, URLs, location |
| **Badge Definition** | `app.certified.badge.definition` | Defines a badge type with title, icon, optional issuer allowlist |
| **Badge Definition** | `app.certified.badge.definition` | Defines a badge with type, title, icon, optional issuer allowlist |
| **Badge Award** | `app.certified.badge.award` | Awards a badge to a user, project, or activity |
| **Badge Response** | `app.certified.badge.response` | Recipient accepts or rejects a badge award |
| **EVM Link** | `app.certified.link.evm` | Verifiable ATProto DID to EVM wallet link via EIP-712 signature |
Expand All @@ -256,18 +256,18 @@ CLAIMS
(the hypercert) │ │ │
│ v │
├──> contribution (role, timeframe)
├──> contributorInformation (identity, avatar)
├──> contributorInformation (identity, image)
├──> rights (licensing terms)
└──> workScope
├── cel (CEL expression)
└── tag (reusable scope atom)
├── cel ──> tag (CEL expression referencing tags)
└── string (free-form scope)

CONTEXT
attachment ────────────> activity / evaluation / ...
measurement ───────────> activity / ...
evaluation ────────────> activity / attachment
attachment ────────────> any record (activity, evaluation, …)
measurement ───────────> any record (activity, …)
evaluation ────────────> any record (activity, measurement, …)
└──────> measurement
acknowledgement ───────> activity / collection (bidirectional)
acknowledgement ───────> any record (bidirectional)

FUNDING
receipt ───────────────> activity (from funder -> to recipient)
Expand All @@ -276,6 +276,13 @@ HYPERBOARDS
board ─────────────────> activity / collection
└── contributorConfig > contributorInformation
displayProfile (per-user visual defaults)

CERTIFIED
location (geo coordinates, GeoJSON, H3, …)
link/evm (ATProto DID <-> EVM wallet link)
actor/profile (user profile)
actor/organization (org metadata)
badge/response ──> badge/award ──> badge/definition
```

Every arrow is a `strongRef` or union reference stored on AT Protocol.
Expand Down Expand Up @@ -313,10 +320,10 @@ const activity = {
### Creating a Collection

```typescript
import { COLLECTION_NSID } from "@hypercerts-org/lexicon";
import { HYPERCERTS_COLLECTION_NSID } from "@hypercerts-org/lexicon";

const project = {
$type: COLLECTION_NSID,
$type: HYPERCERTS_COLLECTION_NSID,
type: "project",
title: "Carbon Offset Initiative",
shortDescription: "Activities focused on carbon reduction",
Expand All @@ -342,15 +349,17 @@ const project = {
### Creating an Acknowledgement

```typescript
import { ACKNOWLEDGEMENT_NSID } from "@hypercerts-org/lexicon";
import { CONTEXT_ACKNOWLEDGEMENT_NSID } from "@hypercerts-org/lexicon";

const ack = {
$type: ACKNOWLEDGEMENT_NSID,
$type: CONTEXT_ACKNOWLEDGEMENT_NSID,
subject: {
uri: "at://did:plc:bob/org.hypercerts.claim.activity/3k2abc",
cid: "bafy...",
},
// context is a union — use $type to specify the variant
context: {
$type: "com.atproto.repo.strongRef",
uri: "at://did:plc:alice/org.hypercerts.collection/7x9def",
cid: "bafy...",
},
Expand All @@ -369,7 +378,10 @@ const location = {
lpVersion: "1.0",
srs: "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
locationType: "coordinate-decimal",
location: { string: "-3.4653, -62.2159" },
location: {
$type: "app.certified.location#string",
string: "-3.4653, -62.2159",
},
name: "Amazon Research Station",
createdAt: new Date().toISOString(),
};
Expand Down Expand Up @@ -402,10 +414,10 @@ const evmLink = {
### Creating an Attachment

```typescript
import { ATTACHMENT_NSID } from "@hypercerts-org/lexicon";
import { CONTEXT_ATTACHMENT_NSID } from "@hypercerts-org/lexicon";

const attachment = {
$type: ATTACHMENT_NSID,
$type: CONTEXT_ATTACHMENT_NSID,
title: "Field Survey Report",
contentType: "report",
subjects: [
Expand All @@ -414,9 +426,13 @@ const attachment = {
cid: "...",
},
],
// content items are a union — use $type to specify the variant
content: [
{ uri: "https://example.com/reports/survey-2024.pdf" },
{ uri: "ipfs://Qm..." },
{
$type: "org.hypercerts.defs#uri",
uri: "https://example.com/reports/survey-2024.pdf",
},
{ $type: "org.hypercerts.defs#uri", uri: "ipfs://Qm..." },
],
shortDescription: "Quarterly field survey documenting project progress",
createdAt: new Date().toISOString(),
Expand All @@ -426,20 +442,17 @@ const attachment = {
### Recording a Funding Receipt

```typescript
import { RECEIPT_NSID } from "@hypercerts-org/lexicon";
import { FUNDING_RECEIPT_NSID } from "@hypercerts-org/lexicon";

const receipt = {
$type: RECEIPT_NSID,
subject: {
uri: "at://did:plc:alice/org.hypercerts.claim.activity/abc123",
cid: "...",
},
$type: FUNDING_RECEIPT_NSID,
to: "did:plc:recipient",
amount: "1000.00",
currency: "USD",
paymentRail: "ethereum",
transactionId: "0xabc...",
paidAt: new Date().toISOString(),
for: "at://did:plc:alice/org.hypercerts.claim.activity/abc123",
occurredAt: new Date().toISOString(),
createdAt: new Date().toISOString(),
};
```
Expand Down
13 changes: 13 additions & 0 deletions .changeset/fix-readme-lexicon-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@hypercerts-org/lexicon": patch
---

Fix incorrect NSID reference in `org.hyperboards.board` subject field description (`org.hypercerts.claim.collection` → `org.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 (`avatar` → `image`)
- Fix context target descriptions (generalized to `any record` since subjects use generic `strongRef`)
- Add missing `$type` discriminators to union member examples
18 changes: 17 additions & 1 deletion .claude/skills/writing-changesets/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,23 @@ Add a changeset when making changes that affect consumers:
- Modifying generation scripts that affect exported code
- Any change that requires a version bump or affects package consumers

Skip changesets for internal changes (build scripts, documentation only).
Skip changesets for purely internal changes that don't reach any users
(e.g. CI config, `AGENTS.md`, `tests/`).

**Do not skip changesets for changes to files that are published in the
npm package.** Check the `files` field in `package.json` to see what
ships. Currently that includes `dist/`, `lexicons/`, `SCHEMAS.md`, and
`CHANGELOG.md`. Additionally, npm automatically includes `README.md`
regardless of the `files` field. Changes to any of these files warrant
a changeset.

**Also do not skip changesets for changes to
`.agents/skills/building-with-hypercerts-lexicons/SKILL.md`.** Although
this file is not in the npm package, it is installed by downstream AI
agents via `npx skills add hypercerts-org/hypercerts-lexicon` and acts
as the primary usage guide for those agents. Changes to it are
effectively user-facing (or at least AI-agent-facing) and warrant a
changeset.

## Format

Expand Down
23 changes: 18 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,31 @@ scripts/ Build and codegen scripts
- **Include all fields except facet fields** (they're cosmetic and
don't affect structure)

4. Update `README.md` as appropriate:
- If README.md already references that lexicon, it must be updated
4. Update `README.md` and `SKILL.md` as appropriate:
- If `README.md` or
`.agents/skills/building-with-hypercerts-lexicons/SKILL.md`
already references that lexicon, **both files must be updated**
to reflect the lexicon changes (modified properties updated,
removed lexicons removed from docs). If it doesn't already then
it's _recommended_ but _not mandatory_ to add some docs to it for
the lexicon in question.
removed lexicons removed from docs, code examples corrected).
If neither file already references the lexicon then it's
_recommended_ but _not mandatory_ to add docs for it.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- For any newly added or modified **required/public** lexicon, add
or update documentation in both files even if neither previously
referenced it, so the docs stay in sync with the schema.
The "recommended but not mandatory" exemption above applies only
to optional or internal-only lexicons.

- Document new lexicons or changes to existing ones

- Document all properties **except facet fields** (facets may be
omitted)

- `npm run test` runs `tests/validate-doc-snippets.test.ts` which
auto-checks that all TypeScript code blocks in both files use
valid export names, `$type` strings, and API call signatures.
This will catch many (but not all) documentation errors.

5. Run `npm run gen-schemas-md` to regenerate `SCHEMAS.md`

6. Run `npm run format` to ensure everything is formatted correctly
Expand Down
Loading
Loading