Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
123 changes: 71 additions & 52 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# AGENTS.md

This file provides guidance to AI coding assistants when working with
code in this repository.
This file provides guidance to AI coding assistants which are
modifying code in this repository.

If however you are building on _top_ of this repository rather than
Comment thread
aspiers marked this conversation as resolved.
_in_ it, then instead see the [`README.md`](README.md).

## ⚠️ CRITICAL REMINDER FOR AI AGENTS

Expand All @@ -16,14 +19,24 @@ Use the `writing-changesets` skill. **DO NOT skip this step!**

## Branch Strategy

**`main` is the only long-lived branch** and the default branch on GitHub.
All pull requests must target `main`.

- `feature/*` — short-lived branches for development work, merged to `main` via PR
- `prerelease/*` — ephemeral branches for beta releases only (see [docs/PUBLISHING.md](docs/PUBLISHING.md))

> **Do not open PRs against `develop`** — it is a stale branch left over from
> a previous workflow and is no longer used.
**`main` is the only evergreen branch** and the default branch on
GitHub. Normal releases are published from `main`. Note that `main`,
the latest npm package release, and the lexicons published on ATProto
may not always be perfectly in sync due to the multiple moving parts
in the publishing process.

- **`main` branch**: Preparation for stable releases, which will be
tagged and published from this branch.
- **`prerelease/*` branches**: Ephemeral branches for beta/prerelease
versions (created from `main`, merged back when done; see
[docs/PUBLISHING.md](docs/PUBLISHING.md))
- **`feature/*` (or `fix/*`) branches**: Short-lived branches for
development work, targeting and merged to `main` or a
`prerelease/*` branch via PR depending on whether a beta or
prerelease is required.

> **Do not open PRs against `develop`** — it is a stale branch left
> over from a previous workflow and is no longer used.

## Overview

Expand All @@ -40,6 +53,35 @@ The codebase consists of:
- **Built output**: Compiled bundles in `dist/` directory (gitignored)
- **Documentation**: Markdown files including README.md and ERD.md.

## Guidance for development of downstream applications

As already mentioned above, downstream applications should _not_
depend on this document for guidance, which is intended for usage when
modifying this repository.

However for the sake of clarity, consume these lexicons **NOT** by
reading from `main` or other development branches of the repository,
but instead via the following published releases:

- **For TypeScript / JavaScript code** — use [the npm package
`@hypercerts-org/lexicon`](https://www.npmjs.com/package/@hypercerts-org/lexicon),
which includes generated types, validation helpers, and schema
constants.
- **For other languages** — use the [tagged
releases](https://github.com/hypercerts-org/hypercerts-lexicon/releases)
published in this GitHub repository.

Both npm releases and git tags follow [SemVer](https://semver.org/).
For npm, you can depend on a version range to receive compatible
updates automatically. For GitHub releases/tags, pin a specific tag
or upgrade manually to a newer compatible SemVer release.

The raw lexicons published on ATProto can also be used, but they are
(unavoidably) missing useful context such as full documentation
(including changelogs), TypeScript type definitions, SemVer
guarantees, git history, and other tooling provided by the packaged
releases.

## Critical Build System Detail

**The `generated/` and `dist/` directories contain auto-generated code.
Expand Down Expand Up @@ -68,7 +110,10 @@ and type declaration files in `dist/`.

## Development Commands

**⚠️ IMPORTANT FOR AI AGENTS**: Always run scripts through npm scripts (e.g., `npm run gen-schemas-md`) rather than executing Node.js files directly (e.g., `node scripts/generate-schemas.js`). This ensures proper environment setup and consistency with the project's workflow.
**⚠️ IMPORTANT FOR AI AGENTS**: Always run scripts through npm scripts
(e.g., `npm run gen-schemas-md`) rather than executing Node.js files
directly (e.g., `node scripts/generate-schemas.js`). This ensures
proper environment setup and consistency with the project's workflow.

### Code Generation

Expand Down Expand Up @@ -162,48 +207,20 @@ Changes should be made to the lexicon JSON files, then regenerated.
### Project Structure

```text
lexicons/ # Source of truth (committed)
app/certified/
badge/
award.json
definition.json
response.json
defs.json
location.json
com/atproto/repo/strongRef.json
org/hypercerts/
claim/
activity.json
collection.json
contribution.json
evaluation.json
evidence.json
measurement.json
project.json
rights.json
defs.json
funding/
receipt.json

scripts/ # Build scripts (committed)
create-shims.sh # Generate type shims for external lexicons
generate-exports.js # Auto-generate generated/exports.ts
generate-schemas.js # Auto-generate SCHEMAS.md from lexicons

generated/ # Auto-generated (gitignored)
index.ts # Generated client (not exposed)
exports.ts # Clean exports (entry point)
lexicons.ts # Schema definitions and validation
types/ # Type definitions for each lexicon
util.ts # Utility types

dist/ # Built output (gitignored)
index.mjs # ESM bundle
index.cjs # CommonJS bundle
index.d.ts # TypeScript declarations
*.map # Source maps
lexicons/ Source of truth (committed)
org/hypercerts/ Hypercerts protocol lexicons
org/hyperboards/ Hyperboards visual layer lexicons
app/certified/ Shared/certified lexicons
com/atproto/ ATProto external references

generated/ Auto-generated TypeScript (gitignored)
dist/ Built bundles (gitignored)
scripts/ Build and codegen scripts
```

> **Never edit `generated/` or `dist/` directly** — they are
> regenerated from lexicon JSON files.

## Common Patterns

### Adding / modifying a lexicon
Expand Down Expand Up @@ -331,7 +348,9 @@ See `ERD.puml` for the entity relationship diagram. Key relationships:

## Issue Tracking with bd (beads)

**IMPORTANT**: This project uses **bd (beads)** for ALL issue tracking. Do NOT use markdown TODOs, task lists, or other tracking methods.
**IMPORTANT**: Developers of this project sometimes use **bd
(beads)**, but _not_ for _all_ issue tracking. At the time of writing,
the GitHub issue tracker is also used.

### Why bd?

Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ details.

## Pull Request Process

1. **Target the `main` branch**
1. **Target the `main` branch** unless there is a specific need
to use a `prerelease/*` branch. Consult the maintainers / community
if unsure.
2. **Ensure all checks pass**: `npm run check`
3. **Include a changeset** if required
4. **Write clear commit messages** using conventional commit format
Expand Down
147 changes: 110 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,116 @@ Every arrow (`►`) is a `strongRef` or union reference stored on the
AT Protocol network. Full field-level documentation is in
[SCHEMAS.md](SCHEMAS.md).

## Consuming These Lexicons

If you are building a downstream application on top of these lexicons,
we strongly recommend **NOT** reading from `main` or other development
branches of the repository, but instead via the following published
releases:

- **For TypeScript / JavaScript code** — use [the npm package
`@hypercerts-org/lexicon`](https://www.npmjs.com/package/@hypercerts-org/lexicon),
which includes generated types, validation helpers, and schema
constants.
- **For other languages** — use the [tagged
releases](https://github.com/hypercerts-org/hypercerts-lexicon/releases)
published in this GitHub repository.

Both npm releases and git tags follow [SemVer](https://semver.org/).
For npm, you can depend on a version range to receive compatible
updates automatically. For GitHub releases/tags, pin a specific tag
or upgrade manually to a newer compatible SemVer release.

The raw lexicons published on ATProto can also be used, but they are
(unavoidably) missing useful context such as full documentation
(including changelogs), TypeScript type definitions, SemVer
guarantees, git history, and other tooling provided by the packaged
releases.

## Maintenance and publishing releases

Clearly stability and predictability for users and developers are
essential.

Unfortunately AT Protocol doesn't support any kind of native
versioning or migrations which could support lexicon schema changes.
Instead, the AT Protocol community recommends minimising changes to
lexicons in general, and to avoid breaking changes wherever possible:

- https://atproto.com/guides/lexicon-style-guide
- https://www.pfrazee.com/blog/lexicon-guidance

This project intends to follow that guidance as much as possible
whilst retaining a pragmatic approach. In practice that means:

- Changes to other tooling within this repository which _do not touch
lexicons_ may be made at any time as long as they follow
[SemVer](https://semver.org/) to avoid negative impact on
developers.

- Non-breaking changes to lexicons, such as adding an optional
property or updating a `description`, may be made sparingly. While
these changes are backwards-compatible at the protocol level, they
may still require consuming applications and indexers to update
their schemas for consistent UX.

- Breaking changes to lexicons will only be made in exceptional
circumstances. Specifically, a breaking change will only proceed
**if and only if**:
- the broader community — not just the Hypercerts core team —
agrees that the benefits clearly outweigh the cost of the
breakage, **and**
- full consideration is given to all affected parties across the
community and wider ecosystem, not only those involved in the
decision, **and**
- no viable alternative exists, such as releasing a new `.v2`
version of the lexicon or introducing a `v2` field.

To date, breaking changes have only occurred during the early
stages of launching Hypercerts on AT Protocol, before external
consumers were building against the lexicons. We intend to keep
it that way.

It is also worth noting that members of the ATProto community have
been working on tooling to make these problems easier to deal with in
future, e.g. see https://panproto.dev/

## Use of branches

`main` is the only evergreen branch and the default branch on GitHub.
We aim to minimise deviations between `main` and versions published on
npm and ATProto. However the publishing processes involve several
moving parts (including third-party systems), and it is technically
impossible to update all three at the same time. So **please do not
assume they will always be perfectly in sync**.

See [docs/PUBLISHING.md](docs/PUBLISHING.md) for the full release workflow.

> If you see a `develop` branch, it is a stale leftover from a
> previous workflow and is no longer used; do not open pull requests
> against it.

## Contributing / development

Please see [CONTRIBUTING.md](CONTRIBUTING.md).

### Project Structure

```text
lexicons/ Source of truth (committed)
org/hypercerts/ Hypercerts protocol lexicons
org/hyperboards/ Hyperboards visual layer lexicons
app/certified/ Shared/certified lexicons
com/atproto/ ATProto external references

generated/ Auto-generated TypeScript (gitignored)
dist/ Built bundles (gitignored)
scripts/ Build and codegen scripts
```

> **Never edit `generated/` or `dist/` directly** — they are
> regenerated from lexicon JSON files.

## Installation

```bash
Expand Down Expand Up @@ -368,15 +478,6 @@ const attachment = {
};
```

## Contributing

`main` is the only long-lived branch and the default branch on GitHub.
Open all pull requests against `main`. If you see a `develop` branch,
it is a stale leftover from a previous workflow and is no longer used;
do not open pull requests against it.

See [docs/PUBLISHING.md](docs/PUBLISHING.md) for the full release workflow.

## Development

### Commands
Expand Down Expand Up @@ -432,34 +533,6 @@ const evmLinkRecord = {
`#eip712Proof` for EOA wallets.
- `createdAt` (required): Timestamp when the record was created

### Adding or Modifying a Lexicon

1. Edit JSON files in `lexicons/` following the namespace structure
2. `npm run gen-api` — regenerate TypeScript types
3. Update `ERD.puml` if relationships changed
4. Update this README if the lexicon reference table needs updating
5. `npm run gen-schemas-md` — regenerate SCHEMAS.md
6. `npm run format` — fix formatting
7. `npm run check` — validate everything
8. Create a changeset (required for all public API changes)

### Project Structure

```text
lexicons/ Source of truth (committed)
org/hypercerts/ Hypercerts protocol lexicons
org/hyperboards/ Hyperboards visual layer lexicons
app/certified/ Shared/certified lexicons
com/atproto/ ATProto external references

generated/ Auto-generated TypeScript (gitignored)
dist/ Built bundles (gitignored)
scripts/ Build and codegen scripts
```

> **Never edit `generated/` or `dist/` directly** — they are
> regenerated from lexicon JSON files.

## License

MIT
35 changes: 27 additions & 8 deletions docs/PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,39 @@

This document describes how to publish the `@hypercerts-org/lexicon`
package to npm using GitHub Actions workflows with Changesets. The
workflow uses `main` as the sole release branch, with ephemeral
prerelease branches for beta testing. All releases are manually
triggered to give you full control over when releases are made.
workflow uses `main` as the branch from which normal releases are
published, with ephemeral prerelease branches for beta testing.

All releases are manually triggered to give you full control over when
releases are made.

## Maintenance and publishing releases

Clearly stability and predictability for users and developers are
essential.

Unfortunately AT Protocol doesn't support any kind of native
versioning or migrations which could support lexicon schema changes.
Our strategy for dealing with this is documented in the ["Maintenance
and publishing releases" section of
`README.md`](../README.md#maintenance-and-publishing-releases).

## Branch Strategy

- **`main` branch**: Stable releases (the only long-lived branch)
- **`feature/*` branches**: Short-lived branches for development work,
merged to `main` via PR
- **`main` branch**: Preparation for stable releases, which will be
tagged and published from this branch. This is the only evergreen
branch.
- **`prerelease/*` branches**: Ephemeral branches for beta/prerelease
versions (created from `main`, merged back when done)
- **`feature/*` (or `fix/*`) branches**: Short-lived branches for
development work, targeting and merged to `main` or a
`prerelease/*` branch via PR depending on whether a beta or
prerelease is required.

**Flow:**

**Flow:** `feature/*` → `main` (stable), or
`prerelease/beta` → `main` (beta cycle)
- `feature/*` or `fix/*` → `main` or `prerelease/*`
- `prerelease/*` → `main` (beta cycle)

Comment thread
coderabbitai[bot] marked this conversation as resolved.
### Release Flow

Expand Down
Loading