'; echo '

Demand Trace

'; echo '

Walk a Demand through arbitration → plan_links → acceptance chain → closure verdicts.

'; // Picker form (replaces v0.6.x free-form text inputs). self::render_picker_form( $surface, $ref ); if ( $surface !== '' && $ref !== '' ) { // Reuse the REST handler. Bypasses URI routing (avoids URL-encoding fragility around `#`). $req = new WP_REST_Request( 'GET' ); $req->set_url_params( [ 'surface' => $surface, 'ref' => $ref ] ); $resp = SA_Orch_Rest::get_demand_trace( $req ); $data = $resp->get_data(); self::render_trace_results( $data ); } echo ''; } /* ---------- Demand Trace picker (v0.6.2) ---------- */ /** * Demand picker: * - surface dropdown (closed enumeration of 4) * - quick-select strip (SA-ORCH-TEST fixtures pinned + last-traced) * - searchable browser of candidates for the selected surface * - manual ref entry as fallback (validated against known per-surface patterns) * * No new schema; no new endpoints. All candidate data is rendered inline * as JSON for client-side filtering. */ private static function render_picker_form( $surface, $ref ) { $candidates = [ 'fluent-support' => self::candidates_fluent_support(), 'fluent-boards' => self::candidates_fluent_boards(), 'fluentcrm' => self::candidates_fluentcrm(), 'derived' => self::candidates_derived(), ]; $quick = self::quick_select_demands( 10 ); $surface_labels = [ 'fluent-support' => 'fluent-support — Fluent Support tickets', 'fluent-boards' => 'fluent-boards — Fluent Boards tasks', 'fluentcrm' => 'fluentcrm — FluentCRM subscribers', 'derived' => 'derived — rowless / inferred demands', ]; // Per-surface validation regex (mirrors SA_Orch_Bridge_Fluent::validate / resolve). $patterns = [ 'fluent-support' => '^ticket#\\d+$', 'fluent-boards' => '^task#\\d+$', 'fluentcrm' => '^subscriber#\\d+$', 'derived' => '^derived#[A-Za-z0-9_\\-]+$', ]; echo '
'; echo ''; // ---------- Quick-select ---------- if ( ! empty( $quick ) ) { echo '
'; echo '

Quick-select

'; echo '

SA-ORCH-TEST fixtures pinned, then the most recently traced Demands.

'; echo '
'; } // ---------- Surface + ref ---------- echo ''; echo ''; echo ''; echo ''; echo '

'; // ---------- Browser ---------- echo '
'; echo '

Browse candidates

'; echo ''; echo '
Pick a surface to load candidates.
'; echo ''; echo '

Click any row to fill the Demand ref field. Ref is also free-form for advanced use; format is validated when you type.

'; echo '
'; // ---------- Inline JSON + JS ---------- $payload = [ 'candidates' => $candidates, 'patterns' => $patterns, ]; echo ''; echo ''; echo '
'; } /** * Vanilla-JS controller for the picker. No jQuery dependency. * Wires: surface change → repopulate browser; filter input → live filter; * candidate click → fill ref input; ref input → pattern hint. */ private static function picker_inline_js() { return <<<'JS' (function () { var data = window.SA_ORCH_PICKER || { candidates: {}, patterns: {} }; var surfaceSel = document.getElementById('demand_surface_select'); var refInput = document.getElementById('demand_ref_input'); var filterInp = document.getElementById('sa-orch-filter'); var listEl = document.getElementById('sa-orch-candidate-list'); var helpEl = document.getElementById('sa-orch-candidate-help'); var statusEl = document.getElementById('sa-orch-ref-status'); if (!surfaceSel || !refInput || !listEl || !helpEl || !filterInp) return; function escapeHtml(s) { return String(s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } function renderCandidates() { var surface = surfaceSel.value; var query = (filterInp.value || '').trim().toLowerCase(); listEl.innerHTML = ''; if (!surface) { helpEl.textContent = 'Pick a surface to load candidates.'; filterInp.disabled = true; return; } filterInp.disabled = false; var pool = (data.candidates || {})[surface] || []; if (!pool.length) { helpEl.textContent = 'No candidates known for this surface.'; return; } var matches = pool; if (query) { matches = pool.filter(function (c) { return c.ref.toLowerCase().indexOf(query) !== -1 || (c.label || '').toLowerCase().indexOf(query) !== -1; }); } helpEl.textContent = matches.length + ' / ' + pool.length + ' candidate' + (pool.length === 1 ? '' : 's') + (query ? ' matching "' + query + '"' : ''); var frag = document.createDocumentFragment(); matches.slice(0, 200).forEach(function (c) { var li = document.createElement('li'); li.style.padding = '5px 8px'; li.style.cursor = 'pointer'; li.style.borderBottom = '1px solid #f0f0f1'; li.style.lineHeight = '1.4'; var tag = c.is_test ? 'TEST' : ''; li.innerHTML = tag + '' + escapeHtml(c.ref) + '' + (c.label ? ' — ' + escapeHtml(c.label) : ''); li.addEventListener('mouseover', function () { li.style.background = '#f6f7f7'; }); li.addEventListener('mouseout', function () { if (!li.classList.contains('selected')) li.style.background = ''; }); li.addEventListener('click', function () { refInput.value = c.ref; Array.prototype.forEach.call( listEl.querySelectorAll('li.selected'), function (e) { e.classList.remove('selected'); e.style.background = ''; } ); li.classList.add('selected'); li.style.background = '#fff7c2'; validateRef(); refInput.focus(); }); frag.appendChild(li); }); listEl.appendChild(frag); } function validateRef() { var surface = surfaceSel.value; var ref = refInput.value.trim(); if (!surface || !ref) { statusEl.textContent = ''; return; } var pattern = (data.patterns || {})[surface]; if (!pattern) { statusEl.textContent = ''; return; } if ((new RegExp(pattern)).test(ref)) { statusEl.textContent = '✓ valid format'; statusEl.style.color = '#0a7d24'; } else { statusEl.textContent = '✗ does not match expected pattern'; statusEl.style.color = '#a02b1f'; } } surfaceSel.addEventListener('change', function () { filterInp.value = ''; renderCandidates(); validateRef(); }); filterInp.addEventListener('input', renderCandidates); refInput.addEventListener('input', validateRef); // Initial state (e.g. arrived via permalink with both fields preset). renderCandidates(); validateRef(); })(); JS; } /* ---------- Candidate fetchers (per surface) ---------- */ /** Fluent Support tickets, SA-ORCH-TEST pinned first. Cap 50. */ private static function candidates_fluent_support() { global $wpdb; $rows = $wpdb->get_results( "SELECT id, title FROM {$wpdb->prefix}fs_tickets ORDER BY (title LIKE '[SA-ORCH-TEST]%') DESC, id DESC LIMIT 50" ); $out = []; foreach ( (array) $rows as $r ) { $title = (string) $r->title; $out[] = [ 'ref' => 'ticket#' . (int) $r->id, 'label' => self::truncate( $title, 80 ), 'is_test' => ( strpos( $title, '[SA-ORCH-TEST]' ) === 0 ), ]; } return $out; } /** Fluent Boards tasks, most-recent first. Cap 50. */ private static function candidates_fluent_boards() { global $wpdb; // Defensive: Fluent Boards may not be installed. $exists = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->prefix . 'fbs_tasks' ) ); if ( ! $exists ) return []; $rows = $wpdb->get_results( "SELECT id, title FROM {$wpdb->prefix}fbs_tasks ORDER BY id DESC LIMIT 50" ); $out = []; foreach ( (array) $rows as $r ) { $title = (string) ( $r->title ?? '' ); $out[] = [ 'ref' => 'task#' . (int) $r->id, 'label' => self::truncate( $title, 80 ), 'is_test' => ( strpos( $title, '[SA-ORCH-TEST]' ) === 0 ), ]; } return $out; } /** FluentCRM subscribers, most-recent first. Cap 50. Label = full_name|email. */ private static function candidates_fluentcrm() { global $wpdb; $exists = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->prefix . 'fc_subscribers' ) ); if ( ! $exists ) return []; $rows = $wpdb->get_results( "SELECT id, full_name, email FROM {$wpdb->prefix}fc_subscribers ORDER BY id DESC LIMIT 50" ); $out = []; foreach ( (array) $rows as $r ) { $name = trim( (string) ( $r->full_name ?? '' ) ); $email = (string) ( $r->email ?? '' ); $label = $name !== '' ? ( $name . ( $email ? " <{$email}>" : '' ) ) : $email; $out[] = [ 'ref' => 'subscriber#' . (int) $r->id, 'label' => self::truncate( $label, 80 ), 'is_test' => false, ]; } return $out; } /** * 'derived' surface has no underlying surface table — list every distinct * derived demand_ref ever recorded in arbitrations or acceptance events. */ private static function candidates_derived() { global $wpdb; $arb = $wpdb->prefix . SA_ORCH_DB_PREFIX . 'arbitration'; $evt = $wpdb->prefix . SA_ORCH_DB_PREFIX . 'acceptance_event'; $rows = $wpdb->get_results( "SELECT demand_ref, MAX(last_at) AS last_at FROM ( SELECT demand_ref, MAX(created_at) AS last_at FROM {$arb} WHERE demand_surface='derived' GROUP BY demand_ref UNION ALL SELECT demand_ref, MAX(observed_at) AS last_at FROM {$evt} WHERE demand_surface='derived' GROUP BY demand_ref ) sub GROUP BY demand_ref ORDER BY last_at DESC LIMIT 50" ); $out = []; foreach ( (array) $rows as $r ) { $out[] = [ 'ref' => (string) $r->demand_ref, 'label' => '(derived demand, no surface row)', 'is_test' => false, ]; } return $out; } /** * Quick-select list: SA-ORCH-TEST tickets pinned, then most-recently-traced * demands across all surfaces (by max(arbitration.created_at, event.observed_at)). */ private static function quick_select_demands( $limit = 10 ) { global $wpdb; $arb = $wpdb->prefix . SA_ORCH_DB_PREFIX . 'arbitration'; $evt = $wpdb->prefix . SA_ORCH_DB_PREFIX . 'acceptance_event'; $rows = $wpdb->get_results( "SELECT demand_surface, demand_ref, MAX(last_at) AS last_at FROM ( SELECT demand_surface, demand_ref, MAX(created_at) AS last_at FROM {$arb} GROUP BY demand_surface, demand_ref UNION ALL SELECT demand_surface, demand_ref, MAX(observed_at) AS last_at FROM {$evt} GROUP BY demand_surface, demand_ref ) sub GROUP BY demand_surface, demand_ref ORDER BY last_at DESC LIMIT 30" ); if ( empty( $rows ) ) return []; // Resolve labels + is_test per row. $out = []; foreach ( $rows as $r ) { $surface = (string) $r->demand_surface; $ref = (string) $r->demand_ref; list( $label, $is_test ) = self::resolve_label( $surface, $ref ); $out[] = [ 'surface' => $surface, 'ref' => $ref, 'label' => $label, 'is_test' => $is_test, 'last_at' => (string) $r->last_at, ]; } // Pin SA-ORCH-TEST first; preserve last_at ordering within each group. usort( $out, function ( $a, $b ) { if ( $a['is_test'] !== $b['is_test'] ) return $a['is_test'] ? -1 : 1; return strcmp( $b['last_at'], $a['last_at'] ); } ); return array_slice( $out, 0, (int) $limit ); } /** Resolve a (surface, ref) to a human label + is_test flag. Best-effort, tolerant of missing tables. */ private static function resolve_label( $surface, $ref ) { global $wpdb; if ( $surface === 'fluent-support' && preg_match( '/^ticket#(\d+)$/', $ref, $m ) ) { $title = (string) $wpdb->get_var( $wpdb->prepare( "SELECT title FROM {$wpdb->prefix}fs_tickets WHERE id=%d", (int) $m[1] ) ); return [ self::truncate( $title, 80 ), strpos( $title, '[SA-ORCH-TEST]' ) === 0 ]; } if ( $surface === 'fluent-boards' && preg_match( '/^task#(\d+)$/', $ref, $m ) ) { if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->prefix . 'fbs_tasks' ) ) ) { $title = (string) $wpdb->get_var( $wpdb->prepare( "SELECT title FROM {$wpdb->prefix}fbs_tasks WHERE id=%d", (int) $m[1] ) ); return [ self::truncate( $title, 80 ), strpos( $title, '[SA-ORCH-TEST]' ) === 0 ]; } } if ( $surface === 'fluentcrm' && preg_match( '/^subscriber#(\d+)$/', $ref, $m ) ) { if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->prefix . 'fc_subscribers' ) ) ) { $row = $wpdb->get_row( $wpdb->prepare( "SELECT full_name, email FROM {$wpdb->prefix}fc_subscribers WHERE id=%d", (int) $m[1] ) ); if ( $row ) { $name = trim( (string) $row->full_name ); $email = (string) $row->email; $label = $name !== '' ? ( $name . ( $email ? " <{$email}>" : '' ) ) : $email; return [ self::truncate( $label, 80 ), false ]; } } } if ( $surface === 'derived' ) { return [ '(derived demand, no surface row)', false ]; } return [ '', false ]; } private static function truncate( $s, $n ) { $s = (string) $s; if ( function_exists( 'mb_strlen' ) && function_exists( 'mb_substr' ) ) { return mb_strlen( $s ) > $n ? ( mb_substr( $s, 0, $n - 1 ) . '…' ) : $s; } return strlen( $s ) > $n ? ( substr( $s, 0, $n - 1 ) . '…' ) : $s; } private static function render_trace_results( array $data ) { $arbs = $data['arbitrations'] ?? []; $links = $data['plan_links'] ?? []; $events = $data['acceptance'] ?? []; echo '

Closure

'; echo ''; echo ''; echo ''; $auth = $data['closure_authority_valid'] ?? null; $auth_disp = $auth === null ? 'null' : ( $auth ? 'true' : 'false' ); echo ''; echo '
closure_state_basic' . esc_html( (string) ( $data['closure_state_basic'] ?? '' ) ) . '
closure_state_role_aware' . esc_html( (string) ( $data['closure_state_role_aware'] ?? '' ) ) . '
closure_authority_valid' . esc_html( $auth_disp ) . '
'; // === Deterministic Trace Audit (layer 2 — rules-based) === self::render_reasoning_review( $data ); echo '

Arbitrations (' . count( $arbs ) . ')

'; if ( empty( $arbs ) ) { echo '

No arbitrations recorded for this demand.

'; } else { echo ''; echo ''; echo ''; foreach ( $arbs as $a ) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } echo '
IDHashProjection TypeTruth ClassActorCorrelationCreated (UTC)Asterion
' . (int) $a->id . '' . esc_html( substr( (string) $a->hash, 0, 12 ) ) . '…' . esc_html( (string) $a->projection_type ) . '' . esc_html( (string) $a->truth_class ) . '' . esc_html( (string) ( $a->actor_user_id ?? '—' ) ) . '' . esc_html( substr( (string) $a->correlation_id, 0, 8 ) ) . '…' . esc_html( (string) $a->created_at ) . '' . esc_html( (string) $a->asterion_path ) . '
Rationale: ' . esc_html( (string) $a->rationale ) . '
'; } echo '

Plan Links (' . count( $links ) . ')

'; if ( empty( $links ) ) { echo '

No plan links — this Demand has no Plan refs (consistent with scope-direct-no-plan or no-plan arbitration).

'; } else { echo ''; echo ''; echo ''; foreach ( $links as $l ) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } echo '
IDArbitrationPlan SurfacePlan RefLink KindCreated (UTC)
' . (int) $l->id . '' . (int) $l->arbitration_id . '' . esc_html( (string) $l->plan_surface ) . '' . esc_html( (string) $l->plan_ref ) . '' . esc_html( (string) $l->link_kind ) . '' . esc_html( (string) $l->created_at ) . '
'; } echo '

Acceptance Events (' . count( $events ) . ')

'; if ( empty( $events ) ) { echo '

No acceptance events.

'; } else { echo ''; echo ''; echo ''; foreach ( $events as $e ) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; if ( ! empty( $e->details ) ) { echo ''; } } echo '
IDEvent TypeActor RoleActorTruth ClassPriorObserved (UTC)Asterion
' . (int) $e->id . '' . esc_html( (string) $e->event_type ) . '' . esc_html( (string) $e->actor_role ) . '' . esc_html( (string) ( $e->actor_user_id ?? '—' ) ) . '' . esc_html( (string) $e->truth_class ) . '' . esc_html( (string) ( $e->prior_event_id ?? '—' ) ) . '' . esc_html( (string) $e->observed_at ) . '' . esc_html( (string) $e->asterion_path ) . '
Details: ' . esc_html( (string) $e->details ) . '
'; } } /** * Deterministic Trace Audit block. * * Local rules-based audit over the trace data. No API calls, no LLM, no * persistence. Recomputed on every page load. * * This is the FLOOR of the review stack: * 1. Trace data * 2. Deterministic Trace Audit ← this section * 3. Strategy LLM Review (future; will sit above this audit) * 4. Human arbitration (final meaning; always wins) */ private static function render_reasoning_review( array $data ) { $r = SA_Orch_Reasoning::evaluate( $data ); echo '

Deterministic Trace Audit (rules-based, mode: ' . esc_html( (string) ( $r['mode'] ?? 'deterministic' ) ) . ')

'; echo '

Local rules-based audit — repeatable, no API, no LLM. Computed on each page load. Floor of a four-layer stack: '; echo '(1) Trace data(2) this Deterministic Trace Audit(3) Strategy LLM Review (future) → (4) Human arbitration (final).

'; $color_map = [ 'high' => '#0a7d24', 'medium' => '#a76b00', 'low' => '#a02b1f', 'n/a' => '#666' ]; $color = $color_map[ $r['closure_confidence'] ] ?? '#666'; echo ''; echo ''; echo ''; // Needs Human Arbitration — prominent row echo ''; $render_list = function ( $label, $items ) { echo ''; }; $render_list( 'Inconsistencies', $r['inconsistencies'] ); $render_list( 'Potential scope drift', $r['scope_drift'] ); $render_list( 'Notes', $r['notes'] ); echo '
Summary' . esc_html( $r['summary'] ) . '
Closure confidence'; echo '' . esc_html( strtoupper( (string) $r['closure_confidence'] ) ) . ''; echo ' — ' . esc_html( $r['closure_confidence_explanation'] ); echo '
Needs Human Arbitration'; if ( ! empty( $r['needs_human_arbitration'] ) ) { echo '⚠ YES — ' . esc_html( (string) $r['human_arbitration_message'] ) . ''; echo '

Triggered by:

'; echo '
    '; foreach ( (array) $r['human_arbitration_triggers'] as $t ) { echo '
  • ' . esc_html( $t ) . '
  • '; } echo '
'; } else { echo 'No — none of the deterministic escalation triggers fired.'; } echo '
' . esc_html( $label ) . ''; if ( empty( $items ) ) { echo '(none)'; } else { echo '
    '; foreach ( $items as $i ) { echo '
  • ' . esc_html( $i ) . '
  • '; } echo '
'; } echo '
'; echo '

Layer 3 — Strategy LLM Review — sits below this section. The audit remains as a sanity-check / fallback layer underneath any LLM verdict.

'; // --- Strategy Review (v0.5) --- self::render_strategy_review( $data, $r ); } /** * Strategy LLM Review block (layer 3). * * Consumes the trace + the deterministic audit; delegates to the active * provider via SA_Orch_Strategy::review(). Strategy Review is advisory: * it cannot override closure_state or needs_human_arbitration. */ private static function render_strategy_review( array $data, array $deterministic_audit ) { $strategy = SA_Orch_Strategy::review( $data, $deterministic_audit ); $provider_id = (string) ( $strategy['provider_id'] ?? 'simulated' ); $provider_name = (string) ( $strategy['provider_name'] ?? 'Simulated (no API call)' ); $configured_id = (string) ( $strategy['configured_provider_id'] ?? $provider_id ); $configured_name = (string) ( $strategy['configured_provider_name'] ?? $provider_name ); $fallback_used = ! empty( $strategy['fallback_used'] ); $provider_err = $strategy['provider_error'] ?? null; $heading_suffix = $fallback_used ? '(layer 3 — used: ' . esc_html( $provider_id ) . ', configured: ' . esc_html( $configured_id ) . ' — FALLBACK)' : '(layer 3 — provider: ' . esc_html( $provider_id ) . ')'; echo '

Strategy Review (simulated LLM) ' . $heading_suffix . '

'; echo '

Layer 3 of the review stack. Provider in use: ' . esc_html( $provider_name ) . '. '; if ( $fallback_used ) { echo 'Configured provider (' . esc_html( $configured_name ) . ') failed and was replaced by the simulated fallback. '; } echo 'Compares its interpretation against the deterministic audit. '; echo 'Strategy Review cannot override closure_state or the needs_human_arbitration flag — those remain governed by the deterministic audit and ultimately by human arbitration.

'; if ( $provider_err ) { echo '

Provider error (configured: ' . esc_html( $configured_id ) . '): ' . esc_html( $provider_err ) . ' — fell back to simulated.

'; } // Color hints $color_map_conf = [ 'high' => '#0a7d24', 'medium' => '#a76b00', 'low' => '#a02b1f' ]; $color_map_agree = [ 'true' => '#0a7d24', 'partial' => '#a76b00', 'false' => '#a02b1f' ]; $strat_conf = (string) ( $strategy['confidence'] ?? 'low' ); $strat_agree = (string) ( $strategy['agreement_with_audit'] ?? 'partial' ); $strat_color = $color_map_conf[ $strat_conf ] ?? '#666'; $agree_color = $color_map_agree[ $strat_agree ] ?? '#666'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
Summary' . esc_html( (string) ( $strategy['summary'] ?? '' ) ) . '
Agreement with Deterministic Audit'; echo '' . esc_html( strtoupper( $strat_agree ) ) . ''; echo '
Additional risks (not caught by audit)'; $risks = (array) ( $strategy['additional_risks'] ?? [] ); if ( empty( $risks ) ) { echo '(none)'; } else { echo '
    '; foreach ( $risks as $r ) { echo '
  • ' . esc_html( (string) $r ) . '
  • '; } echo '
'; } echo '
Suggested next action' . esc_html( (string) ( $strategy['suggested_next_action'] ?? '' ) ) . '
Confidence'; echo '' . esc_html( strtoupper( $strat_conf ) ) . ''; echo '
'; // Visual side-by-side comparison self::render_audit_strategy_comparison( $deterministic_audit, $strategy ); } /** * Side-by-side comparison of Deterministic Audit (layer 2) and Strategy Review (layer 3). */ private static function render_audit_strategy_comparison( array $audit, array $strategy ) { $color_map_conf = [ 'high' => '#0a7d24', 'medium' => '#a76b00', 'low' => '#a02b1f', 'n/a' => '#666' ]; $audit_conf = (string) ( $audit['closure_confidence'] ?? 'n/a' ); $strat_conf = (string) ( $strategy['confidence'] ?? 'low' ); $audit_inc = count( (array) ( $audit['inconsistencies'] ?? [] ) ); $audit_drift = count( (array) ( $audit['scope_drift'] ?? [] ) ); $strat_extra = count( (array) ( $strategy['additional_risks'] ?? [] ) ); $needs_hum = ! empty( $audit['needs_human_arbitration'] ); echo '

Deterministic Audit ↔ Strategy Review (side-by-side)

'; echo ''; echo ''; echo ''; echo ''; echo ''; $audit_conf_color = $color_map_conf[ $audit_conf ] ?? '#666'; $strat_conf_color = $color_map_conf[ $strat_conf ] ?? '#666'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
 Deterministic Audit (layer 2)Strategy Review (layer 3)
Confidence' . esc_html( strtoupper( $audit_conf ) ) . '' . esc_html( strtoupper( $strat_conf ) ) . '
Findings counted' . (int) $audit_inc . ' inconsistenc' . ( $audit_inc === 1 ? 'y' : 'ies' ) . ', ' . (int) $audit_drift . ' scope-drift indicator' . ( $audit_drift === 1 ? '' : 's' ) . '' . (int) $strat_extra . ' additional risk' . ( $strat_extra === 1 ? '' : 's' ) . '
Closure authority' . ( $needs_hum ? 'flagged needs_human_arbitration = YES' : 'no escalation flag' ) . 'cannot override the audit
Mode / characterrules-based, repeatableinterpretive, narrative (' . esc_html( (string) ( $strategy['provider_id'] ?? 'simulated' ) ) . ')
'; echo '

Reminder: closure_state_basic, closure_state_role_aware, closure_authority_valid, and needs_human_arbitration are governed by the deterministic audit (layer 2) and ultimately by human arbitration (layer 4). Strategy Review is advisory.

'; } /* ---------- Recent Arbitrations ---------- */ public static function render_arbitrations() { if ( ! current_user_can( self::CAP ) ) wp_die( 'Insufficient permissions.' ); global $wpdb; $p = $wpdb->prefix . SA_ORCH_DB_PREFIX; $rows = $wpdb->get_results( "SELECT id, demand_surface, demand_ref, projection_type, truth_class, actor_user_id, created_at FROM {$p}arbitration ORDER BY created_at DESC, id DESC LIMIT 20" ); echo '
'; echo '

Recent Arbitrations

'; echo '

Last 20 arbitration records, newest first. Click Trace to walk the full chain.

'; if ( empty( $rows ) ) { echo '

No arbitrations recorded yet.

'; } else { echo ''; echo ''; echo ''; foreach ( $rows as $r ) { $trace_url = admin_url( 'admin.php?page=' . self::PARENT_SLUG . '&demand_surface=' . urlencode( $r->demand_surface ) . '&demand_ref=' . urlencode( $r->demand_ref ) ); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } echo '
IDDemandProjection TypeTruth ClassActorCreated (UTC)Action
' . (int) $r->id . '' . esc_html( $r->demand_surface . ' / ' . $r->demand_ref ) . '' . esc_html( (string) $r->projection_type ) . '' . esc_html( (string) $r->truth_class ) . '' . esc_html( (string) ( $r->actor_user_id ?? '—' ) ) . '' . esc_html( (string) $r->created_at ) . 'Trace
'; } echo '
'; } /* ---------- Language Model Providers (settings page) ---------- */ public static function render_llm_settings() { if ( ! current_user_can( self::CAP ) ) wp_die( 'Insufficient permissions.' ); $message = ''; if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) { check_admin_referer( 'sa_orch_llm_settings' ); SA_Orch_LLM_Settings::save( wp_unslash( $_POST ) ); $message = 'Settings saved.'; } $settings = SA_Orch_LLM_Settings::get(); $choices = SA_Orch_LLM_Providers::get_provider_choices(); $token_label = SA_Orch_LLM_Settings::token_status_label(); echo '
'; echo '

Language Model Providers

'; if ( $message ) { echo '

' . esc_html( $message ) . '

'; } echo '

Configure the provider used by the Strategy Review (layer 3 of the review stack: trace data → deterministic audit → strategy review → human arbitration).

'; echo '

Local-dev posture: secrets are stored in wp_options. Tokens are never displayed back — saving with a blank token field preserves the existing value. This storage layer is the attachment seam for a future SA-Core key vault; replacing it later will not change the consumer surface.

'; echo '
'; wp_nonce_field( 'sa_orch_llm_settings' ); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '

'; echo '
'; echo '
'; echo '

Status

'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
Active provider (resolved)' . esc_html( SA_Orch_LLM_Providers::get_active_provider()->id() ) . '
Settings.enabled' . ( ! empty( $settings['enabled'] ) ? 'true' : 'false' ) . '
Settings.provider' . esc_html( (string) $settings['provider'] ) . '
Settings.model' . esc_html( (string) $settings['model'] ?: '—' ) . '
Settings.api_base_url' . esc_html( (string) $settings['api_base_url'] ?: '—' ) . '
Settings.api_token' . ( SA_Orch_LLM_Settings::has_token() ? '***** (set)' : '(not set)' ) . '
'; echo '

v0.5 ships with the simulated provider only — no external API call is made by this plugin under any settings configuration. Adding real providers (OpenAI, Anthropic, local model endpoint, custom HTTP) is a matter of implementing SA_Orch_LLM_Provider_Interface and adding a case to SA_Orch_LLM_Providers::instantiate().

'; echo '
'; } /* ---------- Acceptance Events ---------- */ public static function render_events() { if ( ! current_user_can( self::CAP ) ) wp_die( 'Insufficient permissions.' ); global $wpdb; $p = $wpdb->prefix . SA_ORCH_DB_PREFIX; $rows = $wpdb->get_results( "SELECT id, event_type, actor_role, demand_surface, demand_ref, observed_at, truth_class, actor_user_id FROM {$p}acceptance_event ORDER BY observed_at DESC, id DESC LIMIT 20" ); echo '
'; echo '

Acceptance Events

'; echo '

Last 20 acceptance events, newest first. Append-only — these rows are never updated or deleted.

'; if ( empty( $rows ) ) { echo '

No acceptance events recorded yet.

'; } else { echo ''; echo ''; echo ''; foreach ( $rows as $r ) { $trace_url = admin_url( 'admin.php?page=' . self::PARENT_SLUG . '&demand_surface=' . urlencode( $r->demand_surface ) . '&demand_ref=' . urlencode( $r->demand_ref ) ); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } echo '
IDEvent TypeActor RoleActorDemandTruth ClassObserved (UTC)Action
' . (int) $r->id . '' . esc_html( (string) $r->event_type ) . '' . esc_html( (string) $r->actor_role ) . '' . esc_html( (string) ( $r->actor_user_id ?? '—' ) ) . '' . esc_html( $r->demand_surface . ' / ' . $r->demand_ref ) . '' . esc_html( (string) $r->truth_class ) . '' . esc_html( (string) $r->observed_at ) . 'Trace
'; } echo '
'; } }