Buffer followed-account posts with GET and DELETE #311

Merged
erik merged 2 commits from feat/task-7e947966-incoming-posts into main 2026-10-27 13:33:21 -05:00
Owner

Summary

Task: task-7e947966, first posts-only slice of parent task-96dcee85. Prerequisite task-444f16f0 was merged as PR #310.

  • Add separate incoming-activity metadata/body tables (migration 028) and durable coalesced-delivery alias metadata (migration 029), never owned publications. Buffer newly delivered signed post Creates from accepted followed accounts only, with actor/account scoping, activity/original-object identities and immutable existing Account/Contact attribution snapshots.
  • Add authenticated GET /api/v1/following/{id}/activity (default 50, maximum 100) with non-consuming receipt-order pagination and actor/account-bound cursors that survive body deletion and empty polls.
  • Add JSON DELETE on that same route (1–100 explicit IDs, maximum 16384 bytes), whole-batch validation and atomic body removal. Missing/already-removed/out-of-scope identities are harmless; duplicate IDs coalesce. Retain minimal duplicate-suppression/cursor metadata indefinitely. No implicit consumption, read acknowledgment, expiry, storage cap or background fetching.
  • Preserve reply moderation and existing engagement behavior. Ordinary posts support Note/Article/Page; preserve untrusted remote HTML and a plain-text derivative, without rendering it or downloading remote attachments. Clients must sanitize before rendering.
  • Version the additive source contract as 2.1.0 across OpenAPI/template metadata and CLI exact-version reference coverage. Npm versions, consumer pins and lockfile are unchanged. Document payloads, client retry/partial persistence, lifecycle, metadata retention/cleanup, migrations and adoption gates in docs/specs/12-incoming-activity.md and linked guidance.

Verification

./scripts/pre-pr.sh passed build, generated CSS, formatting, lint, types and all 1,400 local tests, including federation integration/loopback HTTP coverage. New checks cover:

  • Accepted versus pending/rejected/failed/cancelled/unfollowed and follower-only delivery; actor/account attribution; supported post types; no history/outbox fetch; wrong authors/audiences and unsafe/local object identities, including bracketed private IPv6 literals and unsafe source URLs.
  • Repeated and concurrent GETs without removal/read effects, retained snapshots, interruption/partial-client persistence retries, bounded pages across deletion/new arrivals/empty polls, and cursor/tombstone/alias continuity after isolated database reopen; canonical alias backfill from an isolated 028 database; activity-ID equivocation and mid-resolution actor/unfollow races.
  • Selected-only body removal, ignored foreign/missing IDs, concurrent DELETE, uncertain-response retries, whole-batch validation, request-size limits, SQLite partial FAIL-trigger rollback, ingestion rollback and preserved downloaded arrays/owned publications/comments.
  • Existing bearer scopes, feature-unavailable 501 versus empty 200, shared OpenAPI/metadata and exact unpublished-contract doctor behavior.

Local tested runtime: Node 24.22.1, Hono 4.12.23, @hono/node-server 2.0.3, Fedify 2.2.4. New integration/HTTP coverage is *.integration.test.ts and remains local-only; CI/workflows are unchanged and use npm run test:ci.

Independent review follow-up

Initial independent review of fc38391 found two P2 issues. The fixes normalize IPv6 URL literal brackets and reject non-public ranges in the shared validator, and retain all coalesced activity IDs atomically so a sender cannot reuse an observed activity ID with a different object after removal. Added signed-delivery regressions, alias rollback/reopen tests and isolated 028-to-029 migration evidence. At updated commit 3f4bc0cc73, CI run 552 is green and independent re-review found no actionable findings; both original P2s are resolved. The reviewer independently passed 79 focused tests and confirmed CI for the exact HEAD. Full local pre-PR checks passed 1,400 tests. Explicit human merge approval is still required.

Environment incident and availability gates

An already-running autoreload dev environment applied startup migrations against the existing local template/site/data/slugkit.sqlite: migration 027 during the previous task and 028 during this task. The user was informed, then explicitly authorized stopping the local dev environment; make dev-stop and make dev-status verified stopped. No rollback was attempted and no subsequent operations were run against that existing database. Remaining checks use isolated in-memory/temporary databases and loopback test servers only. Migration 029 has not been run against the existing local database; do not restart new application code there until that separate migration is authorized.

No production deployment, production mutation, release or publication has been performed. Actual production proxy forwarding of DELETE JSON is not claimed as verified; operator-authorized rollout must verify the deployed proxy/client combination. The existing local database remains at its current migrated state.

Boosts and final-contract completion remain task-8c11c803; public contract publication remains task-dbb55f82. Repository support is not production availability. Wait for CI, independent review and explicit human merge approval. Do not close the parent until all slices and publication are complete.

## Summary Task: task-7e947966, first posts-only slice of parent task-96dcee85. Prerequisite task-444f16f0 was merged as PR #310. - Add separate incoming-activity metadata/body tables (migration 028) and durable coalesced-delivery alias metadata (migration 029), never owned publications. Buffer newly delivered signed post Creates from accepted followed accounts only, with actor/account scoping, activity/original-object identities and immutable existing Account/Contact attribution snapshots. - Add authenticated GET /api/v1/following/{id}/activity (default 50, maximum 100) with non-consuming receipt-order pagination and actor/account-bound cursors that survive body deletion and empty polls. - Add JSON DELETE on that same route (1–100 explicit IDs, maximum 16384 bytes), whole-batch validation and atomic body removal. Missing/already-removed/out-of-scope identities are harmless; duplicate IDs coalesce. Retain minimal duplicate-suppression/cursor metadata indefinitely. No implicit consumption, read acknowledgment, expiry, storage cap or background fetching. - Preserve reply moderation and existing engagement behavior. Ordinary posts support Note/Article/Page; preserve untrusted remote HTML and a plain-text derivative, without rendering it or downloading remote attachments. Clients must sanitize before rendering. - Version the additive source contract as 2.1.0 across OpenAPI/template metadata and CLI exact-version reference coverage. Npm versions, consumer pins and lockfile are unchanged. Document payloads, client retry/partial persistence, lifecycle, metadata retention/cleanup, migrations and adoption gates in docs/specs/12-incoming-activity.md and linked guidance. ## Verification ./scripts/pre-pr.sh passed build, generated CSS, formatting, lint, types and all 1,400 local tests, including federation integration/loopback HTTP coverage. New checks cover: - Accepted versus pending/rejected/failed/cancelled/unfollowed and follower-only delivery; actor/account attribution; supported post types; no history/outbox fetch; wrong authors/audiences and unsafe/local object identities, including bracketed private IPv6 literals and unsafe source URLs. - Repeated and concurrent GETs without removal/read effects, retained snapshots, interruption/partial-client persistence retries, bounded pages across deletion/new arrivals/empty polls, and cursor/tombstone/alias continuity after isolated database reopen; canonical alias backfill from an isolated 028 database; activity-ID equivocation and mid-resolution actor/unfollow races. - Selected-only body removal, ignored foreign/missing IDs, concurrent DELETE, uncertain-response retries, whole-batch validation, request-size limits, SQLite partial FAIL-trigger rollback, ingestion rollback and preserved downloaded arrays/owned publications/comments. - Existing bearer scopes, feature-unavailable 501 versus empty 200, shared OpenAPI/metadata and exact unpublished-contract doctor behavior. Local tested runtime: Node 24.22.1, Hono 4.12.23, @hono/node-server 2.0.3, Fedify 2.2.4. New integration/HTTP coverage is *.integration.test.ts and remains local-only; CI/workflows are unchanged and use npm run test:ci. ## Independent review follow-up Initial independent review of fc38391 found two P2 issues. The fixes normalize IPv6 URL literal brackets and reject non-public ranges in the shared validator, and retain all coalesced activity IDs atomically so a sender cannot reuse an observed activity ID with a different object after removal. Added signed-delivery regressions, alias rollback/reopen tests and isolated 028-to-029 migration evidence. At updated commit 3f4bc0cc736bdec8209a5862ebfe393ba651e7d5, CI run 552 is green and independent re-review found no actionable findings; both original P2s are resolved. The reviewer independently passed 79 focused tests and confirmed CI for the exact HEAD. Full local pre-PR checks passed 1,400 tests. Explicit human merge approval is still required. ## Environment incident and availability gates An already-running autoreload dev environment applied startup migrations against the existing local template/site/data/slugkit.sqlite: migration 027 during the previous task and 028 during this task. The user was informed, then explicitly authorized stopping the local dev environment; make dev-stop and make dev-status verified stopped. No rollback was attempted and no subsequent operations were run against that existing database. Remaining checks use isolated in-memory/temporary databases and loopback test servers only. Migration 029 has not been run against the existing local database; do not restart new application code there until that separate migration is authorized. No production deployment, production mutation, release or publication has been performed. Actual production proxy forwarding of DELETE JSON is not claimed as verified; operator-authorized rollout must verify the deployed proxy/client combination. The existing local database remains at its current migrated state. Boosts and final-contract completion remain task-8c11c803; public contract publication remains task-dbb55f82. Repository support is not production availability. Wait for CI, independent review and explicit human merge approval. Do not close the parent until all slices and publication are complete.
feat: buffer followed-account posts for explicit download and removal
All checks were successful
CI / build-lint-test (pull_request) Successful in 59s
fc38391f0f
Task: #task-7e947966
fix: retain delivery aliases and reject private IPv6 incoming URLs
All checks were successful
CI / build-lint-test (pull_request) Successful in 59s
3f4bc0cc73
Task: #task-7e947966
erik merged commit d1d40f2413 into main 2026-10-27 13:33:21 -05:00
erik deleted branch feat/task-7e947966-incoming-posts 2026-10-27 13:33:21 -05:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
erik/slugkit!311
No description provided.