Skip to content

NON-BREAKING: add optional longDescription and visibility fields to organization - #174

Merged
s-adamantine merged 3 commits into
mainfrom
actor-new-props
Apr 22, 2026
Merged

NON-BREAKING: add optional longDescription and visibility fields to organization#174
s-adamantine merged 3 commits into
mainfrom
actor-new-props

Conversation

@satyam-mishra-pce

@satyam-mishra-pce satyam-mishra-pce commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements #169, incorporating feedback from issue comments.

Adds two optional fields to the app.certified.actor.organization lexicon:

  • longDescription — a union of descriptionString (inline plain text or markdown with optional rich-text facets) and strongRef (for any rich-text document, including Leaflet). This follows the description union pattern established across activity, collection, and attachment. Mirrors the longDescription field from the legacy app.gainforest.organization.info lexicon that GainForest is migrating away from.
  • visibility — a string with knownValues: ["public", "unlisted"] to let organizations control whether they are publicly discoverable on platforms that honor this setting.

Also adds the shared descriptionString def to org.hypercerts.defs — the inline variant used by the description union pattern across all schemas.

Changes

  • lexicons/app/certified/actor/organization.json — add longDescription (union) and visibility fields
  • lexicons/org/hypercerts/defs.json — add descriptionString shared def
  • ERD.puml — add longDescription? and visibility? to the organization entity
  • README.md — update Organization row description in the Certified table
  • SCHEMAS.md — regenerated (includes new fields in the property table)
  • tests/validate-actor-organization.test.ts — new test file (7 tests, including inline longDescription)
  • .changeset/add-organization-page-and-visibility.md — minor bump changeset

Backwards Compatibility

  • Both fields are optional — existing records without them remain valid
  • No existing fields were modified, renamed, or removed
  • Clients that don't understand the fields can safely ignore them

Notes on design decisions

  • longDescription uses the description union pattern (descriptionString | strongRef) rather than a bare Leaflet ref, for consistency with CRITICAL-01 changes across the protocol. The field is named longDescription (not description) because the base actor.profile record already owns a short description field, and the organization record extends it.
  • visibility uses knownValues (not enum) per ATProto style convention, as requested by @holkexyz
  • visibility values are lowercase (public, unlisted) consistent with all other knownValues fields in this repo
  • The visibility description is generalized and does not reference any specific platform, as requested by @holkexyz

Test plan

  • npm run check passes (pre-existing viem import errors in EVM link tests are unrelated)
  • Organization tests pass (7/7)
  • Generated types reflect union change

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Extended organization profiles with an optional long description field that supports multiple content formats (plain text, markdown, and rich-text documents).
    • Added visibility control for organizations with public and unlisted discoverability options.
  • Documentation

    • Updated schema documentation to reflect new organization fields.

@changeset-bot

changeset-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c456cda

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@hypercerts-org/lexicon Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Mar 27, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR extends the app.certified.actor.organization lexicon schema by introducing two new optional fields: longDescription (supporting inline text/markdown or rich-text document references) and visibility (controlling discoverability with "public" and "unlisted" values). Schema definitions, documentation, validation tests, and tooling are updated accordingly.

Changes

Cohort / File(s) Summary
Changeset Documentation
.changeset/add-organization-page-and-visibility.md
Version bump documentation for new organization schema fields.
Schema Definitions
lexicons/app/certified/actor/organization.json, ERD.puml, SCHEMAS.md
Added longDescription (union: inline description string, Leaflet document, or strongRef) and visibility (string: "public" or "unlisted") as optional fields to the organization record definition.
Reference Documentation
README.md
Updated lexicon reference table to document the new optional longDescription and visibility fields for organization entities.
Validation Tests
tests/validate-actor-organization.test.ts
New comprehensive test suite validating organization record with required createdAt, optional visibility values, longDescription variants, and failure cases for missing/malformed createdAt.
Lexicon Tooling
scripts/check-lexicon-style.js
Enhanced union ref validation to skip external namespace refs (pub.leaflet., app.bsky., com.atproto.) and prevent false-positive unresolved ref errors.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • aspiers
  • daviddao

Poem

🐰 A rabbit hopped through schemas bright,
Adding fields with utmost delight,
longDescription now can truly shine,
visibility marks what's thine,
The lexicon grows, page by page tonight! ✨

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main change: adding two optional fields (longDescription and visibility) to the organization lexicon.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Lexicon Documentation Sync ✅ Passed JSON lexicon, README.md, ERD.puml, and SCHEMAS.md are properly synchronized with new longDescription and visibility fields consistently documented across all files.
Lexicons Styleguide Compliance ✅ Passed The pull request's lexicon modifications comply with the ATProto Lexicon Style Guide.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch actor-new-props

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/validate-actor-organization.test.ts (1)

38-74: Add explicit rejection tests for the two new fields.

Great baseline coverage, but this PR adds constraints that should be asserted directly: reject invalid visibility values and reject invalid page types.

✅ Suggested test additions
-  it("should accept record with all optional fields populated", () => {
+  it("should accept record with several optional fields populated", () => {
     const result = Organization.validateMain({
       $type: ids.AppCertifiedActorOrganization,
       organizationType: ["nonprofit", "ngo"],
       urls: [{ url: "https://example.org", label: "Website" }],
       foundedDate: "2010-01-01T00:00:00.000Z",
       visibility: "public",
       createdAt: "2024-01-01T00:00:00.000Z",
     });
     expect(result.success).toBe(true);
   });
+
+  it("should reject record with invalid visibility value", () => {
+    const result = validate(
+      {
+        createdAt: "2024-01-01T00:00:00.000Z",
+        visibility: "private",
+      },
+      ids.AppCertifiedActorOrganization,
+      "main",
+      false,
+    );
+    expect(result.success).toBe(false);
+  });
+
+  it("should reject record with invalid page type", () => {
+    const result = validate(
+      {
+        createdAt: "2024-01-01T00:00:00.000Z",
+        page: "not-a-record",
+      },
+      ids.AppCertifiedActorOrganization,
+      "main",
+      false,
+    );
+    expect(result.success).toBe(false);
+  });

As per coding guidelines: "For negative tests in lexicon validation tests, use validate() from generated/lexicons.js."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/validate-actor-organization.test.ts` around lines 38 - 74, Add two
negative tests using validate() to assert the new constraints: one that calls
validate(..., ids.AppCertifiedActorOrganization, "main", false) with an invalid
visibility (e.g., visibility: "privateish") and expects result.success to be
false and result.error to be defined, and another that calls validate(...,
ids.AppCertifiedActorOrganization, "main", false) with an invalid page type
(e.g., page: 123 or page: {type: "unknown"}) and expects result.success to be
false; place these alongside the existing tests and use validate() (not
Organization.validateMain) per the lexicon testing guideline.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/validate-actor-organization.test.ts`:
- Around line 38-74: Add two negative tests using validate() to assert the new
constraints: one that calls validate(..., ids.AppCertifiedActorOrganization,
"main", false) with an invalid visibility (e.g., visibility: "privateish") and
expects result.success to be false and result.error to be defined, and another
that calls validate(..., ids.AppCertifiedActorOrganization, "main", false) with
an invalid page type (e.g., page: 123 or page: {type: "unknown"}) and expects
result.success to be false; place these alongside the existing tests and use
validate() (not Organization.validateMain) per the lexicon testing guideline.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 23b5336f-181f-4baf-b293-4aabf413eb80

📥 Commits

Reviewing files that changed from the base of the PR and between 9ea4051 and f585260.

📒 Files selected for processing (6)
  • .changeset/add-organization-page-and-visibility.md
  • ERD.puml
  • README.md
  • SCHEMAS.md
  • lexicons/app/certified/actor/organization.json
  • tests/validate-actor-organization.test.ts

@holkexyz holkexyz changed the title feat: add optional page and visibility fields to app.certified.actor.organization feat: add optional longDescription and visibility fields to organization Apr 1, 2026
@holkexyz
holkexyz self-requested a review April 1, 2026 08:54

@holkexyz holkexyz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good to me

changed the format and name of the longDescription to fit the pattern from #181

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Line 150: Update the phrasing in the table cell that currently reads "future
proof methods" to the hyphenated compound adjective "future-proof methods" so
the phrase modifying "methods" is grammatically correct (refer to the text
inside the table row containing "**EVM Link**" and "`app.certified.link.evm`").
- Line 146: Update the README entry for app.certified.actor.organization to
include the missing non-facet property createdAt and simplify the wording by
replacing "discoverability visibility" with "visibility"; specifically, in the
table row for `app.certified.actor.organization` add "createdAt" to the list of
documented properties (with its brief meaning, e.g., creation timestamp) and
change the phrase "discoverability visibility" to just "visibility" so the
description reads: Organization metadata: legal structure, URLs, location,
founding date, optional long description, createdAt, and visibility.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0e3ca883-032d-49fa-8407-0784c04f9182

📥 Commits

Reviewing files that changed from the base of the PR and between f585260 and 027ae8d.

📒 Files selected for processing (7)
  • .changeset/add-organization-page-and-visibility.md
  • ERD.puml
  • README.md
  • SCHEMAS.md
  • lexicons/app/certified/actor/organization.json
  • lexicons/org/hypercerts/defs.json
  • tests/validate-actor-organization.test.ts
✅ Files skipped from review due to trivial changes (3)
  • .changeset/add-organization-page-and-visibility.md
  • lexicons/org/hypercerts/defs.json
  • tests/validate-actor-organization.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • ERD.puml
  • lexicons/app/certified/actor/organization.json
  • SCHEMAS.md

Comment thread README.md
Comment thread README.md
@satyam-mishra-pce

Copy link
Copy Markdown
Contributor Author

@holkexyz
Thanks for the update for allowing strings as well.
However, I am concerned on using bsky facets here. I was expecting to have leaflet like description - i.e. with support of images, and other formattings like bold, italics, underlined, etc.
Are we moving away from leaflet?

@holkexyz

holkexyz commented Apr 1, 2026

Copy link
Copy Markdown
Member

@holkexyz Thanks for the update for allowing strings as well. However, I am concerned on using bsky facets here. I was expecting to have leaflet like description - i.e. with support of images, and other formattings like bold, italics, underlined, etc. Are we moving away from leaflet?

Yes, the idea is just that we don't want to force leaflet. You can still use leaflet via the strongRef. Does that work for you?

From the other PR: "Now a union of descriptionString (inline plain text or markdown with optional rich-text facets) and strongRef (for any rich-text document, including Leaflet)."

PS.: The nice thing with the bsky facets is that if it is used but not rendered by a frontend, it is still shown in a reasonable way (just the string). So, the facet is just an add-on. See https://www.pfrazee.com/blog/why-facets

EDIT: Adam raised a similar question in #181. I guess maybe we should add it directly and not just use strongRef. WDYT @satyam-mishra-pce ?

@satyam-mishra-pce

satyam-mishra-pce commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

@holkexyz Thanks for the update for allowing strings as well. However, I am concerned on using bsky facets here. I was expecting to have leaflet like description - i.e. with support of images, and other formattings like bold, italics, underlined, etc. Are we moving away from leaflet?

Yes, the idea is just that we don't want to force leaflet. You can still use leaflet via the strongRef. Does that work for you?

From the other PR: "Now a union of descriptionString (inline plain text or markdown with optional rich-text facets) and strongRef (for any rich-text document, including Leaflet)."

PS.: The nice thing with the bsky facets is that if it is used but not rendered by a frontend, it is still shown in a reasonable way (just the string). So, the facet is just an add-on. See https://www.pfrazee.com/blog/why-facets

EDIT: Adam raised a similar question in #181. I guess maybe we should add it directly and not just use strongRef. WDYT @satyam-mishra-pce ?

Thanks for clarifying, Holke. I am open to both the ideas of having a strongRef, and an open union with leaflet as an option. My preference would be having the open union with linear document, because a strongRef is just too vague (on what data type does it actually expect underneath) for developers (and also for AI), and requires an extra fetch, with extra validation logic as well. However, I would also like to know what @aspiers thinks on this.

@aspiers

aspiers commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

I think an open union which allows both inline linearDocuments and strongRefs is OK. A ref to string is another thing we could add to the union.

As always being less opinionated means more flexibility, but the downside is that it makes interoperability between apps harder. A good SDK can help mitigate the latter to a large degree.

@satyam-mishra-pce

Copy link
Copy Markdown
Contributor Author

I think an open union which allows both inline linearDocuments and strongRefs is OK. A ref to string is another thing we could add to the union.

As always being less opinionated means more flexibility, but the downside is that it makes interoperability between apps harder. A good SDK can help mitigate the latter to a large degree.

I agree. Added the leaflet lexicon support inline. Can this be merged now?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/check-lexicon-style.js`:
- Around line 611-621: The code unconditionally returns when ref.startsWith any
knownExternalPrefixes (knownExternalPrefixes), which skips union ref validation
even if the target lexicon is vendored and present locally; change the
early-return logic to only skip when the referenced namespace is not present in
the local index. Specifically, replace the plain if
(knownExternalPrefixes.some((prefix) => ref.startsWith(prefix))) return; with a
check that first determines whether the ref corresponds to a locally indexed
lexicon (e.g., consult the existing indexedLexicons map or isLocalLexicon
function), and only return/skip when the namespace is both in
knownExternalPrefixes and NOT found in the local index; otherwise continue with
the unresolved/type checks for that ref so typos and invalid union variants are
caught.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 35f9581b-620f-468a-9aef-0e4ec4a08c50

📥 Commits

Reviewing files that changed from the base of the PR and between b7b1d89 and 22884e7.

📒 Files selected for processing (8)
  • .changeset/add-organization-page-and-visibility.md
  • ERD.puml
  • README.md
  • SCHEMAS.md
  • lexicons/app/certified/actor/organization.json
  • lexicons/org/hypercerts/defs.json
  • scripts/check-lexicon-style.js
  • tests/validate-actor-organization.test.ts
✅ Files skipped from review due to trivial changes (4)
  • ERD.puml
  • lexicons/org/hypercerts/defs.json
  • lexicons/app/certified/actor/organization.json
  • tests/validate-actor-organization.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/add-organization-page-and-visibility.md

Comment thread scripts/check-lexicon-style.js
@aspiers aspiers changed the title feat: add optional longDescription and visibility fields to organization NON-BREAKING: add optional longDescription and visibility fields to organization Apr 7, 2026
satyam-mishra-pce and others added 2 commits April 22, 2026 13:35
…organization

- page: optional ref to pub.leaflet.pages.linearDocument#main for rich
  long-form org content (mission, history, etc.)
- visibility: optional string with knownValues [public, unlisted] to
  control discoverability on platforms that honor the setting

Closes #169
- Renamed `page` to `longDescription` on organization for clarity
- Changed from bare Leaflet ref to union of `descriptionString` and
  `strongRef`, matching the pattern used across activity, collection,
  and attachment (CRITICAL-01)
- Added `descriptionString` shared def to `org.hypercerts.defs`
- Updated ERD, README, SCHEMAS.md, changeset, and tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Insert pub.leaflet.pages.linearDocument#main as the second variant in
the longDescription union, between descriptionString and strongRef,
so clients can embed a Leaflet document directly rather than only via
a strongRef indirection.

Also fix the style checker to skip ref-resolution for known-external
namespaces (pub.leaflet.*, app.bsky.*, com.atproto.*) in union types,
consistent with how file-level checks already exempt those namespaces.
@s-adamantine
s-adamantine merged commit c5daaa2 into main Apr 22, 2026
6 checks passed
@hypercerts-release-bot hypercerts-release-bot Bot mentioned this pull request Apr 22, 2026
s-adamantine added a commit that referenced this pull request Apr 22, 2026
Two follow-ups to PR #174:

1. Drop the redundant `#main` suffix from the `longDescription` union's
   Leaflet ref in `app.certified.actor.organization`, so it matches the
   bare `pub.leaflet.pages.linearDocument` form already used on activity,
   collection, and attachment after the cleanup in 06fce2c. PR #174 was
   rebased onto that cleanup but re-introduced `#main` for the new
   organization field. Purely a ref-string normalization — the target
   def is identical.

2. Update the unreleased changeset description to describe the actual
   3-way union (inline string / embedded Leaflet linear document /
   strongRef), not a 2-way union, so the v0.12.0 CHANGELOG entry is
   accurate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants