Table of Contents generated with DocToc

github-rollup

Capability: contract:tracker

Kind: implementation

Vendor: GitHub

Append to (or create) the status-rollup comment on a GitHub issue without bringing the rollup body into agent context.

Prerequisites

  • Runtime: Python 3.11+ run via uv (uv run --directory tools/github-rollup github-rollup …); stdlib-only, no third-party dependencies.
  • CLIs: uv; gh — the script shells out to it for all GitHub access (the default @user comes from gh api user).
  • Credentials / auth: an authenticated gh session (gh auth status must pass) — the comment read / append / PATCH all go through gh.
  • Network: api.github.com via gh.

Configuration

This helper has no persistent config file of its own. Callers pass the target issue from <project-config>/project.mdtracker_repo; the status-rollup comment format is the GitHub tracker convention documented in tools/github/status-rollup.md and reused by security lifecycle skills.

Why

Every skill that updates a <tracker> issue (import receipt, sync passes, CVE allocation, dedupe, fix-PR announcements) folds its status update into one rollup comment per tracker. The existing recipe in tools/github/status-rollup.md walks the agent through: fetch the comment, concatenate <old body> + ruler + new entry, PATCH the comment. That loops the full rollup body — which grows monotonically and is the single largest comment on a long-running tracker — through agent context every sync pass.

This tool does the read / append / PATCH in a subprocess. Only a one-line confirmation lands on the agent’s stderr. The body never crosses the boundary.

Invocation

uv run --directory tools/github-rollup github-rollup <subcommand> ...

append <issue> --action "<label>" ...

Append a new entry to the rollup comment on <issue>. Creates the rollup if none exists. Required: --action <label> (the right-hand field of the entry’s summary line). Body comes from either --entry-body "<text>" or --entry-body-file <path> (- reads stdin).

Optional flags:

  • --user @handle — override the summary’s @user field (default: the authenticated gh user from gh api user).
  • --now <ISO8601> — override the date used in the summary (default: real now). Useful for deterministic replay tests.
  • --dry-run — print the decision (create vs append) without writing.

list <issue>

Print every entry’s summary line in order (or --json for a machine-readable array of {date, user, action}). Exit 3 if the issue has no rollup yet.

latest <issue>

Print just the body of the most recent entry. Useful for “what did the last sync do?” in a follow-up script. Exit 3 if the rollup or entries are missing.

Failure modes

Exit Meaning
0 Success (or --dry-run planned).
2 CLI argument error (mutually-exclusive flags, missing required).
3 Issue has no rollup yet, or rollup has no entries (for latest).
other gh returned non-zero; the underlying stderr is forwarded.
Suggest a change