Spaces:
Sleeping
Sleeping
| defined( 'ABSPATH' ) || exit; | |
| /** | |
| * Simulated Strategy LLM provider. | |
| * | |
| * No external API call. Pattern-based heuristic expansion of the trace + | |
| * deterministic audit, written to feel LLM-like (interpretive narrative, | |
| * additional risk identification, suggested next action) without making | |
| * any network request. | |
| * | |
| * Always available as the fallback provider. | |
| */ | |
| class SA_Orch_LLM_Provider_Simulated implements SA_Orch_LLM_Provider_Interface { | |
| public function id(): string { return 'simulated'; } | |
| public function name(): string { return 'Simulated (no API call)'; } | |
| public function requires_api_key(): bool { return false; } | |
| public function review_trace( array $trace, array $deterministic_audit ): array { | |
| $arbs = isset( $trace['arbitrations'] ) ? (array) $trace['arbitrations'] : []; | |
| $links = isset( $trace['plan_links'] ) ? (array) $trace['plan_links'] : []; | |
| $events = isset( $trace['acceptance'] ) ? (array) $trace['acceptance'] : []; | |
| $authority = $trace['closure_authority_valid'] ?? null; | |
| $audit_conf = $deterministic_audit['closure_confidence'] ?? 'n/a'; | |
| $needs_hum = ! empty( $deterministic_audit['needs_human_arbitration'] ); | |
| $summary = $this->build_narrative( $arbs, $links, $events, $trace, $deterministic_audit ); | |
| $additional_risks = $this->identify_additional_risks( $arbs, $links, $events, $trace ); | |
| $agreement = $this->determine_agreement( $additional_risks, $deterministic_audit ); | |
| $next_action = $this->suggest_next_action( $audit_conf, $trace, $needs_hum, count( $additional_risks ) ); | |
| $confidence = $this->compute_confidence( $audit_conf, count( $additional_risks ), $needs_hum ); | |
| return [ | |
| 'summary' => $summary, | |
| 'agreement_with_audit' => $agreement, | |
| 'additional_risks' => $additional_risks, | |
| 'suggested_next_action' => $next_action, | |
| 'confidence' => $confidence, | |
| ]; | |
| } | |
| /* ---------- internals ---------- */ | |
| private function build_narrative( $arbs, $links, $events, $trace, $audit ) { | |
| $arb_n = count( $arbs ); | |
| $event_n = count( $events ); | |
| $closure_basic = $trace['closure_state_basic'] ?? null; | |
| $authority = $trace['closure_authority_valid'] ?? null; | |
| if ( $arb_n === 0 && $event_n === 0 ) { | |
| return "No trace data found for this Demand reference. The system has no record of the Demand passing through arbitration or acceptance — the surface_ref may be wrong, or this Demand has not yet been arbitrated."; | |
| } | |
| $patterns = []; | |
| foreach ( $arbs as $a ) { | |
| if ( ( $a->truth_class ?? null ) === 'derived' ) $patterns['derived'] = true; | |
| if ( ( $a->projection_type ?? null ) === 'scope-direct-no-plan' ) $patterns['no_plan'] = true; | |
| } | |
| if ( $arb_n > 1 ) $patterns['multi_arb'] = true; | |
| if ( $authority === false ) $patterns['agent_self'] = true; | |
| $had_dispute = false; | |
| foreach ( $events as $e ) { | |
| if ( ( $e->event_type ?? null ) === 'acceptance_disputed' ) { $had_dispute = true; break; } | |
| } | |
| if ( $had_dispute ) $patterns['dispute'] = true; | |
| if ( $closure_basic === 'closed' && $authority === true && ! $had_dispute ) $patterns['clean'] = true; | |
| if ( is_string( $closure_basic ) && strpos( $closure_basic, 'open:' ) === 0 ) $patterns['open'] = true; | |
| $bits = []; | |
| // Opening sentence — lead with the dominant pattern | |
| if ( isset( $patterns['agent_self'] ) ) { | |
| $bits[] = "The closure pattern here is concerning: the same role that claimed the result also affirmed acceptance, bypassing the originating stakeholder."; | |
| } elseif ( isset( $patterns['derived'] ) && $event_n === 0 ) { | |
| $bits[] = "The Demand was reconstructed from Plan-side evidence rather than captured at the originating surface. With no acceptance events on record, there is no evidence that the actual stakeholder agrees this Plan addresses their need."; | |
| } elseif ( isset( $patterns['open'] ) && isset( $patterns['dispute'] ) ) { | |
| $bits[] = "The Demand was claimed resolved but disputed; the dispute remains unresolved. The surface state may signal in-progress, but the strategic reality is that the original demand-constraint is unmet."; | |
| } elseif ( isset( $patterns['open'] ) ) { | |
| $bits[] = "The Demand is in-flight: the claim and acceptance steps are not yet complete."; | |
| } elseif ( isset( $patterns['clean'] ) ) { | |
| $bits[] = "This Demand followed a routine path: scoped, executed, and confirmed by the stakeholder."; | |
| } else { | |
| $bits[] = "The Demand chain has " . $arb_n . " arbitration" . ( $arb_n === 1 ? '' : 's' ) | |
| . " and " . $event_n . " acceptance event" . ( $event_n === 1 ? '' : 's' ) . " on record."; | |
| } | |
| // Mid-narrative annotations | |
| if ( isset( $patterns['no_plan'] ) && isset( $patterns['clean'] ) ) { | |
| $bits[] = "The Plan layer was bypassed (`scope-direct-no-plan`), suggesting an inline operational fix rather than a tracked work unit. Appropriate for small UX changes, but a recurring pattern would erode the Plan layer's value as a work-tracking signal."; | |
| } | |
| if ( isset( $patterns['multi_arb'] ) ) { | |
| $bits[] = "Multiple arbitrations on this Demand suggest the scope was re-interpreted at least once. Each re-arbitration is an opportunity for meaning to drift from the original demand-constraint."; | |
| } | |
| if ( isset( $patterns['dispute'] ) && ! isset( $patterns['open'] ) ) { | |
| $bits[] = "A dispute appeared earlier in the chain but was followed by an affirmation. Verify the dispute root cause was actually addressed, not merely time-elapsed."; | |
| } | |
| // Closing strategic verdict | |
| if ( ! empty( $audit['needs_human_arbitration'] ) ) { | |
| $bits[] = "Strategy interpretation: this trace requires human arbitration before closure can be trusted. The deterministic audit has flagged this; Strategy Review concurs."; | |
| } elseif ( isset( $patterns['clean'] ) ) { | |
| $bits[] = "Strategy interpretation: routine resolution. No further action required."; | |
| } else { | |
| $bits[] = "Strategy interpretation: defer to the deterministic audit's confidence rating before treating this Demand as resolved."; | |
| } | |
| return implode( ' ', $bits ); | |
| } | |
| private function identify_additional_risks( $arbs, $links, $events, $trace ) { | |
| $risks = []; | |
| // Scope-direct-no-plan as a recurring shortcut | |
| foreach ( $arbs as $a ) { | |
| if ( ( $a->projection_type ?? null ) === 'scope-direct-no-plan' ) { | |
| $risks[] = "Pattern shortcut watch: 'scope-direct-no-plan' arbitration may indicate a class of Demand that routinely bypasses Plan tracking. Recommend monitoring its frequency to catch systemic Plan-layer underuse."; | |
| break; | |
| } | |
| } | |
| // Reconstruction-then-affirmation | |
| $has_derived = false; | |
| foreach ( $arbs as $a ) { | |
| if ( ( $a->truth_class ?? null ) === 'derived' ) { $has_derived = true; break; } | |
| } | |
| $has_affirm = false; | |
| foreach ( $events as $e ) { | |
| if ( ( $e->event_type ?? null ) === 'acceptance_affirmed' ) { $has_affirm = true; break; } | |
| } | |
| if ( $has_derived && $has_affirm ) { | |
| $risks[] = "Reconstruction-then-affirmation: the Demand was reconstructed from Plan-side evidence and later affirmed. Verify the affirming actor saw the original Demand intent, not just the Plan they were asked to validate."; | |
| } | |
| // Stale affirmation: long gap between claim and affirm | |
| $claim_time = null; | |
| $affirm_time = null; | |
| foreach ( $events as $e ) { | |
| if ( ( $e->event_type ?? null ) === 'result_claimed' && $claim_time === null ) { | |
| $claim_time = strtotime( (string) $e->observed_at ); | |
| } | |
| if ( ( $e->event_type ?? null ) === 'acceptance_affirmed' ) { | |
| $affirm_time = strtotime( (string) $e->observed_at ); | |
| } | |
| } | |
| if ( $claim_time && $affirm_time ) { | |
| $delta_days = ( $affirm_time - $claim_time ) / 86400; | |
| if ( $delta_days > 30 ) { | |
| $risks[] = sprintf( | |
| "Stale affirmation: %d days between result_claimed and acceptance_affirmed. The stakeholder's confirmation may not reflect current state.", | |
| (int) round( $delta_days ) | |
| ); | |
| } | |
| } | |
| // Plan complexity | |
| if ( count( $links ) > 2 ) { | |
| $risks[] = "Plan complexity: this Demand fans out to " . count( $links ) . " plan refs. Verify each sub-plan is individually traceable to the original demand-constraint."; | |
| } | |
| // Long event chain | |
| if ( count( $events ) >= 4 ) { | |
| $risks[] = "State-transition complexity: " . count( $events ) . " acceptance events on this Demand. Each transition is an opportunity for meaning to drift; review for chain coherence."; | |
| } | |
| return $risks; | |
| } | |
| private function determine_agreement( $additional_risks, $audit ) { | |
| // The simulated layer reads the same data — it does not contradict the audit's | |
| // factual findings. Agreement is 'true' when nothing additional is identified; | |
| // 'partial' when extra risk dimensions are added but the audit's findings stand. | |
| if ( count( $additional_risks ) === 0 ) { | |
| return 'true'; | |
| } | |
| return 'partial'; | |
| } | |
| private function suggest_next_action( $audit_conf, $trace, $needs_hum, $extra_risk_count ) { | |
| if ( $needs_hum ) { | |
| return "Escalate to human arbiter. The deterministic audit has flagged this trace as requiring human review; Strategy Review concurs that closure cannot be trusted without it."; | |
| } | |
| $closure_basic = $trace['closure_state_basic'] ?? null; | |
| if ( $audit_conf === 'high' && $extra_risk_count === 0 ) { | |
| return "No further action needed; routine closure."; | |
| } | |
| if ( $audit_conf === 'high' && $extra_risk_count > 0 ) { | |
| return "Closure is sound. Optionally surface the additional risks above to the relevant stakeholders for awareness; no blocking action required."; | |
| } | |
| if ( $audit_conf === 'medium' ) { | |
| return "Closure is sound but with notable history. Recommend a follow-up audit in 30 days to confirm the resolution held."; | |
| } | |
| if ( $audit_conf === 'low' && $closure_basic === 'closed' ) { | |
| return "Closure is recorded but not authoritative. Drive to stakeholder affirmation before treating as final."; | |
| } | |
| if ( $audit_conf === 'low' && is_string( $closure_basic ) && strpos( $closure_basic, 'open:' ) === 0 ) { | |
| return "Demand is open. Drive to result_claimed and stakeholder affirmation; or escalate if blocked."; | |
| } | |
| if ( $audit_conf === 'n/a' ) { | |
| return "Demand has no acceptance events. Either drive through claim → affirmation, or close as scope-direct-no-plan if no work is owed."; | |
| } | |
| return "Review the deterministic audit's recommendations and the human-arbitration flag before next action."; | |
| } | |
| private function compute_confidence( $audit_conf, $extra_risk_count, $needs_hum ) { | |
| if ( $needs_hum ) return 'low'; | |
| if ( $audit_conf === 'high' && $extra_risk_count === 0 ) return 'high'; | |
| if ( $audit_conf === 'high' && $extra_risk_count <= 2 ) return 'medium'; | |
| if ( $audit_conf === 'medium' ) return 'medium'; | |
| if ( $audit_conf === 'n/a' ) return 'low'; | |
| return 'low'; | |
| } | |
| } | |