Repository navigation
Maple Review Bot / Maple / review
succeeded
Nov 13, 2026 in 3m 48s
Confidence 10/10 · No issues found
🟢 Confidence 10/10 · safe to merge. Changed page, lab and normalizer code hold up; removal by source id, the refusal link and first-sync copy all trace to code I read.
no findings · tests covered · risk high · 4/4 new units observable
Adds GitHub as a cost source read through the App installation: normalizer, a billing read on the provider port, internal routes, and the Cost page's installations step with add and remove. The changes since the last review hold up; the two listed webhook-enqueue errors are unrelated to this diff.
- GitHub step lists installations with Add, and a GitHub source row gets Remove behind a confirm
fetchBillingUsageandinstallationSettingsUrljoin the VCS provider port, implemented by GitHub- A usage date must be a real day or a real UTC timestamp, or the pull fails
- Provider marks, removal copy and first-sync copy now name GitHub
Before merge
- Manual · Add
Administration: readto the GitHub App registration and accept it in one organization; until then adds are refused
Production impact
Open errors in the changed files (1)
| Issue | Service | Occurrences | File |
|---|---|---|---|
| @maple/api/routes/VcsWebhookEnqueueFailure (2 issues) | maple-api | 9 | apps/api/src/runtime/http-graph.ts |
After this merges, Maple checks whether they stop.
Production traffic of the changed files (last 7 days)
| File | Calls/day | Busiest operations |
|---|---|---|
packages/backend/src/services/integrations/vcs/vendor/github/GithubAppClient.ts |
69 | GithubAppClient.listInstallationRepositories 69/day, 0.0% err |
Telemetry this change adds and removes (11)
- ➕ span name
HttpGithubCost.list·apps/api/src/routes/internal/github-cost.http.ts:33 - ➕ span name
HttpGithubCost.add·apps/api/src/routes/internal/github-cost.http.ts:47 - ➕ span name
HttpGithubCost.remove·apps/api/src/routes/internal/github-cost.http.ts:61 - ➕ span name
CostSyncService.reconcileGithub·packages/backend/src/services/cost/CostSyncService.ts:211 - ➕ span name
GithubCostSourceService.list·packages/backend/src/services/cost/GithubCostSourceService.ts:116 - ➕ span name
GithubCostSourceService.add·packages/backend/src/services/cost/GithubCostSourceService.ts:152 - ➕ attribute
maple.cost.error_reason·packages/backend/src/services/cost/GithubCostSourceService.ts:203 - ➕ span name
GithubCostSourceService.remove·packages/backend/src/services/cost/GithubCostSourceService.ts:234 - ➕ span name
GithubCostProvider.pull·packages/backend/src/services/cost/providers/github/GithubCostProvider.ts:34 - ➕ attribute
maple.cost.github.months·packages/backend/src/services/cost/providers/github/GithubCostProvider.ts:78 - ➕ span name
GithubAppClient.getOrganizationBillingUsage·packages/backend/src/services/integrations/vcs/vendor/github/GithubAppClient.ts:984
What was checked
- Removal is keyed by source id (
update.ts:251), so a GitHub and an OpenRouter source each clear only their own row github_cost_permission_missingmatches the API error code (github-cost.ts:103), so the settings link shows only on a permission refusal- First-sync copy matches
planCostSync:monthStart(today,-1)first, then monthly backfill tomonthStart(today,-3)
Observability coverage: 4 of 4 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
GET /internal/cost/github (installations to pick from) |
HTTP route | yes | Effect.withSpan("HttpGithubCost.list") at apps/api/src/routes/internal/github-cost.http.ts:33 |
PUT/DELETE /internal/cost/github/{installationId} |
HTTP route | yes | withSpan HttpGithubCost.add/.remove at github-cost.http.ts:47 and :61, audited on write |
| GitHub billing usage read (outbound) | outbound call | yes | GithubAppClient.getOrganizationBillingUsage is an Effect.fn span; fetchBillingUsage wraps it on the provider port |
| Cost sync pull for a GitHub source | background work | yes | GithubCostProvider.pull span annotates maple.cost.provider, maple.cost.start_day/end_day, maple.cost.rows and maple.cost.error_reason (GithubCostProvider.ts:34-83) |
221ba3d · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Loading