feat: a "Run now" button for the memory lints — one pass, for whoever asked
Nightly Build / build (push) Successful in 7m33s
Nightly Build / build (push) Successful in 7m33s
The two memory lints run weekly, which is right for maintenance and wrong for the moment somebody has just reorganised their notes and wants to know what the lint makes of them. Each agent's tab now carries a button that starts one pass immediately, for the caller. It runs as the caller — their pool, their sessions, their hub — so the report lands with the person who asked. The shared lint is the interesting case: its scheduled pass runs as the admin because the shared store belongs to nobody, but a member pressing the button reads the same store and gets the report themselves, which is coherent with shared memory being readable by every member anyway. Two settings are treated differently on purpose. Due-ness is skipped, exactly as manual /compact skips the compactor's token threshold: the interval answers *when*, and a human asking is a good enough answer to that. The Enabled switch is honoured: it answers *whether*, and that one is the admin's. The conversation review gets no button (AgentScope::PerSubject): it is about somebody else and picks its own subjects, so "run it for me" has no meaning. The frontend reads that from the agent's scope, not from a list of ids. A second starter breaks an invariant the scheduler used to hold for free. system_agent_runs::start sweeps any leftover `running` row of the same agent to `failed` before inserting, which was safe only because one sequential loop was the only thing that ever started a pass; a manual run overlapping a scheduled one would have marked a healthy run as interrupted and duplicated its work. So the agent list moves out of the scheduler and onto Skald as SystemAgents, which holds the registry plus an in-flight guard both paths claim through — keyed on what the pass is *about*, so an instance-wide agent is one slot no matter who runs it, and a per-subject review is keyed on the subject rather than on the supervisor lending the runtime. has_work is answered synchronously, before anything is spawned: it leaves no run row, so without that the button would say "started" over a log that never gains a row. Everything after it is spawned — a pass is an LLM turn, and no HTTP request should be held open for one. The run row exists before the browser is answered, so the log itself is the progress surface; the page polls it quietly until the pass leaves `running`.
This commit is contained in:
+14
-1
@@ -44,7 +44,7 @@ There are two of them because the two stores are not the same job.
|
||||
|
||||
**Shared memory lint** runs once over the group's shared store, and looks for one extra thing that only exists there: **a note that fails the table rule** — one person's private business written somewhere every member can read. The rule is that something belongs in shared memory only if you would say it out loud with every member in the room; health, school results, money, worries and one member's opinion of another do not. When it finds one it says *which note* and *what kind of problem*, without repeating the sensitive content — restating it in a notification would spread it further, which is exactly the harm being flagged.
|
||||
|
||||
The shared store belongs to nobody in particular, so that pass runs **as the admin** and its report goes to them. That is about who can act on it, not about privacy: everything in shared memory is already readable by every member.
|
||||
The shared store belongs to nobody in particular, so the *scheduled* pass runs **as the admin** and its report goes to them. That is about who can act on it, not about privacy: everything in shared memory is already readable by every member — which is also why any member can press **Run now** on it and get the report themselves.
|
||||
|
||||
## Conversation review
|
||||
|
||||
@@ -93,6 +93,19 @@ Clicking a row opens the conversation the run happened in, for anyone who wants
|
||||
|
||||
A run appears **only when there was something to look at**. Long gaps mean quiet connectors or an untouched memory store, not a broken agent.
|
||||
|
||||
### Running one now
|
||||
|
||||
Each agent's tab has a **Run now** button, next to its description. It starts one pass immediately, for **you**, without waiting for the schedule — useful after tidying up a lot of notes, or when someone wants to see what an agent actually does instead of reading about it.
|
||||
|
||||
- It runs **as you**, over your own things, and reports to you. The shared memory lint is the interesting case: pressed by a member it reads the same shared store the admin's nightly pass reads, and the report simply goes to the member who asked instead of the admin.
|
||||
- **"Nothing to look at right now"** is a normal answer and arrives straight away — an empty memory store or an empty event queue starts no run at all, exactly like a scheduled pass that finds nothing.
|
||||
- The pass then runs in the background: the row appears in the log below as *running*, and the notification arrives when it is done. Leaving the page does not stop it.
|
||||
- Pressing it again while it is still going does nothing — one pass of one agent at a time, so a manual run and the nightly one can never collide.
|
||||
- Running it by hand **counts as that person's pass**: the next scheduled one is then a full interval away, rather than arriving an hour later.
|
||||
- An agent an admin has switched **off** cannot be started this way. The schedule is a question of *when*, which the button answers; enabled is a question of *whether*, which stays the admin's.
|
||||
|
||||
The conversation review has no button: it is about somebody else and picks its own subjects, so "run it for me" would not mean anything.
|
||||
|
||||
**The run history is personal.** Each run is written into that user's own encrypted database, so every user — the admin included — sees their own runs and nobody else's. There is no instance-wide view.
|
||||
|
||||
## What the admin can change
|
||||
|
||||
Reference in New Issue
Block a user