fix(flows): render address-review skill before dispatching author #1221
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/agent-hooks!1221
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/render-skill-address-review"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
review-changes-requested.ymlwas dispatching withtask: event.pr.title(bare PR title) — agent received no instruction to read review comments or invoke theaddress-reviewskill; it would re-implement from scratch instead of fixing feedbackrender_skillop +RenderSkillCapabilitythat callsrenderPromptagainst the agent's type and skill name; flow now renders theaddress-reviewtemplate before dispatchsteps.skill.outputs.foundso missing skill aborts cleanly rather than sending an empty promptnav-sections.tsxsessionStorage-based back navigation (was breaking the pre-push QA gate) with the stale test updated to matchCommits
fix(flows): render address-review skill before dispatching authorrender_skill(+ test) wrappingRenderSkillCapability.renderRenderSkillCapability/RenderSkillAdapterDepsadded totypes.ts+live-capabilities.tsengine-bootstrap.ts: resolves agent by login → callsrenderPromptwithfilesystemFallback: trueops/index.tsregistry +registry.test.tscount bump (31 → 32) + representative outputrenderSkill: { render: async () => ({ body: null }) }stubflows.schema.jsonregenerated (33 ops)fix(web): sessionStorage-based back navigation + update stale testBackToMainNavinnav-sections.tsx: replacewindow.history.back()with sessionStorage lookup (ch_pre_settings_path),useEffecttracks last non-settings pathsidebar-nav.test.tsx: stale assertion (expect(back).toHaveBeenCalledTimes(1)) flipped toexpect(back).not.toHaveBeenCalled()Test plan
just qagreen (3367 server tests pass, web tests pass with chromium)pull_request_review_rejectedwebhook on a dev-authored PR → confirm agent receives renderedaddress-reviewbody (not bare PR title) in task logaddress-reviewskill row missing → confirm dispatch is skipped (no empty-body task enqueued)/settings/appearance, then back → confirm landing on last non-settings path🤖 Generated with Claude Code
The review-changes-requested.yml flow was dispatching with task: event.pr.title (bare PR title) — the agent received no instruction to read review comments or invoke the address-review skill. It would re-implement from scratch instead of fixing feedback. Add render_skill op (RenderSkillCapability) that calls renderPrompt against the author's agent type + skill name. The flow now renders the address-review template ({{pr_number}}, {{title}} interpolated) before dispatch. Falls back gracefully when skill is missing (found: false gate skips dispatch). Wire render_skill into live, shadow, and test capability bags. Regenerate flows.schema.json (33 ops → 32+1). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>Review —
fix(flows): render address-review skill before dispatching authorOverview
Correctly fixes a real bug:
review-changes-requested.ymlwas dispatchingtask: event.pr.title(bare PR title) to the author agent, giving it no signal to read review comments or invoke theaddress-reviewskill. The newrender_skillop renders the correct template before dispatch and gates onsteps.skill.outputs.found, cleanly aborting when the skill is missing.✅ What's done well
address-reviewbody. Thefoundguard prevents empty-body task enqueue.RenderSkillCapability(object-input) andRenderSkillAdapterDeps(positional) follow the established cap/adapter pattern exactly. Shadow pass-through is correctly marked read-only.render_skill.test.tscovers arg validation, found=true, found=false (null), empty-vars default, and outputsSchema round-trip. The 4 existing test fixtures get the correct{ body: null }stub.filesystemFallback: trueis the right call for resilient cold-start skill resolution.render_skillstep inherits all preconditions from the old dispatch; dispatch additionally gates onsteps.skill.outputs.found. Vars passed (repo,pr_number,title) are appropriate for theaddress-reviewtemplate.window.history.length > 1heuristic with deterministic sessionStorage lookup; falls back to/board.⚠️ Minor issues
1.
foundderived solely frombody !== null— empty string passes silentlyIf
renderPromptever returns""for a malformed/empty skill file,foundistrueand dispatch fires with an empty task. IfrenderPrompthas a documented null-for-empty contract this is a non-issue; otherwise a one-linerresult.body !== null && result.body.length > 0closes it.2. Type cast in
render_skill.tsis slightly unsafeA misconfigured capability bag produces
TypeError: Cannot read properties of undefinedrather than a clear "missing dep" error. Consistent with the existing op pattern — acceptable here, systemic issue to track separately.3.
getSettings()called per render invocation — trivial given once-per-webhook usage, low priority.4. Bundled unrelated web fix — explained in the PR description (QA gate blocker), acknowledged.
Verdict
APPROVED. The fix is correct, well-implemented, and follows project conventions throughout. The empty-string edge case is the only substantive concern — worth a one-line guard if
renderPromptdoesn't already guarantee null-for-empty output.