Skip to content
Closed
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
34 changes: 34 additions & 0 deletions .changeset/add-ops-lexicon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
"@hypercerts-org/lexicon": minor
---

Add work scope logic lexicons (ops and workScopeExpr)

**New Features:**

- **New lexicon (`org.hypercerts.helper.ops`):**
- Operator node record type for work scope logic expressions
- Supports nested boolean logic operations (AND, OR, NOT)
- Fields:
- `op` (required): Operator identifier with knownValues `'all'`, `'any'`, `'not'`
- `args` (required): Array of strongRefs pointing to `org.hypercerts.helper.workScopeTag` (leaf atoms) or other `org.hypercerts.helper.ops` records (nested expressions)
- `createdAt` (required): Client-declared timestamp
- Enables complex work scope logic by allowing operators to reference other operators or scope tags recursively
- Operator semantics are defined by consuming applications

- **New lexicon (`org.hypercerts.helper.workScopeExpr`):**
- A flat boolean expression for simple work-scope definitions: (ALL allOf) AND (ANY anyOf) AND (NONE noneOf)
- Covers the majority of practical scope definitions without recursion
- Fields:
- `version` (required): Schema version integer (start with 1)
- `label`: Optional short human-readable label for UI display
- `description`: Optional longer explanation of scope intent
- `allOf`: Array of strongRefs — all must match for in-scope
- `anyOf`: Array of strongRefs — at least one must match
- `noneOf`: Array of strongRefs — none may match (exclusion)
- `createdAt` (required): Client-declared timestamp
- An empty expression (all arrays absent/empty) represents an unconstrained scope

**Usage:**

The `org.hypercerts.helper.ops` and `org.hypercerts.helper.workScopeExpr` lexicons work together with `org.hypercerts.helper.workScopeTag` to define work scope logic. Use `workScopeExpr` for simple flat include/exclude/require patterns, and `ops` for full nested boolean logic. Both can be referenced via strongRefs in activity records' `workScope` field.
46 changes: 46 additions & 0 deletions ERD.puml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,42 @@ dataclass location {
!endif
}

' org.hypercerts.helper.workScopeTag
dataclass workScopeTag {
!if (SHOW_FIELDS == "true")
createdAt
key
label
kind?
description?
parent?
aliases[]?
externalReference?
!endif
}

' org.hypercerts.helper.workScopeExpr
dataclass workScopeExpr {
!if (SHOW_FIELDS == "true")
version
label?
description?
allOf[]?
anyOf[]?
noneOf[]?
createdAt
!endif
}

' org.hypercerts.helper.ops
dataclass ops {
!if (SHOW_FIELDS == "true")
createdAt
op
args[]
!endif
}

' Certified badges (data class + award + response)
dataclass badgeDefinition {
!if (SHOW_FIELDS == "true")
Expand Down Expand Up @@ -316,6 +352,16 @@ activity::contributors -l--> contributorInformation
activity::contributors --> contributionDetails
activity::rights --> rights
activity::locations --> location
activity::workScope --> workScopeTag
activity::workScope --> workScopeExpr
activity::workScope --> ops

workScopeExpr::allOf --> workScopeTag
workScopeExpr::anyOf --> workScopeTag
workScopeExpr::noneOf --> workScopeTag

ops::args --> workScopeTag
ops::args --> ops : "recursive\nnesting"

contributorInformation::identifier --> contributorEntity : identifies

Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,16 @@ const activityRecord = {
$type: ACTIVITY_NSID,
title: "My Impact Work",
shortDescription: "Description here",
// workScope can be a strongRef to a work-scope record:
// workScope can be:
// 1. A strongRef to a workScopeExpr (flat boolean expression):
workScope: {
uri: "at://did:plc:alice/org.hypercerts.helper.workScopeTag/abc123",
uri: "at://did:plc:alice/org.hypercerts.helper.workScopeExpr/abc123",
cid: "...",
},
// OR a simple string: workScope: "Environmental conservation",
// 2. A strongRef to an ops record (nested logic tree):
// { uri: "at://did:plc:alice/org.hypercerts.helper.ops/abc123", cid: "..." }
// 3. A simple string:
// "Environmental conservation",
startDate: "2023-01-01T00:00:00Z",
endDate: "2023-12-31T23:59:59Z",
createdAt: new Date().toISOString(),
Expand Down
70 changes: 55 additions & 15 deletions SCHEMAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ Hypercerts-specific lexicons for tracking impact work and claims.

#### Properties

| Property | Type | Required | Description | Comments |
| ------------------------ | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `title` | `string` | ✅ | Title of the hypercert. | maxLength: 256 |
| `shortDescription` | `string` | ✅ | Short summary of this activity claim, suitable for previews and list views. Rich text annotations may be provided via `shortDescriptionFacets`. | maxLength: 3000, maxGraphemes: 300 |
| `shortDescriptionFacets` | `ref` | ❌ | Rich text annotations for `shortDescription` (mentions, URLs, hashtags, etc). | |
| `description` | `string` | ❌ | Optional longer description of this activity claim, including context or interpretation. Rich text annotations may be provided via `descriptionFacets`. | maxLength: 30000, maxGraphemes: 3000 |
| `descriptionFacets` | `ref` | ❌ | Rich text annotations for `description` (mentions, URLs, hashtags, etc). | |
| `image` | `union` | ❌ | The hypercert visual representation as a URI or image blob. | |
| `workScope` | `union` | ❌ | Work scope definition. Either a strongRef to a work-scope logic record (structured, nested logic), or a free-form string for simple or legacy scopes. The work scope record should conform to the org.hypercerts.helper.workScopeTag lexicon. | |
| `startDate` | `string` | ❌ | When the work began | |
| `endDate` | `string` | ❌ | When the work ended | |
| `contributors` | `ref` | ❌ | An array of contributor objects, each containing contributor information, weight, and contribution details. | |
| `rights` | `ref` | ❌ | A strong reference to the rights that this hypercert has. The record referenced must conform with the lexicon org.hypercerts.claim.rights. | |
| `locations` | `ref` | ❌ | An array of strong references to the location where activity was performed. The record referenced must conform with the lexicon app.certified.location. | |
| `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created | |
| Property | Type | Required | Description | Comments |
| ------------------------ | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `title` | `string` | ✅ | Title of the hypercert. | maxLength: 256 |
| `shortDescription` | `string` | ✅ | Short summary of this activity claim, suitable for previews and list views. Rich text annotations may be provided via `shortDescriptionFacets`. | maxLength: 3000, maxGraphemes: 300 |
| `shortDescriptionFacets` | `ref` | ❌ | Rich text annotations for `shortDescription` (mentions, URLs, hashtags, etc). | |
| `description` | `string` | ❌ | Optional longer description of this activity claim, including context or interpretation. Rich text annotations may be provided via `descriptionFacets`. | maxLength: 30000, maxGraphemes: 3000 |
| `descriptionFacets` | `ref` | ❌ | Rich text annotations for `description` (mentions, URLs, hashtags, etc). | |
| `image` | `union` | ❌ | The hypercert visual representation as a URI or image blob. | |
| `workScope` | `union` | ❌ | Defines the scope of work covered by this activity claim. May be a string, a structured scope expression (via org.hypercerts.helper.workScopeExpr), or an advanced logic tree (via org.hypercerts.helper.ops). If no inclusion or exclusion constraints are defined, the scope is treated as unconstrained and all work is considered in scope. | |
| `startDate` | `string` | ❌ | When the work began | |
| `endDate` | `string` | ❌ | When the work ended | |
| `contributors` | `ref` | ❌ | An array of contributor objects, each containing contributor information, weight, and contribution details. | |
| `rights` | `ref` | ❌ | A strong reference to the rights that this hypercert has. The record referenced must conform with the lexicon org.hypercerts.claim.rights. | |
| `locations` | `ref` | ❌ | An array of strong references to the location where activity was performed. The record referenced must conform with the lexicon app.certified.location. | |
| `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created | |

#### Defs

Expand Down Expand Up @@ -268,6 +268,46 @@ Hypercerts-specific lexicons for tracking impact work and claims.

---

### `org.hypercerts.helper.ops`

**Description:** Operator node for work scope logic. Nesting is achieved by having args strongRefs point to either workScopeTag records (leaf atoms) or other ops records (nested expressions). Operator semantics are defined by consuming applications.

Examples: op='all' (AND), op='any' (OR), op='not' (NOT; typically unary).

**Key:** `tid`

#### Properties

| Property | Type | Required | Description | Comments |
| ----------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| `op` | `string` | ✅ | Operator identifier. Semantics are defined by the evaluating application. Examples: 'all' (AND), 'any' (OR), 'not' (NOT). | maxLength: 64, Known values: `all`, `any`, `not` |
| `args` | `ref` | ✅ | Arguments. Each strongRef should point to either org.hypercerts.helper.workScopeTag (leaf) or org.hypercerts.helper.ops (nested). For op='not', args SHOULD have exactly one element (enforced by clients). | maxLength: 100 |
| `createdAt` | `string` | ✅ | Client-declared timestamp when this record was originally created | |

---

### `org.hypercerts.helper.workScopeExpr`

**Description:** A reusable work-scope boolean expression (simple flat form): (ALL allOf) AND (ANY anyOf, if present) AND (NONE noneOf). Designed to cover the vast majority of practical work-scope definitions (include, require, exclude) without recursion. For full nested boolean logic or complex conditional expressions, use org.hypercerts.helper.ops.

An empty work-scope expression represents an unconstrained scope. If `allOf`, `anyOf`, and `noneOf` are all absent or empty, the expression imposes no filtering constraints. In this case, all work is considered in scope by default.

**Key:** `tid`

#### Properties

| Property | Type | Required | Description | Comments |
| ------------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| `version` | `integer` | ✅ | Schema version for this expression. Start with 1. Enables forward-compatible evolution of evaluation semantics. | |
| `label` | `string` | ❌ | Optional short human-readable label for UI display (e.g., 'OSS docs/code — no marketing'). | maxLength: 140 |
| `description` | `string` | ❌ | Optional longer explanation of the scope intent, interpretation guidance, or edge-case clarifications. | maxLength: 4000 |
| `allOf` | `ref` | ❌ | All referenced tags must match for something to be considered in-scope. Typically refs to org.hypercerts.helper.workScopeTag. | maxLength: 100 |
| `anyOf` | `ref` | ❌ | At least one referenced tag must match (if anyOf is present and non-empty). Typically refs to org.hypercerts.helper.workScopeTag. | maxLength: 100 |
| `noneOf` | `ref` | ❌ | None of the referenced tags may match. If any excluded tag matches, the contribution or activity is considered out-of-scope. | maxLength: 100 |
| `createdAt` | `string` | ✅ | Timestamp when this work-scope expression was created. | |

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

createdAt description is inconsistent with the rest of the document.

Every other lexicon uses "Client-declared timestamp when this record was originally created" for this field. Line 307 uses "Timestamp when this work-scope expression was created." which deviates from the established pattern.

🔧 Proposed fix
-| `createdAt`   | `string`  | ✅       | Timestamp when this work-scope expression was created.                                                                                            |                 |
+| `createdAt`   | `string`  | ✅       | Client-declared timestamp when this record was originally created.                                                                                |                 |
📝 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
| `createdAt` | `string` || Timestamp when this work-scope expression was created. | |
| `createdAt` | `string` || Client-declared timestamp when this record was originally created. | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@SCHEMAS.md` at line 307, Update the `createdAt` field description in the
SCHEMAS.md table to match the project's standard phrasing; replace "Timestamp
when this work-scope expression was created." with "Client-declared timestamp
when this record was originally created" for the `createdAt` entry (the table
row that currently references the work-scope expression) so it is consistent
with other lexicons.


---

### `org.hypercerts.helper.workScopeTag`

**Description:** A reusable scope atom for work scope logic expressions. Scopes can represent topics, languages, domains, deliverables, methods, regions, tags, or other categorical labels.
Expand Down
Loading