<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/36/changes/paperclip/36 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - GitHub review agents publish findings and wait for an authorized reply or head change. > - Review tools could retain the requester after resume while completion lost that same wait proof. > - A yielded report could then queue its own continuation or repeat a missing-wait error. > - Ordinary Retry could also select an older failed turn while a newer saved request had no admission. > - This change shares the existing authority proofs and canonical admission owners. > - Current access, publication, execution and budget gates remain required. ## Linked Issues or Issue Description Refs #17318. Builds on the canonical saved-input retry owner in #17733. Related #16550 covers deferred legacy comments after ownership waits. The separate recovery repair in #17724 owns the cleanup-to-saved-input handoff; this PR does not add a second admission owner. A resumed review could publish an assessment, then turn its `response_wake` into an immediate `issue_status_changed` wake. A provider that omitted its continuation could instead repeat a completion error. A newer linked-human message saved during a budget hold could also remain unstarted because Retry selected the older failed source. ## What Changed - Resolve passive review waits through the accepted requester ledger used by GitHub tools. Require the latest reviewed head, exact company, task, agent, repository and processed publication under current access. - Fill omitted/null yielded continuation from that server proof. Permit an inherited normal tree resume only through its accepted parent identity. Permit an ordinary follow-up only after this run has a processed useful reply linked to its exact inbound message. Reject acknowledgements, partial assessments, pending or uncertain writes as that reply proof. - Recheck the same run/review/head/source proof during feedback, finalization and final status commit. Preserve explicit malformed-input rejection and Done policy. Add no monitor permission or publication grant. - Keep heartbeat and publication projections narrow. Preserve both published Copilot v62 identities and generate source-bound v63 from the pinned merged base. No v63 live qualification is claimed. - Certify the structured isolated-directory binding failure only at its pre-allocation boundary and only through canonical task Retry. Other workspace validation reasons and unknown effects remain denied. - Route Retry to eligible newer saved input through the existing canonical owner. Preserve the old result and skipped receipt. Require current principal, source, App, runtime fence, budget, native ownership and exact cleanup proof. - Recover absent historical App metadata only through an earlier trusted processed response receipt and an immutable non-null endpoint claim. Explicit malformed or conflicting metadata stays denied. - Revalidate execution through the exact claimed wake, coalesced task Retry and resolved user-continuation receipt after admission. A second normal Retry can recover the exact never-started authorization failure with unchanged saved input. Require empty execution evidence, exact diagnostics and no allocated or active executor. - Explain when a recorded result prevents exact replay. Ordinary board Retry directs a new task message to continue from saved work. Inherited requester identity alone never grants replay. - Keep accepted board-message preparation failures with the canonical task Retry owner. Certify the exact unchanged comment, original user wake, accepted same-user identity and absence of provider execution. Pin that source, recheck it at admission, and bind identity initialization to the coalesced intent and exact claimed successor receipt. Uncertifiable sources retain an actionable fresh-message refusal. - Return safe named authority categories for board Retry refusals. Update execution documentation and capability maps. Add no schema or polling loop. ## Verification - A fresh external review request exposed a separate isolated-directory preparation failure before allocation. Its first normal Retry saved an intent but admitted no successor. This follow-up certifies only that exact structured preparation boundary through the existing canonical Retry owner, with trusted failed settlement and no executor, lease, result or output. A real HTTP/queue regression reproduces the missing successor before the repair. Twenty-three current-source safety cases and the final 98-case Retry/HTTP group pass, including a fresh click after a denied intent, source revocation, accepted results and the older direct API remaining denied. The warning case uses actual configuration preparation and production event append; unknown warning shape or provider provenance stays denied. Full workspace typecheck, build, maps and diff checks pass. Renewed hosted normal Retry now succeeds on the final combined source: it preserves the exact saved request and linked requester, starts one native successor in a fresh attempt workspace, publishes the current-head 2/5 assessment and commits In review with passive response wake. - A later hosted normal Retry published a low-score assessment but lost its accepted source identity because the previous attempt failed before identity initialization. It repeated continuation errors, then submitted Done. This is failed acceptance, not a successful qualification. The initializer now retains the exact source only after execution-time failed-chat Retry authorization; generic Retry and Done policy are unchanged. A real queue/initializer regression fails with a null source on the previous code and passes with the newer saved source. Two real database completion cases verify that source yields the authoritative wait and commits In review. Renewed hosted normal Retry now retains the accepted source and exposes the authoritative current-review wait. It completed after two semantic feedback corrections (wrong contract revision, then wrong criterion IDs); the correct contract was present in emitted input. The third finish was accepted and committed In review, with no missing-wait loop or Done escalation. - Repeated board-message preparation failures now walk their canonical intent, failed dispatch and accepted parent identity, rechecking each contained predecessor. A production queue regression fails the second ordinary HTTP Retry before the repair and passes afterward. Changed source, contradictory execution evidence and cyclic receipts remain denied; traversal stops after twenty links. - New inherited omission cases failed before the repair. The final full PostgreSQL 18 wait/status suite passes **252 tests** under Node 24.22. It covers omitted/null input, malformed-first recovery, same-head resume, exact-source replies, changed heads, revoked access, pending/uncertain/mixed publications, final commit revalidation, no duplicate review and no self-wake. - **15 existing publication tests passed before the pinned merge** on a separate fresh database. They retain default partial-delivery and failure-fallback behavior. Context reads remain below the unchanged 16 KiB heartbeat and publication response limits with large saved output present. - Saved-input tests cover a real signed PR webhook, production accounting-budget refusal, normal policy recovery and canonical Retry. Historical producer-shaped tests prove the missing-App case red, then check trusted prior receipts and malformed, late, revoked or mismatched proof. A broader order-coupled test was reproduced on the prior source; its global fault injector now targets its own authorization query. The 43-case sequence passes without changing production behavior or its safety assertions. - New signed-ingress and real heartbeat execution tests reproduced the admitted-successor failure, then the next normal Retry failure. The final pinned merged source passes 249 full GitHub review/publication and Retry cases on a fresh database, including all 49 saved-input cases. A separate 74-case Retry/HTTP run also passes. Exact dispatch negatives cover source, company, agent, task, successor, receipt, pause, assignment, accepted success, controller and cleanup proof. Bootstrap contradictions remain denied. The canonical Retry suite passes 16 cases through its supported external PostgreSQL test connection. - The normal board HTTP route reproduced the unusable inherited-result refusal. It now returns actionable guidance without starting a successor. The actual UI Retry hook and banner tests pass 12 cases. - A production-shaped accepted board comment followed by a pre-provider qualification failure reproduced HTTP 409 before the repair. The final real HTTP/queue test certifies one canonical successor and preserves the accepted identity. It rejects changed source, actor, task, agent, result, controller, process, profile, allocation and receipt evidence. A post-acceptance source change keeps the same intent pending. Execution revalidation rejects removed or mismatched proof. The probe stops deliberately after production identity initialization; it does not claim provider execution. The final source passes the 75-case Retry group, the focused two-case board/inherited-policy group and 19 canonical Retry cases. Full workspace typecheck, build and map checks pass. - Full workspace `pnpm -r typecheck` and `pnpm build` pass. Map, module-boundary and diff checks pass. Full local `pnpm test:run` remains unverified. The 256-case explicit-native suite cannot initialize its packaged PostgreSQL because libzstd is absent; an existing command-scoped fallback did not resolve it. Current-head remote full-suite checks are required. Merged-source full GitHub+Retry (249), separate Retry/HTTP (74), full wait/status (252), profile/history and completion (75), and visible Retry hook/banner (12) checks pass. The fresh owned PostgreSQL 18 databases applied all 377 migrations. - Actual Rust Runner, OpenCode 1.18.34 and exact DeepSeek used unchanged production-generated synthetic contexts. Resume finished with an explicit server wait. The author-reply trial omitted continuation twice: its first report failed the existing empty-criteria check; the corrected second report still omitted continuation and received the exact server wait. It completed once with no missing-wait loop or Done escalation. Controller acknowledgments were synthetic; these probes do not establish hosted publication or board state. - Hosted combined testing proved automatic admission of the exact saved author reply, a useful GitHub answer and committed passive wait. It required two malformed-continuation rejections before a nullish fallback succeeded. A later normal Pause/Resume completed in one finish with explicit response_wake and no new review/comment. The admitted normal Retry then exposed the execution guard gap repaired here. Those remain checkpoint results. On the final combined source, renewed normal Retry completed actual native provider work and GitHub publication, committed the passive wait, released ownership and cleaned up its environment. A subsequent ordinary unmentioned author reply woke once, made no GitHub tool calls or new assessment, and completed its first finish with an explicit response wake. Both exact leases expired with successful cleanup and the queue was empty. However, final destination inspection found a separate automatic fallback overwrote the existing summary with a generic no-final-response message. External summary preservation therefore remains failed acceptance; the separate publication repair in #17726 owns that producer. Full combined publication preservation has not passed. These hosted runs include the pinned-base native additions; they do not qualify Copilot v63. - Current-head automated review is 5/5 with zero unresolved threads. All current-head CI gates passed (54 successful checks/contexts, four skipped, none pending). The earlier login-cleanup idle-work assertion also reproduced locally while its controlled baseline passed; its cause remains unknown, but the exact assertion passed in the fresh current-head CI shard. No timeout, assertion or production workaround was added. This PR is ready for review within its source, authority, native finalization, state, wake and cleanup scope. The independent automatic fallback publication regression is tracked by #17726; no complete combined workflow pass is claimed. ## Risks - The latest saved review defines the durable head boundary. Ingress must record a new head before admission. A reply receipt proves delivery only for its exact saved source; a shared GitHub comment ID alone cannot authorize this wait. - Historical App recovery cannot infer identity without direct proof or an earlier valid server response receipt. It never replays that response. - This does not infer review-score policy from instructions or override Done. No deployment, merge or repair of historical tasks is claimed by the PR. ## Model Used OpenAI `gpt-6.1-sol`, with reasoning, repository inspection, code editing and test execution. The context-window size is not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (focused database and native suites; full local suite limitation described above) - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green (verified on immutable latest head) - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (verified on the latest head) - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
22 KiB
GitHub managed connection
GitHub is a Paperclip Cloud-managed GitHub App connection with an advanced PAT compatibility method. Cloud owns the fixed public OAuth callback and signed webhook inbox; provider tokens are sealed to the enrolled instance and stored only in its existing encrypted secret system.
Catalog entries
GitHub connects an account for repository tools, Git, and gh, and opens
Access → Connect directly. GitHub Code Review Bot connects one agent to a
GitHub App for pull-request reviews and mentions, and opens Choose agent directly.
The bot entry follows Settings → Experimental → GitHub review bots
(enableGitHubReviewBots), which defaults to off. It is independent of Chat
connectors: enabling one does not enable the other. Turning off the GitHub
setting hides setup and management; existing bots keep running.
Both entries reuse the existing GitHub integrations. Bot endpoints retain the
github provider identity and existing setup, reconnect, and management URLs;
saved bot connections and drafts appear under GitHub Code Review Bot. GitHub
repository and MCP URLs still resolve to the ordinary GitHub tool connection.
Bot instructions and triggers
Bot Settings uses the shared Markdown editor for common and event-specific
instructions. Type / and select a company skill to insert a saved skill link.
Common instructions accompany every admitted GitHub task; event-specific
instructions accompany that event. Selected skills are materialized for the run
and explicitly invoked by the native Runner, subject to existing tool and
isolation restrictions. The admitted configuration snapshot determines skill
selection for each wake, including queued events. GitHub messages, repository
content and other companies' skills cannot assign skills to the run.
Authorized @mentions remain available when Run automatically is on or off.
The switch in Settings reveals the PR and issue event checkboxes. Access lists
company members and external contributors separately. Author include/exclude filters
in Settings control whose activity starts automatic work; there is no per-person
automatic-run switch. Automatic events still require an authorized author and an
enabled event. Legacy people[].automaticReviews values are accepted but ignored.
External contributors additionally need Allow automatic runs for external contributors.
Their restricted guest profile and sponsor requirements are unchanged.
The passing-score number field accepts a whole number from 1 to 5, defaulting to 5. Paperclip publishes a successful Paperclip Review check only after a complete assessment of the current commit meets the threshold; lower scores fail and incomplete assessments require action. To block merging, separately require this check from the dedicated App in GitHub branch protection or a ruleset. A new head commit needs its own check. Report-only mode publishes a neutral conclusion, which GitHub can accept for a required check; it does not enforce a score requirement. This includes incomplete assessments and failed runs: their checks remain neutral and explain the failure without presenting a passing assessment. A passing score does not formally approve a PR. Approvals and change requests contains those optional agent permissions. Scheduling filters, ignored files, and inline-comment options have separate disclosures. The header shows the App identity, copyable mention, avatar download, and GitHub branding settings.
Published review summaries use the GitHub bot's display name in their heading. The check name remains Paperclip Review. Multiple bots can review the same PR through separate GitHub Apps: each keeps its own task, summary, findings, and check. Check updates match both the App ID and the endpoint/PR/commit identity. Repository branch rules decide separately which App's check is required to merge.
Self-hosted setup
The setup screen states the default access in one line, with Change for other choices. Continue to GitHub on that screen starts the provider handoff.
A self-hosted instance needs one Paperclip Cloud approval before its first managed connection. After approval, setup returns to the connect screen and continues to GitHub without another instance approval or a service restart.
If an unapproved enrollment link expires, return to setup and select Continue. Paperclip asks the server for a valid link. The server reuses a live pending enrollment or replaces an expired one; this does not revoke or repeat an existing instance approval.
Identity resolution
Every MCP call, gh invocation, native Git operation, checkout, health check,
and webhook binding uses the same order:
- An active dedicated GitHub grant for the current agent.
- The active personal GitHub grant owned by the run's
responsibleUserId. - For automated work without a responsible user, a personal grant only when an existing standing delegation names the agent.
- Legacy
GH_TOKEN/GITHUB_TOKENonly when no managed GitHub connection is configured for the company.
An unavailable or ambiguous managed identity fails visibly. It never falls
through to another person, an organization credential, or a legacy token.
Agent grants are company-scoped, have exactly one subjectAgentId, cannot be
organization defaults, and are installed only for that agent.
The connection installation is the credential owner's consent boundary. A
personal setup may target every agent or a selected set, and runtime resolution
considers only an enabled, active connection installed for the current agent.
Within that boundary, Paperclip treats the run's server-resolved
responsibleUserId as its credential principal, including for automated work;
agents cannot choose or spoof this field. The owner must still be an active
non-viewer company member at each use. A standing delegation is needed only
when a run genuinely has no responsible user.
Credential lifecycle
The production, staging, and development GitHub Apps deliberately disable
user-to-server token expiration. The resulting long-lived access token is
checked with GitHub's /user endpoint every 30 days, together with installation
and repository summary refresh. Routine continuity requires no browser visit.
If GitHub returns an expiring access token and rotating refresh token instead, Paperclip stores both encrypted and:
- refreshes at least one hour before access expiry;
- forces a rotation at least every 30 days while the instance is active;
- serializes refresh through the existing database refresh lease and compare- and-swap update;
- atomically advances both secret values before clearing the lease;
- retries one forced refresh after a provider
401.
Only an unrecoverable provider invalidation marks a grant
needs_reauthorization. Installation removal or suspension is reported as an
installation-health failure, not as token expiry.
Repository access
OAuth completion verifies /user, every page of /user/installations, and every
page of each installation's accessible repositories. Setup remains incomplete
until at least one installation and repository are available. Paperclip stores
the authenticated username and a grant-scoped display snapshot containing only
repository IDs, full names, installation IDs, and private-repository flags. GitHub stays authoritative:
this snapshot never authorizes repository access.
The permissions page shows repositories across authorized accounts by default. Use the account filter and search to narrow the list. The list scrolls after about ten rows and marks known private repositories with a lock. Configure on GitHub opens the app account chooser so users can add or update organization access. Refresh access after changing the selection. Older snapshots omit the private flag until refreshed. If a legacy grant lacks its app chooser URL, Load GitHub configuration refreshes access and recovers the app slug from GitHub installation metadata. The page does not substitute a single-installation settings URL for the account chooser.
The permissions page shows the authenticated GitHub account and the complete accessible repository list. Refresh access reloads it from GitHub. Older grants and grants invalidated by newer installation lifecycle events prompt for a refresh instead of presenting a stale list. The page links to GitHub's installation management page. Selected repositories are recommended; all- repository access retains its warning.
Fresh local test-drives use production Paperclip Cloud. Instance enrollment
and provider enablement are separate: enrollment alone does not enable GitHub
OAuth. Production must advertise the github.code profile (see Cloud's
docs/github-connector-deploy-bootstrap.md). If it is unavailable, setup
preserves the sign-in intent and offers a retry instead of silently switching
to a personal access token. A successful retry preserves the chosen audience.
GitHub Actions tools
Managed and PAT connections request X-MCP-Toolsets: default,actions for MCP
discovery and invocation. GitHub's default catalog excludes Actions; granting
Actions permissions alone does not expose workflow tools. Existing connections
can use Refresh actions after upgrading to discover the added tools.
The normal catalog, access, approval, and quarantine rules still apply.
To dispatch an existing workflow, use actions_run_trigger with
method: "run_workflow", the repository owner and name, workflow_id, ref,
and any workflow inputs. The workflow must declare workflow_dispatch.
The GitHub App installation or fine-grained PAT needs Actions: Read and
write for the repository. App owners set that permission on the GitHub App
registration; installation owners must approve an increase before it takes
effect. Paperclip's action controls do not grant GitHub permissions.
The tool also supports rerunning and cancelling runs and deleting run logs.
It retains GitHub's destructive classification. Read tools include
actions_list, actions_get, and get_job_logs.
Provider references: MCP toolset configuration and workflow dispatch permissions.
GitHub response reconciliation reads run status and request identity without
loading prompts, runtime profiles, results, or log excerpts. Request ownership
checks still use current company, agent, task, and accepted message provenance.
The run context projection retains issueId, taskId, wakeCommentId, and
wakeCommentIds; larger runtime data stays in its owning reads.
Webhook delivery recovery
The Cloud connector authenticates the outer event batch before it processes individual encrypted App deliveries. If an inner delivery cannot be decrypted or fails its route binding check, the instance reports a failed delivery and leaves it unacknowledged in Cloud. A local warning includes the authenticated delivery ID and a fixed failure reason, without event contents or raw errors. Other valid events in the batch can still finish and acknowledge independently. Failed ciphertext never reaches the GitHub webhook handler. The broker retains failed deliveries for retry under its normal lease and retention policy; this does not recover a lost old key.
Webhooks
For the shared GitHub account connector, Paperclip Cloud verifies
X-Hub-Signature-256 against the exact bounded request
body before parsing, deduplicates by X-GitHub-Delivery, and persists a minimal
normalized event before returning 202. Raw webhook payloads are discarded.
When registering an active binding, Paperclip sends the current user token only
inside the signed, payload-bound broker request so Cloud can verify access to
that exact installation; Cloud neither logs nor persists that proof token.
Deliveries fan out independently to every enrolled instance bound to the GitHub
installation and are sealed to each instance's public key.
The instance polls with backoff, stores a company-scoped idempotency receipt, and acknowledges only successful applications. A merged pull request updates its matching external-object snapshot and immediately runs the existing merge- confirmation resolver. It wakes the assignee only when that interaction's continuation policy requests it; unrelated Paperclip issues are not closed. The periodic GitHub merge sweep remains the reconciliation fallback.
Installation lifecycle events refresh or invalidate installation summaries and remove obsolete Cloud bindings. Activity records contain event identifiers and outcomes but no webhook content. GitHub webhook content is never first-party telemetry.
Dedicated agent Apps
The bot wizard uses Cloud gateway protocol version 2. The stack builds the private manifest for a personal account or organization. GitHub still asks the user to confirm creation and repository installation. The stack exchanges the returned manifest code directly with GitHub and stores every App secret in its vault, including the private key, client secret, and webhook verifier.
Cloud stores only opaque, instance-bound callback routes and encrypted callback claims. It does not exchange codes, track App or installation identity, store GitHub secrets, or interpret bot events. It forwards original webhook bytes, provider headers, and signature in an envelope sealed to the stack before writing the inbox. The stack decrypts and authenticates those bytes through its existing durable ingress. Cloud-managed Apps are excluded from the direct-tenant callback recovery scanner and its callback-mismatch warning; the Cloud inbox owns relay delivery retries. Only that local check can verify a connection or admit work. After a repair, a fresh authenticated event for the bound installation can verify webhook delivery even when the relay deduplicates a redelivered old ping. This also applies while the connection needs attention: the signed event verifies delivery without retaining its content, admitting work, or changing repository access, even when its repository is disabled or unavailable. Verification returns the connection to the provider-setup step; later installation events cannot activate it. The manager must still complete reconnect and activation before new review requests can run. Shared-App account connectors keep the behavior described above.
Unverified gateway traffic has request, byte, pending-queue, retention and wake limits. Its transport deduplication includes the body and signature, so a forged request cannot occupy a real delivery's identifier. A ping received before its verifier reaches the vault remains queued for retry. Malformed and forged traffic is discarded after local verification. Installation returns only request a state refresh; the stack queries GitHub to establish installation authority.
OAuth state, PKCE, consent, repository discovery, recovery and lifecycle changes also stay in the stack. Interrupted single-use manifest exchanges require recovery of the existing App instead of a second creation. Direct webhook and manual existing-App recovery remain available. Connecting does not prove that an agent runtime can execute a review.
One main response per pull request
A pull request task can retain both its main discussion and inline finding threads. Bot tool discovery lists each endpoint/catalog tool once across those threads. Publishing an inline finding therefore does not duplicate the tool catalog on the task's next run. Both conversation mappings remain available for authorized follow-up replies.
The main PR conversation shares one App-owned comment across pushes, mentions, and repeat reviews. A new request updates that comment to Review queued…; agent progress and the final assessment update the same comment. Its identity survives restarts and reconnects. Existing request comments can be adopted without creating another main comment. Issue conversations and inline-review threads retain one editable response per request. Description mentions and automatic tasks also receive an acknowledgement. No new eyes reaction is added; cleanup still handles receipts created by older versions.
The agent's update_comment tool edits the current request's working comment.
It takes a body and a stable idempotency key, with no caller-selected comment ID
or destination. Instructions encourage brief, factual progress updates during
longer work. Distinct updates use distinct keys; retries reuse the same key.
Progress does not complete an assessment or change a review check.
The comment tool replaces that same comment with the final answer.
submit_review replaces it with the allowed review summary; checks, inline
findings and explicitly permitted formal reviews remain separate. Corrected
assessments can update the summary again. Delayed progress cannot overwrite a
final answer. Native final text stays in Paperclip and creates no extra comment.
Legacy connections without a saved review configuration retain automatic run
progress and final replies until upgraded to this tool-owned response model.
Receipts are bound to the company, App, task, accepted request and original
runtime generation. The existing publication lease serializes edits, and
App-owned markers recover uncertain creation without posting duplicates.
Deleted or no-longer-owned comments are not recreated or edited. Coalesced runs
settle a deleted earlier working comment without blocking the current response,
review findings, or check publication. Failed runs
update the same comment when no final reply is confirmed or unresolved. Maintenance
also reconciles acknowledged requests when recovery stops before a publication
is staged. Requests saved on a blocked task report that work is paused and stay
open for resumed progress or stopped-run cleanup. An older
run cannot replace a newer run's response. A run
that ends without a final reply clears a remaining working state honestly.
Repository restrictions, person authorization and governed tool checks remain
in effect for edits. Existing disabled or quarantined tools stay disabled.
Existing native sessions refresh incompatible tool checkpoints so the agent
can see update_comment. The same Paperclip task and saved history remain.
Explicit bot mentions and subscriptions
Issue and PR descriptions, discussion comments, inline comments, and review summaries retain uploaded attachment references when they mention the bot. Private images use the exact unchanged source's authenticated GitHub rendering; repository/thread identity and body hashes remain bound across restarts. Signed image URLs and credentials are never added to durable attachment descriptors.
A manual message beginning with another recipient's @mention does not wake this
bot through its thread subscription, including Apps outside Paperclip such as
@greptile review. Mentions of other connected GitHub bots are also filtered
elsewhere in the body. Paperclip filters that
delivery before creating task work or adding an acknowledgement. Explicitly
mentioning both bots allows both to receive the request, subject to their normal
authorization and repository checks.
Unaddressed follow-ups and incidental human or unknown mentions retain the existing subscription behavior. Explicitly mentioning this bot admits a request even when another recipient is named. The routing rule does not change automatic issue or PR event policies. Archived bots and identities from other companies or providers are excluded from the routing lookup.
Retrying a saved request
A normal task Retry can continue a newer saved GitHub message after an earlier attempt failed. Execution revalidates the exact admitted successor, its current linked principal and repository access, and the durable continuation receipt; it does not repeat the admission that already consumed the recovery hold. A failed native predecessor still requires its committed failed result and exact executor termination proof. Successful results and uncertain delivery do not grant a replay. A certified failed-chat Retry retains the exact accepted message identity when its predecessor stopped before identity initialization, so a published review can expose its authorized passive response wait. If an inherited task-resume attempt already recorded a result, ordinary Retry explains that exact replay is unavailable and directs the user to send a new message to continue from saved work. That new turn still passes normal current requester, access and executor-containment checks.
If that successor failed at Retry authorization before runtime or provider
startup, the next normal Retry follows its canonical source receipt. The exact
system diagnostic, settlement events, empty execution evidence and absence of
allocated resources establish that narrow recovery path. A generic setup
failure or a claimed providerWorkStarted: false does not establish it.
The canonical task Retry also recognizes an isolated-directory binding failure at the workspace preparation boundary before allocation. Its structured reason and task binding, trusted failed settlement, dispatch-only profile and absence of execution resources must all agree. Other workspace validation failures do not inherit this permission. Current request authorization still runs at both admission and execution; a failed unadmitted Retry intent does not replace the saved request or prevent a later deliberate Retry.
Run projection
The resolved token is leased at run start as an audited class-3 secret and is projected only into the child process:
GH_TOKEN,GITHUB_TOKEN, and an internal credential-helper environment key;GIT_TERMINAL_PROMPT=0;- process-scoped
GIT_CONFIG_COUNT/KEY_n/VALUE_nentries that clear ambient helpers, install agithub.com-only helper, and rewrite GitHub SSH remotes to HTTPS; - author and committer identity using
<numeric-id>+<login>@users.noreply.github.com.
Tokens never appear in arguments, URLs, files, logs, events, or model context,
and the projection never replaces HOME.
Cloud deployment and exact GitHub App registration settings live in
paperclip-cloud/docs/github-connector-deploy-bootstrap.md.