Governancemaintenance - Source Excerpt 02
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Services/GovernanceMaintenance.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Services/GovernanceMaintenance.php
'queue_counts' => $queue_counts,
'stale_review_items' => array_slice($stale_review_items, 0, 10),
'urgent_review_items' => array_slice($urgent_review_items, 0, 10),
'stale_appeal_items' => array_slice($stale_appeal_items, 0, 10),
'automatic_fallback_items' => array_slice($automatic_fallback_items, 0, 10),
'limit' => $limit,
];
update_option(self::LAST_RUN_OPTION, $summary, false);
$this->audit->log(null, 'governance_maintenance_run', 'workspace', null, $summary);
return $summary;
}
/**
* Applies reversible automatic governance fallback during moderator absence.
*
* @param array<string,mixed> $prompt
* @param array<string,mixed> $review_summary
* @param array<string,mixed> $appeal_summary
* @param array<string,mixed> $governance_summary
* @return array<string,mixed>
*/
private function apply_automatic_fallback(array $prompt, array $review_summary, array $appeal_summary, array $governance_summary): array
{
$current = PromptMetaRegistry::normalize_moderation_status((string) ($prompt['moderation_status'] ?? 'draft'));
$target = $this->resolve_automatic_fallback_status($prompt, $review_summary, $appeal_summary, $governance_summary);
if ($target['status'] === '' || $target['status'] === $current) {
return [];
}
$updated = $this->prompts->set_moderation_status((int) ($prompt['id'] ?? 0), $target['status']);
if (empty($updated)) {
return [];
}
$this->audit->log(
null,
'prompt_governance_automatic_fallback',
'prompt',
(int) ($prompt['id'] ?? 0),
[
'from' => $current,
'to' => $target['status'],
'reason' => $target['reason'],
'trigger' => $target['trigger'],
'summary' => $review_summary,
'appeal_summary' => $appeal_summary,
]
);
return [
'prompt' => $updated,
'from' => $current,
'to' => $target['status'],
'reason' => $target['reason'],
'trigger' => $target['trigger'],
'action_kind' => $target['action_kind'],
];
}
/**
* Resolves scheduled fallback state from peer signals, reports, risk, and queue age.
*
* @param array<string,mixed> $prompt
* @param array<string,mixed> $summary
* @param array<string,mixed> $appeal_summary
* @param array<string,mixed> $governance_summary
* @return array{status:string,reason:string,trigger:string,action_kind:string}
*/
private function resolve_automatic_fallback_status(array $prompt, array $summary, array $appeal_summary, array $governance_summary): array
{
$visibility = (string) ($prompt['visibility'] ?? 'private');
$prompt_status = (string) ($prompt['prompt_status'] ?? 'draft');
$current = PromptMetaRegistry::normalize_moderation_status((string) ($prompt['moderation_status'] ?? 'draft'));
$empty = [
'status' => '',
'reason' => '',
'trigger' => '',
'action_kind' => '',
];
if ($visibility !== 'public' || $prompt_status !== 'published' || $current === 'archived') {
return $empty;
}
if ((string) ($appeal_summary['latest_resolution'] ?? '') === 'archive') {
return [
'status' => 'archived',
'reason' => 'Latest steward appeal resolution archived the prompt.',
'trigger' => 'appeal_archive_resolution',
'action_kind' => 'auto_archived_by_appeal',
];
}
$peer = is_array($summary['peer'] ?? null) ? (array) $summary['peer'] : [];
$restrict = (int) ($peer['restrict'] ?? 0);
$revert = (int) ($peer['revert'] ?? 0);
$endorse = (int) ($peer['endorse'] ?? 0);
$unique_reporters = (int) ($summary['unique_reporters'] ?? 0);
$reports_total = (int) ($summary['reports_total'] ?? 0);
if ($revert >= self::PEER_REVERT_QUORUM) {
return [
'status' => 'reverted',
'reason' => 'Peer reversion quorum was met during scheduled maintenance.',
'trigger' => 'revert_quorum',
'action_kind' => 'auto_reverted_by_quorum',
];
}
if ($restrict >= self::PEER_RESTRICT_QUORUM || $unique_reporters >= self::REPORT_RESTRICTION_QUORUM) {
return [
'status' => 'restricted_review',
'reason' => 'Restriction or report quorum was met during scheduled maintenance.',
'trigger' => $restrict >= self::PEER_RESTRICT_QUORUM ? 'restrict_quorum' : 'report_quorum',
'action_kind' => 'auto_restricted_by_quorum',
];
}
if ($endorse >= self::PEER_ENDORSE_QUORUM) {
return [
'status' => (string) ($prompt['publication_lane'] ?? 'community_library') === 'official_canon'
? 'official_canon'
: 'peer_reviewed',
'reason' => 'Peer endorsement quorum was met during scheduled maintenance.',
'trigger' => 'endorsement_quorum',
'action_kind' => 'auto_promoted_by_quorum',
];
}
if ($current !== 'provisional_public') {
return $empty;
}
$queue_age = is_array($governance_summary['queue_age'] ?? null) ? (array) $governance_summary['queue_age'] : [];
$hours_since_activity = (int) ($queue_age['hours_since_activity'] ?? 0);
if ($reports_total >= 2 && $hours_since_activity >= self::STALE_REPORTED_RESTRICTION_HOURS) {
return [
'status' => 'restricted_review',
'reason' => 'Reported provisional prompt had no governance activity after the stale-review window.',
'trigger' => 'stale_reported_prompt',
'action_kind' => 'auto_restricted_by_absence',
];
}
if ($reports_total >= 1 && $hours_since_activity >= self::URGENT_REPORTED_RESTRICTION_HOURS) {
return [
'status' => 'restricted_review',
'reason' => 'Reported provisional prompt reached the urgent-review window without resolution.',
'trigger' => 'urgent_reported_prompt',
'action_kind' => 'auto_restricted_by_absence',
];
}
if ($hours_since_activity >= self::URGENT_RISK_RESTRICTION_HOURS && $this->has_high_risk_label($prompt)) {
return [
'status' => 'restricted_review',
'reason' => 'High-risk provisional prompt reached the urgent-review window without peer judgment.',
'trigger' => 'urgent_high_risk_prompt',
'action_kind' => 'auto_restricted_by_absence',
];
}
return $empty;
}
/**
* Returns whether a prompt carries labels that should slow down during moderator absence.
*
* @param array<string,mixed> $prompt
*/
private function has_high_risk_label(array $prompt): bool
{
$risk_labels = array_values(array_map('strval', (array) ($prompt['risk_labels'] ?? [])));
return !empty(array_intersect($risk_labels, self::HIGH_RISK_LABELS));
}
/**
* Returns a compact item describing an automatic fallback transition.
*
* @param array<string,mixed> $prompt
* @param array<string,mixed> $fallback
* @param array<string,mixed> $governance_summary
* @return array<string,mixed>
*/
private function automatic_fallback_item(array $prompt, array $fallback, array $governance_summary): array
{
$queue_age = is_array($governance_summary['queue_age'] ?? null) ? (array) $governance_summary['queue_age'] : [];
return [
'prompt_id' => (int) ($prompt['id'] ?? 0),
'prompt_title' => (string) ($prompt['title'] ?? ''),
'prompt_slug' => (string) ($prompt['slug'] ?? ''),
'from' => (string) ($fallback['from'] ?? ''),
'to' => (string) ($fallback['to'] ?? ''),
'reason' => (string) ($fallback['reason'] ?? ''),
'trigger' => (string) ($fallback['trigger'] ?? ''),
'hours_since_activity' => (int) ($queue_age['hours_since_activity'] ?? 0),
'duration_label' => (string) ($queue_age['duration_label'] ?? ''),
'updated_utc' => gmdate('c'),
];
}
/**