GeezerVison is showing github.com — Add PR-description staleness guardrails (PROF-16592) by jbachorik · Pull Request #980 · DataDog/java-profiler
Conversation
jbachorik
commented
Nov 11, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
What does this PR do?:
Agents evolve a branch after its PR is open — review fixes, rebase replays, scope changes — without re-verifying the PR title and description. This adds a warn-level guardrail set that keeps descriptions in sync:
pr-writing skill rule plus an AGENTS.md routing line: whenever commits are added to a branch with an open PR, re-verify the title and description against the new diff and update what no longer holds.
.githooks/pre-push: every branch push that passes the marker, copyright and CLAUDE.md gates and targets a branch with an open PR warns (never blocks) to re-verify the description.
- The Claude Code / Pi review-freshness hook: the PR-ready subcommand is blocked when the PR description was last edited before the PR's head commit (one
gh pr view probe; comments also bump updatedAt, so a fresh value allows). The probe fails open.
Motivation:
The pre-PR review gate certifies the code but nothing watches the description afterwards, so stale descriptions (wrong scope, dead numbers, dropped accepted costs) reach reviewers and merge. The pre-push path warns because the common write-description-then-commit-then-push flow has the description edit predating the head commit — a timestamp gate there would false-fire; the ready path blocks because marking ready is an explicit freshness claim.
Additional Notes:
Accepted costs, flagged for reviewer acknowledgment:
pre-push now makes one gh pr list call on every branch push (previously skipped for a fresh marker); offline pushes fail open, at up to a 10s timeout.
- A rebase or
--force-with-lease replay rewrites commit dates, so marking ready blocks until the description is re-saved — a no-op edit clears it.
- The description gate dates the head commit by its committer timestamp, which is backdatable; an older commit force-pushed as head passes the gate (documented in
utils/README.md known limits).
Agentic review (sphinx, seven rounds — initial, two fix re-reviews, post-rebase re-review, PR-thread fixes, and the follow-up re-review round): 0 CRITICAL/HIGH. LOW findings were fixed or dismissed with evidence (per-ref probe cost and probe fail-open are accepted design; git refnames cannot contain spaces, so the 4-token split in ready_target is safe; the isdigit/slash guards are behaviorally indistinguishable under fail-open). PR review threads are addressed: the description probe now dates the body by its own edit time, reads the head from commits(last: 1), and resolves the repository from the PR URL over -R.
A base-commit spotless break (unformatted JvmtiEventTimingTest from #947) was fixed in this branch and then dropped on rebase: #982 landed the identical formatting on main. The gap it exposed — local gates cannot see a violation living in the base commit — remains unguarded.
How to test the change?:
bash utils/tests/test_review_marker.sh — 273 tests, 0 failed (adds description-staleness block/equal/fresh, createdAt fallback, unparseable and naive timestamps, future-dated head, PR-moved fail-open, no-commits fail-open, pre-push warning deferral, created-remote-ref probe skip, marker-vs-description precedence, and cross-repository PR-URL description probes).
For Datadog employees:
- If this PR touches code that signs or publishes builds or packages, or handles
credentials of any kind, I've requested a security review (run the dd:platform-security-review
skill, or file a request via the PSEC review form).
bewaire also runs automatically on every PR.
- This PR doesn't touch any of that.
- JIRA: PROF-16592
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
datadog-datadog-us1-prod[bot] reacted with thumbs up emoji
Uh oh!
There was an error while loading. Please reload this page.
dd-octo-sts
Bot
commented
Nov 11, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
CI Test Results
Run: #43229730678 | Commit: 3a40805 | Duration: 20m 3s (longest job)
✅ All 32 test jobs passed
Status Overview
| JDK |
glibc-aarch64/debug |
glibc-amd64/debug |
musl-aarch64/debug |
musl-amd64/debug |
| 8 |
- |
✅ |
- |
- |
| 8-ibm |
- |
✅ |
- |
- |
| 8-j9 |
✅ |
✅ |
- |
- |
| 8-librca |
- |
- |
✅ |
✅ |
| 8-orcl |
- |
✅ |
- |
- |
| 11 |
- |
✅ |
- |
- |
| 11-j9 |
✅ |
✅ |
- |
- |
| 11-librca |
- |
- |
✅ |
✅ |
| 17 |
✅ |
✅ |
- |
- |
| 17-graal |
✅ |
✅ |
- |
- |
| 17-j9 |
✅ |
✅ |
- |
- |
| 17-librca |
- |
- |
✅ |
✅ |
| 21 |
✅ |
✅ |
- |
- |
| 21-graal |
✅ |
✅ |
- |
- |
| 21-librca |
- |
- |
✅ |
✅ |
| 25 |
✅ |
✅ |
- |
- |
| 25-graal |
✅ |
✅ |
- |
- |
| 25-librca |
- |
- |
✅ |
✅ |
Legend: ✅ passed | ❌ failed | ⚪ skipped | 🚫 cancelled
Summary: Total: 32 | Passed: 32 | Failed: 0
Updated: 2026-11-12 14:04:57 UTC
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
dd-octo-sts
Bot
commented
Nov 11, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Scan-Build Report
| User: | runner@runnervmwuk1x |
| Working Directory: | /home/runner/work/java-profiler/java-profiler/ddprof-lib/src/test/make |
| Command Line: | make -j4 all |
| Clang Version: | Ubuntu clang version 21.1.8 (6ubuntu1)
|
| Date: | Thu Nov 12 12:12:59 2026 |
Bug Summary
| Bug Type | Quantity | Display? |
| All Bugs | 2 | |
| Logic error | |
| Dereference of null pointer | 1 | |
| Unused code | |
| Dead initialization | 1 | |
Filter Results by File
Reports
| Bug Group |
Bug Type ▾ |
File |
Function/Method |
Line |
Path Length |
|
| Unused code | Dead initialization | referenceChains.cpp | applyOomRamp | 497 | 1 | |
| Logic error | Dereference of null pointer | perfEvents_linux.cpp | unregisterThread | 720 | 26 | |
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
dd-octo-sts
Bot
commented
Nov 11, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Codex Review Summary: ✅ Completed
This comment shows the latest Codex review activity on this pull request.
| Review |
Status |
Commit |
Review trigger |
| 📝 Code Review |
✅ Completed 2026-11-11T17:57:49.923074Z |
b45dc07 |
Draft marked ready |
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review" or "@codex security review".
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b45dc07d8f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.

On PRs with more than 100 commits, the ready-time guard can compare freshness against commit 100 instead of the head, allowing stale descriptions through.
Open Bits AI session
🤖 Bits Code Review · Commit 5545c35
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
|

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 9a30bde | Docs | Give us feedback!
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Agentic review of head b45dc07d8 against merge base fb82a0012 (main).
The range changes .claude/hooks/require-fresh-review.py and .githooks/pre-push, so the reviewer table's gate row applies. This review ran /code-review at high effort in a fresh context, reading code only at the head commit. I checked each finding below against the code.
What holds
stale_description runs only after the marker check passes, so the new check can only add a block. Its fail-open paths reach only the new check.
gh pr create and the pre-push block condition are unchanged.
- The timestamps are timezone-aware, and committer date is the right field for a rebase.
- The
JvmtiEventTimingTest.java change is formatting only.
High: the staleness check almost never fires (require-fresh-review.py, stale_description)
- It compares the PR's
updatedAt with the head commit's committedDate.
- GitHub bumps
updatedAt on every push, CI status change, review, bot comment and label change, so it is nearly always later than the head commit.
- Example, Fix reference-chain nightly flakes and drop their quarantine #899: the body was last edited on 2026-10-25 (GraphQL
lastEditedAt) and the head commit is from 2026-11-11. The hook's own probe returns updatedAt 2026-11-11T17:27:46Z and committedDate 2026-11-11T14:11:06Z, so it counts the PR as fresh and allows gh pr ready.
- The README's "blocks" and "a rebase blocks until the description is re-saved" do not happen in practice: the rebase push itself bumps
updatedAt.
- The tests inject made-up timestamps, so they cannot catch this.
- Possible fix: query
lastEditedAt through gh api graphql (gh pr view has no such field), and fall back to createdAt when it is null.
- A weaker gap remains even with that fix:
committedDate is when the commit was made, not when it was pushed.
Low
gh pr ready now makes two gh pr view calls on the same PR (ready_target and stale_description), each with a 10 s timeout. One query could serve both.
- pre-push now makes one
gh call per pushed branch ref, not one per push. Offline, git push origin a b c can wait up to 10 s per ref.
- The pre-push warning prints for a passing ref even when another ref in the same push is blocked and nothing is pushed.
utils/README.md: "a fresh marker still skips the marker check itself" contradicts the code, because review-marker.py check always runs.
test_review_marker.sh: the gh stub returns the same updatedAt for any query, so a regression that queries the wrong PR (no selector or -R) would still pass.
This is a comment only, not an approval or a change request.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
pre-push warns on every open-PR push to re-verify the description;
the PR-ready subcommand blocks when the description predates the PR
head commit, failing open; pr-writing skill and AGENTS.md route the
re-verification.
CodeQL code-quality flags implicit adjacent string concatenation;
same string, explicit +.
GitHub's updatedAt also moves on comments and pushed commits, so the
ready gate allowed ready in exactly the stale-description case it
guards. Compare lastEditedAt (createdAt fallback) against the head
commit's date fetched via commits(last:1); commits returns only its
first page, so .[-1] over it can miss the head.
Add the two tests the round-2 sphinx review flagged as mutation-escape
gaps: a stale marker with a stale description must report the marker's
reason (the returncode guard), and a failing check with no open PR must
not block (the and-open_pr guard). Dedupe a doubled VIEW_NUMBER
assignment.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.

PR URL targets can send the description-freshness probe to a different repository, allowing stale descriptions or blocking readiness based on an unrelated PR.
Open Bits AI session
🤖 Bits Code Review · Commit 8fd44f6
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The lastEditedAt probe reintroduced the implicit adjacent string
concatenation the earlier fix removed from the old probe; same jq text,
explicit +.
gh resolves a PR-URL selector's repository over -R, so a cross-repo
ready command checked the -R repository's description. Match
ready_target's resolution order. The test stub now answers only the
queried owner/name and honors URL selectors, so a regression querying
the wrong repository fails the suite.
gh pr view accepts URLs with trailing path fragments (/files) and
still resolves them by the URL's repository; match the same prefix.
|
Addressed in the current head:
- High (updatedAt) — fixed in fbb9c52: the probe reads the body's own edit time (GraphQL
lastEditedAt, createdAt fallback) instead of updatedAt.
- committedDate gap — real; documented as an accepted limit in
utils/README.md (8fd44f6): the committer timestamp is backdatable, and an older commit force-pushed as head passes the gate.
- README "fresh marker skips the marker check" contradiction — fixed in 5bdded4: the sentence now states the actual behavior (the check always runs; a fresh marker only avoids the block).
gh stub fidelity — fixed in e89f855: the graphql stub now answers only the queried owner/name, and the pr view stub honors URL selectors, so a regression querying the wrong repository or selector fails the suite.
Deferred, with reasons: the two pr view/graphql calls on the PR-ready path (each ≤10s and on a fail-open path — sharing one query complicates ready_target for little gain); the per-ref pre-push gh call (documented known limit); the pre-push warning printed for a passing ref when another ref in the same push is blocked (informational only).
Two additional bot findings were fixed in this round: the graphql jq argument's implicit string concatenation (c5e344d) and the description probe querying the -R repository instead of the PR URL's (e89f855, pinned by the new stub).
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.

More details
The PR adds guidance and push reminders to keep descriptions current, plus a freshness gate before marking PRs ready. The URL/repository mismatch is fixed, including URLs ending in /files, and no findings remain open; documented timestamp limitations and per-branch network costs remain.
Was this helpful? React 👍 or 👎
Open Bits AI session
🤖 Bits Code Review · Commit 9edb830
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Agentic re-review of head 9edb83098 against merge base 399ce5e60 (main). The branch was rebuilt since my review of b45dc07d8, so this covers the whole PR again. Reviewer: /code-review at high effort in a fresh context, reading code only at the head commit (gate row; the PR changes require-fresh-review.py and .githooks/pre-push). I checked each finding below against the code.
Earlier findings
- The High is fixed: the check now dates the description by
lastEditedAt, with createdAt when the body was never edited, not by updatedAt. Bot body edits (the Jira bot) come about 5 s after a human edit, so they do not defeat it.
- The README sentence about the marker check now matches the code.
What holds
- The staleness probe runs only after the marker check passes, so it can only add a block. Every fail-open path affects only the new check.
- The pre-push block condition is unchanged.
Medium: the description probe can read a different repository than gh pr ready uses (evaluate, pr_repo)
ready_target gets the PR from gh's own resolution, but the probe resolves the repository again: a PR_URL match (https://github.com/ only), then the -R value, then gh repo view.
- With an
http://, GHES or upper-case-host URL and a different -R, the probe reads the dates of an unrelated PR, so it can block or pass on the wrong PR.
gh repo view has no -R flag (gh 2.91.0: "unknown shorthand flag: 'R' in -R"). So for an -R value that is not OWNER/NAME, for example github.com/DataDog/java-profiler, pr_repo always fails and the check silently fails open.
- Possible fix: return the PR's
id or url from the same gh pr view call in ready_target, and query node(id:). That removes pr_repo and the second selector parse.
Low
- The head commit is dated through a separate
commits(last:1) read, not the headRefOid that the marker check approved. A push between the two calls compares against a different commit. repository.object(oid:) would bind it.
- A commit with a future-dated committer clock blocks
gh pr ready until wall-clock time catches up, and no description edit can clear it.
- It is unconfirmed that re-saving an identical body moves
lastEditedAt, which the README's "a no-op edit clears it" relies on. A title-only edit does not move it.
- The "lacks a UTC designator" test uses a naive time later than the head, so it also passes if naive values were treated as UTC. A naive time earlier than the head would prove fail-open.
- The
gh stub returns $VIEW_GRAPHQL as is, so the jq expression in stale_description never runs in the tests. Its repo view branch ignores -R, which is why the Medium is not caught. The stub's header comment does not list the new variables.
has_open_pr now runs for every pushed branch ref. A ref whose remote sha is all zeros (a new branch) cannot have an open PR and could skip the call.
- The pre-push "re-verify its title and description" warning prints even when another ref in the same push is blocked and nothing is pushed.
- The
stale_description docstring is 7 lines and describes a .[-1] approach that the code no longer uses, and the README uses history wording ("no longer skips the network"). Both are against the AGENTS.md comment and doc rules.
This is a comment only, not an approval or a change request.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, feel free to fix the remaining minor issues here or in a follow-up, as you see fit.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
rkennke re-review: the probe re-resolved the repository (http/GHES URLs
and non-OWNER/NAME -R values read an unrelated PR or fail open, and gh
repo view has no -R), and dated a head commit from a separate read. One
node(id:) query now reuses the PR gh pr view resolved and pins the commit
by the query's headRefOid against the marker-approved oid; a future
committer date fails open. pre-push skips the open-PR probe for remote
refs the push creates and defers the description warning until the push
is decided. The test stub applies the command's real --jq expression and
keys on the queried node id, so the jq path and wrong-PR regressions are
exercised; the naive-timestamp test now proves fail-open.
Single quotes left $WT_TIP literal, so the test passed through the
oid-mismatch guard instead of the empty-commits path it names.
|
Addressed in the current head:
- Medium (probe reads a different repository) — fixed in bc97dab:
ready_target now returns the PR's node id from the same gh pr view call, and the probe queries node(id:) with it. pr_repo and the second URL/-R parse are gone, so the http/GHES/upper-case-host and non-OWNER/NAME -R cases cannot disagree with what gh pr ready targets.
- Low (head commit from a separate read) — fixed in bc97dab: the same query returns the PR's own
headRefOid, which must match the marker-approved oid or the gate fails open; the commit date and the description timestamps now come from one response.
- Low (future-dated committer clock) — fixed in bc97dab: a committer date more than five minutes ahead of the wall clock fails open.
- Low (naive-time test direction) — fixed in bc97dab: the naive timestamp is now earlier than the head, so the test fails if naive values were treated as UTC.
- Low (stub fidelity) — fixed in bc97dab: the stub applies the command's real
--jq expression and keys the graphql answer on the queried node id; the header comment lists the new variables. The jq path in stale_description is now exercised.
- Low (all-zero remote sha) — fixed in bc97dab:
pre-push skips the open-PR probe for refs the push creates.
- Low (warning with a blocked ref) — fixed in bc97dab: the description warning is deferred and prints only when the push is not blocked.
- Low (docstring/README wording) — fixed in bc97dab: the
stale_description docstring describes the current mechanism, and the README sentences are in current-state wording.
Deferred, with reasons: the two pr view/graphql calls on the PR-ready path (both on fail-open paths, each ≤10s; sharing one query complicates ready_target for little gain); a test pinning the exact COMMIT_DATE_SKEW boundary (would race the hook's clock and flake; the boundary behavior on either side is immaterial).
One follow-up review finding was also fixed: the no-commits test's fixture left $WT_TIP unexpanded, so it passed through the oid-mismatch guard instead of the empty-commits path (9a30bde).
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
View all feedbacks in Devflow UI.
2026-11-12 13:10:47 UTC ℹ️ Start processing command /merge
2026-11-12 13:10:52 UTC ℹ️ MergeQueue: pull request added to the queue
The expected merge time in main is approximately 53m (p90).
2026-11-12 13:41:41 UTC ℹ️ MergeQueue: This merge request was merged
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
rkennke
rkennke approved these changes
+1 more reviewer
Reviewers whose approvals may not affect merge requirements
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|