isset( $_POST['actor_name'] ) ? sanitize_text_field( wp_unslash( $_POST['actor_name'] ) ) : '', 'type' => isset( $_POST['actor_type'] ) ? sanitize_text_field( wp_unslash( $_POST['actor_type'] ) ) : '', 'persona' => isset( $_POST['actor_persona'] ) ? sanitize_textarea_field( wp_unslash( $_POST['actor_persona'] ) ) : '', 'scope' => isset( $_POST['actor_scope'] ) ? sanitize_textarea_field( wp_unslash( $_POST['actor_scope'] ) ) : '', ]; $result = SA_Orch_Actor_Registry::create_actor( $data ); if ( is_wp_error( $result ) ) { $msg = 'error&msg=' . rawurlencode( $result->get_error_message() ); } else { $msg = 'created&id=' . (int) $result; } wp_safe_redirect( admin_url( 'admin.php?page=' . self::SUBMENU_SLUG . '¬ice=' . $msg ) ); exit; } if ( $action === 'archive' || $action === 'unarchive' ) { $id = isset( $_POST['actor_id'] ) ? (int) $_POST['actor_id'] : 0; if ( $id > 0 ) { if ( $action === 'archive' ) SA_Orch_Actor_Registry::archive_actor( $id ); if ( $action === 'unarchive' ) SA_Orch_Actor_Registry::unarchive_actor( $id ); } wp_safe_redirect( admin_url( 'admin.php?page=' . self::SUBMENU_SLUG . '¬ice=' . $action . 'd' ) ); exit; } } /** Single-page render with view dispatching. */ public static function render_page() { if ( ! current_user_can( SA_Orch_Admin::CAP ) ) { wp_die( __( 'Insufficient permissions.', 'sa-orchestration' ) ); } $view = isset( $_GET['view'] ) ? sanitize_text_field( wp_unslash( $_GET['view'] ) ) : 'list'; echo '
'; echo '

Sleeper Agents identity-bound roles · non-binding

'; echo self::inline_styles(); self::render_notice(); if ( $view === 'create' ) { self::render_create_form(); } elseif ( $view === 'detail' ) { self::render_detail(); } else { self::render_list(); } echo '
'; // .wrap } private static function render_notice() { if ( empty( $_GET['notice'] ) ) return; $notice = sanitize_text_field( wp_unslash( $_GET['notice'] ) ); $msg = isset( $_GET['msg'] ) ? sanitize_text_field( wp_unslash( $_GET['msg'] ) ) : ''; $kind = 'success'; $body = ''; if ( $notice === 'created' ) { $body = 'Actor created.'; } elseif ( $notice === 'archived' ) { $body = 'Actor archived.'; } elseif ( $notice === 'unarchived' ) { $body = 'Actor unarchived.'; } elseif ( $notice === 'error' ) { $kind = 'error'; $body = $msg !== '' ? $msg : 'Action failed.'; } if ( $body !== '' ) { echo '

' . esc_html( $body ) . '

'; } } private static function render_list() { $include_archived = ! empty( $_GET['show_archived'] ); $actors = SA_Orch_Actor_Registry::list_actors( $include_archived ); $create_url = admin_url( 'admin.php?page=' . self::SUBMENU_SLUG . '&view=create' ); $toggle_archived_url = add_query_arg( 'show_archived', $include_archived ? '0' : '1' ); echo '

Actors are persistent identity-bound roles. They may speak, draft, advise, observe, coordinate. They may not progress Boards, accept gates, mutate Asterion, or act silently.

'; echo '

'; echo '+ Create Actor   '; echo '' . ( $include_archived ? 'Hide archived' : 'Show archived' ) . ''; echo '

'; echo ''; echo ''; echo ''; echo ''; if ( empty( $actors ) ) { echo ''; } else { foreach ( $actors as $u ) { $a = SA_Orch_Actor_Registry::get_actor( (int) $u->ID ); if ( ! $a ) continue; $detail_url = admin_url( 'admin.php?page=' . self::SUBMENU_SLUG . '&view=detail&id=' . $a['user_id'] ); $persona_excerpt = function_exists( 'mb_substr' ) ? mb_substr( $a['persona'], 0, 80 ) : substr( $a['persona'], 0, 80 ); $status_label = $a['is_active'] ? 'active' : 'archived'; echo ''; echo ''; echo ''; echo ''; echo ''; // status_label is pre-built; safe echo ''; echo ''; echo ''; echo ''; } } echo '
NameTypeOwnerStatusPersona (excerpt)CreatedActions
No actors yet. Create the first one with intent.
' . esc_html( $a['name'] ) . '
' . esc_html( $a['type'] ) . '' . esc_html( $a['owner_login'] ?: '—' ) . '' . $status_label . '' . esc_html( $persona_excerpt ) . ( strlen( $a['persona'] ) > 80 ? '…' : '' ) . '' . esc_html( $a['created_at'] ) . ''; if ( $a['is_active'] ) { self::render_post_button( 'archive', $a['user_id'], 'Archive' ); } else { self::render_post_button( 'unarchive', $a['user_id'], 'Unarchive' ); } echo '
'; } private static function render_post_button( string $action, int $actor_id, string $label ) { $url = admin_url( 'admin.php?page=' . self::SUBMENU_SLUG ); echo '
'; wp_nonce_field( 'sa_actor_form', 'sa_actor_nonce' ); echo ''; echo ''; echo ''; echo '
'; } private static function render_create_form() { $list_url = admin_url( 'admin.php?page=' . self::SUBMENU_SLUG ); echo '

Create Actor

'; echo '

Creation discipline: actors must be named with intent, have a defined role, and a scoped purpose. No "random AI assistant" — only purposeful, identity-bound roles.

'; echo '
'; wp_nonce_field( 'sa_actor_form', 'sa_actor_nonce' ); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
'; echo '

'; echo '   '; echo 'Cancel'; echo '

'; echo '
'; } private static function render_detail() { $list_url = admin_url( 'admin.php?page=' . self::SUBMENU_SLUG ); $id = isset( $_GET['id'] ) ? (int) $_GET['id'] : 0; $a = $id > 0 ? SA_Orch_Actor_Registry::get_actor( $id ) : null; if ( ! $a ) { echo '

Actor not found. Back to list

'; return; } echo '

' . esc_html( $a['name'] ) . ' ' . esc_html( $a['login'] ) . '

'; echo '

← Back to list

'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
Type ' . esc_html( $a['type'] ) . '
Status ' . ( $a['is_active'] ? 'active' : 'archived' ) . '
Owner ' . esc_html( $a['owner_login'] ?: '—' ) . ' (user_id=' . (int) $a['owner_user_id'] . ')
Persona
' . esc_html( $a['persona'] ) . '
Scope
' . esc_html( $a['scope'] ?: '—' ) . '
Subscription tier ' . esc_html( $a['subscription_tier'] ?: '— (reserved for future)' ) . '
Created ' . esc_html( $a['created_at'] ) . '
'; echo '

Activity trail

'; echo '

Actor-attributed comments and drafts will appear here once the invocation surface is implemented (deferred to a future Board). For now: empty by design.

'; } private static function inline_styles(): string { return ''; } }