Spaces:
Sleeping
Sleeping
File size: 5,016 Bytes
f51c224 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | <?php
defined( 'ABSPATH' ) || exit;
/**
* Actor Handoff Log β two-axis attribution (Board #23).
*
* Provides a clear, auditable boundary between AI-operated actor mode
* and human-operated actor mode WITHOUT mutating Fluent's own comment
* tables. Strictly additive: a small dedicated table records who
* "pressed send" for a given actor-authored comment.
*
* The two axes:
* created_by β the actor (Bridget, etc.). The displayed author. Unchanged.
* committed_by β the user who pressed send (a human user, or an agent
* service account user). Recorded here, queried via
* SA_Orch_Actor_Handoff::get_committer().
*
* Operator-mode detection β the full provenance chain works once Board #16
* (Token + Usage Visibility) ships its LLM token log. Until then, the
* token-presence check returns 'unknown' and detect_mode reflects that
* honestly:
*
* committer recorded + token row found β 'ai'
* committer recorded + token row NOT found β 'human'
* committer recorded + token state unknown β 'unknown' (pre-#16; honest)
* committer NOT recorded β 'unknown'
*
* The token-presence check is implemented as a filter:
*
* apply_filters( 'sa_orch_handoff_has_llm_token', null, $kind, $comment_id );
*
* Board #16 will register a callback that consults the token log. The
* default return of null means "unknown" β never a false positive.
*
* Doctrine constraints honored:
* - Actors remain non-binding; this layer is observational, not enforcing
* - No impact to Board progression rules
* - No schema refactors β strictly additive (one new table)
* - No Asterion writes
* - No automation
* - No UI surface beyond what already exists
*/
class SA_Orch_Actor_Handoff {
const KIND_FLUENT_BOARDS = 'fluent_boards';
const KIND_FLUENT_SUPPORT = 'fluent_support';
const MODE_AI = 'ai';
const MODE_HUMAN = 'human';
const MODE_UNKNOWN = 'unknown';
private static function table(): string {
global $wpdb;
return $wpdb->prefix . SA_ORCH_DB_PREFIX . 'actor_handoff';
}
/**
* Record (or update) the committer for an actor-authored comment.
* Idempotent on (kind, comment_id) β re-recording replaces the prior row.
*
* Returns true on success, false on invalid input or DB failure.
*/
public static function record_committer( string $kind, int $comment_id, int $committed_by_user_id ): bool {
if ( $comment_id <= 0 || $committed_by_user_id <= 0 ) {
return false;
}
$kind = sanitize_key( $kind );
if ( $kind === '' ) return false;
global $wpdb;
$tbl = self::table();
// Replace prior row, if any. Keeps the table thin.
$wpdb->delete( $tbl, [
'comment_kind' => $kind,
'comment_id' => $comment_id,
] );
$ok = $wpdb->insert( $tbl, [
'comment_kind' => $kind,
'comment_id' => $comment_id,
'committed_by_user_id' => $committed_by_user_id,
'recorded_at' => current_time( 'mysql', true ),
] );
return $ok !== false;
}
/**
* Get the recorded committer for a comment, or null if none recorded.
*/
public static function get_committer( string $kind, int $comment_id ): ?int {
if ( $comment_id <= 0 ) return null;
$kind = sanitize_key( $kind );
if ( $kind === '' ) return null;
global $wpdb;
$row = $wpdb->get_var( $wpdb->prepare(
"SELECT committed_by_user_id FROM " . self::table() . "
WHERE comment_kind = %s AND comment_id = %d
ORDER BY id DESC LIMIT 1",
$kind,
$comment_id
) );
return $row !== null ? (int) $row : null;
}
/**
* Detect operator mode for a comment. Returns one of the MODE_* constants.
* Never lies about uncertainty β returns 'unknown' rather than guessing.
*/
public static function detect_mode( string $kind, int $comment_id ): string {
$committer = self::get_committer( $kind, $comment_id );
if ( $committer === null ) {
return self::MODE_UNKNOWN;
}
/**
* Filter that signals whether an LLM token row exists for this commit.
* Returns: true (token row found β AI mode),
* false (no token row β human mode),
* null (unknown β token log not yet integrated, default).
*
* Board #16 will register a callback that consults the token log.
*/
$token_present = apply_filters(
'sa_orch_handoff_has_llm_token',
null,
$kind,
$comment_id
);
if ( $token_present === null ) return self::MODE_UNKNOWN;
if ( $token_present === true ) return self::MODE_AI;
return self::MODE_HUMAN;
}
}
|