- Fix 1 (ORDER BY): use table alias t.id to force integer PK ordering;
topic_id alias was causing alphabetical sort, breaking rotation offsets
- Fix 2 (PDOException): wrap INSERT/UPDATE in try/catch in kb_topic_save;
duplicate topic_id now returns clean JSON error instead of HTTP 500
- Fix 3 (XSS/onclick): DEL button passes only t.id; tmDelete looks up
name from _topicsData, removing JSON.stringify from onclick attribute
- Fix 4 (validation): topic_id must contain at least one [a-z0-9] after
sanitization; "@@@" to "___" no longer passes required-field check
- Fix 5 (stale logs): guard comment and log messages updated from 20h to
4h to match the actual 14400s threshold
- Fix 6 (dedup): tmEsc() replaced with existing esc() throughout; removed
duplicate function definition
- Fix 7 (toggle rollback): tmToggle uses inline fetch to revert el.checked
on API failure instead of leaving the UI in wrong state
- Fix 8 (confirm): tmDelete uses openModal confirmation instead of
confirm() dialog, consistent with project live-popup convention
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014p87VFec84hNaf2WpvmLrW
- Create kb_generator_topics table (140 topics migrated from hardcoded array)
- kb_intent_generator.php now loads active topics from DB instead of $BATCHES array
- Admin panel: MANAGE TOPICS button opens full topic manager modal
- Browse all 140 topics with search, category, and active/disabled filters
- Inline active toggle per topic (checkbox)
- Add new topic form (topic_id, category, name, description)
- Edit existing topics (all fields)
- Delete topics with confirmation
- Run count display
- Backend API cases: kb_topics, kb_topic_save, kb_topic_delete, kb_topic_toggle
- Topics can now be added/managed without any code changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014p87VFec84hNaf2WpvmLrW
Rich topic library across mathematics (12), sciences (13), history (10),
government/economics, literature, life skills (13), technology (5),
Texas/local (4), national US (3), world affairs (5), human sexuality (2),
astronomy (3), space (2), culture/arts (8), sports (8), food/drink (4),
home/DIY (3), wellness (4), tech continued (3), national continued (2),
world continued (2), medicine (3), math continued (2), communication (2).
Each topic has detailed multi-subtopic descriptions (~200 chars each)
vs prior 8-word descriptions — significantly richer Groq prompts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014p87VFec84hNaf2WpvmLrW
- Expanded $BATCHES from 25 to 122 topics across: life skills, personal
finance, Texas/local, US national, world geopolitics, human sexuality
(educational), deep astronomy (15 topics), and space exploration (15 topics)
- Rotation engine: 25 topics per run cycling through all 122 in order;
wraps to topic 1 on cycle complete (~30h full cycle at 6h interval)
- batch_offset tracked in kb_facts for cross-run persistence
- Cron changed from 0 3 * * * to 0 */6 * * * (every 6 hours)
- 20h skip guard reduced to 4h so 6h cron isn't blocked
- max_tokens bumped 3500 → 5000 to prevent JSON truncation errors
- JSON extraction: partial recovery + raw snippet logged on failure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014p87VFec84hNaf2WpvmLrW
Token budget was too low for 40 intents — responses were truncated mid-JSON,
causing "No JSON array found" on ~88% of batches. Fixes 880 errors/run.
Also adds partial-JSON truncation recovery and raw response debug logging.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014p87VFec84hNaf2WpvmLrW
- Always runs when triggered from admin (JARVIS_FORCE_RUN=1 bypasses 20h guard)
- Closing popup stops UI polling but server job continues; toast confirms background run
- History panel at top of popup shows last success time/count + failures from last 7 days
- New intent_gen_history backend case parses cron.log for status summary
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014p87VFec84hNaf2WpvmLrW