fed-sx-m2: Step 5d — inbox handler wires the ingestion chain
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 38s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 38s
POST /actors/<id>/inbox is now special-cased in route/2 (next to
POST /activity) so the body + Cfg reach the new handle_inbox_post/3
handler.
Wire format: body = term_codec:encode(SignedActivity); the receiver
decodes into the activity proplist and runs the chain.
handle_inbox_post/3 orchestration:
1. kernel_has_actor(field(kernel, Cfg), TargetId) -> 404 if missing
2. decode_activity(Body) -> 422 on bad shape
3. envelope:get_field(actor, Activity) -> 422 if no peer id
4. resolve_peer_as(PeerId, Cfg) -> 401 if unknown
5. nx_kernel:inbox_state_for(TargetAtom) -> 404 belt-and-braces
6. pipeline:validate_inbound(Activity, PeerAS, InboxLog)
ok -> nx_kernel:append_inbox + 202
{error, bad_signature} -> 401
{error, no_signature} -> 401
{error, _} -> 422
resolve_peer_as/2 supports three Cfg paths in priority order:
{peer_as, [{PeerId, AS}, ...]} pure-fn pre-populated map
{peer_actors, AtomName} peer_actors gen_server cache
{peer_fetch_fn, fun/1} fallback on srv cache miss
Empty Cfg returns {error, no_peer_resolver} -> 401.
v1 actor_post/1 4a stub deleted; M1 actor_inbox_post_response/0
kept for response composition.
Projection broadcast on inbox success intentionally deferred to a
follow-up sub-deliverable.
inbox.sh 11/11 (acceptance suite for the basic chain):
- happy path -> 202
- inbox tip advances; outbox tip unchanged (per-actor bucket
independence carried through from Step 5a)
- empty / garbage body -> 422
- unknown peer -> 401
- bad peer-AS keys -> 401
- replay (same activity twice) -> 422 on second
- unknown target actor -> 404
- two distinct activities -> tip = 2
inbox_peer_resolution.sh 6/6 (Cfg resolution variants):
- peer_actors gen_server hit -> 202
- FetchFn fallback -> 202
- FetchFn error -> 401
- FetchFn caches into peer_actors (peers_srv shows [bob] after)
- No resolver -> 401
Tests split into two files because each epoch's kernel start_link
+ outbox construct + term_codec encode is expensive and a single
suite hits the wall-clock budget.
http_server.erl is now 1181 lines. erlang-load-module on this port
scales superlinearly with function count, so eight http_*.sh tests'
internal sx_server timeout bumped 60s -> 360s (http_route,
http_actors, http_accept, http_capabilities, http_capabilities_format,
http_content_type, http_artifacts, http_projections).
Conformance 761/761.
This commit is contained in:
@@ -375,12 +375,30 @@ actor *received*), and broadcasts to projections.
|
||||
for tests / fixtures. 19/19 in `peer_actors.sh`. The actual
|
||||
fetch implementation (HTTP GET of the peer's actor doc) is
|
||||
Step 5d's responsibility — for 5c, FetchFn is just a contract.
|
||||
- [ ] **5d** — http_server inbox handler wires the chain:
|
||||
`POST /actors/<id>/inbox` body is the signed activity wire bytes;
|
||||
parse → resolve peer-AS → `validate_inbound` → `append_inbox` →
|
||||
202 on accept, 401 on bad sig, 422 on replay/shape failure,
|
||||
404 on unknown target actor. Activity broadcast to receiving
|
||||
actor's projections (via `projection:async_fold`).
|
||||
- [x] **5d** — http_server inbox handler wires the chain. POST
|
||||
/actors/<id>/inbox is now special-cased in `route/2` (next to
|
||||
POST /activity) so the body + full Cfg reach the handler. New
|
||||
`handle_inbox_post/3` orchestrates: `kernel_has_actor` →
|
||||
`decode_activity` (term_codec wire format) → `resolve_peer_as`
|
||||
(Cfg `:peer_as` map > `:peer_actors` srv > `:peer_fetch_fn`
|
||||
fallback) → `pipeline:validate_inbound/3` → `nx_kernel:append_inbox`.
|
||||
Status codes:
|
||||
- 202 Accepted on pipeline ok + inbox append
|
||||
- 401 Unauthorized on bad_signature / no_signature / unknown
|
||||
peer / fetch error
|
||||
- 404 Not Found on unknown target actor
|
||||
- 422 Unprocessable on shape / decode / replay failure
|
||||
v1 stub `actor_post/1` removed; the route/2 special case
|
||||
supersedes it. M1 `actor_inbox_post_response/0` kept for
|
||||
callers that need to compose the response shape.
|
||||
Projection broadcast on success is intentionally deferred —
|
||||
the same TODO covers outbox broadcast invariance and lands in
|
||||
a follow-up sub-deliverable. `inbox.sh` 11/11 covers happy
|
||||
path / shape / sig / replay / unknown-target / multi-message;
|
||||
`inbox_peer_resolution.sh` 6/6 covers the four peer-AS
|
||||
resolution paths. Tests split into two files because the
|
||||
cumulative cost of one kernel start_link per epoch pushed a
|
||||
single suite past the wall-clock budget.
|
||||
|
||||
**Acceptance:** `bash next/tests/inbox.sh` passes 16+ cases.
|
||||
|
||||
@@ -790,6 +808,27 @@ proceed.
|
||||
|
||||
Newest first.
|
||||
|
||||
- **2026-06-06** — Step 5d: POST /actors/<id>/inbox real ingestion.
|
||||
`route/2` now special-cases POST `/actors/<id>/inbox` next to POST
|
||||
`/activity` so the body + full Cfg reach the new
|
||||
`handle_inbox_post/3` handler. Flow:
|
||||
`kernel_has_actor` -> `decode_activity` (term_codec wire format)
|
||||
-> `resolve_peer_as` (Cfg `:peer_as` map > `:peer_actors` srv >
|
||||
`:peer_fetch_fn` fallback) -> `pipeline:validate_inbound/3` ->
|
||||
`nx_kernel:append_inbox`. Status codes 202 / 401 / 404 / 422
|
||||
per design §16.1. v1 stub `actor_post/1` removed; M1
|
||||
`actor_inbox_post_response/0` kept for response shape composition.
|
||||
Projection broadcast on inbox success intentionally deferred to a
|
||||
follow-up. `inbox.sh` 11/11 (basic ingestion: happy path / shape
|
||||
/ sig / replay / unknown-target / multi-message);
|
||||
`inbox_peer_resolution.sh` 6/6 (peer-AS resolution variants).
|
||||
Split into two files because cumulative per-epoch kernel
|
||||
start_link + outbox construct + term_codec encode pushed a
|
||||
single suite past the wall-clock budget. http_server.erl now
|
||||
1181 lines — load time on this Erlang port scales superlinearly
|
||||
with function count, so eight http_*.sh tests' internal sx_server
|
||||
timeout bumped 60s → 360s. Conformance 761/761.
|
||||
|
||||
- **2026-06-06** — Step 5c: peer-actors cache (`peer_actors.erl`).
|
||||
Pure-functional cache of `{PeerActorId, PeerAS}` entries with
|
||||
the load-bearing `lookup_or_fetch/3(PeerId, FetchFn, State)`
|
||||
|
||||
Reference in New Issue
Block a user