Skip to content

Commit d3876a1

Browse files
authored
Merge pull request #101 from hypercerts-org/copilot/check-lexicons-against-guide
2 parents fb09b0d + a631af7 commit d3876a1

File tree

6 files changed

+948
-0
lines changed

6 files changed

+948
-0
lines changed

.github/workflows/style.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Style Guide Check
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
jobs:
10+
style:
11+
runs-on: blacksmith-4vcpu-ubuntu-2404
12+
13+
steps:
14+
- uses: actions/checkout@v6
15+
16+
- name: Setup Node.js
17+
uses: actions/setup-node@v6
18+
with:
19+
node-version: "20"
20+
cache: "npm"
21+
22+
- name: Install dependencies
23+
run: npm ci
24+
25+
- name: Run lexicon style guide checker
26+
run: npm run style:check

CONTRIBUTING.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Contributing to Hypercerts Lexicon
2+
3+
Thank you for your interest in contributing! This guide covers the
4+
contribution process. For technical details about the codebase, see
5+
[AGENTS.md](AGENTS.md).
6+
7+
## Quick Start
8+
9+
```bash
10+
# Fork and clone the repository
11+
git clone https://github.com/your-username/hypercerts-lexicon.git
12+
cd hypercerts-lexicon
13+
14+
# Install dependencies
15+
npm install
16+
17+
# Verify setup
18+
npm run check
19+
```
20+
21+
## Making Changes
22+
23+
### Using AI Agents (Recommended)
24+
25+
The easiest way to contribute is using an AI agent that respects the
26+
guidance in [AGENTS.md](AGENTS.md). The agent will handle code
27+
generation, formatting, and changesets automatically.
28+
29+
### Manual Changes
30+
31+
If making changes manually, follow the workflow in [AGENTS.md § Adding
32+
/ modifying a lexicon](AGENTS.md#adding--modifying-a-lexicon).
33+
34+
**Key points:**
35+
36+
- Never edit `generated/` or `dist/` directories directly
37+
- Run `npm run gen-api` after modifying lexicon JSON files
38+
- Run `npm run format` before committing
39+
- Run `npm run check` to validate everything
40+
- **Always create a changeset** for public API changes
41+
42+
## Changesets (Required)
43+
44+
Create a changeset for any user-facing changes:
45+
46+
```bash
47+
npm run changeset
48+
```
49+
50+
Follow the prompts to select version bump type and describe
51+
changes. See [AGENTS.md § Versioning](AGENTS.md#versioning) for
52+
details.
53+
54+
## Pull Request Process
55+
56+
1. **Target the `develop` branch** (not `main`)
57+
2. **Ensure all checks pass**: `npm run check`
58+
3. **Include a changeset** if required
59+
4. **Write clear commit messages** using conventional commit format
60+
5. **Respond to review feedback** promptly
61+
62+
### Before Submitting
63+
64+
```bash
65+
npm run format # Format code
66+
npm run check # Validate everything passes
67+
```
68+
69+
## Code Quality Standards
70+
71+
- **Formatting**: Run `npm run format` (uses Prettier + EditorConfig)
72+
- **Linting**: Run `npm run lint`
73+
- **Type checking**: Run `npm run typecheck`
74+
- **Lexicon style**: Run `npm run style:check`
75+
76+
See [LEXICON_STYLE_GUIDE.md](LEXICON_STYLE_GUIDE.md) for lexicon best
77+
practices.
78+
79+
## Development Commands
80+
81+
See [AGENTS.md § Development Commands](AGENTS.md#development-commands)
82+
for the complete list of available npm scripts.
83+
84+
## Project Structure
85+
86+
See [AGENTS.md § Project Structure](AGENTS.md#project-structure) for
87+
directory layout and file organization.
88+
89+
## Getting Help
90+
91+
- **Issues**: [GitHub Issues](https://github.com/hypercerts-org/hypercerts-lexicon/issues)
92+
- **Discussions**: [GitHub Discussions](https://github.com/hypercerts-org/hypercerts-lexicon/discussions)
93+
- **Documentation**: [README.md](README.md), [AGENTS.md](AGENTS.md), [SCHEMAS.md](SCHEMAS.md)
94+
95+
## Release Process
96+
97+
**Contributors only create changesets.** Releases are handled by
98+
maintainers via GitHub Actions on the `develop` (beta) and `main`
99+
(stable) branches.
100+
101+
## License
102+
103+
Contributions are licensed under the MIT License.
104+
105+
---
106+
107+
**Thank you for contributing!** Your work helps make the Hypercerts
108+
protocol better for everyone.

LEXICON_STYLE_GUIDE.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# ATProto Lexicon Style Guide
2+
3+
This document summarizes the ATProto Lexicon Style Guide rules that are checked by our automated checker. For the complete guide, visit: https://atproto.com/guides/lexicon-style-guide
4+
5+
## Key Style Rules
6+
7+
### 1. Naming Conventions
8+
9+
#### Lexicon IDs (NSIDs)
10+
11+
- **Format**: Reverse-DNS notation (e.g., `org.hypercerts.claim.activity`)
12+
- **Case**: All lowercase
13+
- **Segments**: Use descriptive, concise names
14+
- **Avoid**: Numbers in authority segments, generic names like "item" or "thing"
15+
16+
#### Record Keys
17+
18+
- **Recommendation**: Use `any` for most record keys to allow flexible client-side naming
19+
- **TIDs**: When using TIDs (Timestamp IDs), ensure they're appropriate for the use case
20+
- **Literal keys**: Only use for singleton records or very specific use cases
21+
22+
#### Property Names
23+
24+
- **Format**: camelCase
25+
- **Clarity**: Use clear, descriptive names
26+
- **Avoid**: Abbreviations unless widely understood
27+
- **Consistency**: Use consistent terminology across related lexicons
28+
29+
### 2. Descriptions
30+
31+
#### Lexicon Descriptions
32+
33+
- **Completeness**: Every lexicon should have a clear description
34+
- **Detail**: Explain the purpose and usage
35+
- **Context**: Provide enough information for developers to understand
36+
37+
#### Property Descriptions
38+
39+
- **Required**: All properties should have descriptions
40+
- **Clarity**: Explain what the property represents and how it should be used
41+
- **Format hints**: Include format expectations when relevant
42+
43+
#### Definition Descriptions
44+
45+
- **Coverage**: All definitions (objects, arrays, etc.) should have descriptions
46+
- **Purpose**: Explain the role of the definition in the schema
47+
48+
### 3. Schema Design
49+
50+
#### Type Selection
51+
52+
- **Primitives**: Use appropriate primitive types (string, integer, boolean)
53+
- **Formats**: Apply format constraints (datetime, uri, cid, did, etc.)
54+
- **Refs**: Use refs for reusable types and relationships
55+
- **Unions**: Use unions when a property can be one of several types
56+
57+
#### Constraints
58+
59+
- **String lengths**: Always set maxLength for strings
60+
- **maxGraphemes**: Consider using maxGraphemes for user-visible text
61+
- **Array constraints**: Consider maxLength for arrays
62+
- **Required fields**: Mark truly required fields, keep optional what can be optional
63+
64+
#### Blob Handling
65+
66+
- **Size limits**: Always specify maxSize for blobs
67+
- **MIME types**: Specify accepted MIME types with the `accept` property
68+
- **Documentation**: Document blob size limits and types clearly
69+
70+
### 4. Relationships and References
71+
72+
#### Strong References
73+
74+
- **Usage**: Use `com.atproto.repo.strongRef` for references to other records
75+
- **Documentation**: Clearly document what type of record is expected
76+
- **Validation**: Specify the expected lexicon type in the description
77+
78+
#### Arrays of References
79+
80+
- **Consistency**: Use consistent patterns for arrays of references
81+
- **Documentation**: Explain the relationship and cardinality
82+
83+
### 5. Timestamps
84+
85+
#### DateTime Fields
86+
87+
- **Format**: Always use `format: "datetime"` for timestamp fields
88+
- **Naming**: Use clear names like `createdAt`, `updatedAt`, `publishedAt`
89+
- **Requirement**: Mark as required when appropriate
90+
- **Documentation**: Explain when the timestamp should be set
91+
92+
### 6. Common Patterns
93+
94+
#### Created At
95+
96+
- **Standard**: Include a `createdAt` field for records
97+
- **Type**: `string` with `format: "datetime"`
98+
- **Description**: "Client-declared timestamp when this record was originally created"
99+
100+
#### Updated At
101+
102+
- **Usage**: Include `updatedAt` for mutable records
103+
- **Type**: `string` with `format: "datetime"`
104+
- **Description**: "Client-declared timestamp when this record was last updated"
105+
106+
#### Versioning
107+
108+
- **Consideration**: Think about versioning strategy for evolving schemas
109+
- **Migration**: Document breaking changes
110+
111+
### 7. Validation and Constraints
112+
113+
#### String Validation
114+
115+
- **maxLength**: Always set for strings (prevents abuse)
116+
- **maxGraphemes**: Use for user-facing text (better UX for internationalization)
117+
- **Patterns**: Use regex patterns when format validation is needed
118+
119+
#### Number Validation
120+
121+
- **Range**: Consider minimum and maximum values
122+
- **Integers**: Use integer type when fractional values don't make sense
123+
124+
#### Required vs Optional
125+
126+
- **Conservative**: Only mark as required if truly necessary
127+
- **Flexibility**: Allow optional fields for future extensibility
128+
- **Documentation**: Explain when optional fields should be used
129+
130+
### 8. Documentation Best Practices
131+
132+
#### Inline Documentation
133+
134+
- **Comprehensive**: Document all types, properties, and constraints
135+
- **Examples**: Include example values in descriptions when helpful
136+
- **Context**: Explain relationships and dependencies
137+
138+
#### External Documentation
139+
140+
- **README**: Maintain high-level documentation
141+
- **Migration guides**: Document schema changes and migrations
142+
- **Examples**: Provide usage examples
143+
144+
### 9. Lexicon Organization
145+
146+
#### File Structure
147+
148+
- **Grouping**: Group related lexicons in namespaces
149+
- **Definitions**: Use `defs.json` for shared definitions
150+
- **Modularity**: Keep lexicons focused and modular
151+
152+
#### Dependencies
153+
154+
- **Explicit**: Clearly document dependencies on other lexicons
155+
- **Minimal**: Minimize cross-lexicon dependencies
156+
- **Standard**: Use standard ATProto lexicons when appropriate
157+
158+
### 10. Security and Privacy
159+
160+
#### Data Sensitivity
161+
162+
- **PII**: Be careful with personally identifiable information
163+
- **Access control**: Consider who can read/write records
164+
- **Validation**: Validate all input data
165+
166+
#### Size Limits
167+
168+
- **DoS prevention**: Set appropriate size limits on all fields
169+
- **Blob limits**: Be conservative with blob size limits
170+
- **Array limits**: Limit array sizes to prevent abuse
171+
172+
## Automated Checks
173+
174+
The `style:check` script checks for:
175+
176+
1. ✅ All lexicons have descriptions
177+
2. ✅ All properties have descriptions
178+
3. ✅ All definitions have descriptions
179+
4. ✅ String properties have maxLength constraints
180+
5. ✅ Blob properties have maxSize and accept properties
181+
6. ✅ DateTime fields use the correct format
182+
7. ✅ Property names use camelCase
183+
8. ✅ Required fields are properly marked
184+
9. ✅ StrongRef usage is documented
185+
10. ✅ Lexicon IDs follow naming conventions
186+
187+
## Running the Checker
188+
189+
```bash
190+
npm run style:check
191+
```
192+
193+
This will check all lexicons in the `lexicons/` directory and report any style guide violations.

opencode.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"npm run list": "allow",
2323
"npm run prepublishOnly": "deny",
2424
"npm run release": "deny",
25+
"npm run style": "allow",
2526
"npm run test": "allow",
2627
"npm run test:watch": "allow",
2728
"npm run typecheck": "allow",

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"eslint": "eslint generated/exports.ts",
5858
"typecheck": "tsc --noEmit",
5959
"clean": "rm -rf dist generated",
60+
"style:check": "node ./scripts/check-lexicon-style.js",
6061
"prepublishOnly": "npm run check",
6162
"changeset": "changeset",
6263
"version-packages": "changeset version && npm install --package-lock-only",

0 commit comments

Comments
 (0)