feat(maintainer-workflows): cross-workflow review memory + backfill#1458
feat(maintainer-workflows): cross-workflow review memory + backfill#1458
Conversation
The maintainer-standup brief had no signal for "I already triaged that
PR via maintainer-review-pr 2 days ago" — it just kept listing reviewed
PRs in P1-P4 with no acknowledgement of prior work. Result: maintainer
ends up re-skimming the same PR several mornings in a row.
This adds a shared persistent state file at:
.archon/maintainer-standup/reviewed-prs.json (gitignored, per-maintainer)
shape:
{
"1338": {
"reviewed_at": "2026-04-27T16:34:57Z",
"gate_verdict": "review", // review | decline | needs_split | unclear
"run_id": "..."
},
...
}
Three pieces:
1. WRITER — new `record-review` script node in maintainer-review-pr.yaml,
runs after whichever branch fired (post-review / post-decline /
approve-unclear) with trigger_rule: one_success. Inline bun script;
reads $gate.output.verdict, $ARTIFACTS_DIR/.pr-number, and
$WORKFLOW_ID; appends/upserts the entry. report node now depends on
record-review so the state write happens before the run completes.
2. READER — read-context.ts loads reviewed-prs.json into a new
reviewed_prs field on the standup gather output. Same pattern as
prior_state and recent_briefs.
3. SURFACE — maintainer-standup command file gets a Phase 2h rule:
when listing PRs in P1-P4 / Polite-decline sections, append:
- "✓ reviewed Nd ago" for review-branch entries
- "✓ declined Nd ago" for decline / needs_split branches
- "✓ triaged Nd ago (unclear)" for unclear branch
and a STALENESS marker — compare reviewed_at to PR's updatedAt; if
contributor pushed since the prior review, append
"⚠ contributor pushed since" so the maintainer knows the prior pass
may need to be re-run.
Plus a one-shot backfill script:
.archon/scripts/maintainer-standup-backfill-reviews.ts
Scans the maintainer's gh comments in the last 7 days, pattern-matches
"## Review Summary" / direction-clause-citation / split-up wording, and
populates reviewed-prs.json. Idempotent; existing entries (from real
workflow runs) take precedence over backfilled ones (the writer-node
record is more authoritative than a body-pattern guess). Uses 64MB
maxBuffer on the gh exec because --paginate over 7 days of an active
repo's comments easily exceeds Node's default 1MB.
Backfill verified: 363 comments scanned, 18 matched, 17 unique PRs
populated — exactly the 17 PRs we reviewed via the workflow yesterday.
The new state file is gitignored alongside the existing per-maintainer
files (profile.md, state.json, briefs/).
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR introduces a cross-workflow review metadata persistence system for the maintainer standup. It adds a backfill script to scan GitHub comments and infer review verdicts, updates the maintainer-review workflow to record reviews in shared state, and extends the read-context script to load persisted review history for downstream synthesis. Changes
Sequence DiagramsequenceDiagram
participant WF as Maintainer-Review<br/>Workflow
participant FS as File System<br/>(reviewed-prs.json)
participant RC as Read-Context<br/>Script
participant BP as Backfill<br/>Script
participant GH as GitHub API
WF->>FS: record-review node<br/>persists verdict, timestamp, run_id
Note over FS: reviewed-prs.json updated<br/>with PR entry
BP->>GH: scan maintainer's comments<br/>past 7 days
GH-->>BP: comment bodies & metadata
BP->>BP: infer verdict from patterns<br/>(review/decline/needs_split)
BP->>FS: load existing reviewed-prs.json
BP->>FS: merge backfill results<br/>(skip existing workflow entries)
RC->>FS: read reviewed-prs.json
FS-->>RC: parsed review history
RC->>RC: include reviewed_prs<br/>in output
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
maintainer-review-pr. Reviewed PRs kept re-appearing in P1-P4 with no marker, leading the maintainer to re-skim the same items each morning..archon/maintainer-standup/reviewed-prs.jsonshared between the two workflows. Writer node inmaintainer-review-pr.yamlrecords each run; standup's read-context loads it; standup synthesizer prompt surfaces "✓ reviewed Nd ago" markers in P1-P4 with a staleness flag when the contributor pushed since..archon/user content + a small inline persist node + a one-shot backfill script. Other workflows untouched.Three pieces
1. Writer —
maintainer-review-pr.yamlrecord-reviewnodeInline bun script that runs after whichever branch fires (
post-review/post-decline/approve-unclear) withtrigger_rule: one_success. Reads$gate.output.verdict, the PR number from$ARTIFACTS_DIR/.pr-number, and the workflow run ID; upserts an entry intoreviewed-prs.json. Thereportnode's dependency moved from[post-review, post-decline, approve-unclear]to[record-review]so the state-write happens before the run terminates.2. Reader —
maintainer-standup-read-context.tsLoads
reviewed-prs.jsoninto a newreviewed_prsfield on the standup gather output. Same pattern asprior_stateandrecent_briefs. Empty object on first run / missing file.3. Surface —
maintainer-standup.mdPhase 2hNew rule appended to Phase 2 instructing the synthesizer to mark PRs:
✓ reviewed Nd ago✓ declined Nd ago✓ triaged Nd ago (unclear)And a staleness check: compare
reviewed_atto the PR'supdatedAt; if the contributor pushed since, append⚠ contributor pushed sinceso the maintainer knows the prior review may need re-running.Plus: one-shot backfill script
.archon/scripts/maintainer-standup-backfill-reviews.tsscans the maintainer's GitHub comments in the last 7 days, pattern-matches## Review Summary/ direction-clause-citation / split-up wording, and populatesreviewed-prs.jsonfrom history. Idempotent — workflow-recorded entries take precedence over backfilled ones (the writer node is authoritative; pattern-matching is a best-effort historical reconstruction). Uses 64MBmaxBufferon the gh exec because--paginateover 7 days easily exceeds Node's default 1MB.Validation Evidence (required)
17 PRs populated — exactly matches the count from yesterday's review session (14 reviews + 1 decline + 2 retries = 17 unique PRs). Spot-checked the entries against the actual workflow runs.
Security Impact (required)
gh api repos/.../issues/comments. Same scope as existing standup gather; uses the sameghauth..archon/maintainer-standup/(gitignored, run-scoped path).Compatibility / Migration
reviewed-prs.jsonis purely additive; absent file → empty object → no markers in the brief (current behavior). Existing maintainer-review-pr runs continue to work; the newrecord-reviewnode only adds a state-write. Thereportnode's dependency change ([post-review, post-decline, approve-unclear]→[record-review]) is internal — the report content is unchanged.bun .archon/scripts/maintainer-standup-backfill-reviews.tsto seed the file from the last 7 days of comments. Without it, the file populates from new runs going forward.Human Verification (required)
read-context.tsreturnsreviewed_prs: {}; standup brief shows no markers (correct: no prior runs to surface).maintainer-review-prandmaintainer-standupvalidate cleanly from the subfolder.originremote — backfill script exits with a clear error before any work.Conflicts with direction.mdcould appear in non-decline contexts) — pattern-match is best-effort by design; workflow-recorded entries supersede backfilled ones viaexisting[num]check on merge.reviewed_prspopulated). Today's standup already ran before this PR was authored, so the next run will be the first to read the new field.Side Effects / Blast Radius (required)
maintainer-review-pr(new node + dependency reorder),maintainer-standup(new field in gather + new rendering rule). No engine code touched.reportnode now depends onrecord-reviewinstead of the three branch-end nodes directly. Ifrecord-reviewfails (file write error, JSON parse on corrupt existing file),reportwould skip. Mitigation: the writer try/catches the JSON parse and falls back toreviewed = {}; the only realistic failure is a permission error on the .archon dir, which would be diagnosable from the bash node's stderr.Rollback Plan (required)
git revert <merge-sha>— single commit, 5 files. The new state file remains on disk locally but goes unused (no reader, no writer); cleanup isrm .archon/maintainer-standup/reviewed-prs.jsonif the user wants tidy disk.record-reviewfailing →reportskipped → workflow statusfailed. Either is loud and resumable.Risks and Mitigations
record-reviewruns after the public-facinggh pr comment. If recording fails after the comment posted, the comment is on GitHub but the standup forgets it ever happened — same morning re-skim problem the feature was meant to solve..archon/maintainer-standup/, which is rare. Future improvement: also stash a copy in$ARTIFACTS_DIR/so it can be replayed if the canonical file is unwritable.author == ghHandle. False positives only possible when the maintainer themselves authored a non-review comment containing the marker text — unlikely but possible. Mitigation if it surfaces: tighten the regex to also require the maintainer-review-pr footer lineReviewed via maintainer-review-pr workflow.headRefOidor commit-only push events via a more specific gh query.Linked Issue
Summary by CodeRabbit
Release Notes
New Features
Chores