fed-sx-m2: Step 2b — actor_state projection fold + 19 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s
next/kernel/actor_state.erl mirrors define_registry's structure: a
2-arity fold_fn that plugs into projection:start_link/3, an
Erlang-fun stand-in for the genesis actor-state.sx projection body.
State shape:
[{ActorId, Profile}, ...]
Profile is a property list with :type, :name, :preferredUsername,
:summary, :icon, :public_keys, :moved_to, :created. Maps #{} aren't
registered in this substrate, so this matches the kernel bucket /
registry shape convention.
Folding rules per design §9.1-§9.4:
- Create{Person|Service|Group}: register profile, capturing object
fields + :published seq as :created. Duplicate Create no-overwrite.
- Update{Person|Service|Group, patch}: deep-merge :patch into
profile last-write-wins per key.
- Move: record :moved_to.
Other activity types and non-actor object Creates pass through.
Local find_keyed/has_keyed/set_keyed helpers (same gap as Step 1a:
no lists:keyfind/keymember in this substrate).
19/19 in next/tests/actor_state_pure.sh covering:
- new/0/has/2/lookup/2/actors/1 base cases
- Create for Person/Service/Group all three actor types
- Profile field capture (name, preferredUsername, public_keys, created)
- Duplicate Create no-overwrite
- Two independent actors
- Update field merge + per-key last-write-wins
- Update for unknown actor pass-through
- Move :moved_to
- Non-actor Creates pass through
- Activities without :actor pass through
- fold_fn/0 returns is_function(F, 2)
Conformance 761/761. Step-2-adjacent no-regression gate 106/106
across 6 suites (define_registry_pure, projection_pure,
projection_server, nx_kernel_multi, bootstrap_start, smoke_app_pure).
This commit is contained in:
@@ -169,16 +169,25 @@ publicKey rotation history, profile fields, follower counts, etc.
|
||||
`bootstrap_load.sh` 15/15, `bootstrap_populate.sh` 14/14,
|
||||
`bootstrap_start.sh` 10/10). `bootstrap_build.sh` 12/12 picks
|
||||
up the new bundle CID dynamically.
|
||||
- [ ] **2b** — Actor-state projection fold (Erlang-fun stand-in,
|
||||
mirrors Step 5d-pure's `define_registry`):
|
||||
- On `Create{Person|Service|Group}`: register the actor's profile
|
||||
in `{ActorId => #{type, name, preferredUsername, summary, icon,
|
||||
public_keys, created}}`.
|
||||
- On `Update{Person|Service|Group, patch}`: deep-merge the patch.
|
||||
- On `Move`: record `:movedTo` pointer.
|
||||
- `next/kernel/actor_state.erl` with `fold_fn/0` plugging into
|
||||
`projection:start_link/3`. Pure-functional + gen_server-bridged
|
||||
tests as a single `actor_state_pure.sh`.
|
||||
- [x] **2b** — Actor-state projection fold (Erlang-fun stand-in,
|
||||
mirrors Step 5d-pure's `define_registry`). `next/kernel/actor_state.erl`
|
||||
with state shape `[{ActorId, Profile}, ...]` where `Profile` is a
|
||||
proplist with `:type / :name / :preferredUsername / :summary /
|
||||
:icon / :public_keys / :moved_to / :created`. Maps `#{}` aren't
|
||||
registered in the substrate, so the profile is a property list
|
||||
(same shape choice as the kernel's bucket / registry state).
|
||||
Folding rules:
|
||||
- `Create{Person|Service|Group}` (from a known `:actor`):
|
||||
captures profile fields + `:created` (=`:published` seq).
|
||||
Duplicate Creates are no-overwrite.
|
||||
- `Update{Person|Service|Group, patch}`: merges `:patch` into the
|
||||
profile last-write-wins per key.
|
||||
- `Move`: records `:moved_to` on the profile.
|
||||
Other activity types and non-actor object Creates pass through.
|
||||
`fold_fn/0` plugs into `projection:start_link/3`. Local
|
||||
`find_keyed/has_keyed/set_keyed` helpers (same gap as 1a — no
|
||||
`lists:keyfind`/`keymember` in the substrate). 19 cases in
|
||||
`actor_state_pure.sh`.
|
||||
- [ ] **2c** — `nx_kernel:bootstrap_actor/4(ActorId, Profile,
|
||||
KeySpec, State)` — publishes `Create{Person{...}}` as the actor's
|
||||
first activity, exercising the full pipeline. Integration test
|
||||
@@ -691,6 +700,18 @@ proceed.
|
||||
|
||||
Newest first.
|
||||
|
||||
- **2026-06-06** — Step 2b: actor-state projection Erlang module.
|
||||
New `next/kernel/actor_state.erl` with `fold/2` over Create / Update
|
||||
/ Move activities. Profile is a property list of `:type / :name /
|
||||
:preferredUsername / :summary / :icon / :public_keys / :moved_to /
|
||||
:created`. Create captures fields and `:published` as `:created`;
|
||||
duplicate Create is no-overwrite; non-actor Creates and `:actor`-
|
||||
less envelopes pass through. Update last-write-wins per patch key.
|
||||
Move records `:moved_to`. `fold_fn/0` is a 2-arity Erlang fun for
|
||||
`projection:start_link/3` (structural twin of `define_registry`).
|
||||
`next/tests/actor_state_pure.sh` 19/19. Conformance 761/761.
|
||||
Step-2-adjacent no-regression gate 106/106 across 6 suites.
|
||||
|
||||
- **2026-06-06** — Step 2a: genesis Person/Service/Group object-
|
||||
types. Three new SX files in `next/genesis/object-types/` with
|
||||
the same shape as `note.sx` / `sx-artifact.sx` (`:name`, `:doc`,
|
||||
|
||||
Reference in New Issue
Block a user