Expand description
Listening for what happens after a review.
Every other command does one pass and exits, so a review asked for again
after spar posted one waited for a person to notice and run spar again.
spar listen waits instead, and it waits for free: the only thing that
calls an agent is a review, a second look, or a check-in, and none of those
starts until GitHub says something happened.
A second look is asked for, never assumed: a review requested again or a mention starts one, and a push or a comment alone does not. The author may still be working, and a comment may be another reviewer’s review rather than an answer to this one. The look that runs reads every commit and reply since the review on record.
Two sources feed it, because neither is enough alone. GitHub’s notifications say why a thread moved, a review request, a mention, a comment, and they are polled with a conditional request that costs nothing against the rate limit when nothing changed. But a push raises no notification for a reviewer, so a slower sweep of the open pull requests compares each head with the commit spar last read. Notifications are never raised for the viewer’s own actions, which is also why spar’s own comments never wake it.
Events settle before anything runs: a review request followed by three
comments in the same minute is one second look, not four. What runs is
decided by a table that is a pure function of the event, a few facts about
the item, and the [listen] settings, so it can be read and tested on its
own.
Structs§
- Event
- One thing that happened to one item.
- Facts
- What
planneeds to know about an item beyond what is pending. Read once per dispatch, never per tick. - Listen
State - Everything the listener keeps between ticks and between runs, in
.spar/state/listen.json. - Opts
- How one
spar listenwas asked to run. - Pending
- What has happened to one item since spar last acted on it. Persisted, so a restart in the middle of settling loses nothing: the notification is already past the watermark and will not come again.
- Subject
- Thread
- One notification thread, as
GET /repos/{owner}/{repo}/notificationsreturns it. - Watched
- What the listener knows about one item it is watching.
Enums§
Constants§
Functions§
- backoff_
secs - A minute, doubling, to a quarter of an hour.
- dispatch_
backoff_ secs - A quarter of an hour, doubling, to six hours.
- due
- Whether an item has settled: quiet for
settleseconds, or pending formax_waithowever noisy, or--once. - events_
from_ sweep - What a sweep of the open pull requests says happened.
- events_
from_ threads - Turn a poll’s threads into events, skipping what was already seen, and advance the watermark past them.
- merge
- Fold one event into what is pending for its item.
- next_
due - When the earliest pending item this run acts on becomes due and is past any wait a failure put on it. Leaving the wait out woke the loop every second until it ended.
- next_
link - The URL of the next page, from a
Linkheader. - number_
from_ url - The number at the end of an issue or pull request API URL.
- parse_
duration 30m,2h,1d,1h30m.- plan
- The dispatch table.
- poll_
interval - How long to wait before the next poll: the config, what GitHub asked for, and the floor, whichever is largest.
- prune_
seen - Forget threads not seen for a week.
- rate_
limit_ wait - How long a rate limited answer says to wait, clamped to a minute and an hour, or None when the answer was not about the rate limit.
- request_
answered - Whether the review the viewer is asked for is already on record: the newest
request that counts for the viewer, as
review_pendingcounts one, was made no later than the posted review began atreviewed_at. - retry_
wait - How long an item whose dispatch did not finish waits to run again. A head that moved under it is GitHub or the author rather than a failure, so the next look starts once the push settles. Anything else backs off.
- review_
pending - Whether a pull request’s
reviewRequestsask the viewer now: by name, or through a teamin_teamsays the viewer is in. A team nobody could check counts as asking, which is how every team request used to be read. - run
- Listen until stopped, or once.
- settle
- A notification’s reason is the one its thread was first raised for and it never changes, so a thread that began as a review request says so on every later update, spar’s own review among them. What the pull request says now decides: when nobody is asking any more, or the request is older than the review on record and so was answered by it, the update is only something happening on a thread the viewer is part of. True when it was.
- settle_
mention - A mention is a reason a thread keeps too, so a thread that began with one
says so on every later update. On a pull request spar reviewed, or an issue
whose pull request it reviewed, only a mention made since that review asks
for a second look; any other is only something happening on a thread the
viewer is part of. On any other issue only a mention
spar answerhas not judged asks anything, which is what keeps spar’s own answer, moving the thread it was raised on, from asking for another. True when it was.