fix(observability): canonicalise child-logger entity id under entityNumber - #178
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (10)
📝 WalkthroughWalkthroughThis PR establishes a canonical ChangesEntity Number Logging Correlation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Canonicalizes the per-request entity identifier across webhook handlers and the workflow executor under a single entityNumber field so operators can grep one field name to reconstruct a request end-to-end, resolving the field-name drift described in issue #175.
Changes:
- Widen
createChildLoggerto accept the four canonical fields plus arbitrary extra bindings, and route 4 webhook handlers (issues,pull-request,issue-comment,review-comment) through it, replacingissueNumber/prNumberwithentityNumber. Also addentityNumberonreview.ts/review-thread.tslog lines and a flatentityNumber(alongside nestedtarget) inworkflow-executor.ts. - Update
docs/operate/observability.mdlede and Common log fields table with theentityNumberrow. - Add tests in
test/utils/logger.test.tsfor the bindings contract.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/logger.ts | Widens createChildLogger signature with & Record<string, unknown> and expands the contract docstring. |
| src/webhook/events/issues.ts | Routes labeled-handler through createChildLogger and renames issueNumber → entityNumber. |
| src/webhook/events/pull-request.ts | Same migration for pull_request.labeled (prNumber → entityNumber). |
| src/webhook/events/issue-comment.ts | Migration plus comment noting PR comments share the canonical field. |
| src/webhook/events/review-comment.ts | Migration and rename for review-comment handler. |
| src/webhook/events/review.ts | Adds entityNumber to the per-request log line. |
| src/webhook/events/review-thread.ts | Adds entityNumber to the per-request log line. |
| src/daemon/workflow-executor.ts | Adds flat entityNumber from context.entityNumber next to nested target. |
| docs/operate/observability.md | Updates lede and Common log fields table with entityNumber row. |
| test/utils/logger.test.ts | New tests for canonical bindings and extras passthrough. |
…umber Webhook event handlers hand-rolled `logger.child` with drifting entity field names (issueNumber vs prNumber), bypassing the canonical createChildLogger helper, so an operator could not grep one field name to reconstruct a request end-to-end. - Widen createChildLogger to accept the 4 required canonical fields plus arbitrary extra bindings, so handlers route through the single source of truth while keeping per-handler context (event, label, senderLogin). - Migrate issues / pull-request / issue-comment / review-comment handlers to createChildLogger emitting canonical `entityNumber`. - Add entityNumber to review.ts and review-thread.ts per-request log lines (they previously emitted no entity id). - workflow-executor.ts: add flat entityNumber alongside the nested `target` envelope (target retained). - Docs: observability.md lede + new entityNumber row in Common log fields. - Tests: assert createChildLogger binds entityNumber and passes extras through, and that drifted issueNumber/prNumber names do not leak back. No compatibility mirror or installationId: nothing consumes the old field names (grep-clean), and installationId is tracked separately as #177. Closes #175 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# [1.14.0](v1.13.0...v1.14.0) (2026-06-30) ### Bug Fixes * **agent-sdk:** pass settingSources [] so SDK ignores cloned PR .claude/settings.json ([#195](#195)) ([153fef3](153fef3)) * **check:** derive scoped-executor scan set from filesystem (dead guard) ([#208](#208)) ([8b0e8ef](8b0e8ef)) * **daemon:** sweep full workspace triple on startup and crash exit ([#239](#239)) ([56fa714](56fa714)) * **idempotency:** gate side-effecting handlers with Valkey claim to prevent redelivery duplicates ([#212](#212)) ([68dacdb](68dacdb)) * **infrastructure:** patch krb5 HIGH CVE-2026-40356 in shared Docker base ([#180](#180)) ([1d1bc3b](1d1bc3b)) * **mcp:** redact Octokit error tool-results and widen GitHub token regex ([#238](#238)) ([675d610](675d610)) * **mcp:** wrap GitHub-touching MCP servers + state-fetchers in retryWithBackoff ([#205](#205)) ([319beb9](319beb9)) * **observability:** canonicalise child-logger entity id under entityNumber ([#178](#178)) ([808ca46](808ca46)) * **security:** gate LLM scanner redacted_body to deletion-only ([#206](#206)) ([d52cf78](d52cf78)) * **security:** set strictMcpConfig to block cloned-PR .mcp.json auto-load ([#210](#210)) ([2c58ec1](2c58ec1)) * **testing:** run colocated src/**/*.test.ts in CI + add drift guard ([#204](#204)) ([5990e0d](5990e0d)) ### Features * **agent-sdk:** block destructive Bash at runtime via PreToolUse hook ([#241](#241)) ([f3132f2](f3132f2)) * **observability:** add 12 structured Pino event families with Zod-strict schemas ([#251](#251)) ([eaad36b](eaad36b)) * **observability:** add queue_wait_ms to dispatcher offer/no-daemon logs ([#207](#207)) ([7a5cfb0](7a5cfb0)) * **observability:** add structured retry.* events ([#225](#225)) ([6713cbf](6713cbf)) * **observability:** emit failed_stage and failed_stage_delta_ms on pipeline.failed ([#244](#244)) ([4f2483c](4f2483c)) * **observability:** emit structured idempotency events on all 4 claimDelivery outcomes ([#242](#242)) ([e1e7f9e](e1e7f9e)) * **observability:** installationId on loggers + config-free MCP retry ([#189](#189)) ([ba09f76](ba09f76)), closes [#177](#177) [#184](#184) * **observability:** log + persist SDK token usage on executions ([#209](#209)) ([5407dcd](5407dcd)) * **observability:** log octokit rate-limit headers via hook.after ([#183](#183)) ([30e1715](30e1715)) * **observability:** periodic fleet-state gauge snapshot ([#186](#186)) ([7429460](7429460)) * **observability:** redact crash logs via uncaughtException/unhandledRejection handlers ([#181](#181)) ([d4248f4](d4248f4)) * **observability:** structured dispatcher + heartbeat log events ([#188](#188)) ([c615bc4](c615bc4)) * **observability:** structured pino logger for stdio MCP servers ([#185](#185)) ([5244e8a](5244e8a)) * **observability:** structured pipeline.stage timing events with delta_ms ([#182](#182)) ([4125971](4125971))
|
🎉 This PR is included in version 1.14.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
What
Resolves #175. The canonical
createChildLoggerhelper (src/logger.ts) defines the{deliveryId, owner, repo, entityNumber}correlation contract and is already used byapp.ts,core/context.ts, anddaemon/job-executor.ts— but the webhook event handlers bypassed it, hand-rollinglogger.childwith a drifting entity field name (issueNumberin issues/issue-comment,prNumberin pull-request/review-comment). An operator who knows a PR/issue number could not grep one field name to reconstruct a request end-to-end.Changes
createChildLoggerto accept the 4 required canonical fields plus arbitrary extra bindings (& Record<string, unknown>), so handlers route through the single source of truth while keeping per-handler context (event,label,senderLogin). Existing 4-field callers are unaffected (verified typecheck).issues,pull-request,issue-comment,review-comment) tocreateChildLogger, emitting canonicalentityNumber.entityNumbertoreview.tsandreview-thread.tsper-request log lines (they previously emitted no entity id), so every webhook handler with a per-request line is greppable by entity.workflow-executor.ts: add a flatentityNumberalongside the nestedtargetenvelope (target retained).entityNumberrow in the Common log fields table (documents the surviving adjacent layers: job-payloadprNumber/issueNumberand scoped-rail snake_casepr_number/issue_number).test/utils/logger.test.tsassertscreateChildLogger().bindings()carriesentityNumber, passes extras through, and that the driftedissueNumber/prNumbernames do not leak back.Verification
bun run typecheck,eslint .(0 errors),prettier --check,check:docs-citations,check:no-em-dashes→ clean.bun test test/utils/logger.test.ts→ 16 pass (2 new). Webhook/workflow-executor tests pass per-file; the combined-run 4 fail/4 error are a pre-existing cross-file test-isolation issue (identical count on cleanmain, verified by stash).Scope decisions (judgement calls)
prNumber/issueNumbercompatibility mirror. Verified grep-clean — nothing consumes those field names (no docs, dashboards, or alerts). A mirror would be tech debt + a needless follow-up. This also makes the proposedisPRdiscriminator unnecessary.installationIddescoped → tracked as feat(observability): emit installationId on per-request child loggers for per-installation quota triage #177. It is a separate correlation enhancement and interacts with installation-guard ordering; not the field-name-drift bug.ws-messages.ts/job-queue.ts/job-dispatcher.ts) untouched — theprNumber/issueNumberthere are the job-payload contract, a different layer not cited by the issue.issues.ts,pull-request.ts) and one internal-error fallback (pull-request.tsrepos.getCommit failed, retainsprNumber) are not request-correlation lines; left as-is, can fold into feat(observability): emit installationId on per-request child loggers for per-installation quota triage #177 for full uniformity.Senior-review gate: 3 iterations, converged clean (CodeRabbit unavailable this run — org out of credits — so senior-review is the quality gate).
🤖 Generated with Claude Code
Summary by CodeRabbit