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
17 changes: 17 additions & 0 deletions .changeset/fix-certified-did-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@hypercerts-org/lexicon": minor
Comment on lines +1 to +2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use a major bump for this breaking change.
Changing app.certified.defs#did from a string to an object is a breaking change for consumers, so the changeset should use a major bump.

🔧 Proposed fix
--- 
-"@hypercerts-org/lexicon": minor
+"@hypercerts-org/lexicon": major
---
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
---
"@hypercerts-org/lexicon": minor
---
"@hypercerts-org/lexicon": major
🤖 Prompt for AI Agents
In @.changeset/fix-certified-did-type.md around lines 1 - 2, The changeset
currently marks "@hypercerts-org/lexicon" as a minor bump but changing
app.certified.defs#did from a string to an object is a breaking change; update
the changeset so the version bump is "major" (replace minor with major in the
changeset header for "@hypercerts-org/lexicon") and save/commit the updated
.changeset entry so consumers get a major release.

---

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
27 changes: 27 additions & 0 deletions .changeset/fix-union-string-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
"@hypercerts-org/lexicon": minor
---

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.
Comment thread
aspiers marked this conversation as resolved.
1 change: 1 addition & 0 deletions LEXICON_STYLE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ The `style:check` script checks for:
8. ✅ Required fields are properly marked
9. ✅ StrongRef usage is documented
10. ✅ Lexicon IDs follow naming conventions
11. ✅ Union types only contain object or record types (no primitives)

## Running the Checker

Expand Down
26 changes: 26 additions & 0 deletions SCHEMAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ Hypercerts-specific lexicons for tracking impact work and claims.
| `contributionWeight` | `string` | ❌ | The relative weight/importance of this contribution (stored as a string to avoid float precision issues). Must be a positive numeric value. Weights do not need to sum to a specific total; normalization can be performed by the consuming application as needed. |
| `contributionDetails` | `union` | ❌ | Contribution details as a string via org.hypercerts.claim.activity#contributorRole, or a strong reference to a contribution details record. |

##### `org.hypercerts.claim.activity#contributorIdentity`

| Property | Type | Required | Description |
| ---------- | -------- | -------- | ---------------------------------------------------- |
| `identity` | `string` | ✅ | The contributor identity string (DID or identifier). |

##### `org.hypercerts.claim.activity#contributorRole`

| Property | Type | Required | Description |
| -------- | -------- | -------- | --------------------------------- |
| `role` | `string` | ✅ | The contribution role or details. |

##### `org.hypercerts.claim.activity#workScopeString`

| Property | Type | Required | Description |
| -------- | -------- | -------- | ---------------------------------- |
| `scope` | `string` | ✅ | The work scope description string. |

---

### `org.hypercerts.claim.attachment`
Expand Down Expand Up @@ -342,6 +360,14 @@ Certified lexicons are common/shared lexicons that can be used across multiple p

**Description:** Common type definitions used across certified protocols.

#### Defs

##### `app.certified.defs#did`

| Property | Type | Required | Description |
| -------- | -------- | -------- | --------------------- |
| `did` | `string` | ✅ | The DID string value. |

---

## Type Definitions
Expand Down
14 changes: 11 additions & 3 deletions lexicons/app/certified/defs.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
"description": "Common type definitions used across certified protocols.",
"defs": {
"did": {
"type": "string",
"format": "did",
"description": "A Decentralized Identifier (DID) string."
"type": "object",
"description": "A Decentralized Identifier (DID) string.",
"required": ["did"],
"properties": {
"did": {
"type": "string",
"format": "did",
"description": "The DID string value.",
"maxLength": 256
}
Comment on lines 6 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for .changeset directory and look for relevant changesets
echo "=== Checking .changeset directory ==="
if [ -d .changeset ]; then
  echo ".changeset directory found"
  echo ""
  echo "=== Contents of .changeset directory ==="
  ls -la .changeset
  echo ""
  echo "=== Searching for changeset files mentioning DID or defs ==="
  find .changeset -type f \( -name "*.md" -o -name "*.json" \) -exec grep -l "did\|defs\|DID" {} \; 2>/dev/null | head -20
  echo ""
  echo "=== Content of changeset files ==="
  find .changeset -type f \( -name "*.md" \) ! -name "README*" -exec echo "File: {}" \; -exec cat {} \; 2>/dev/null
else
  echo "No .changeset directory found"
fi

Repository: hypercerts-org/hypercerts-lexicon

Length of output: 24894


🏁 Script executed:

#!/bin/bash
# Examine the defs.json file to understand the DID definition context
echo "=== Reading lexicons/app/certified/defs.json ==="
cat lexicons/app/certified/defs.json | head -100

echo ""
echo "=== Checking initial-version-post-repo-migration.md for DID details ==="
grep -A 5 -B 5 "did" .changeset/initial-version-post-repo-migration.md

Repository: hypercerts-org/hypercerts-lexicon

Length of output: 1143


Expand the changeset to fully document the DID definition change.

The DID definition in app.certified.defs is documented in .changeset/initial-version-post-repo-migration.md, but the changeset lacks detail about the object structure and breaking change. Expand the changeset entry to include:

  • Explicit "Breaking Changes" section marking the DID shape change (string → object)
  • The complete object structure with required fields and property definitions
  • A migration example showing how existing code using the DID should be updated

Example format:

**Breaking Changes:**
- `app.certified.defs#did`: Changed from string to object type with required `did` property
🤖 Prompt for AI Agents
In `@lexicons/app/certified/defs.json` around lines 6 - 16, Update the
.changeset/initial-version-post-repo-migration.md to document the DID schema
change by adding a "Breaking Changes" section that explicitly lists
app.certified.defs#did as changed from string to an object (required property
"did"), include the complete object shape (object with required ["did"],
properties: did: string, format: "did", maxLength: 256, and description), and
add a short migration example showing old usage (plain DID string) and the new
usage (object with { "did": "did:..." }) and a note to update any code that
reads/writes the DID value accordingly.

}
Comment on lines +7 to +17

Copilot AI Jan 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The from field uses app.certified.defs#did as a required field, but the description states "Leave empty if sender wants to stay anonymous." With the conversion of app.certified.defs#did from a string to an object type with a required did property, this creates an inconsistency: the field cannot be truly "empty" anymore since it must be an object with a did property if present.

This is not directly caused by this PR, but the conversion highlights the issue. The field should probably be marked as optional (removed from the required array) if anonymity is intended to be supported. Consider whether this breaking change affects the intended semantics of the funding receipt schema.

Copilot uses AI. Check for mistakes.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}
}
39 changes: 31 additions & 8 deletions lexicons/org/hypercerts/claim/activity.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,43 @@
}
},
"contributorIdentity": {
"type": "string",
"description": "Contributor information as a string (DID or identifier)."
"type": "object",
"description": "Contributor information as a string (DID or identifier).",
"required": ["identity"],
"properties": {
"identity": {
"type": "string",
"description": "The contributor identity string (DID or identifier).",
"maxLength": 1000,
"maxGraphemes": 100
}
}
},
"contributorRole": {
"type": "string",
"type": "object",
"description": "Contribution details as a string.",
"maxLength": 10000,
"maxGraphemes": 1000
"required": ["role"],
"properties": {
"role": {
"type": "string",
"description": "The contribution role or details.",
"maxLength": 1000,

Copilot AI Jan 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The maxLength constraint has been significantly reduced from 10000 to 1000 (a 10x decrease). This is a breaking change that may cause existing valid data to be rejected. If this reduction is intentional due to the ATProto spec requirements for union types, it should be explicitly noted in the changeset and carefully considered for backward compatibility. Consider whether this stricter limit is necessary or if a less restrictive limit would still satisfy the requirements.

Suggested change
"maxLength": 1000,
"maxLength": 10000,

Copilot uses AI. Check for mistakes.
"maxGraphemes": 100
Comment on lines +139 to +140

Copilot AI Jan 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The maxLength and maxGraphemes constraints for the role property have been significantly reduced from the original values. The original contributorRole string type had maxLength: 10000 and maxGraphemes: 1000, but the new nested role property only has maxLength: 1000 and maxGraphemes: 100 (a 10x reduction). This represents an additional breaking change beyond just the structural conversion from string to object. Consider whether these tighter constraints are intentional, or if they should match the original values to minimize breaking changes.

Suggested change
"maxLength": 1000,
"maxGraphemes": 100
"maxLength": 10000,
"maxGraphemes": 1000

Copilot uses AI. Check for mistakes.
}
Comment thread
cursor[bot] marked this conversation as resolved.
}
},
"workScopeString": {
"type": "string",
"type": "object",
"description": "A free-form string describing the work scope for simple or legacy scopes.",
"maxLength": 10000,
"maxGraphemes": 1000
"required": ["scope"],
"properties": {
"scope": {
"type": "string",
"description": "The work scope description string.",
"maxLength": 1000,
"maxGraphemes": 100
Comment thread
aspiers marked this conversation as resolved.
}
}
}
}
}
2 changes: 1 addition & 1 deletion opencode.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"npm run list": "allow",
"npm run prepublishOnly": "deny",
"npm run release": "deny",
"npm run style": "allow",
"npm run style:check": "allow",
"npm run test": "allow",
"npm run test:watch": "allow",
"npm run typecheck": "allow",
Expand Down
Loading