Files
10Backward/docs/guides/daily-run.md
T
2026-08-04 17:53:15 +00:00

119 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: guide
title: Daily Run Guide
description: Operator- and tester-focused walkthrough of one daily cron tick — startup, pipeline pass, silent-on-no-matches, and retry behaviour.
tags: [guide, run, daily, tester]
timestamp: 2026-08-04T17:51:00Z
---
# Purpose
A tester or operator needs to know **what should happen** each time
the cron tick fires. This guide describes the contract from the
outside of the container, in observable terms: log lines, exit codes,
files appearing on the volume, and the "silent on no matches"
behaviour that the runner enforces.
# Triggering a Run Manually
```bash
docker compose exec tenbackward /usr/local/bin/python -m tenbackward
```
This is the same command the container's cron entry issues once per
day at `RUN_AT`. Use it to verify behaviour without waiting for the
scheduled tick.
# What You Should See
The bot uses a **JSON-per-line** logger that writes to
`/app/data/cron.log` (because the cron line redirects with
`>> /app/data/cron.log 2>&1`). Inspecting the file with
`docker compose exec tenbackward tail -n 100 /app/data/cron.log`
should show output similar to:
```json
{"ts": "2026-08-04T09:00:00+00:00", "level": "INFO", "logger": "tenbackward", "message": "startup", "event": "startup", "version": "0.1.0", "site_url": "https://blog.example.com", "run_at": "09:00", "tz": "Europe/Berlin", "hashtags": "#throwback,#10backward", "throwback_prefix": "Throwback:"}
```
On the current scaffold (`_iter_candidates` is intentionally empty),
this is the **only** line you should see — the runner emits no
`run_complete` when no candidates were found. This is the
"silent on no matches" contract.
# Expected Container Behaviour
| Scenario | Lines in `cron.log` | Container exit |
|-------------------------------------------|----------------------------------------------------------------|------------------|
| Config valid, zero candidates (scaffold) | 1× `startup` | `0` |
| Config valid, future blog step posts N≥1 | 1× `startup`, then 1× `run_complete` with `posted=N` | `0` |
| Pipeline raises once, recovers | 1× `pipeline_error`, then 1× `run_complete` | `0` |
| Pipeline keeps raising (budget exhausted) | `MAX_RETRIES + 1` × `pipeline_error`, then 1× `pipeline_failed` | `1` |
| Config invalid | 1× `configuration_error` (extras describe what failed) | `2` |
> **Tester tip** — `docker compose ps` should report the container as
> `running` after a `pipeline_failed` exit *only* if cron has not yet
> fired again. A single failed pipeline tick does not kill the container
> itself; cron re-runs it the next day.
# Files the Tester Should Look For
| Path (inside container) | When it appears |
|-------------------------|--------------------------------------------|
| `/app/data/cron.log` | Always (cron appends stdout/stderr here). |
| `/app/data/posted.json` | Created on first persist; only rewritten when a new id is posted. The scaffold run does **not** create this file. |
To verify these from the host:
```bash
docker compose exec tenbackward ls -la /app/data
docker compose exec tenbackward cat /app/data/cron.log
```
# Visual Elements
This is a server-side bot, so there is no UI. The "UI" consists of:
* **Log lines on stdout** — one JSON object per `INFO`/`ERROR` event.
* **Exit code** — `0` (healthy), `1` (pipeline exhausted), or `2` (config).
* **`posted.json`** — JSON state file; its mtime changes whenever a new id is persisted.
# Examples
## Healthy scaffold tick
```bash
$ docker compose exec tenbackward python -m tenbackward
{"ts":"...","event":"startup",...}
$ echo $?
0
```
## Bad `RUN_AT`
```bash
$ RUN_AT=25:99 docker compose exec tenbackward python -m tenbackward
ERROR: RUN_AT='25:99' must be in HH:MM (24-hour) format
$ docker compose ps
tenbackward Exit 1
```
(The error message lands on stderr in the entrypoint path and is
captured by `cron.log`.)
## Missing required env var
Unset `MAX_RETRIES`, restart the container:
```bash
$ docker compose up --build
tenbackward | ERROR: missing required environment variable(s): MAX_RETRIES
tenbackward exited with code 1
```
# Related
* [Environment Variable Setup](/operations/environment-setup.md)
* [Pipeline Runner](/architecture/pipeline-runner.md)
* [Logging & Run Summary](/architecture/logging.md)