fed-sx-m2: Step 2a — Person/Service/Group genesis object-types
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
Three new DefineObject artefacts in next/genesis/object-types/ for the canonical actor object-types per design §9.1: - Person: human-controlled identity (display name + handle + bio) - Service: automated / programmatic actor (bot, feed, organisation) - Group: multi-controller actor (member-set managed via Add/Remove) Each is a small SX form with :name / :doc / :schema, identical shape to existing object-types (note.sx, sx-artifact.sx etc) so the existing bootstrap:populate_registry walk picks them up without code changes. Manifest extended (object-types: 10 -> 13, total entries: 31 -> 34). Tests: - genesis_parse.sh +7 cases (head form, :name, manifest membership); 57/57. - Hardcoded counts bumped in bootstrap_read.sh, bootstrap_load.sh, bootstrap_populate.sh, bootstrap_start.sh. - bootstrap_build.sh 12/12 (bundle CID computed dynamically). Conformance 761/761 preserved. 211/211 across 12 Step-2-adjacent suites.
This commit is contained in:
@@ -24,6 +24,9 @@
|
||||
:object-types ("object-types/sx-artifact.sx"
|
||||
"object-types/note.sx"
|
||||
"object-types/tombstone.sx"
|
||||
"object-types/person.sx"
|
||||
"object-types/service.sx"
|
||||
"object-types/group.sx"
|
||||
"object-types/define-activity.sx"
|
||||
"object-types/define-object.sx"
|
||||
"object-types/define-projection.sx"
|
||||
|
||||
11
next/genesis/object-types/group.sx
Normal file
11
next/genesis/object-types/group.sx
Normal file
@@ -0,0 +1,11 @@
|
||||
;; next/genesis/object-types/group.sx
|
||||
;;
|
||||
;; Per design §9.1: a Group is a multi-controller actor — typically
|
||||
;; a working group, channel, or collective whose membership is
|
||||
;; managed via Add/Remove activities. Sig-suite validation honours
|
||||
;; the current key-set rather than a single keypair.
|
||||
|
||||
(DefineObject
|
||||
:name "Group"
|
||||
:doc "Multi-controller actor. :name is the group's display name; :preferredUsername is the local handle; :summary is the description; :icon is a CID or URL; :members is the current member list (managed via Add/Remove)."
|
||||
:schema (fn (obj) (string? (-> obj :name))))
|
||||
11
next/genesis/object-types/person.sx
Normal file
11
next/genesis/object-types/person.sx
Normal file
@@ -0,0 +1,11 @@
|
||||
;; next/genesis/object-types/person.sx
|
||||
;;
|
||||
;; Per design §9.1: a Person is the canonical actor type for a
|
||||
;; human-controlled identity. Bootstrapped via Create{Person{...}}
|
||||
;; as the actor's first activity (see nx_kernel:bootstrap_actor/4).
|
||||
;; ActivityPub-Person-compatible.
|
||||
|
||||
(DefineObject
|
||||
:name "Person"
|
||||
:doc "Human-controlled actor. :name is the display name; :preferredUsername is the local handle; :summary is the profile bio; :icon is a CID or URL."
|
||||
:schema (fn (obj) (string? (-> obj :name))))
|
||||
11
next/genesis/object-types/service.sx
Normal file
11
next/genesis/object-types/service.sx
Normal file
@@ -0,0 +1,11 @@
|
||||
;; next/genesis/object-types/service.sx
|
||||
;;
|
||||
;; Per design §9.1: a Service is a non-human actor — a bot, an
|
||||
;; automated feed, an organisational publisher. Same activity
|
||||
;; surface as Person, different ActivityPub Actor type. Tooling
|
||||
;; treats a Service identically to a Person except for UX hints.
|
||||
|
||||
(DefineObject
|
||||
:name "Service"
|
||||
:doc "Automated / programmatic actor. :name is the display name; :preferredUsername is the local handle; :summary is the profile bio; :icon is a CID or URL."
|
||||
:schema (fn (obj) (string? (-> obj :name))))
|
||||
@@ -107,7 +107,7 @@ check 11 "strip suffix hello unchanged" "true"
|
||||
check 12 "strip suffix .sx -> empty" "true"
|
||||
check 13 "load_genesis rejects bad shape" "ok"
|
||||
check 20 "loaded activity_types count = 3" "3"
|
||||
check 21 "loaded object_types count = 10" "10"
|
||||
check 21 "loaded object_types count = 13" "13"
|
||||
check 22 "loaded projections count = 7" "7"
|
||||
check 23 "loaded validators count = 3" "3"
|
||||
check 24 "loaded codecs count = 3" "3"
|
||||
|
||||
@@ -99,9 +99,9 @@ check() {
|
||||
check 2 "gen_server loaded" "gen_server"
|
||||
check 3 "registry loaded" "registry"
|
||||
check 4 "bootstrap loaded" "bootstrap"
|
||||
check 10 "populate returns total 31" "31"
|
||||
check 10 "populate returns total 34" "34"
|
||||
check 20 "activity_types count = 3" "3"
|
||||
check 21 "object_types count = 10" "10"
|
||||
check 21 "object_types count = 13" "13"
|
||||
check 22 "projections count = 7" "7"
|
||||
check 23 "validators count = 3" "3"
|
||||
check 24 "codecs count = 3" "3"
|
||||
|
||||
@@ -103,7 +103,7 @@ check 11 "ends_with_sx create.sx" "true"
|
||||
check 12 "ends_with_sx hello" "false"
|
||||
check 13 "ends_with_sx empty" "false"
|
||||
check 20 "section activity_types count" "3"
|
||||
check 21 "section object_types count" "10"
|
||||
check 21 "section object_types count" "13"
|
||||
check 22 "section projections count" "7"
|
||||
check 23 "section validators count" "3"
|
||||
check 24 "section codecs count" "3"
|
||||
|
||||
@@ -116,9 +116,9 @@ check() {
|
||||
check 10 "bootstrap module loaded" "bootstrap"
|
||||
check 20 "whereis(nx_kernel) is Pid" "true"
|
||||
check 21 "activity_types count = 3" "3"
|
||||
check 22 "object_types count = 10" "10"
|
||||
check 22 "object_types count = 13" "13"
|
||||
check 23 "projections count = 7" "7"
|
||||
check 24 "total entries = 31" "31"
|
||||
check 24 "total entries = 34" "34"
|
||||
check 25 "fresh log_tip = 0" "0"
|
||||
check 26 "publish advances tip to 1" "1"
|
||||
check 27 "actor_id = alice" "true"
|
||||
|
||||
@@ -64,6 +64,20 @@ cat > "$TMPFILE" <<'EPOCHS'
|
||||
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/define-sig-suite.sx\")))) :name)")
|
||||
(epoch 40)
|
||||
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/snapshot.sx\")))) :name)")
|
||||
(epoch 42)
|
||||
(eval "(first (parse (file-read \"next/genesis/object-types/person.sx\")))")
|
||||
(epoch 43)
|
||||
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/person.sx\")))) :name)")
|
||||
(epoch 44)
|
||||
(eval "(first (parse (file-read \"next/genesis/object-types/service.sx\")))")
|
||||
(epoch 45)
|
||||
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/service.sx\")))) :name)")
|
||||
(epoch 46)
|
||||
(eval "(first (parse (file-read \"next/genesis/object-types/group.sx\")))")
|
||||
(epoch 47)
|
||||
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/group.sx\")))) :name)")
|
||||
(epoch 48)
|
||||
(eval "(some (fn (p) (= p \"object-types/person.sx\")) (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :object-types))")
|
||||
(epoch 41)
|
||||
(eval "(len (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :object-types))")
|
||||
(epoch 50)
|
||||
@@ -166,7 +180,14 @@ check 37 "define-validator.sx name" "DefineValidator"
|
||||
check 38 "define-codec.sx name" "DefineCodec"
|
||||
check 39 "define-sig-suite.sx name" "DefineSigSuite"
|
||||
check 40 "snapshot.sx name" "Snapshot"
|
||||
check 41 "manifest has 10 object-types" "10"
|
||||
check 42 "person.sx head form" "DefineObject"
|
||||
check 43 "person.sx name" "Person"
|
||||
check 44 "service.sx head form" "DefineObject"
|
||||
check 45 "service.sx name" "Service"
|
||||
check 46 "group.sx head form" "DefineObject"
|
||||
check 47 "group.sx name" "Group"
|
||||
check 48 "manifest lists person.sx" "true"
|
||||
check 41 "manifest has 13 object-types" "13"
|
||||
check 50 "activity-log.sx head form" "DefineProjection"
|
||||
check 51 "activity-log.sx name" "activity-log"
|
||||
check 52 "by-type.sx name" "by-type"
|
||||
|
||||
@@ -158,21 +158,32 @@ publicKey rotation history, profile fields, follower counts, etc.
|
||||
|
||||
**Deliverables:**
|
||||
|
||||
- Genesis additions: `DefineObject{Person}` / `DefineObject{Service}` /
|
||||
`DefineObject{Group}` — three object-type SX files.
|
||||
- Actor-state projection fold (Erlang-fun stand-in, mirrors Step 5d-pure):
|
||||
- On `Create{Person|Service|Group}`: register the actor's profile.
|
||||
- On `Update{Person, patch}`: apply patch.
|
||||
- [x] **2a** — Genesis additions: `DefineObject{Person}` /
|
||||
`DefineObject{Service}` / `DefineObject{Group}` — three new SX
|
||||
files in `next/genesis/object-types/` plus manifest entries (now
|
||||
13 object-types total, 34 total genesis entries). Each defines
|
||||
`:name`, `:doc`, `:schema (fn (obj) (string? (-> obj :name)))`.
|
||||
`next/tests/genesis_parse.sh` extended +7 cases (head form +
|
||||
:name + manifest membership), now 57/57. Bootstrap suite
|
||||
count assertions bumped (`bootstrap_read.sh` 15/15,
|
||||
`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.
|
||||
- `nx_kernel:bootstrap_actor/4(ActorId, Profile, KeySpec, State)` —
|
||||
publishes `Create{Person{...}}` as the actor's first activity,
|
||||
bootstrapping their own log.
|
||||
|
||||
**Tests:**
|
||||
|
||||
- `Create{Person}` registers the actor.
|
||||
- Two actors created via lifecycle activities have independent state.
|
||||
- Profile updates apply.
|
||||
- `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`.
|
||||
- [ ] **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
|
||||
in `actor_lifecycle.sh` ties 2a artefacts (SX files), 2b
|
||||
projection, and 2c bootstrap together.
|
||||
|
||||
**Acceptance:** `bash next/tests/actor_lifecycle.sh` passes 10+ cases.
|
||||
|
||||
@@ -680,6 +691,17 @@ proceed.
|
||||
|
||||
Newest first.
|
||||
|
||||
- **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`,
|
||||
`:schema` checking `(string? (-> obj :name))`). Manifest extended
|
||||
to 13 object-types / 34 total entries. `genesis_parse.sh` +7
|
||||
cases (57/57). Hardcoded counts bumped in `bootstrap_read.sh`,
|
||||
`bootstrap_load.sh`, `bootstrap_populate.sh`, `bootstrap_start.sh`
|
||||
(66/66 across those four). `bootstrap_build.sh` 12/12 (bundle CID
|
||||
computed dynamically). Conformance 761/761 preserved. 211 / 211
|
||||
across 12 Step-2-adjacent suites.
|
||||
|
||||
- **2026-06-06** — Step 1b: gen_server multi-actor calls.
|
||||
`nx_kernel` exports `add_actor/3`, `publish_to/2`, `log_tip_for/1`,
|
||||
`actors/0`, `state_for/1`, `bucket_for/1`,
|
||||
|
||||
Reference in New Issue
Block a user