{"id":362691,"date":"2026-09-14T02:32:49","date_gmt":"2026-09-14T02:32:49","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/axismundi-actors\/"},"modified":"2026-09-14T02:33:56","modified_gmt":"2026-09-14T02:33:56","slug":"axismundi-actors","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/axismundi-actors\/","author":21128503,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.2","stable_tag":"0.1.2","tested":"7.1","requires":"6.7","requires_php":"8.1","requires_plugins":null,"header_name":"Axismundi Actors","header_author":"KIM JIWOON","header_description":"Identity registry for Axismundi. Gives every local person and every remote actor this site has cached one immutable identity URI and one human profile hub, and wires each domain plugin's archive in as a projection. Identity only \u2014 it owns no content, likes, collections, or activity.","assets_banners_color":"","last_updated":"2026-09-14 02:33:56","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/Jiwoon-Kim\/axismundi\/tree\/main\/products\/wordpress\/plugins\/axismundi-actors","header_author_uri":"https:\/\/designbusan.ai.kr","rating":0,"author_block_rating":0,"active_installs":0,"downloads":32,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"0.1.2":{"tag":"0.1.2","author":"kimjiwoon","date":"2026-09-14 02:33:56","revision":3694371}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":{"axismundi\/actor-name":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-name","version":"0.1.0","title":"Actor Name","category":"theme","icon":"admin-users","description":"The display name of the Actor resolved by the enclosing Account Header or Object card. A sibling of Core's Post Title, so it carries its own typography.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"attributes":{"level":{"type":"number","default":0},"isLink":{"type":"boolean","default":true}},"supports":{"html":false,"anchor":true,"color":{"gradients":true,"link":true,"text":true,"background":true},"spacing":{"margin":true,"padding":true},"typography":{"fontSize":true,"lineHeight":true,"__experimentalFontFamily":true,"__experimentalFontWeight":true,"__experimentalFontStyle":true,"__experimentalTextTransform":true,"__experimentalLetterSpacing":true,"__experimentalDefaultControls":{"fontSize":true}},"__experimentalBorder":{"radius":true,"color":true,"width":true,"style":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-social-counts":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-social-counts","version":"0.1.0","title":"Actor Social Counts","category":"theme","icon":"groups","description":"Links to an Actor's public followers and following lists.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"supports":{"html":false,"spacing":{"margin":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-profile-fields":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-profile-fields","version":"0.4.0","title":"Actor Profile Fields","category":"theme","icon":"admin-links","description":"Ordered profile links for the Actor in context, with a verified reciprocal-link indicator. Card styling is a style sibling of Core's Latest Posts list\/grid.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"attributes":{"display":{"type":"string","default":"list"},"columns":{"type":"number","default":2},"itemsToShow":{"type":"number","default":8}},"supports":{"html":false,"multiple":false,"anchor":true,"spacing":{"margin":true,"padding":true},"color":{"link":true,"__experimentalDefaultControls":{"background":true,"text":true}},"typography":{"fontSize":true,"lineHeight":true,"__experimentalFontFamily":true,"__experimentalFontWeight":true,"__experimentalDefaultControls":{"fontSize":true}},"__experimentalBorder":{"radius":true,"color":true,"width":true,"style":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-handle":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-handle","version":"0.1.0","title":"Actor Handle","category":"theme","icon":"at-symbol","description":"The federated @user@host handle of the Actor resolved by the enclosing Account Header or Object card, with typography independent of the display name.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"attributes":{"isLink":{"type":"boolean","default":false},"shortForm":{"type":"boolean","default":false}},"supports":{"html":false,"anchor":true,"color":{"gradients":true,"link":true,"text":true,"background":true},"spacing":{"margin":true,"padding":true},"typography":{"fontSize":true,"lineHeight":true,"__experimentalFontFamily":true,"__experimentalFontWeight":true,"__experimentalFontStyle":true,"__experimentalTextTransform":true,"__experimentalLetterSpacing":true,"__experimentalDefaultControls":{"fontSize":true}},"__experimentalBorder":{"radius":true,"color":true,"width":true,"style":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-identity":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-identity","version":"0.1.2","title":"Actor Identity","category":"theme","icon":"id-alt","description":"The display name, federated handle, and optional Actor type badge for the Actor resolved by the enclosing Account Header.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"attributes":{"showHandle":{"type":"boolean","default":true},"showUsername":{"type":"boolean","default":false},"variant":{"type":"string","default":"profile"},"showTypeBadge":{"type":"boolean","default":false}},"supports":{"html":false,"multiple":false,"spacing":{"margin":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-avatar":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-avatar","version":"0.3.1","title":"Actor Avatar","category":"theme","icon":"admin-users","description":"The avatar of the Actor in context: the current Actor on a profile, or the author resolved through attributedTo on an object. The Actor sibling of Core's Avatar, for identities -- remote and Group Actors included -- that carry no WordPress user ID.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"attributes":{"size":{"type":"number","default":128},"isLink":{"type":"boolean","default":false},"linkTarget":{"type":"string","default":"_self"},"rel":{"type":"string","attribute":"rel","default":""}},"supports":{"html":false,"align":true,"alignWide":false,"shadow":{"__experimentalSkipSerialization":true},"spacing":{"margin":true,"padding":true},"filter":{"duotone":true},"interactivity":{"clientNavigation":true},"__experimentalBorder":{"radius":true,"width":true,"color":true,"style":true,"__experimentalSkipSerialization":true,"__experimentalDefaultControls":{"radius":true}}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-follow-list":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-follow-list","version":"0.1.0","title":"Actor Follow List","category":"theme","icon":"groups","description":"Displays the followers or following Actors for the current profile.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"attributes":{"collection":{"type":"string","default":"followers"}},"supports":{"html":false,"spacing":{"margin":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/group-directory":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/group-directory","version":"0.1.0","title":"Group Directory","category":"theme","icon":"groups","description":"Displays public Group Actors known to this server.","textdomain":"axismundi-actors","supports":{"html":false,"spacing":{"margin":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-profile":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-profile","version":"0.1.0","title":"Actor Profile","category":"theme","icon":"admin-users","description":"Displays the actor resolved by the current profile route.","textdomain":"axismundi-actors","supports":{"html":false,"align":["wide","full"],"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/actor-biography":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/actor-biography","version":"0.2.1","title":"Actor Biography","category":"theme","icon":"text-page","description":"The short summary for the Actor in context. The Actor sibling of Core's Author Biography, for identities -- remote and Group Actors included -- that carry no WordPress user ID. Defaults to a 20px serif voice.","textdomain":"axismundi-actors","usesContext":["axismundi\/actorId"],"example":{"viewportWidth":350},"supports":{"html":false,"multiple":false,"anchor":true,"spacing":{"margin":true,"padding":true},"color":{"gradients":true,"link":true,"__experimentalDefaultControls":{"background":true,"text":true}},"typography":{"fontSize":true,"lineHeight":true,"textAlign":true,"__experimentalFontFamily":true,"__experimentalFontWeight":true,"__experimentalFontStyle":true,"__experimentalTextTransform":true,"__experimentalTextDecoration":true,"__experimentalLetterSpacing":true,"__experimentalDefaultControls":{"fontSize":true}},"interactivity":{"clientNavigation":true},"__experimentalBorder":{"radius":true,"color":true,"width":true,"style":true,"__experimentalDefaultControls":{"radius":true,"color":true,"width":true,"style":true}}},"editorScript":"file:.\/edit.js","style":"file:.\/style.css","render":"file:.\/render.php"}},"tagged_versions":["0.1.2"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[162216,27882,65034,22649],"plugin_category":[],"plugin_contributors":[270183],"plugin_business_model":[],"class_list":["post-362691","plugin","type-plugin","status-publish","hentry","plugin_tags-activitypub","plugin_tags-actor","plugin_tags-federation","plugin_tags-identity","plugin_contributors-kimjiwoon","plugin_committers-kimjiwoon"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/axismundi-actors.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Axismundi Actors gives every identity this site knows about <strong>one stable identity\nrecord<\/strong> and <strong>one human profile hub<\/strong> (<code>\/@handle\/<\/code>), without collapsing that identity\ninto the WordPress user account and without owning the content it points at.<\/p>\n\n<p>Each domain plugin keeps its own storage and screens; Actors holds identity and wires\neach archive in as a <strong>projection<\/strong> (Posts, Media, Notes, ...) under one actor. The\nidentity URI (<code>\/actors\/{uuid}<\/code>, with <code>\/?ax_actor={uuid}<\/code> as the plain fallback) is\nderived from an immutable UUID. The <code>\/@handle\/<\/code> alias is registered once when the Actor\nis activated and does not follow later WordPress username changes, so an address that\nhas been given out keeps working.<\/p>\n\n<h4>What this version does<\/h4>\n\n<ul>\n<li>An identity record and profile hub for each <strong>local person<\/strong>, built from their\nWordPress user account without becoming that account.<\/li>\n<li><strong>Managed actors<\/strong> -- a Group, Organization or Service that belongs to no single user\nand is administered by the people listed as its managers.<\/li>\n<li>An <strong>acting Actor<\/strong> switch in the admin bar, so somebody who manages more than one\nidentity can choose which one they are working as. It is not an account switch: no\npassword is shared and the WordPress user does not change.<\/li>\n<li><strong>WebFinger<\/strong> and <strong>NodeInfo<\/strong> endpoints, so other servers can find the identities\nthis site publishes.<\/li>\n<li>A <strong>cache of remote actors<\/strong> this site has been asked about, with cached copies of\ntheir avatar and header images, and their follower\/following counts where they\npublish them.<\/li>\n<li>Profile links with <strong><code>rel=\"me\"<\/code> verification<\/strong>, checked against the page the person\nentered.<\/li>\n<li>A <strong>JSContact Card<\/strong> at <code>\/@handle.jscontact<\/code> for a local public Actor.<\/li>\n<\/ul>\n\n<h4>What this version does not do<\/h4>\n\n<p>Nothing here sends anything to anybody. There is no activity ledger, no likes, no\ninbox or outbox processing, no follow, no HTTP signatures, and no delivery -- those\nbelong to other plugins in the Axismundi suite. The site's own Instance Actor is seeded\nin a disabled state and has no screen, because what it should be has not been designed\nyet.<\/p>\n\n<h4>Data, and what happens when a user is deleted<\/h4>\n\n<p>Deleting a WordPress user does not delete the identity it belonged to. The identity is\n<strong>tombstoned<\/strong> instead: the record stays, marked as gone, and its URI keeps answering as\ngone rather than as never having existed. That is deliberate. An address that has been\npublished to other servers should be able to say \"this person is no longer here\"; an\naddress that simply disappears tells a reader nothing, and the same UUID could later be\nhanded to somebody else.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin contacts other websites, and only ever reads from them -- every request is a\n    GET, and nothing about your site's content or your users is sent as data. As with any\noutgoing HTTP request, the server being contacted receives <strong>your site's IP address<\/strong>,\nand a <code>User-Agent<\/code> header naming this plugin, its version, and <strong>your site's home URL<\/strong>,\nwhich is how that server can tell who asked. The address of the site being contacted is\nalways one that somebody at your site entered or that a request to your site named.<\/p>\n\n<ul>\n<li><strong>Discovering somebody at another site.<\/strong> When a remote address (<code>@name@example.com<\/code>)\nor a remote profile is looked up, this plugin reads that server's WebFinger document\n(<code>\/.well-known\/webfinger<\/code>), its actor document, and its NodeInfo document. What is\nstored locally is a copy of that public actor document: handle, display name, summary,\nprofile URL, and the addresses on it.<\/li>\n<li><strong>Avatar and header images.<\/strong> Images named by a cached remote actor are downloaded and\nstored in this site's uploads directory, so that showing them does not send your\nvisitors' browsers to another server. This happens in the background, on a scheduled\ntask, after the actor has been cached.<\/li>\n<li><strong>Follower and following counts.<\/strong> Where a cached remote actor publishes its follower\nor following collection, the collection is read for its <code>totalItems<\/code> number, hourly on\na scheduled task. Nothing but the number is kept.<\/li>\n<li><strong>Verifying a profile link.<\/strong> When somebody adds a link to their own profile and asks\nfor it to be verified, the page at that address is fetched once and checked for a\n  rel=\"me\" link back to their profile. Only that page is read, and only when asked.<\/li>\n<\/ul>\n\n<p>Every one of these requests goes through <code>wp_safe_remote_get()<\/code>, is limited in size, and\nis refused for any address inside your own network. Which sites are contacted therefore\ndepends entirely on which remote identities are looked up at your site; this plugin has\nno service of its own, and sends nothing to its author. Each server contacted is somebody\nelse's, run under its own terms of service and privacy policy.<\/p>\n\n<p>Sending anything outward -- inboxes, outboxes, activity delivery, HTTP signatures -- is\nnot done here. Where another plugin performs that federation, it discloses it itself; this\nsection covers only what this plugin's own code requests.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code>, or install it through\n<strong>Plugins &gt; Add New<\/strong>.<\/li>\n<li>Activate it through the <strong>Plugins<\/strong> screen.<\/li>\n<li>Go to <strong>Users &gt; Actor Profile<\/strong> and activate an Actor for your account. This is where\nthe handle is chosen; it is fixed once set.<\/li>\n<li>Optionally, go to <strong>Users &gt; Managed actors<\/strong> to create a Group, Organization or\nService that is not tied to one account.<\/li>\n<\/ol>\n\n<p>Activation creates this plugin's own database tables. Nothing is contacted on the\ninternet during installation.<\/p>\n\n<!--section=changelog-->\n<h4>0.1.2<\/h4>\n\n<ul>\n<li>Stop the actor management screen from creating an actor while rendering. It read a\nuser id from the query string and created a record for it, so a link could make an\nadministrator perform that write; the screen now only reads, and creation happens in\nthe activation form, which carries a nonce.<\/li>\n<li>Sanitize profile-link names and addresses where the form is read, not only where they\nare saved.<\/li>\n<li>Pass every custom table name to the database through a prepared identifier placeholder\nrather than interpolating it into the query text.<\/li>\n<\/ul>\n\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Sanitize filtered Actor display names and biographies immediately before rendering.<\/li>\n<li>Harden route parsing and align Group Directory render-template variable prefixes.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>First release.<\/li>\n<li>Identity records and profile hubs (<code>\/@handle\/<\/code>) for local people, built from the\nWordPress user account without becoming it, plus an immutable identity URI at\n  \/actors\/{uuid} that survives a username change.<\/li>\n<li>Managed actors -- a Group, Organization or Service belonging to no single user and\nadministered by the people listed as its managers.<\/li>\n<li>An acting Actor switch in the admin bar, checked again on every read so that a\nrevoked manager stops publishing as that identity immediately.<\/li>\n<li>WebFinger and NodeInfo endpoints, and a JSContact Card at <code>\/@handle.jscontact<\/code> for a\nlocal public Actor.<\/li>\n<li>Bounded discovery and caching of remote actors, with local copies of their avatar and\nheader images and their published follower and following counts.<\/li>\n<li>Profile fields with <code>rel=\"me\"<\/code> link verification.<\/li>\n<li>Deleting a WordPress user tombstones its identity rather than removing it, so an\naddress that has been published answers as gone instead of as never having existed.<\/li>\n<\/ul>","raw_excerpt":"Identity registry for Axismundi: one immutable actor URI and one profile hub per identity.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/362691","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=362691"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/kimjiwoon"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=362691"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=362691"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=362691"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=362691"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=362691"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=362691"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}