Phase 8: Mission Directives — OKR/goal tracking with AI review

- DB: directives, directive_key_results, directive_links tables
- reactor.py v8.0.0: directive_review handler — fetches active directives + KRs + links, Claude generates executive progress briefing, injects into conversations
- directives.php: new API endpoint (list/get/save/delete/key_result_update/link/summary)
- api.php: routes directives/* endpoint
- admin/index.php: Directives nav + tab — objective cards with progress bars, editor with multi-KR builder (title/current/target/unit), AI Review button per directive and global
- index.html: DIRECTIVES tab — collapsible objective cards with progress bars, KR counts, AI Review button, link to admin
- chat.php: Tier 0.9i directive review detection; daily briefing now includes active directive progress %

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 11:59:44 +00:00
parent b6c417948e
commit aaf07edacb
5 changed files with 690 additions and 1 deletions
+40
View File
@@ -760,6 +760,21 @@ if (!$reply) {
if ($ov > 0) $parts[] = $ov . ' overdue task' . ($ov > 1 ? 's' : '') . ' need attention';
$ai = (int)($email_actions['cnt'] ?? 0);
if ($ai > 0) $parts[] = $ai . ' email' . ($ai > 1 ? 's' : '') . ' require action';
// Include active directive progress summary
$active_dirs = JarvisDB::query(
"SELECT d.title,
COALESCE(SUM(kr.current_value),0) AS cur,
COALESCE(SUM(kr.target_value),1) AS tgt
FROM directives d
LEFT JOIN directive_key_results kr ON kr.directive_id=d.id
WHERE d.status='active'
GROUP BY d.id
ORDER BY d.priority DESC LIMIT 3"
) ?? [];
if ($active_dirs) {
$dp = array_map(fn($d) => $d['title'] . ' (' . round($d['cur'] / max($d['tgt'],1) * 100) . '%)', $active_dirs);
$parts[] = count($active_dirs) . ' active directive' . (count($active_dirs) > 1 ? 's' : '') . ': ' . implode(', ', $dp);
}
$reply = $parts
? "Good morning, {$userAddr}. " . implode('. ', $parts) . '.'
: "Good morning, {$userAddr}. Your schedule is clear — no tasks, appointments, or email actions pending today.";
@@ -1355,6 +1370,31 @@ if (!$reply) {
}
}
// ── Tier 0.9i: Directives — review objectives, progress check ─────────────────
if (!$reply) {
$dirReviewPatterns = [
'/^(?:jarvis[,\s]+)?(?:review\s+(?:my\s+)?(?:directives?|objectives?|goals?|OKRs?))/i',
'/^(?:jarvis[,\s]+)?(?:how\s+am\s+i\s+doing\s+on\s+(?:my\s+)?(?:directives?|objectives?|goals?))/i',
'/^(?:jarvis[,\s]+)?(?:directives?\s+(?:review|status|update|progress|briefing))/i',
'/^(?:jarvis[,\s]+)?(?:OKR\s+(?:review|update|status))/i',
'/^(?:jarvis[,\s]+)?(?:what(?:\'s|\s+is)\s+(?:my\s+)?(?:progress|status)\s+on\s+(?:my\s+)?(?:directives?|goals?|objectives?))/i',
];
foreach ($dirReviewPatterns as $pat) {
if (preg_match($pat, $message)) {
$arcRes = arcSubmitJob('directive_review', ['provider' => 'claude'], $sessionId);
if (isset($arcRes['job_id'])) {
$arcJobId = $arcRes['job_id'];
$reply = "◈ DIRECTIVE REVIEW INITIATED (Job #{$arcJobId}). I'm analyzing your active objectives and key results now, {$userAddr}. Stand by for your progress briefing.";
$source = 'arc:directive_review';
} else {
$reply = "Directive review is offline, {$userAddr}. Arc Reactor may be unavailable.";
$source = 'arc:offline';
}
break;
}
}
}
// ── Tier 1: Intent Engine (instant, no LLM) ───────────────────────────────
if (!$reply) {
$matched = KBEngine::match($message);