Add incoming boosts and finalize the activity contract #312

Merged
erik merged 3 commits from feat/task-8c11c803-incoming-boosts into main 2026-10-27 15:26:03 -05:00
Owner

Summary

Task: task-8c11c803, second implementation slice under task-96dcee85. Prerequisites task-444f16f0 and task-7e947966 were merged in PRs #310/#311.

  • Buffer newly delivered Announce boosts of remote Note/Article/Page originals, including originals older than the follow. Reuse existing auth, configured actor and per-followed-account GET/DELETE; no opt-in boost filter or new reader service.
  • Resolve the referenced canonical original instead of trusting a sharer's inline body/author. Keep the Announce's audience authoritative, validate remote identities, preserve local-publication engagement handling, and recheck actor/account/follow generation after asynchronous resolution.
  • Keep sharing Account/Contact separate from original-author attribution. Use a unique saved original-author mapping when available, otherwise an Account-shaped snapshot with null stored/owner IDs and no permanent Contact creation; URI-only attribution is explicit when enrichment is unavailable. A five-second deadline bounds optional author and nested-context enrichment, forwards cancellation and falls back even when custom loaders ignore it. A separate ten-second total deadline bounds required original/object/audience resolution, including contexts; timeout/late completion retains no ingestion identity, allowing a later retry.
  • Preserve post deduplication and all retained aliases. Repeated/equivocating seen activity IDs never resurrect removed copies or trigger another original fetch. Distinct new boosts of the same original remain distinct deliveries, separate from its post copy. GET remains non-consuming and DELETE remains explicit, atomic and retry-safe.
  • Add transactional migration 030: preserve IDs, byte-identical old post snapshots, tombstones, aliases, cursor positions and allocation high-water marks; use post-only original-object uniqueness; add an internal persistent follow generation to reject in-flight work across rapid same-timestamp state transitions. Existing following responses are unchanged.
  • Record the user-selected minor API contract increment 2.1.0 -> 2.2.0, not 3.0.0. Existing IncomingPost schema/payloads remain unchanged; a new boost variant is added to the same stream and readers must handle its kind/null-ID author shape. Slug CLI commands do not consume this endpoint. Npm versions, pins and lockfile are unchanged.
  • Finalize Spec 12 and add docs/incoming-activity-consumers.md and docs/incoming-activity-evidence.md. Explicitly identify Rott's stale combined-stream/shared-read/removal-on-read expectations without modifying Rott or implementing shared read state. Source support is not public publication/adoption.

Verification

./scripts/pre-pr.sh passed build, generated CSS, formatting, lint, types and all 1,424 local tests. Signed federation/actual HTTP coverage remains *.integration.test.ts and local-only; no CI workflow/runtime/container testing changes.

Evidence includes old-original boosts; known/unknown/ambiguous/unavailable author enrichment without contact creation; canonical-content and audience safety; accepted/inactive/follower-only boundaries; refollow/same-timestamp and actor races; duplicate/equivocation/post/self-boost separation; body/alias failures and retries; mixed-kind pagination, interrupted/partial client persistence, independent concurrent GETs and JSON DELETE with a discarded response plus identical-ID retry; account isolation and preservation of owned publications/comments/engagement/client copies. Migration fixtures verify old snapshots/aliases/tombstones, old cursors, allocation gaps, foreign keys and injected-failure rollback.

An isolated SQLite measurement (Node24.22.1, SQLite3.53.4, 4096-byte pages) buffered 100 bodies plus 200 aliases, then removed those 100 bodies. Metadata/aliases remained 100/200, free pages increased 0->825, and database file size remained 3,907,584 bytes. No VACUUM was run. This is logical-removal/storage evidence, not a production-cost estimate or secure-erasure claim.

Gates and availability

The running dev environment was stopped with make dev-stop before edits. Migration030 has not run against the existing local database, and the environment remains stopped; no existing local/production data migration is authorized/performed by this task. All fixtures/measurements used isolated in-memory/temporary databases and loopback test servers. Restarting new code against legacy data requires separate migration authorization.

Pipeline: full pre-PR passed 1,424 local tests; exact-HEAD CI run556 is green at d49eeef4a7. Independent re-review passed 95 targeted tests plus isolated deadline probes with no actionable findings; both initial timeout P2s are resolved. Human merge approval is pending; branch cleanup and post-merge verification have not started. No release/publication, production deployment or production mutation performed. Task-dbb55f82 owns final public publication/release gates; operators own adoption/deployment and actual reverse-proxy DELETE-body verification. The parent and Rott E4 consumer requirements remain incomplete until their respective publication/adoption/policy reconciliation gates are satisfied. No new shared-read backend, automatic expiry/caps/cleanup, background Rott Download, website RSS fetch or broader conversation/change delivery is included.

## Summary Task: task-8c11c803, second implementation slice under task-96dcee85. Prerequisites task-444f16f0 and task-7e947966 were merged in PRs #310/#311. - Buffer newly delivered Announce boosts of remote Note/Article/Page originals, including originals older than the follow. Reuse existing auth, configured actor and per-followed-account GET/DELETE; no opt-in boost filter or new reader service. - Resolve the referenced canonical original instead of trusting a sharer's inline body/author. Keep the Announce's audience authoritative, validate remote identities, preserve local-publication engagement handling, and recheck actor/account/follow generation after asynchronous resolution. - Keep sharing Account/Contact separate from original-author attribution. Use a unique saved original-author mapping when available, otherwise an Account-shaped snapshot with null stored/owner IDs and no permanent Contact creation; URI-only attribution is explicit when enrichment is unavailable. A five-second deadline bounds optional author and nested-context enrichment, forwards cancellation and falls back even when custom loaders ignore it. A separate ten-second total deadline bounds required original/object/audience resolution, including contexts; timeout/late completion retains no ingestion identity, allowing a later retry. - Preserve post deduplication and all retained aliases. Repeated/equivocating seen activity IDs never resurrect removed copies or trigger another original fetch. Distinct new boosts of the same original remain distinct deliveries, separate from its post copy. GET remains non-consuming and DELETE remains explicit, atomic and retry-safe. - Add transactional migration 030: preserve IDs, byte-identical old post snapshots, tombstones, aliases, cursor positions and allocation high-water marks; use post-only original-object uniqueness; add an internal persistent follow generation to reject in-flight work across rapid same-timestamp state transitions. Existing following responses are unchanged. - Record the user-selected minor API contract increment **2.1.0 -> 2.2.0**, not 3.0.0. Existing IncomingPost schema/payloads remain unchanged; a new boost variant is added to the same stream and readers must handle its kind/null-ID author shape. Slug CLI commands do not consume this endpoint. Npm versions, pins and lockfile are unchanged. - Finalize Spec 12 and add docs/incoming-activity-consumers.md and docs/incoming-activity-evidence.md. Explicitly identify Rott's stale combined-stream/shared-read/removal-on-read expectations without modifying Rott or implementing shared read state. Source support is not public publication/adoption. ## Verification ./scripts/pre-pr.sh passed build, generated CSS, formatting, lint, types and all **1,424 local tests**. Signed federation/actual HTTP coverage remains *.integration.test.ts and local-only; no CI workflow/runtime/container testing changes. Evidence includes old-original boosts; known/unknown/ambiguous/unavailable author enrichment without contact creation; canonical-content and audience safety; accepted/inactive/follower-only boundaries; refollow/same-timestamp and actor races; duplicate/equivocation/post/self-boost separation; body/alias failures and retries; mixed-kind pagination, interrupted/partial client persistence, independent concurrent GETs and JSON DELETE with a discarded response plus identical-ID retry; account isolation and preservation of owned publications/comments/engagement/client copies. Migration fixtures verify old snapshots/aliases/tombstones, old cursors, allocation gaps, foreign keys and injected-failure rollback. An isolated SQLite measurement (Node24.22.1, SQLite3.53.4, 4096-byte pages) buffered 100 bodies plus 200 aliases, then removed those 100 bodies. Metadata/aliases remained 100/200, free pages increased 0->825, and database file size remained 3,907,584 bytes. No VACUUM was run. This is logical-removal/storage evidence, not a production-cost estimate or secure-erasure claim. ## Gates and availability The running dev environment was stopped with make dev-stop before edits. Migration030 has not run against the existing local database, and the environment remains stopped; no existing local/production data migration is authorized/performed by this task. All fixtures/measurements used isolated in-memory/temporary databases and loopback test servers. Restarting new code against legacy data requires separate migration authorization. Pipeline: full pre-PR passed 1,424 local tests; exact-HEAD CI run556 is green at d49eeef4a7af53dbf35fd86e0132df5eac5725f6. Independent re-review passed 95 targeted tests plus isolated deadline probes with no actionable findings; both initial timeout P2s are resolved. Human merge approval is pending; branch cleanup and post-merge verification have not started. No release/publication, production deployment or production mutation performed. Task-dbb55f82 owns final public publication/release gates; operators own adoption/deployment and actual reverse-proxy DELETE-body verification. The parent and Rott E4 consumer requirements remain incomplete until their respective publication/adoption/policy reconciliation gates are satisfied. No new shared-read backend, automatic expiry/caps/cleanup, background Rott Download, website RSS fetch or broader conversation/change delivery is included.
feat: buffer incoming boosts with distinct original-author attribution
All checks were successful
CI / build-lint-test (pull_request) Successful in 58s
ad07d99e33
Task: #task-8c11c803

Extend the per-account incoming contract as approved minor version 2.2.0. Preserve existing post payloads and leave npm release versions unchanged.
fix: bound optional incoming-author enrichment
All checks were successful
CI / build-lint-test (pull_request) Successful in 1m1s
670e289325
Resolve independent review P2: forward cancellation to author and JSON-LD context loaders, and guarantee URI-only fallback after five seconds even if a loader ignores cancellation.
fix: bound complete incoming object and context resolution
All checks were successful
CI / build-lint-test (pull_request) Successful in 1m0s
d49eeef4a7
Resolve re-review P2 with shared ten-second required-resolution deadlines, including canonical JSON-LD contexts and audience actor lookups. Retain five-second optional enrichment fallback and verify cancellation, safe late completion, empty deduplication state and successful retries.
erik merged commit c86dd96a9b into main 2026-10-27 15:26:03 -05:00
erik deleted branch feat/task-8c11c803-incoming-boosts 2026-10-27 15:26:03 -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!312
No description provided.