Repository navigation
feat: let an agent mention configured people when a change needs a human review - #90
Conversation
🤖 AI code reviewDecision: Ready for human review Overall PR risk: Medium. The change modifies comment rendering and adds a 🔎 Reviewer summaries (3)
No findings. This review is advisory — it never blocks a merge and never auto-approves. |
220aadf to
585a605
Compare
Each reviewer pass may return a short `summary` of what it reviewed and concluded. The engine keeps one row per roster agent (its summary, or why it did not run: `paths` or the router) in an engine-owned `agentSummaries` field, and the comment lists them in a collapsed section under the overall summary. Summaries are model text, so the reporter flattens them to one line, escapes HTML, and breaks `@` mentions.
…man review An agent's front matter can list GitHub logins or teams under `mention`. When the agent sets `humanReview` with a reason, the review comment shows a visible line that mentions those people. Only the trusted config names people; the model writes only the reason, and the reporter breaks every `@` in it. An invalid `mention` is a setup warning.
585a605 to
397311c
Compare
…hen the comment is too big - plainModelLine let `_@login_` (rendered as `<em>@login</em>`) and character references (`@login`, `@login`, `@octocat`) through, and GitHub decodes references before it looks for mentions. Escape every reference's `&`, and break each `@` that doesn't follow an ASCII letter or digit, which keeps email addresses whole. - Only the aggregate comment checked MAX_COMMENT_CHARS. Escaping and the base64 state copy make summaries several times their byte budget, and a single comment over GitHub's limit failed to post, so the finished review was replaced by the failure notice. Over the limit, leave the summaries out with the same note the aggregate uses. - Summary parts lived in a plain object, so an agent named `constructor` or `toString` crashed the whole run; they are now a Map. Parts are kept in diff order rather than pass-completion order, and a `cross-cutting` agent is listed once. - Clipping no longer leaves half an emoji, and an unknown "not run" reason from an old or newer engine's state reads "not run". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Escaping every reference made model text like `<T>` or `&` show up literally. Only a reference that decodes to `@` itself can start a mention: one after the `@` spells a login character, but that `@` is broken like any other. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lded away - Titles, rationales, suggestions, source titles, the summary and the requalification reason went through stripStateMarkers only, so model text could still notify anyone (a title citing `@param` or `@types/node` pings a user or team). They now go through the same mention breaking as the summaries, in the single, aggregate and inline bodies. - In the aggregate comment, a scope with no findings kept its fold closed, so the person a request notified landed on a collapsed section. A mention line now opens it. - humanReview is recomputed every run, and GitHub notifies when an edit adds a mention, so a request that dropped out and came back notified again. The comment state now remembers who was notified; a returning handle renders without notifying. - MENTION_TARGET_RE now follows GitHub's rules: single inner hyphens, at most 39 characters, an optional EMU `_shortcode` suffix, and team slugs. One invalid entry no longer drops the agent's whole `mention` list: it is left out with a warning naming it. - Document that team mentions posted with GITHUB_TOKEN are untested. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Resolved so the one filter, breakMentions, carries #89's rules (`@` character references escaped, every `@` not after a letter or digit broken) for both the summary rows and the multi-line model text #90 added. humanReviewReasons and buildMentions take a Map, like the summary parts, so an agent named `constructor` can't read an inherited property. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Review notes from a multi-model review (Codex, Grok and Claude, each finding then re-checked against the code). Fixes are in 7b2eab6, pushed to this branch, and merge 514dada, which also merges #89's fixes so the mention filter stays one function. 1. Model text could still mention anyone (holds). The summary, and each finding's title, rationale, suggestion, source titles and requalification reason, went through
2. In the aggregate comment, a request was hidden when its scope had no findings (holds). The fold only opened for findings, requalified findings or replies. Fix: a mention line opens it. 3. Repeat notifications (holds). GitHub notifies when an edit adds a mention, and
4.
5. Team mentions posted with Also: Checks: typecheck, |
The capture in `(^|[^A-Za-z0-9])@` consumed the first `@` of `@@login`, so the second never matched and `@@login` still notified. A lookbehind breaks each one. Found by the repo's own AI review. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Follow-up: |
Resolves the conflicts with #86 and #87: both import lists, the inline heading (knownSeverity + modelText), buildMentions/attachMentions beside the new policy doc, both sets of config-load tests, and a duplicate renderInlineCommentBody import. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Stacked on #89.
Why
The docs agent in expo/expo can tell when docs or doc comments change in a way that needs a human review, but it has no way to bring in the docs owner. The agent already runs only on its
paths, so it should be able to ask for a person when it decides one is needed.Change
mentiontakes a list of GitHub logins ororg/teamslugs (an optional leading@is dropped). It's the only source of whom a review notifies, and CI loads agent files from the base commit, so a PR can't change it.MENTION_TARGET_RE) is a setup warning and the agent mentions no one, the same policy aspaths.humanReview: one sentence on why a person should review the change, parsed likesummary. The engine keeps the first reason per agent.buildMentionsturns a reason into a mention only for an agent that ran and has amentionlist.attachMentionsattaches an engine-ownedmentionsfield and strips any coordinator-written value.📣 <logins>: the docs reviewer asks for your review. <reason>. The reason goes throughplainModelLine, and the renderer re-checks every login because a re-render reads the state back from the comment body.shared.mdtemplate documentshumanReview. README,templates/config.jsonc, LLP 0002, LLP 0005 and LLP 0006 documentmention.mentionto its docs agent.Test Plan
bun test(810 pass), typecheck, lint,fmt:check,llp:checkandecr ref-checkall pass.The new tests fail before the change and pass after. They cover:
mentionlogins and teamshumanReviewfail-soft parsingbuildMentionsand the coordinator boundaryI also ran
ecr reviewlocally with a scratch docs agent (mentionset tooctocat, and a prompt asking forhumanReviewon substantive docs changes) on this branch's README changes. It returned a mention foroctocatwith the model's reason. I haven't run it against a live PR, so the GitHub notification itself is untested.