Error ownership and GitHub workflow
Use Errors → Workflow in the selected application and environment. This workflow requires Errors read and People PII read to inspect private owner, repository and tracker details. Mutations additionally require Errors write, same-origin CSRF protection, a passkey verified within ten minutes and a reason. No permission or ingest-key capability is added.
Ownership rules
Up to 20 ordered rules can each have one to four case-sensitive AND conditions:
error name, top relevant captured file path or normalized function, with equals,
starts-with or ends-with matching. File inputs remove URL hosts, query strings,
fragments and line locations and normalize slashes; function inputs use the
existing error wrapper normalization. Missing frame inputs use <anonymous>.
Source-map output and message text are not ownership inputs.
The first enabled matching rule with an active organization member who has Errors read assigns a newly created issue. Unavailable owners are skipped. Existing issues keep their owner; manual assignment and clearing remove the automatic ownership marker. Each assignment stores the exact rule snapshot and policy revision on the issue and appends an audit event. Editing a rule does not rewrite that snapshot. The preview evaluates the latest retained event for up to 200 current issues from the past seven days, capped by application retention. It explains current matches and does not reassign existing issues.
The existing app/environment grouping advisory lock protects rule updates, first-event assignment and issue triage. The ingest batch locks eligible owner records before processing errors and writes assignment audit events after the batch's assignments. Ingest never calls GitHub.
Connect one repository
- Create a fine-grained GitHub personal access token limited to the repository,
with Metadata and Issues read access. Enter
owner/repository, the token and a reason in Workflow. Both the token and generated webhook secret use the existing envelope-encrypted vault. The encrypted provider identity binds the environment UUID; the vault purpose isconnector. - Save the webhook secret shown once, then verify repository access. Verification checks the repository's immutable ID, exact name, enabled Issues feature and Issues read access. Renamed/transferred repositories refuse redirects; reconnect deliberately to the new repository.
- In the GitHub repository's webhook settings, enter the shown payload URL,
choose
application/json, set the generated secret, enable SSL verification and subscribe to Issues events. The endpoint isPOST /api/v1/webhooks/github-errors/{connectionId}. - Open a local error occurrence, expand Link an existing GitHub issue to this occurrence, enter a GitHub issue number and review the fetched title/state. Linking requires the actor-bound ten-minute review token and re-fetches the issue; a changed issue, occurrence, configuration or review is refused.
The provider adapter uses only authenticated GET requests to
https://api.github.com/repos/..., pins API version 2026-03-10, refuses
redirects, and bounds calls to eight seconds and response bodies to 256 KiB.
Pull requests and inconsistent repository/issue identities are refused. There
is no remote issue creation, remote assignment, commenting, or outbound status
mutation. See GitHub's get-an-issue contract,
repository API, and
API version policy.
Pausing stops provider checks and local sync while recording signed deliveries as ignored. Token rotation revokes the old stored credential and requires access verification. Webhook-secret rotation invalidates the old signature immediately; update GitHub with the new one-time secret. Disconnect revokes both local vault credentials and deletes local links, receipts and resolution details. GitHub issues and the append-only audit ledger remain unchanged.
Exact links and resolution
A link records the accepted event ID and timestamp, the original capture issue, repository/issue immutable IDs and the reviewed remote issue number. An original issue has at most one link. Links follow original error evidence through merge and undo. If evidence expires, the occurrence link is replaced by an explicit unavailable-evidence notice and a link to any remaining local issue; expired evidence is not reconstructed. Existing issue and session, feedback, release and source-map links continue to refer to the actual captured occurrence.
Linking leaves local status unchanged. Optional automatic inward sync handles
future GitHub open/closed transitions. It applies only to an unmerged original
issue with no merged aliases, unchanged local triage and grouping revisions,
and a transition newer than link creation. Ignored issues require review.
GitHub's actual closed_at must not predate a newer retained failure's receive
time. Later title edits update tracker details and never reapply closure.
When these conditions fail, the tracker state and the reason are recorded for review. Apply resolved/reopened status explicitly applies the last stored remote state after an operator reviews local evidence, including manual triage or newer failures. It checks current local and link revisions and refuses any related active merge; undo those merges first. Check GitHub now queues an authenticated read if the stored state needs refreshing. Enabling sync changes only the starting revision for future transitions, not existing local status.
Delivery, retries and retention
GitHub's signature verification contract
is applied to the exact bounded request text using HMAC-SHA256 and constant-time
comparison. Only signed ping and issues envelopes are accepted; the supported
issue actions are closed, reopened, and edited, as documented by
GitHub's Issues webhook.
The verified repository must match. Delivery IDs deduplicate for 90 days;
reusing an ID with a different body or event is refused. Older remote states and
issue payloads older than seven days are ignored. Conflicting states at an equal
timestamp queue an authenticated read rather than applying the webhook.
Per connection, ingress uses the existing instance-local rate limiter at 40 requests per ten seconds, a 256 KiB body bound and 10,000 retained receipt limit. There are at most 1,000 links per connection and 20 original failures per GitHub issue, bounding webhook fan-out. Webhooks only update existing links; unlinking cannot be undone by a delayed delivery.
The worker's errors.workflow.reconcile job runs every minute, claims at most
ten due links with 30-second leases, and normally rechecks each every 15 minutes.
Provider retries honor bounded rate-limit delays or exponential backoff up to
one hour, stopping after six consecutive failures until explicitly queued again.
A configuration change or credential revocation during a call discards its
result. Operator diagnostics show check freshness, errors and retry state.
errors.workflow.retention runs hourly, scans 100 least-maintained configured
scopes per pass, deletes receipts after 90 days and resolution details after the
application retention period (at most 90 days), and deletes at most 1,000 rows from each table per scope/pass. Each
recorded transition also trims its link to the latest 100 events before auditing. Private history reads enforce the same age cutoff before physical cleanup.
Configuration, assignment snapshots and the bounded reviewed links are operator
state retained until changed, unlinked or scope-deleted. Resolution details are
PII-gated; mutation audit records contain identifiers and outcomes, not secrets
or copied private tracker titles.