Skip to content
Open
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
2 changes: 1 addition & 1 deletion .agents/skills/hypercerts-api/references/endpoint-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ An `unanswered` award is a successful indexed award result, not a not-found resp
| List entities an actor follows | `app.certified.graph.listEntityFollowing` | `actor` is an actor DID; targets are hydrated from indexed records. |
| Browse recent raw follow records | `app.certified.graph.listRecentFollows` | Beta feed across publishers; `before` and pagination have distinct feed semantics. Not a per-actor relationship check. |

Do not confuse actor follows with entity follows; their identifiers and list outputs differ. Recent raw follows preserve duplicates and are not a snapshot; consult that endpoint's description before using cursors.
Account-follow endpoints (`getFollow`, `getFollows`, `listActorFollowers`, `listActorFollowing`, `getFollowerCounts`, and account records in `listRecentFollows`) skip legacy project follows: a `graph.follow` whose `via` points to an `org.hypercerts.collection` owned by the followed DID. Other `via` values (starter pack, list, another DID's collection) are kept, and `entityFollow` is unaffected. Expect lower org follower counts than older responses showed; the lists and counts agree. Do not confuse actor follows with entity follows; their identifiers and list outputs differ. Recent raw follows preserve duplicates and are not a snapshot; consult that endpoint's description before using cursors.

## Feed reactions (6)

Expand Down
12 changes: 6 additions & 6 deletions .agents/skills/hypercerts-api/references/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1431,7 +1431,7 @@
"get": {
"operationId": "app_certified_graph_getFollow",
"tags": ["app.certified.graph"],
"description": "Returns the representative follow record for an actor-to-actor relationship, or null if none is indexed. No authentication is required.",
"description": "Returns the representative follow record for an actor-to-actor relationship, or null if none is indexed. No authentication is required. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -1470,7 +1470,7 @@
"get": {
"operationId": "app_certified_graph_getFollowerCounts",
"tags": ["app.certified.graph"],
"description": "Returns current indexed follower counts for a mixed list of accounts and entities. No authentication is required. A DID subject counts distinct publishers of app.certified.graph.follow records naming that DID; an AT-URI subject counts distinct publishers of app.certified.graph.entityFollow records naming that URI. Counts match listActorFollowers and listEntityFollowers totalCount, and do not require the subject to be indexed.",
"description": "Returns current indexed follower counts for a mixed list of accounts and entities. No authentication is required. A DID subject counts distinct publishers of app.certified.graph.follow records naming that DID; an AT-URI subject counts distinct publishers of app.certified.graph.entityFollow records naming that URI. Counts match listActorFollowers and listEntityFollowers totalCount, and do not require the subject to be indexed. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "subjects",
Expand Down Expand Up @@ -1520,7 +1520,7 @@
"get": {
"operationId": "app_certified_graph_getFollows",
"tags": ["app.certified.graph"],
"description": "Returns the representative raw follow record, or null, for each requested actor-to-actor relationship. Authentication is not required. Supply 1–100 repeated subjects values; the encoded GET request-target must not exceed 7,000 bytes.",
"description": "Returns the representative raw follow record, or null, for each requested actor-to-actor relationship. Authentication is not required. Supply 1–100 repeated subjects values; the encoded GET request-target must not exceed 7,000 bytes. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -1573,7 +1573,7 @@
"get": {
"operationId": "app_certified_graph_listActorFollowers",
"tags": ["app.certified.graph"],
"description": "Lists actors whose follow records name the requested DID as subject. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.",
"description": "Lists actors whose follow records name the requested DID as subject. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -1628,7 +1628,7 @@
"get": {
"operationId": "app_certified_graph_listActorFollowing",
"tags": ["app.certified.graph"],
"description": "Lists actors named as subjects by the requested DID's follow records. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.",
"description": "Lists actors named as subjects by the requested DID's follow records. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -1799,7 +1799,7 @@
"get": {
"operationId": "app_certified_graph_listRecentFollows",
"tags": ["app.certified.graph"],
"description": "Beta query for raw account- and entity-follow records from any publisher. No authentication is required; duplicates are preserved, and before is an exclusive bound on publisher-declared createdAt. Pages are not a snapshot, so late indexing or concurrent changes may cause records to be missed.",
"description": "Beta query for raw account- and entity-follow records from any publisher. No authentication is required; duplicates are preserved, and before is an exclusive bound on publisher-declared createdAt. Pages are not a snapshot, so late indexing or concurrent changes may cause records to be missed. Legacy project follows are not listed: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is skipped. Follows with any other via are listed.",
"parameters": [
{
"name": "before",
Expand Down
8 changes: 8 additions & 0 deletions .changeset/hide-legacy-project-follows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@hypercerts-org/happyview-modules': patch
'@hypercerts-org/api': patch
---

Follower counts and follow lists no longer include old project follows saved as account follows.

Some apps followed a project by saving an account follow whose `via` points to the followed organization's own collection. Those records are now ignored by `getFollow`, `getFollows`, `listActorFollowers`, `listActorFollowing`, `getFollowerCounts` and `listRecentFollows`, so organization follower counts may drop. Follows with any other `via` (a starter pack, a list, or another account's collection) are unchanged, and nothing is deleted.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ The HTTP gate fails if it discovers no suites, executes no `node:test` cases, or
- Context attachment and evaluation retrieval with publisher/evaluator sidecar hydration, list filters, pagination across tied `createdAt` values, and named runtime errors. Batched comment counts cover per-record counting, CID-independent subject matching, excluded non-comment attachments, and agreement with `listAttachments`.
- Activity retrieval with contributor-sidecar hydration, author/organization/contributor/URI filters, tied timestamp pagination, and literal wildcard search.
- Collection retrieval with CBOR-derived CIDs, location/tag projections, author, organization, item and tag filters, title/shortDescription search, `createdAt`/URI pagination ties, and source-order item pagination with exact-version resolution.
- Graph actor/entity lookups and lists, tied-key pagination, nullable profile/organization sidecars, entity target resolution, entity-follower totals across pages and empty pages, and the global recent-follows `before` filter. The `getFollows` and `getEntityFollows` batch queries also cover repeated target order and duplicates, explicit target keys, nullable raw views, and invalid-entry rejection. The `getFollowerCounts` batch covers mixed DID and entity subjects, input order and duplicates, deduplicated publishers, zero counts, agreement with each list endpoint's `totalCount`, and invalid-subject rejection.
- Graph actor/entity lookups and lists, tied-key pagination, nullable profile/organization sidecars, entity target resolution, entity-follower totals across pages and empty pages, the global recent-follows `before` filter, and exclusion of legacy project follows (a `via` collection owned by the followed DID) across follow lookups, lists, counts, and the recent feed while real `via` follows stay. The `getFollows` and `getEntityFollows` batch queries also cover repeated target order and duplicates, explicit target keys, nullable raw views, and invalid-entry rejection. The `getFollowerCounts` batch covers mixed DID and entity subjects, input order and duplicates, deduplicated publishers, zero counts, agreement with each list endpoint's `totalCount`, and invalid-subject rejection.
- Feed-reaction subject and actor queries, earliest duplicate selection, URI-only subject matching across CIDs, distinct-actor totals, tied cursor pagination, page-only sidecar hydration, raw `via`/signature preservation, and actor queries without hydration.
- Contribution exact-record retrieval, repeated publisher filters, tied ascending/descending cursor pagination, nullable publisher sidecars, and named errors.
- Badge, badge-query, acknowledgement, contribution, and rights HTTP fixtures with CBOR-derived record CIDs; contribution DIDs are distinct from baseline fixture identities.
Expand Down
12 changes: 6 additions & 6 deletions docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1846,7 +1846,7 @@
"tags": [
"app.certified.graph"
],
"description": "Returns the representative follow record for an actor-to-actor relationship, or null if none is indexed. No authentication is required.",
"description": "Returns the representative follow record for an actor-to-actor relationship, or null if none is indexed. No authentication is required. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -1900,7 +1900,7 @@
"tags": [
"app.certified.graph"
],
"description": "Returns current indexed follower counts for a mixed list of accounts and entities. No authentication is required. A DID subject counts distinct publishers of app.certified.graph.follow records naming that DID; an AT-URI subject counts distinct publishers of app.certified.graph.entityFollow records naming that URI. Counts match listActorFollowers and listEntityFollowers totalCount, and do not require the subject to be indexed.",
"description": "Returns current indexed follower counts for a mixed list of accounts and entities. No authentication is required. A DID subject counts distinct publishers of app.certified.graph.follow records naming that DID; an AT-URI subject counts distinct publishers of app.certified.graph.entityFollow records naming that URI. Counts match listActorFollowers and listEntityFollowers totalCount, and do not require the subject to be indexed. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "subjects",
Expand Down Expand Up @@ -1956,7 +1956,7 @@
"tags": [
"app.certified.graph"
],
"description": "Returns the representative raw follow record, or null, for each requested actor-to-actor relationship. Authentication is not required. Supply 1–100 repeated subjects values; the encoded GET request-target must not exceed 7,000 bytes.",
"description": "Returns the representative raw follow record, or null, for each requested actor-to-actor relationship. Authentication is not required. Supply 1–100 repeated subjects values; the encoded GET request-target must not exceed 7,000 bytes. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -2023,7 +2023,7 @@
"tags": [
"app.certified.graph"
],
"description": "Lists actors whose follow records name the requested DID as subject. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.",
"description": "Lists actors whose follow records name the requested DID as subject. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -2100,7 +2100,7 @@
"tags": [
"app.certified.graph"
],
"description": "Lists actors named as subjects by the requested DID's follow records. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.",
"description": "Lists actors named as subjects by the requested DID's follow records. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": [
{
"name": "actor",
Expand Down Expand Up @@ -2331,7 +2331,7 @@
"tags": [
"app.certified.graph"
],
"description": "Beta query for raw account- and entity-follow records from any publisher. No authentication is required; duplicates are preserved, and before is an exclusive bound on publisher-declared createdAt. Pages are not a snapshot, so late indexing or concurrent changes may cause records to be missed.",
"description": "Beta query for raw account- and entity-follow records from any publisher. No authentication is required; duplicates are preserved, and before is an exclusive bound on publisher-declared createdAt. Pages are not a snapshot, so late indexing or concurrent changes may cause records to be missed. Legacy project follows are not listed: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is skipped. Follows with any other via are listed.",
"parameters": [
{
"name": "before",
Expand Down
2 changes: 1 addition & 1 deletion docs/sources/lexicons/app.certified.graph.getFollow.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"defs": {
"main": {
"type": "query",
"description": "Returns the representative follow record for an actor-to-actor relationship, or null if none is indexed. No authentication is required.",
"description": "Returns the representative follow record for an actor-to-actor relationship, or null if none is indexed. No authentication is required. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": {
"type": "params",
"required": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"defs": {
"main": {
"type": "query",
"description": "Returns current indexed follower counts for a mixed list of accounts and entities. No authentication is required. A DID subject counts distinct publishers of app.certified.graph.follow records naming that DID; an AT-URI subject counts distinct publishers of app.certified.graph.entityFollow records naming that URI. Counts match listActorFollowers and listEntityFollowers totalCount, and do not require the subject to be indexed.",
"description": "Returns current indexed follower counts for a mixed list of accounts and entities. No authentication is required. A DID subject counts distinct publishers of app.certified.graph.follow records naming that DID; an AT-URI subject counts distinct publishers of app.certified.graph.entityFollow records naming that URI. Counts match listActorFollowers and listEntityFollowers totalCount, and do not require the subject to be indexed. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": {
"type": "params",
"required": [
Expand Down
2 changes: 1 addition & 1 deletion docs/sources/lexicons/app.certified.graph.getFollows.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"defs": {
"main": {
"type": "query",
"description": "Returns the representative raw follow record, or null, for each requested actor-to-actor relationship. Authentication is not required. Supply 1–100 repeated subjects values; the encoded GET request-target must not exceed 7,000 bytes.",
"description": "Returns the representative raw follow record, or null, for each requested actor-to-actor relationship. Authentication is not required. Supply 1–100 repeated subjects values; the encoded GET request-target must not exceed 7,000 bytes. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": {
"type": "params",
"required": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"defs": {
"main": {
"type": "query",
"description": "Lists actors whose follow records name the requested DID as subject. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.",
"description": "Lists actors whose follow records name the requested DID as subject. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": {
"type": "params",
"required": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"defs": {
"main": {
"type": "query",
"description": "Lists actors named as subjects by the requested DID's follow records. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.",
"description": "Lists actors named as subjects by the requested DID's follow records. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated. Legacy project follows are excluded: an account follow whose via points to an org.hypercerts.collection owned by the followed DID is not an account follow. Follows with any other via are kept.",
"parameters": {
"type": "params",
"required": [
Expand Down
Loading
Loading