flowchart LR
subgraph macs [Every Mac, 23:55]
C1[collect: Claude Code + Cursor transcripts, plans, todos, file sweep]
end
C1 --> SN[(worklog snapshots via Syncthing)]
subgraph hub [mac-studio, 02:30 · retry 03:30]
C2[collect] --> AG[aggregate Work Monitor]
AG --> SC[register scan]
SC --> EV[evidence dossier per project]
EV --> AS[Partitur project-monitor ×60, parallel]
AS --> BR[Partitur project-monitor-briefing]
BR --> RP[registry/monitor/DAY.json]
end
SN --> EV
RP --> PG["/admin/monitor"]
Project Monitor
The Project Monitor answers one question at 4 a.m.: which projects need me today, and for what? Open it at /admin/monitor on the hub (publicly https://ai-platform.lettre.ai/admin/monitor; private projects are shown only on this Mac and the tailnet).
It is the single successor of three earlier approaches that tracked the same thing in parallel:
| Before | Problem | Now |
|---|---|---|
Projects-development register (projects-dev build, 05:40; scan every 2 h) |
Good facts, but the per-section audits were written without evidence of the actual work and read like generic goals; the 2-hourly scan collided with the catalog lock | Its scan stays as the project universe and fact source; its audit, render and the 2-hourly scan are no longer scheduled |
Morning Plan (projects-dev morning, 06:00) |
Superseded on 26 Sep 2026 but still running; noisy field diffs | Retired; /admin/morning redirects to the Project Monitor |
Work Monitor (worklog) |
Session-centred, not project-centred; the aggregator ran on openscience while mac-studio — where most agent work happens — did not report at all | Its collector feeds the monitor; the hub host (mac-studio) is now the only aggregator |
ai-projects (port 5065) keeps managing tasks for its publication projects; the monitor reads its open tasks.
The nightly chain
One launchd job, com.ai-platform.project-monitor, runs ae-platform monitor nightly --if-missing at 02:30; the 03:30 slot runs again only when the 02:30 report is missing or incomplete. A full run takes about four minutes (60 assessments, 8 in parallel). Each step is recorded with its time and result and shown in the Pipeline section of the page; a failing step never stops the following ones (a failed scan falls back to the previous facts).
What the monitor reads
Every project gets a dossier. Each item has an id that the assessment must cite:
| Id | Source |
|---|---|
S1… |
Agent sessions of the last 14 days from every Mac: the owner’s prompts, the agent’s last reports, plans, todos not completed, failed tool calls. A session counts for a project when most of its file work (writes ×3, paths in shell commands, files read) lies in the project folder; a session that mainly served another project is marked “context only”. |
W1… |
Work items of the Work Monitor (owner-set status, notes and next steps win) |
D1… |
Project documents: STATUS.md, ROADMAP.md, TODO.md/NEXT.md (open checkboxes), issues.yml (open issues), a confirmed PROJECT.yaml, otherwise the README |
M1… |
Claude Code agent memories that mention the project |
T |
Open ai-projects tasks |
F |
File activity from one walk of the umbrella (24 h / 7 d / 30 d, newest code and doc files) |
Projects are the register’s projects, the top-level LWgrammar, and every PDAI collection (pdai:<name>, code in pdai/collections/ and data on PDAI-1). The 60 liveliest projects are assessed; the rest are listed as Not assessed tonight when they showed any file activity in the last 90 days.
Attention classes
| Class | Meaning |
|---|---|
| Needs your decision | Waits for an answer, approval, credentials, quota or material only you can supply |
| Ready to start | Planned or requested, implementation has not begun |
| Stalled — resume | Stopped half-way: open todos, unfinished plan, failed run, or a complaint not yet fixed, idle 2+ days |
| Ready to conclude | Built; verify, render, publish or close |
| Running | Progressing; nothing waits for you |
| Quiet | No meaningful work and nothing open |
The judgement is made by the Partitur flows/register/project_monitor.yaml in ai-agent-orchestrator (runtime gemini-3.8-flash, the default Gemini model since 20 Oct 2026); the morning summary and the five first things to do come from project_monitor_briefing.yaml. Python only gathers evidence and checks the answer: every open issue, next step or result that cites no evidence id present in the dossier is removed before display. Private projects (privat/, privatkanzlei, korrespondenz) never enter the briefing.
Recording: what changed for complete activity capture
- Claude Code in VS Code Insiders is read in full: subagent transcripts,
Agent,TodoWrite,ExitPlanMode(plan text),AskUserQuestion, failed tool results (Claude Code stores them, unlike Cursor), the agent’s report at the end of every turn, and the paths named in shell commands — most edits in these sessions run through Bash, so Write/Edit paths alone missed most projects. - mac-studio now records (it reported nothing before); mac-mini got the collector and audit daemon. mac-air still needs
scripts/install-worklog.shwhen it is online. - The aggregator runs only on the hub host, so two machines no longer write the same Work Monitor report.
Commands
ae-platform monitor nightly # the whole chain now
ae-platform monitor nightly --skip-collect # reassess only, from existing snapshots and facts
ae-platform monitor nightly --only development/famulus-proof
ae-platform monitor dossier development/famulus-proof # what the assessment sees
ae-platform monitor show # latest report as markdown
scripts/install-worklog.sh --hub # hub host: audit daemon + Project Monitor job
scripts/install-worklog.sh # every other Mac: collector + audit daemonOutput: platform/registry/monitor/<day>.json, latest.json, latest.md; API /api/monitor/report?day=, /api/monitor/days. Logs: platform/logs/project-monitor.{out,err}.log.
Landing backends
A second nightly job controls whether the landing pages’ backends work, not only whether they answer. ae-platform landings nightly (launchd com.ai-platform.landing-health, 02:10, hub host only) builds its task list every night from three sources:
config/landings.yaml, the register of landing pages;- the live public pages on GitHub Pages, read for every
https://lettre.ngrok.devlink they carry; config/routes.yaml, which tells which machine serves a path and how the proxy rewrites it.
A link that appears on a landing page tomorrow is therefore checked tomorrow, with no list to maintain. Each backend function is probed twice, at its origin (openscience or mac-studio directly) and publicly through ngrok, and curl’s timings are kept (connect, first byte, total).
| Backend | Functions checked |
|---|---|
| edition viewer | registered documents (an empty registry is the known Registered documents: 0 failure), document viewer, thumbnail, facsimile (a 404 “No smaller derivative” falls back to the master, as the viewer does), transcript XML, Bedeutung frame, dossiers page |
| Kármán archive | archive summary, facsimile, transcript, Bedeutung frame, dossiers page |
| glider, notebook, mitanni | /api/health with content (glider: searchable collections) |
| notebooks | the notebook content behind every ?nb= link |
| newsletter | manifest, and the subscribe form’s CORS preflight from famulus.lettre.ai |
| every openscience child | start page, plus the edition functions above |
The openscience host is read over SSH:
- the editions supervisor and each child: running, waiting or restarting;
- load, free disk and memory, and its own proxy;
- every edition registry: how many registered document paths are missing on its disk;
- code files changed after the supervisor started, which means a restart is needed because Syncthing delivered new code to an old process.
When a function fails on openscience, the same request goes to mac-studio. The finding then says whether the cause lies on openscience only or everywhere.
Findings. A finding names a cause, not each symptom.
- One per edition when its pages are missing on openscience.
- One for all collections whose Bedeutung is not prepared.
- A child that is down absorbs the findings of its route.
- slow: over the budget in
config/landing_health.yaml. - slower than usual: more than twice the median of the last 14 nights and at least 0.5 s more. This needs 3 nights of history in
registry/health/landing_health.duckdb. - fallback: a public request was answered by mac-studio instead of openscience.
Rules that keep the findings honest:
- A failed function is asked once more, two seconds later and alone. A failure that does not repeat (a database lock held by a writer, a busy machine) is noted in the row, not reported.
- A function over its budget is measured once more alone, and the faster answer counts. The batch runs eight requests at a time and can slow itself down.
- Image and transcript checks follow the viewer’s own fallbacks: the next leaf when the first has no scan, the master when no smaller derivative exists,
.pngor.jpg. - A child stopped with
editionsctl stopis intended, and so is a waiting child whose route no longer names openscience.
Routing decision (owner, 20 Oct 2026). openscience holds only the landing editions (scripts/build_pdai_collection_server.py). The routes whose data it lacks are served by mac-studio as primary, and their children on openscience are stopped. These are library, kirch, rock-art, phototechnology, architektur-antik, babylonian-astronomy, wissenschaftstheorie, waterclocks, pirckheimer, glider and lemma-search. The old routes file is kept in ~/Library/Application Support/ai-platform/backups/.
Mail. Open findings are mailed to the owner. The sender is the first one in config/landing_health.yaml whose password is in the Keychain: the Famulus News Gmail App Password, else the HU account of the Privatkanzlei mail service. A run that fails itself is mailed too.
Acknowledging. A known finding can be listed under known: with an id, a reason and an end date. It is then shown but not mailed until that date; an entry without an end date is ignored.
Where to see it. The task list with status and times is in the section Landing backends of /admin/monitor, in registry/health/latest.md and in /api/monitor/landing-health.
ae-platform landings nightly # probe, assess, record, report, mail open findings
ae-platform landings nightly --no-mail # the same without the mail
ae-platform landings nightly --only euler kepler # a quick look at some landings (no history, no report)
ae-platform landings show # latest task list and findingsCode: src/ai_platform/health/ (probe, catalog, host, assess, mailer, nightly), tests tests/test_landing_health.py. Logs: platform/logs/landing-health.{out,err}.log.
Limits
- An agent’s closing report is a claim, not a verification. The assessment treats a later complaint or repeated request as evidence that the problem is still open, but it cannot run the project’s tests.
- File activity counts generated data and sync arrivals as well as edits; it is a signal of life, not of progress.
- A session that touched no project folder (questions, machine care, mail) appears under Sessions without a project.