Activity · 可見性
可見性與 host-owned policy
Activity 根據簽署後的 tenant 與 actor context 執行可重用的 feed visibility。Host 仍須在簽署請求前,判斷使用者能否發佈、follow、block、report,或代表特定 actor。
Host authorization
└─ may this user perform this product action?
Activity enforcement
└─ is this post visible to this signed actor now? Activity 無法只從 actor_id 得知 business role、subscription state、organization membership 或 object permission。
Post visibility
發佈 post 時設定 visibility:
| 值 | 作者 | Active follower | Tenant 內其他 actor | Follower fan-out |
|---|---|---|---|---|
public | 可見 | 可見 | 可見 | 有 |
followers | 可見 | 可見 | 不可見 | 有 |
private | 可見 | 不可見 | 不可見 | 無 |
Visibility 會在 tenant isolation 之後套用。Public post 只在自己的 Activity tenant 內公開,不會跨 tenant 公開。
目前的 post update contract 可以修改 body、metadata 與 render_refs,但沒有提供 visibility transition。請在 publish 時決定 visibility。
Profile 與 home read
Home timeline 會讀取簽署 actor 的 materialized entry,再套用目前的 deletion、moderation、hide、mute 與 block filter。
Profile endpoint 會在讀取來源 post 時判斷 visibility:
GET /api/v1/actors/{actor_id}/posts 作者可以讀取自己的 visible post。其他 actor 可以看到 public post;有 active follow 時,也可以看到 follower-only post。Private post 只有作者可見。
兩個 endpoint 都會在沒有可見 post 時回傳空結果。Post-level action 如果看不到 target,會回傳 post_not_found,不會洩漏 hidden 或 inaccessible post 是否存在。
Follow 與 unfollow
Follow 會建立或重新啟用從簽署 actor 指向 followed_id 的 edge:
POST /api/v1/follows
Content-Type: application/json
{ "followed_id": "actor-b" } 這條 edge 會啟用 follower visibility 與未來的 follower fan-out,但不會立刻把較舊的 post backfill 到 home timeline。
Unfollow 會刪除 edge,並移除該作者既有的 following entry,不會刪除來源 post。
Mute
Mute 會把 caller-to-target relationship state 改成 muted,並從 caller timeline 移除 target 既有的 entry:
POST /api/v1/relationships/{actor_id}/mute Muted viewer 讀取 target profile 時,也看不到其 post。Mute 是單向的,不會阻止另一位 actor 讀取或 follow caller。
目前的 unmute operation 會把 relationship state 還原成 active:
DELETE /api/v1/relationships/{actor_id}/mute 即使先前沒有 active follow,這仍是目前的契約。Consumer 不應把 mute 建模成獨立的 preference flag。
Block
Block 會建立 caller 指向 target 的 blocked relationship。接著 Activity 會:
- 移除兩位 actor 之間既有的 timeline entry
- 阻止任一方讀取另一方的 profile post
- 任一方向存在 block edge 時,阻止新的 follow
- 排除 blocked pair 之間未來的 follower fan-out
POST /api/v1/relationships/{actor_id}/block Unblock 會刪除 caller 的 block edge,不會還原先前的 follow 或 timeline entry:
DELETE /api/v1/relationships/{actor_id}/block Hide
Hide 只適用於一位 viewer 與一筆 post:
POST /api/v1/posts/{post_id}/hide Activity 會記錄 hidden pair,並從該 viewer 的 materialized timeline 移除 post。其他 viewer 與來源 post 不受影響。Rebuild 之後仍會排除 hidden post。
Hidden pair 有 database uniqueness constraint。Hide 完成後,該 viewer 已看不到 post,因此重複呼叫 endpoint 會回傳 post_not_found,不會建立另一筆 record。目前公開契約沒有 unhide operation。
Report 與 moderation
每個 tenant、post 與 actor 組合會保留一筆 report:
POST /api/v1/posts/{post_id}/reports
Content-Type: application/json
{
"reason": "host-policy-code",
"metadata": { "case_id": "case_1842" }
} 重複 report 會更新 reason 與 metadata。Activity 也會寫入 post.reported outbox event。
Report 不會隱藏 post、改變 moderation_state,也不會決定 moderation outcome。目前公開 API 沒有 moderation transition、review queue、report export、restore 或 webhook delivery contract。這些 decision 與 workflow 由 host 負責。
權責矩陣
| Decision 或 state | 負責方 |
|---|---|
| Caller 可以代表哪個 tenant 與 actor | Host |
| 使用者能否 publish 或 follow | Host |
| Post visibility enum 與 graph enforcement | Activity |
| 單一 viewer 與 post 的 hide state | Activity |
| Report record 與 outbox event | Activity |
| Report review 與 moderation decision | Host |
| Product ranking 與 recommendation policy | Host |
| Host object 與 media reference 的 rendering | Host |
目前缺口
目前沒有 protected account 與 follow request model。公開 API 無法在 publish 後修改 visibility。Report 沒有公開的 review 或 delivery workflow。雖然已有 moderation state field,但 host 無法透過 /api/v1 改變它。
這些是產品缺口,不是未明說的 extension point。