feat(emdash-bot): reporter-verified pkg.pr.new fix loop (bot next-gen 4/5) - #2382
feat(emdash-bot): reporter-verified pkg.pr.new fix loop (bot next-gen 4/5)#2382ascorbic wants to merge 3 commits into
Conversation
…acts push Reader-side of the fix loop's preview build. `preview.ts` centralises the full-ref pkg.pr.new install URL (which the poll probes and the ask advertises), the fix/artifacts branch names, a bounded readiness probe, and the reap branch-set. `comments.ts` gains the ask renderer (bot-ask marker, install command, screenshots served from the artifacts branch with filename validation and markdown escaping, reporter ask) and the confirmed draft-PR body. The outbound push proxy now admits `bot/artifacts-<n>` alongside `bot/fix-<n>` for the issue, and the fix agent reports screenshots and pushes the orphan artifacts branch so the ask can render them.
…ose cleanup The orchestrator now drives the fix loop end to end. On entering preview_building it schedules a bounded pkg.pr.new poll on the DO alarm (one probe per tick, ~10min budget); a 200 fires preview.ready, exhaustion fires preview.failed back to the reproduced verdict. preview.ready composes the ask from the persisted fix notes, screenshots, and the reporter login and posts it before flipping labels, so a failed comment can't strand the issue in awaiting-reporter with no ask. Branch reaping now guards the fix branch behind an open-PR check and always drops the artifacts branch (review flag F4), on the reject/expire/decline edges and a new issues.closed cleanup path that bypasses the machine. Also fixes a latent drain bug: a standalone side effect (runId undefined) with no dispatch pending matched `undefined === pendingDispatch?.runId` and was deferred forever. The poll-fired ask is the first non-dry-run standalone effect to exercise it.
|
Scope checkThis PR changes 860 lines across 13 files. Large PRs are harder to review and more likely to be closed without review. If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs. See CONTRIBUTING.md for contribution guidelines. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | dcdec94 | Aug 08 2026, 04:52 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | dcdec94 | Aug 08 2026, 04:53 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-do | dcdec94 | Aug 08 2026, 04:55 PM |
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/auth-atproto
@emdash-cms/blocks
@emdash-cms/cloudflare
@emdash-cms/contentful-to-portable-text
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/plugin-cli
@emdash-cms/plugin-types
@emdash-cms/registry-client
@emdash-cms/registry-lexicons
@emdash-cms/registry-verification
@emdash-cms/sandbox-workerd
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-field-kit
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
ce08dab to
aa22dad
Compare
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| 🔵 In progress View logs |
docs | aa22dad | Aug 08 2026, 04:47 PM |
There was a problem hiding this comment.
Pull request overview
Wires the reporter-verified fix loop into the next-gen emdash-bot orchestration: adds pkg.pr.new preview polling, a preview-ready “ask” comment (with optional screenshots), and an issues.closed cleanup path that reaps fix-loop branches safely.
Changes:
- Add pkg.pr.new preview helpers and orchestrator polling to advance
preview_building→awaiting_reporteronly once the preview URL resolves. - Introduce a preview-ready ask comment renderer (install command, notes, screenshots) and a richer draft PR body.
- Add
issues.closedwebhook normalization + synchronous cleanup to reapbot/fix-*/bot/artifacts-*with an open-PR guard.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| infra/emdash-bot/tests/unit/webhook.test.ts | Adds unit coverage for issues.closed cleanup normalization. |
| infra/emdash-bot/tests/unit/preview.test.ts | Adds unit tests for preview URL/branch helpers and readiness probe behavior. |
| infra/emdash-bot/tests/unit/orchestrator-comments.test.ts | Tests new comment/body renderers (ask + draft PR) including screenshot escaping/injection rejection. |
| infra/emdash-bot/tests/unit/github-proxy.test.ts | Extends push-proxy tests to allow artifacts branch pushes scoped to the issue. |
| infra/emdash-bot/tests/integration/webhook.test.ts | Verifies issues.closed drives the cleanup path in the worker. |
| infra/emdash-bot/tests/integration/orchestrator.test.ts | Adds integration coverage for preview polling outcomes and comment-first side-effect ordering. |
| infra/emdash-bot/.flue/skills/verify/SKILL.md | Minor markdown formatting adjustments. |
| infra/emdash-bot/.flue/skills/investigate/SKILL.md | Minor markdown formatting adjustments. |
| infra/emdash-bot/.flue/skills/fix/SKILL.md | Minor markdown formatting adjustments. |
| infra/emdash-bot/.flue/skills/diagnose/SKILL.md | Minor markdown formatting adjustments. |
| infra/emdash-bot/.flue/routes.ts | Adds synchronous issue-close cleanup handling in the webhook route. |
| infra/emdash-bot/.flue/lib/webhook.ts | Normalizes issues.closed to a cleanup action (skipping PR-as-issue closes). |
| infra/emdash-bot/.flue/lib/preview.ts | New helpers for fix/artifacts branches, preview URL/install command, and readiness probing. |
| infra/emdash-bot/.flue/lib/orchestrator.ts | Implements preview polling, preview-ready ask composition, comment-first side effects, and branch reaping guard via open-PR check. |
| infra/emdash-bot/.flue/lib/github-proxy.ts | Allows receive-pack updates for both bot/fix-* and bot/artifacts-* for the current issue. |
| infra/emdash-bot/.flue/lib/comments.ts | Adds preview-ready ask and draft PR body renderers; introduces screenshot rendering/escaping. |
| infra/emdash-bot/.flue/agents/investigate.ts | Extends agent result schema to include screenshots for preview ask rendering. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const SCREENSHOT_FILENAME_RE = /^[a-zA-Z0-9._-]{1,80}$/; | ||
| const MD_ESCAPE_RE = /([\\[\]()])/g; | ||
|
|
||
| function mdEscape(text: string): string { | ||
| return text.replace(MD_ESCAPE_RE, "\\$1"); | ||
| } |
| const screenshotSchema = v.object({ | ||
| filename: v.pipe(v.string(), v.minLength(1), v.maxLength(80)), | ||
| description: v.optional(v.string()), | ||
| }); |
Overlapping PRsThis PR modifies files that are also changed by other open PRs:
This may cause merge conflicts or duplicated work. A maintainer will coordinate. |
There was a problem hiding this comment.
This is a focused, well-scoped slice of the bot next-gen work: it wires the reporter-confirmed fix loop onto the existing machine states, adds bounded pkg.pr.new polling, comment-first ask ordering, open-PR-guarded branch cleanup, and the corresponding tests. The approach fits the stated maintainer-directed design and reuses gen-1 conventions (bot/fix-* branches, the bot-ask marker, and the emdash package-name URL).
I checked the diff and the full changed files, traced call sites in machine.ts, router.ts, github.ts, and investigation-result.ts, and looked for the usual cross-cutting issues. The new code is clean:
- No new SQL, content-table queries, admin UI strings, or logged-out hot-path queries (AGENTS.md items are n/a for the infra worker).
- The side-effect drain guard fix correctly distinguishes
undefinedrun ids from pending-dispatch run ids. - Preview poll state is set/cleared only on entry/exit of
preview_building, and the alarm multiplexing uses earliest-deadline-wins correctly. commentFirstordering is implemented so a failed ask comment leaves labels unchanged and the effect pending for retry.- Push-proxy admission now allows the issue-scoped artifacts branch alongside the fix branch, and the receive-pack parser is unchanged in its security-critical bounds checks.
- Tests cover poll success/timeout, comment-first ordering, open-PR reap guard, ask composition/injection rejection, and
issues.closedcleanup.
I did not find any new blocking issues. One pre-existing inconsistency worth noting: the legacy agent.fix_ready path in renderAgentComment still advertises https://pkg.pr.new/emdash-cms/emdash@..., while the new next-gen path (and gen-1 investigate.yml) uses the package-name URL https://pkg.pr.new/emdash@.... That’s not introduced by this PR, but it would be good to align the legacy lane with the canonical helper in a follow-up.
What does this PR do?
Slice 4 of the bot next-gen stack (on #2381). Wires the reporter-verified fix loop onto the machine states from #2376, reusing gen-1's
bot/fix-*+ pkg.pr.new conventions with the worker as orchestrator.bot/fix-<n>(+ orphanbot/artifacts-<n>screenshots) through the capability-scoped push proxy;preview-releases.yml(untouched — Actions/OIDC is the only pkg.pr.new publisher) builds the package preview; the DO polls the install URL on its existing alarm tick (bounded, 10-min budget as a tunable constant) and only advertises once it resolves — removing gen-1's "if npm i 404s, retry" reporter-facing race.bot-askmarker, notes, full-refnpm i https://pkg.pr.new/emdash@bot/fix-<n>, screenshots, @reporter), posted comment-first so a failed post can't strand the state; restart-safe via a persisted marker check (no duplicate asks).issues.closedpath mirroring gen-1's bot-cleanup semantics.undefined === undefined, deferring standalone effects forever — first reachable here (the ask), but also affecting readonly status replies. Now guarded explicitly; restart idempotency covered by tests.Adversarially reviewed: single-alarm multiplexing traced (the poll rides the existing tick, earliest-deadline-wins), push-proxy admission HMAC-scoped per issue, injection surfaces validated.
Closes #
Type of change
Checklist
pnpm typecheckpasses — n/a-with-note: same pre-existinginfra/emdash-botbaseline as the stack; zero new production error classespnpm lintpasses — oxlint--type-aware --deny-warningsexit 0pnpm testpasses — unit 126/126, integration 42/42 (workers pool)pnpm formathas been run — oxfmt (note:.flue/is dot-dir-skipped; tab style verified by review)AI-generated code disclosure
Screenshots / test output
Try this PR
Open a fresh playground →
A full working EmDash site, deployed from this branch. Each visit gets its own session-scoped sandbox: no login needed and no shared state. Try the admin, edit content, hit the public site.
Tracks
bot-nextgen/04-fix-loop-wiring. Updated automatically when the playground redeploys.