readest/apps/readest-app/docs
Huang Xin f4b0102ebd
chore(agent): maintenance loops with a Reply Desk, lessons and acceptance rules (#6796)
* chore(agent): add the maintenance loops, lessons and acceptance rules

Reproduces the Magpie workflow: three /loop skills that run in parallel
(triage-github for issues and PRs, watch-social for X/Discord/Reddit with a
Haiku pre-filter, nightly-review for the retrospective), a LESSONS.md that
every session imports, acceptance criteria that lessons seen on three days
are promoted into, and a community-PR policy (harm first, close unreviewed,
proposed blocks).

LESSONS.md is seeded from a review of the 86 commits from 2026-10-04 to
v0.12.16; three lessons seen on three days are already promoted.

Verified: pnpm format:check passes; the triage step-0 query was run against
the repo (needs --include-prs to see PRs). Not run: the loops themselves,
which reply on GitHub, X and Discord.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): route triage replies through the Reply Desk for approval

Drafts go to a private review page; the loop posts only approved replies,
re-checks the thread first, and treats edits and notes as feedback. The
window is threads created in the last 3 days.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): filter triage search by date; GitHub ignores timestamps

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): real timestamps on the Reply Desk; foliate-js fixes go first

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): the triage loop follows its own PRs: dependencies, CI, reviews, merge cards

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): edit PR bodies through the REST API

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): wake the triage loop on CI results and reviews

watch-prs.py polls the loop's open PRs every minute and prints one line
per event (CI finished green or red, CodeRabbit done, a new review or
comment, merged or closed, a failed read) for a Monitor to deliver. The
loop also checks a PR is still open before writing its merge card: the
maintainer merges on GitHub too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): the loops only process the owner's own PRs

The loops run unattended with the owner's credentials, so a PR from anyone
else is skipped unread: its description, diff, comments and branch are
never opened or run, and the loop never comments on, closes or merges it.
On the owner's PRs they act only on CodeRabbit (login and type checked) and
the owner, and stop on a commit the owner didn't author. The watcher
enforces the same: it skips other people's PRs, reports foreign commits,
and tags each review or comment trusted or untrusted. The nightly review
reads only the merged code of community PRs and no longer proposes blocks;
the social loop never fetches code a post links to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): propose English titles for non-English issues

A non-English issue title gets an English newTitle on its Reply Desk card,
applied when the card is approved; the reply stays in the reporter's
language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): send approved Reply Desk cards within five minutes

A light job checks the desk for approved cards every 5 minutes and runs
only the send step; merges go through the REST merge endpoint pinned to
the approved head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): read the Reply Desk URL from local loop config

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): keep the PR watcher honest on a failed login or a null status

The watcher now stops with WATCH_ERROR when it can't read the gh login,
instead of treating every PR as foreign and later replaying old events.
A CodeRabbit status with a null description no longer raises before the
status is recorded.

Verified: py_compile; a --once pass on #6796 against a scratch state dir;
GH_TOKEN=invalid exits 1 with "WATCH_ERROR cannot read the gh login: gh:
Bad credentials (HTTP 401)"; a stubbed status with description null emits
CODERABBIT_DONE and records it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): tighten the send step, rules and checklists from review

- Send step: drop a PR card whose PR is no longer open, keep other
  people's comments on owner PRs unread, claim a card as "sending" before
  any GitHub action, and send a failed action back as stale instead of
  retrying it; record prUrl, and open a fix PR only through its card.
- Acceptance: the failing-test rule is for behavior changes; a red test on
  main is fixed in its own PR; reporters are credited by their public name
  only.
- Nightly review: CI at merge is the runs that finished before mergedAt;
  "Fixed in" only when a fix exists.
- Social loop: the filter agent reads only the collected file, and the loop
  acts only on items that match it.
- Community PR checklist: run their code only in a credential-free sandbox.

Verified: docs and agent files only; read through for consistency with the
trust boundary and the Reply Desk flow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): write PR descriptions for GitHub, not from commit bodies

The loop's PRs reused hard-wrapped commit bodies, which GitHub renders with
a forced break at every line. PR descriptions now follow the format of the
earlier Claude Code PRs: a Closes/Part of line, Problem, Fix and
Verification sections, unwrapped lines and code in backticks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): the social loop posts only approved Reply Desk cards

Replies on X, Discord and Reddit, and issues it opens, are now drafted as
social cards and posted only after approval; the triage send step skips
them. A post asking the loop to act gets nothing beyond a card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): leave approved social cards to the social loop

The triage send step now skips kind: social cards, as 7e87d684c described.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): fetch sending cards too, so a stopped send gets reported

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): give a follow-up draft its own card after a sent one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 16:00:36 +02:00
..
superpowers refactor(wordlens): rename "Word Wise" to "Word Lens" (#4633) 2026-06-17 19:09:29 +02:00
architecture.md fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
book-config.md feat(reader): pair local audiobooks with ebooks (#5754) 2026-08-17 08:46:00 +02:00
bookshelves.md fix(library): improve e-ink pagination and bookshelf sync (#6330) 2026-09-21 10:44:19 +02:00
code-layout.md feat(dictionaries): add bundled plugin and Yomitan support (#5764) 2026-08-18 13:43:58 +02:00
contributors.md chore(agent): maintenance loops with a Reply Desk, lessons and acceptance rules (#6796) 2026-10-14 16:00:36 +02:00
google-play-all-files-access.md fix(android): keep All Files Access on the Play build (#5372) (#2862) (#5378) 2026-07-28 16:59:48 +02:00
i18n.md feat(i18n): add Uzbek and Brazilian Portuguese translations (#4061) 2026-05-05 09:20:44 +02:00
read-along-narration.md fix: iOS reader polish for drawing dock, short sheets, bookshelf header and read aloud (#6778) 2026-10-14 00:25:00 +02:00
safe-area-insets.md fix(ios): hide the status bar through the view controller for Xcode 27 builds (#6508) 2026-10-01 11:20:25 +02:00
sentry-symbolication.md feat(sentry): upload browser source maps for symbolicated JS crashes (#5027) 2026-07-09 09:18:48 +02:00
stats-archive.md fix(stats): survive PostgREST's row cap when building archive segments (#5844) 2026-08-24 15:07:01 +02:00
testing.md fix: iOS reader polish for drawing dock, short sheets, bookshelf header and read aloud (#6778) 2026-10-14 00:25:00 +02:00
view-settings.md refactor: rename ColorPanel to ThemePanel (#5042) 2026-07-11 12:48:13 +09:00