feat: conversation review — a nightly report on a supervised person's conversations
Nightly Build / build (push) Successful in 7m40s

The first AgentScope::PerSubject system agent, and the reason that scope
exists. Once a night, for each person with a supervision edge, it reads every
message that person and the assistant exchanged since the previous review —
across all their conversations — and writes one report for the people who
supervise them.

Schema (all registry except reports):
- supervision(subject_user_id, supervisor_user_id): the generic §0.1 edge,
  answering both 'whom does a background agent look at' and 'who may read
  what it produced', with real FKs so deleting a user cascades both ways
- system_agent_coverage(agent_id, subject_user_id, covered_through): the
  per-subject watermark that makes 'everything since last time' a window —
  neither system_agent_runs (history for humans) nor system_agent_state
  (advances before the work), and advanced only on a completed pass so a
  crash re-covers instead of skipping
- reports (owner schema, the second two-homes table after memory_docs):
  instance rows land in system.db, deliberately cleartext to the box owner,
  who is the intended reader (§2); the subject cannot see them structurally

The pass reads the subject's database inside a supervisor's runtime, so the
ephemeral session and run row land in the watcher's file; iteration is over
subjects, so two parents watching one child get one review; and the subject
need not be logged in when their space is unencrypted — via the new
UserManager::open_unencrypted, which refuses an encrypted user outright (no
key to be had) and never registers the pool as unlocked.

The agent declares the new AgentMeta flag allow_tools: false, so its turn
gets an empty tool registry — nothing for a prompt injection in the
transcript to call — and produces its report as its final assistant message,
read back from chat_history and parsed (NOTHING_TO_REPORT sentinel, no row on
quiet days). chat_history::conversation_window is the transcript query; its
four filters (non-ephemeral, depth 0, non-synthetic, non-empty) each guard a
specific way the review would otherwise be wrong, and tool calls are absent
by construction.

Cadence is Run at (hour) rather than Interval — 4am local by default — with
due-ness answered inside has_work against the coverage watermark, so a
machine off for three days covers the whole stretch in one pass. Reports
announce ReportCreated on the system bus (no subscriber yet). run_ephemeral_turn
gains a per-pass system_substitutions map, which the review uses to hand the
model the subject's profile under __SUBJECT_PROFILE__ — the system-context
substitutions describe the session owner, the wrong person here.

docs/system-agents.md gains the conversation review section; CLAUDE.md
documents the scope, the tables and the tool-less design.
This commit is contained in:
2026-08-02 20:30:27 +01:00
parent e6818408cb
commit 4f10528368
19 changed files with 2394 additions and 35 deletions
+19
View File
@@ -0,0 +1,19 @@
{
"name": "Conversation review",
"description": "Hidden background agent. Spawned nightly by the system-agent scheduler, once per supervised person, running inside the runtime of one of their supervisors. Reads a transcript of everything that person and the assistant said to each other since the previous review — handed to it in the trigger message, across all their conversations — and answers with a single written report. It has no tools of any kind and reaches nothing: no filesystem, no memory, no connectors, no notifications. Its answer IS the report; the caller stores it. Ephemeral session.",
"friendly_description": "A nightly read of the conversations of the people you supervise. It goes through everything said since the last review — across every chat, not one report per chat — and writes you a short summary followed by what it noticed. It only reads and writes: it cannot open a file, look anything up, or act on what it finds.",
"i18n": {
"it": {
"name": "Revisione delle conversazioni",
"friendly_description": "Una lettura notturna delle conversazioni delle persone che segui. Ripercorre tutto quello che è stato detto dall'ultima revisione — su tutte le chat, non un rapporto per chat — e ti scrive un riassunto breve seguito da ciò che ha notato. Sa solo leggere e scrivere: non può aprire file, cercare nulla, né agire su quello che trova."
},
"fr": {
"name": "Revue des conversations",
"friendly_description": "Une lecture nocturne des conversations des personnes que vous suivez. Elle reprend tout ce qui a été dit depuis la dernière revue — sur toutes les discussions, pas un rapport par discussion — et vous écrit un court résumé suivi de ce qu'elle a remarqué. Elle ne sait que lire et écrire : elle ne peut ni ouvrir un fichier, ni rechercher quoi que ce soit, ni agir sur ce qu'elle trouve."
}
},
"type": "system",
"inject_skills": false,
"allow_tools": false,
"strength": "high"
}