MemtraceDOCS

memtrace pr

Check and refresh the local watches that memtrace code-review --post --watch registers, and see the human response to a posted review.

Usage#

memtrace pr [status | sync [--no-execute] | help]

memtrace pr manages the local PR review watches that memtrace code-review --post --watch registers on this machine. There's no separate add/remove subcommand — watches are created only by posting a review with --watch, and tracked in ~/.memtrace/pr-watches.json.

status is the default when no subcommand is given. Any value other than status, sync, or help errors out with unknown pr subcommand and a non-zero exit.

status#

Read-only and purely local. Prints one line per watched PR — owner/repo#number, current status, posted-comment count, and pending/completed/failed @memtrace-command counts — or No Memtrace PR watches registered. when the state file is missing, empty, or unreadable. status never fails and never touches the network.

NOTE

A corrupt pr-watches.json is silently treated as empty (just a warn-level log). An empty status output doesn't prove watches were never registered — check the file directly if you suspect corruption.

sync#

memtrace pr sync [--no-execute]

A one-shot poll. sync initializes Memtrace auth, drains any pending relay events from the Memtrace cloud, then for each watch (up to 50 per invocation) mints a short-lived GitHub App installation token, fetches the PR plus its issue comments, reviews, and review comments from api.github.com, refreshes that watch's status, parses any @memtrace commands newer than the watch's registration time, and — by default — executes them.

FlagDescription
--no-executeDetect and record @memtrace commands found in PR comments as pending, but don't run them: no reactions, check runs, child processes, or GitHub writes. Watch statuses are still refreshed normally.
SYNC EXECUTES COMMANDS BY DEFAULT

Without --no-execute, sync runs any queued @memtrace review, rerun, explain, ignore, fix this, or merge command it finds in PR comments — which can post comments/reactions/check runs, push commits, or merge the PR. The top-level memtrace help text only says pr sync "polls GitHub once" and doesn't mention command execution; the full behavior is documented in memtrace pr help.

Command execution is permission-gated through GitHub's collaborator-permission API: ignore, fix this, and merge require write/maintain/admin access; review, rerun, and explain only require the PR author or any collaborator with read access. Unauthorized commands get an "I can't run that command" reply instead of running. Commands are matched case-insensitively with word-boundary checks, bot-authored comments are skipped, and each command is deduplicated so the same comment can't re-trigger a command twice.

Executing a recognized command follows the same shape for all of them: an eyes-emoji acknowledgment reaction, a "Memtrace / <label>" check run on the head SHA (updated to success/failure/action_required), a completion reaction, and a reply comment with the outcome. The commands themselves differ:

CommandEffect
@memtrace review / rerunRe-execs the memtrace binary as memtrace code-review --pr <url> --post with the watch’s saved max-comments, min-severity, graph-mode, repo-root, and accumulated --ignore-finding flags.
@memtrace explainReplies with a description of the finding; enriched by MEMTRACE_PR_AGENT_COMMAND’s first non-empty stdout line when set, otherwise a static description.
@memtrace ignoreAppends the referenced finding to the watch’s ignored_findings list.
@memtrace fix thisCreates a git worktree on a memtrace-fix-pr-* branch tracking the PR head, pipes a JSON payload to MEMTRACE_PR_AGENT_COMMAND, and if files changed, commits as the bot identity and pushes to the PR’s head branch. Rejected outright on fork PRs.
@memtrace mergePUTs /pulls/{n}/merge pinned to the current head SHA.
YOU RARELY NEED TO RUN SYNC BY HAND

Any running memtrace start or memtrace mcp process already spawns a background poller (every MEMTRACE_PR_POLL_INTERVAL_SECS, default 5s) plus a cloud relay long-poll doing the same work continuously. Manual sync is for a one-off check right now, or a non-daemon/CI context.

LOCK CONTENTION IS SILENT

sync takes an exclusive advisory lock on ~/.memtrace/pr-watches.lock (4 retries, 50–400ms exponential backoff with jitter). If a background poller already holds it, this invocation silently skips the cycle and just prints the unchanged status table — it does not error.

Watch states#

Each watch carries one status, refreshed by every sync:

StatusMeaning
awaiting_responseNo human review or newer comment since the watch was registered.
human_repliedA newer human comment exists, with no formal approve/changes-requested review yet.
approvedThe most recent post-registration PR review event is APPROVED.
changes_requestedThe most recent post-registration PR review event is CHANGES_REQUESTED.
mergedThe PR was merged.
closedThe PR was closed without merging.
stale_after_pushThe PR’s head SHA has changed since the review was posted — the posted findings no longer match the current diff.
poll_errorThe last GitHub fetch for this watch failed; a classified error kind is recorded alongside it.
PR watch lifecycleFLOW
commentAPPROVEDCHANGES_REQUESTEDnew push
--post --watch
awaiting_response
human_replied
Review event?
approved
changes_requested
stale_after_push
merged / closed
TRIGGERSUPPORTINGDECISIONSUCCESSREMEDIATION

Environment variables#

VariableDefaultDescription
MEMTRACE_PR_POLL_INTERVAL_SECS5Interval for the background PR-watch poller running inside memtrace start/memtrace mcp processes — not the one-shot pr sync. Clamped to 2–300 seconds; grows geometrically up to 300s while every watch is stuck in poll_error.
MEMTRACE_PR_AGENT_COMMANDShell command run via /bin/sh -lc with a JSON payload (PR URL, worktree, target finding, head SHA, ...) on stdin. Required for @memtrace fix this; optionally enriches @memtrace explain with its first non-empty stdout line. Without it, fix this fails and explain falls back to a static description.
MEMTRACE_GITHUB_BOT_LOGINmemtrace-code-reviewer[bot]Git author/committer name used when @memtrace fix this commits to the PR branch.
MEMTRACE_GITHUB_BOT_EMAIL286493472+memtrace-code-reviewer[bot]@users.noreply.github.comGit author/committer email used when @memtrace fix this commits to the PR branch.
MEMTRACE_AUTH_URLhttps://www.memtrace.ioBase URL of the Memtrace cloud used by sync for the GitHub App installation-token broker and the PR relay long-poll.

Gotchas#

SYNC NEEDS A LOGGED-IN SESSION

sync requires a real Memtrace cloud session (memtrace auth login). With no session token it fails with "no Memtrace session token available for PR watch sync". An offline license does not provide that cloud session token. status has no such requirement.

NO UNWATCH COMMAND

There's no pr unwatch or pr remove. Watches are added only via memtrace code-review --post --watch; to drop one, edit ~/.memtrace/pr-watches.json directly.

ONLY 50 WATCHES PER SYNC

A single sync invocation polls at most 50 watches. With more than that registered, extras wait for the next cycle (or the background poller, which runs continuously).

FIX THIS HAS REAL PREREQUISITES

@memtrace fix this only works when MEMTRACE_PR_AGENT_COMMAND is set in the syncing process's environment, the watch has a saved repo root, and the PR is same-repo (not a fork) — fork PR fixes are rejected.

TELEMETRY IS COUNTS ONLY

sync emits one aggregate pr_watch_synced telemetry event with counts only — never PR URLs, repo names, paths, or SHAs.

Examples#

terminal
$ memtrace pr
# Same as `memtrace pr status`.

$ memtrace pr status
# Memtrace PR watches
#   owner/repo#123  approved  comments=3  commands=pending:0 completed:2 failed:0  updated=2026-07-04T12:00:00+00:00
#   owner/repo#456  awaiting_response  comments=1  commands=pending:1 completed:0 failed:0  updated=2026-07-04T11:00:00+00:00

$ memtrace pr sync
# Poll GitHub once, refresh every watch's status, and execute
# any queued @memtrace commands found in PR comments.

$ memtrace pr sync --no-execute
# Refresh statuses and record newly seen @memtrace commands
# as pending, without running them.

$ MEMTRACE_PR_AGENT_COMMAND='claude -p "$(cat)"' memtrace pr sync
# Provide the local agent command that @memtrace fix this
# and @memtrace explain invoke (payload arrives as JSON on stdin).

See also memtrace code-review, memtrace start, memtrace mcp, and memtrace auth.