Uh oh!
There was an error while loading. Please reload this page.
feat: add bounded issue-to-PR workflows - #29
Conversation
Deliver the v0.4 milestone: a scoped, labeled GitHub issue can become an investigated, implemented, verified, review-ready pull request without widening the runtime's authority. - shared: add the issue trigger, IssueRef, and acceptance criteria to the decision, result, and evidence contracts; render criteria in reports - config: add the issues policy (enabled, requireLabel, branchPrefix) with branch-prefix validation; issue work is opt-in twice - models: let the model record verifiable acceptance criteria and treat issue text as an untrusted change request - agent: bound model-authored criteria before they become evidence and require an isolated runner for issue-triggered fixes when configured - github: parse issues webhooks behind the required label, build runtime input with observe as the default mode, and publish verified changes through the Git data API on a fresh branch that is never force-updated; prepareIssuePullRequest is the single publication gate and refuses any run that is not completed, accepted, and verified, or that proposes a high-impact change - server: ingest issues events behind repository policy, and compose the publication from stored evidence through a read-only runner; a failed publication reports its reason instead of failing the run Verification: aube run check:repo, oxfmt --check, type-aware oxlint and tsc on every changed package, and 333 vitest tests across shared, config, models, agent, github, runner, cli, auth, and server all pass locally. Closes#11 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B4XhMKBtf98NZZmETE1XR4
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Before an issue task is trusted, the runtime already decides from repository evidence whether the issue reports a real problem. Make that triage visible where the work was requested, in the style of Pullfrog: a finished run posts one comment on the issue with its verdict — confirmed with the cited evidence and acceptance criteria, not confirmed with every rejection reason, or inconclusive for a human to decide. - config: add issues.validationComment (default true); the comment is report-only and never changes what a run may write - github: prepareIssueValidationComment composes the verdict from the persisted evidence bundle alone, so it can never claim more than the run proved; a run that failed before reaching a verdict gets no comment; items are collapsed and bounded, credentials redacted; the new GitHubIssueComments adapter can only create a comment — no path to label, edit, or close an issue - server: publishIssueValidation supplies stored evidence and posts the composed comment; ingestWebhook reports the outcome per issue event, and a failed post is a reported reason, never a failed run Verification: check:repo, oxfmt --check, type-aware oxlint and tsc on config, github, and server, and 349 vitest tests across all packages pass locally. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B4XhMKBtf98NZZmETE1XR4
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…apshot, and delivery key Address three review findings on the issue-to-PR flow: - Bind issue events and publication to the checkout's trusted origin repository via a new RepositoryBoundary.originRepository, rejecting events whose claimed repository does not match the checkout. - Publish pull requests from an immutable snapshot of the verified changed files captured under the run lease, instead of re-reading the mutable checkout at publication time. - Deduplicate webhook deliveries with an atomic delivery-key claim (delivery GUID or payload digest) so redeliveries return the recorded outcome instead of starting a second task.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The checkout identity parser now refuses any remote whose host is not github.com, so an owner/repo path on an attacker-controlled host can no longer approve publication to the GitHub repository of the same name. Issue delivery claims gain a durable, atomically claimed store shared across restarts and instances: the claim is persisted before the run starts, the recorded outcome replays to redeliveries, and a transport failure releases the claim so a retry can proceed.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…y claims Verified snapshots are now captured through a new byte-safe Runner.readBytes and stored as base64, and publication creates base64 blobs through the Git data API instead of the text-only inline tree content field, so a verified binary change lands with exactly the bytes the run verified. Delivery claims on drivers without a conditional write no longer trust a bare read-then-write: every contender writes a random arbitration token and only the writer whose token survives the read-back owns the delivery, so two instances that both observed the key absent resolve to a single owner. The production Nitro server gains POST /webhooks/github, which injects the shared taskStore and durable deliveryClaimStore into ingestWebhook and fails closed (503, nothing ingested) until GITHUB_WEBHOOK_SECRET and AGENT_ZERO_CHECKOUT_PATH are configured.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Merge origin/main (PR #29, "add bounded issue-to-PR workflows") into this branch. #29 landed after this branch forked and built a new GitHub-issue-to-PR feature directly on the old packages/github APIs — the exact package this branch renamed to packages/source-control and restructured into provider-neutral adapters, so a textual merge alone could not reconcile the two. Resolution: ported comments.ts, issues.ts, and pulls.ts into packages/source-control/src/providers/github-{comments,issues,pulls}.ts unchanged in behavior, re-exported from the package's public surface, and rewired apps/server/src/router.ts so ingestWebhook dispatches GitHub `issues` events to the ported pipeline ahead of the provider-neutral review-event path (issue-to-PR remains GitHub-only; it has no equivalent on the other providers yet). WebhookRequest keeps its provider-neutral `{ body, headers }` shape; the issue workflow reads its delivery id from `X-GitHub-Delivery` via the newly exported `readHeader` helper instead of a GitHub-specific request field. WebhookOutcome now carries two `accepted` variants (review vs. issue), distinguished structurally as `'changeRequest' in outcome` / `'issue' in outcome`, matching the pattern main's own tests already used for `'pullRequest' in outcome`. Also updated: apps/server/server/routes/webhooks/github.post.ts to build a headers-record request and pass `providers: [...]` instead of a bare secret; SKILL.md, docs/architecture.md, and README's remaining `packages/github` mentions; router.test.ts's issue-webhook suite rebuilt against the header-based request shape. Verification: 161 packages/source-control tests, 97 apps/server tests, and the full suite for agent/config/models/runner/shared/cli/auth (188 tests) pass; typecheck and oxlint type-aware lint are clean for every touched package; oxfmt is clean repo-wide; check:repo passes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky
Deliver the v0.4 milestone: a scoped, labeled GitHub issue can become an investigated, implemented, verified, review-ready pull request without widening the runtime's authority.
Verification: aube run check:repo, oxfmt --check, type-aware oxlint and tsc on every changed package, and 333 vitest tests across shared, config, models, agent, github, runner, cli, auth, and server all pass locally.
Closes#11
Claude-Session: https://claude.ai/code/session_01B4XhMKBtf98NZZmETE1XR4
Summary
Why
Verification
aube run check:repoaube run lint:ciaube run typecheckaube testaube run buildSafety and compatibility
observemode as read-only, or explained the policy change above.Reviewer notes
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is enabled.Confidence Score: 5/5
No blocking failure remains.
No accepted blocking findings remain after executable checks exercised the previously reported publication, repository-binding, delivery-claim, and remote-origin paths.
What T-Rex did
Reviews (7): Last reviewed commit: "fix(server): arbitrate fallback delivery..." | Re-trigger Greptile