| name | enclave-pr-annotator |
| description | GitHub PR attestation comment service for Latch Enclave. Posts session receipts as Markdown comments on GitHub PRs via the REST API. Use when working on PR annotations, attestation comments, or GitHub integration for session receipts. |
PR Annotator Service
File: src/main/services/pr-annotator.ts
Posts Latch attestation session receipts as structured Markdown comments on GitHub pull requests. Uses the GitHub REST API directly (no SDK dependency).
API
parsePrUrl(url: string): PrUrlParts | null
Extracts owner, repo, and prNumber from a GitHub PR URL of the form https://github.com/{owner}/{repo}/pull/{number}. Returns null for non-GitHub URLs or malformed paths.
formatReceiptComment(receipt: SessionReceipt): string
Formats a SessionReceipt as a Markdown PR comment body containing:
- Header with policy ID and data tier
- Markdown table with activity metrics (network requests, blocked requests, redactions, tokenizations, tool calls, tool denials, sandbox type, duration, exit reason)
- Collapsible
<details> section with cryptographic proof (Merkle root, audit event count, truncated signature and public key)
- Footer linking to Latch Desktop
annotatePR(receipt: SessionReceipt, prUrl: string, githubToken: string): Promise<{ ok, commentUrl?, error? }>
Posts the formatted receipt comment on a GitHub PR. Steps:
- Parses the PR URL with
parsePrUrl
- Formats the receipt with
formatReceiptComment
- POSTs to
https://api.github.com/repos/{owner}/{repo}/issues/{prNumber}/comments
- Returns the
html_url of the created comment on success
Headers sent: Authorization: Bearer {token}, Accept: application/vnd.github+json, X-GitHub-Api-Version: 2022-11-28.
GitHub Token Resolution
The IPC handler (latch:attestation-annotate-pr in src/main/index.ts) resolves the GitHub token from the secrets store under the key service:github. It attempts to parse the stored value as JSON (extracting .token or .apiKey) and falls back to the raw string value.
Comment Format
The generated Markdown comment has this structure:
## Latch Attestation
Policy and tier summary line.
| Metric | Value |
|--------|-------|
| Network requests | ... |
| Blocked requests | ... |
| ... | ... |
<details>
<summary>Cryptographic proof</summary>
- Merkle root, audit event count, signature, public key
</details>
---
*Generated by Latch Desktop*
Testing
- Test file:
src/main/services/pr-annotator.test.ts
- Test count: 6 tests
- Run:
npx vitest run src/main/services/pr-annotator.test.ts
Tests cover: URL parsing (valid and invalid), policy ID inclusion, activity metrics inclusion, Merkle root inclusion, and sandbox type inclusion in the formatted comment.