Files
the-custodian/docs/hourly-recently-on-scope-runbook.md

138 lines
3.6 KiB
Markdown

# Hourly RecentlyOnScope Runbook
## Purpose
This runbook answers whether the hourly RecentlyOnScope routine ran without
opening Codex Desktop.
The intended steady state is:
- activity-core owns the hourly schedule and ActivityRun audit trail.
- State Hub owns active-domain selection, report generation, report storage,
and the `recently_on_scope_hourly` progress event.
- Codex app automation is not part of the primary hourly reporting path after
`CUST-WP-0046-T06`.
## Schedule Check
From the activity-core host, confirm the definition is synced and the Temporal
schedule exists:
```bash
cd ~/activity-core
ACTIVITY_DEFINITION_DIRS=/home/worsch/the-custodian make sync-activity-definitions
make sync-schedules
```
Expected definition:
- name: `Hourly RecentlyOnScope Reports`
- trigger: `0 * * * *`
- timezone: `Europe/Berlin`
- misfire policy: `skip`
- enabled: `false` until manual canary passes, then `true`
## Temporal Check
Use the Temporal UI or CLI on the activity-core host to inspect schedules and
recent workflows.
Look for:
- a schedule for `Hourly RecentlyOnScope Reports`
- the most recent `RunActivityWorkflow`
- a successful workflow result with `tasks_spawned: 0`
A failure in the required State Hub context source should fail the workflow
visibly rather than recording an empty context.
## ActivityRun Check
Query the activity-core database for the most recent run of the hourly
definition:
```sql
select
run_id,
fired_at,
scheduled_for,
context_snapshot->'recently_on_scope_hourly' as batch_result
from activity_runs
where activity_id = 'd104348c-d792-4377-943c-70a31e81a9bc'
order by fired_at desc
limit 5;
```
The `batch_result` should include `generated`, `skipped`, `failed`, and
`progress_event_id`.
## State Hub Progress Check
Ask State Hub for the latest batch progress events:
```bash
curl -s "http://127.0.0.1:8000/progress/?event_type=recently_on_scope_hourly&limit=5" \
| python3 -m json.tool
```
Expected:
- `event_type`: `recently_on_scope_hourly`
- `author`: `state-hub`
- `detail.generated`: domains with qualifying activity
- `detail.skipped`: quiet active domains
- `detail.failed`: empty in the healthy case
## Report Check
List reports for a domain:
```bash
curl -s "http://127.0.0.1:8000/domains/custodian/recently-on-scope/" \
| python3 -m json.tool
```
Read a report:
```bash
curl -s "http://127.0.0.1:8000/domains/custodian/recently-on-scope/<report_id>"
```
Default report directory:
```text
~/state-hub/reports/recently-on-scope/<domain_slug>/
```
## Manual Batch Canary
Before enabling the hourly schedule, run:
```bash
curl -s -X POST "http://127.0.0.1:8000/recently-on-scope/hourly" \
-H "Content-Type: application/json" \
-d '{"range":"1h","active_only":true,"include_attention":false}' \
| python3 -m json.tool
```
Then trigger the activity-core path with the same payload and confirm an
ActivityRun captures the batch response under `recently_on_scope_hourly`.
## Offline Behavior
The schedule uses `misfire_policy: skip`.
If the activity-core host is offline at the top of the hour, that hourly run is
missed. When the host returns, activity-core should resume with the next hourly
slot rather than replaying stale runs in a burst.
## Retention
State Hub currently writes one Markdown report per domain and report id. Report
ids are deterministic for exact windows and are replaced on rerun. The current
implementation does not delete old reports automatically.
Until a retention job exists, operators should treat the report directory as an
append-only operational record and prune only after confirming that no audit or
handoff references point at the target files.