Files
rose-ash/next/tests/genesis_parse.sh
giles 80f6fc9279
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
fed-sx-m2: Step 11a — Announce + Endorse genesis activity-types + 4 tests
Two new DefineActivity SX files in next/genesis/activity-types/
per design §13.5 / Step 11:

  announce.sx — Re-broadcast a peer's activity to followers.
    :object is the CID of the activity being announced.
    :schema requires :object to be a string.
    Followers see the Announce in their inbox; their projection
    decides whether to fetch the wrapped activity body.

  endorse.sx — Cross-actor signal on a target activity.
    :object is the target activity's CID; :kind is the
    endorsement variant (e.g. 'like', 'share').
    :schema requires both :object and :kind to be strings.
    Projections aggregate endorsements into counters / heat /
    ranking signals.

M1's Note object-type is unchanged — Create{Note{...}} is still
the publish path for short authored messages. The runtime-publish
demo (verb extensibility via Create{DefineActivity{...}} at
runtime) from M1 §9a continues to work; these files are the
genesis pre-shipped variants for v2 baseline so peers don't have
to negotiate verb definitions on first contact.

Manifest extended:
  :activity-types  3 -> 5 entries
  total genesis    34 -> 36 entries

Hardcoded count assertions bumped in:
  bootstrap_read.sh  (activity_types 3->5, first-section-count 3->5)
  bootstrap_load.sh  (activity_types 3->5)
  bootstrap_populate.sh (total 34->36, activity_types 3->5)
  bootstrap_start.sh (activity_types 3->5, total 34->36)

genesis_parse.sh +4 cases (head form + name for both files).
bootstrap_populate.sh internal sx_server timeout bumped
300s -> 600s to fit the larger genesis bundle.

61/61 in genesis_parse.sh, 15/15 in bootstrap_read.sh,
15/15 in bootstrap_load.sh, 14/14 in bootstrap_populate.sh,
12/12 in bootstrap_build.sh.
2026-06-07 04:38:32 +00:00

240 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
# next/tests/genesis_parse.sh — Step 4a acceptance test.
#
# Confirms the seed genesis SX files parse cleanly and have the
# expected top-level head form. The bundler (Step 4c+) consumes
# these forms directly as data. 50 cases.
set -uo pipefail
cd "$(git rev-parse --show-toplevel)"
SX_SERVER="${SX_SERVER:-hosts/ocaml/_build/default/bin/sx_server.exe}"
if [ ! -x "$SX_SERVER" ]; then
SX_SERVER="/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe"
fi
if [ ! -x "$SX_SERVER" ]; then
echo "ERROR: sx_server.exe not found." >&2
exit 1
fi
VERBOSE="${1:-}"
PASS=0; FAIL=0; ERRORS=""
TMPFILE=$(mktemp); trap "rm -f $TMPFILE" EXIT
cat > "$TMPFILE" <<'EPOCHS'
(epoch 10)
(eval "(first (parse (file-read \"next/genesis/manifest.sx\")))")
(epoch 11)
(eval "(first (parse (file-read \"next/genesis/activity-types/create.sx\")))")
(epoch 12)
(eval "(first (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :activity-types))")
(epoch 13)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/activity-types/create.sx\")))) :name)")
(epoch 14)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :version)")
(epoch 15)
(eval "(first (parse (file-read \"next/genesis/activity-types/update.sx\")))")
(epoch 16)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/activity-types/update.sx\")))) :name)")
(epoch 17)
(eval "(first (parse (file-read \"next/genesis/activity-types/delete.sx\")))")
(epoch 18)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/activity-types/delete.sx\")))) :name)")
(epoch 27)
(eval "(first (parse (file-read \"next/genesis/activity-types/announce.sx\")))")
(epoch 28)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/activity-types/announce.sx\")))) :name)")
(epoch 29)
(eval "(first (parse (file-read \"next/genesis/activity-types/endorse.sx\")))")
(epoch 200)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/activity-types/endorse.sx\")))) :name)")
(epoch 19)
(eval "(len (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :activity-types))")
(epoch 30)
(eval "(first (parse (file-read \"next/genesis/object-types/sx-artifact.sx\")))")
(epoch 31)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/sx-artifact.sx\")))) :name)")
(epoch 32)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/note.sx\")))) :name)")
(epoch 33)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/tombstone.sx\")))) :name)")
(epoch 34)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/define-activity.sx\")))) :name)")
(epoch 35)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/define-object.sx\")))) :name)")
(epoch 36)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/define-projection.sx\")))) :name)")
(epoch 37)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/define-validator.sx\")))) :name)")
(epoch 38)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/object-types/define-codec.sx\")))) :name)")
(epoch 39)
(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)
(eval "(first (parse (file-read \"next/genesis/projections/activity-log.sx\")))")
(epoch 51)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/projections/activity-log.sx\")))) :name)")
(epoch 52)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/projections/by-type.sx\")))) :name)")
(epoch 53)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/projections/by-actor.sx\")))) :name)")
(epoch 54)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/projections/by-object.sx\")))) :name)")
(epoch 55)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/projections/actor-state.sx\")))) :name)")
(epoch 56)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/projections/define-registry.sx\")))) :name)")
(epoch 57)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/projections/audience-graph.sx\")))) :name)")
(epoch 58)
(eval "(len (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :projections))")
(epoch 60)
(eval "(first (parse (file-read \"next/genesis/validators/envelope-shape.sx\")))")
(epoch 61)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/validators/envelope-shape.sx\")))) :name)")
(epoch 62)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/validators/signature.sx\")))) :name)")
(epoch 63)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/validators/type-schema.sx\")))) :name)")
(epoch 64)
(eval "(len (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :validators))")
(epoch 70)
(eval "(first (parse (file-read \"next/genesis/codecs/dag-cbor.sx\")))")
(epoch 71)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/codecs/dag-cbor.sx\")))) :name)")
(epoch 72)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/codecs/raw.sx\")))) :name)")
(epoch 73)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/codecs/dag-json.sx\")))) :name)")
(epoch 74)
(eval "(len (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :codecs))")
(epoch 80)
(eval "(first (parse (file-read \"next/genesis/sig-suites/rsa-sha256-2018.sx\")))")
(epoch 81)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/sig-suites/rsa-sha256-2018.sx\")))) :name)")
(epoch 82)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/sig-suites/ed25519-2020.sx\")))) :name)")
(epoch 83)
(eval "(len (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :sig-suites))")
(epoch 90)
(eval "(first (parse (file-read \"next/genesis/audience/public.sx\")))")
(epoch 91)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/audience/public.sx\")))) :name)")
(epoch 92)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/audience/followers.sx\")))) :name)")
(epoch 93)
(eval "(get (apply dict (rest (parse (file-read \"next/genesis/audience/direct.sx\")))) :name)")
(epoch 94)
(eval "(len (get (apply dict (rest (parse (file-read \"next/genesis/manifest.sx\")))) :audience))")
EPOCHS
OUTPUT=$(timeout 30 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
check() {
local epoch="$1" desc="$2" expected="$3"
local actual
actual=$(echo "$OUTPUT" | awk -v e="$epoch" '
$0 ~ "^\\(ok-len " e " " { getline; print; exit }
$0 ~ "^\\(ok " e " " { print; exit }
$0 ~ "^\\(error " e " " { print; exit }
')
[ -z "$actual" ] && actual="<no output for epoch $epoch>"
if echo "$actual" | grep -qF -- "$expected"; then
PASS=$((PASS+1))
[ "$VERBOSE" = "-v" ] && echo " ok $desc"
else
FAIL=$((FAIL+1))
ERRORS+=" FAIL [$desc] (epoch $epoch) expected: $expected | actual: $actual
"
fi
}
check 10 "manifest.sx head form" "GenesisManifest"
check 11 "create.sx head form" "DefineActivity"
check 12 "manifest lists create.sx" "activity-types/create.sx"
check 13 "create.sx name is Create" "Create"
check 14 "manifest version present" "0.0.1"
check 15 "update.sx head form" "DefineActivity"
check 16 "update.sx name is Update" "Update"
check 17 "delete.sx head form" "DefineActivity"
check 18 "delete.sx name is Delete" "Delete"
check 27 "announce.sx head form" "DefineActivity"
check 28 "announce.sx name is Announce" "Announce"
check 29 "endorse.sx head form" "DefineActivity"
check 200 "endorse.sx name is Endorse" "Endorse"
check 19 "manifest has 5 activity-types" "5"
check 30 "sx-artifact.sx head form" "DefineObject"
check 31 "sx-artifact.sx name" "SXArtifact"
check 32 "note.sx name" "Note"
check 33 "tombstone.sx name" "Tombstone"
check 34 "define-activity.sx name" "DefineActivity"
check 35 "define-object.sx name" "DefineObject"
check 36 "define-projection.sx name" "DefineProjection"
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 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"
check 53 "by-actor.sx name" "by-actor"
check 54 "by-object.sx name" "by-object"
check 55 "actor-state.sx name" "actor-state"
check 56 "define-registry.sx name" "define-registry"
check 57 "audience-graph.sx name" "audience-graph"
check 58 "manifest has 7 projections" "7"
check 60 "envelope-shape.sx head form" "DefineValidator"
check 61 "envelope-shape.sx name" "envelope-shape"
check 62 "signature.sx name" "signature"
check 63 "type-schema.sx name" "type-schema"
check 64 "manifest has 3 validators" "3"
check 70 "dag-cbor.sx head form" "DefineCodec"
check 71 "dag-cbor.sx name" "dag-cbor"
check 72 "raw.sx name" "raw"
check 73 "dag-json.sx name" "dag-json"
check 74 "manifest has 3 codecs" "3"
check 80 "rsa-sha256-2018.sx head form" "DefineSigSuite"
check 81 "rsa-sha256-2018.sx name" "rsa-sha256-2018"
check 82 "ed25519-2020.sx name" "ed25519-2020"
check 83 "manifest has 2 sig-suites" "2"
check 90 "public.sx head form" "DefineAudience"
check 91 "public.sx name" "Public"
check 92 "followers.sx name" "Followers"
check 93 "direct.sx name" "Direct"
check 94 "manifest has 3 audience" "3"
TOTAL=$((PASS+FAIL))
if [ $FAIL -eq 0 ]; then
echo "ok $PASS/$TOTAL next/tests/genesis_parse.sh passed"
else
echo "FAIL $PASS/$TOTAL passed, $FAIL failed:"
echo "$ERRORS"
fi
[ $FAIL -eq 0 ]