Table of Contents generated with DocToc
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.
uv (uv run --directory tools/github-rollup github-rollup …); stdlib-only, no third-party dependencies.uv; gh — the script shells out to it for all GitHub access (the default @user comes from gh api user).gh session (gh auth status must pass) — the comment read / append / PATCH all go through gh.api.github.com via gh.This helper has no persistent config file of its own. Callers pass the target issue from <project-config>/project.md → tracker_repo; the status-rollup comment format is the GitHub tracker convention documented in tools/github/status-rollup.md and reused by security lifecycle skills.
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. append and amend-latest print the rollup comment’s URL on stdout, so a caller can link to it without reading the rollup.
uv run --directory tools/github-rollup github-rollup <subcommand> ...
Under the secure agent setup this CLI's gh runs sandboxed and fails, so skills call the same procedures through vetted-ops instead: vetted-op-tracker --caller <skill> rollup-append <N> "<action>" <scratch>/entry.md, rollup-amend-latest <N> "<action>" <scratch>/entry.md, and rollup-fold <N> <comment-id> "<action>". The uv CLI remains for use outside the sandbox.
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.A new rollup's marker line is <!-- apache-magpie: status-rollup v1 -->. An existing rollup is found by that marker first, then by the legacy <!-- <name> status rollup v<N> marker, so a tracker with both keeps growing the canonical one.
Only a comment written by a trusted author can be the rollup: the authenticated gh user, or a collaborator of the repository (the security-team roster, see operations.md). A marker line in a comment by anyone else is ignored by every subcommand, so a commenter outside the roster cannot plant a comment that append, amend-latest, list or latest would then use. Listing collaborators needs push access to the repository; when the list cannot be read, only comments by the authenticated gh user count, and when the first marked comment is someone else‘s the command stops with an error rather than risk starting a second rollup next to a collaborator’s.
amend-latest <issue> --action "<label>" ...Replace the body of the most recent entry, keeping its date and user. Use it when a later step of the same pass has to fill in a value the entry already mentions (for example a draft id). Refuses with exit 4 when the latest entry's action is not <label>, so an entry someone else appended in the meantime is never overwritten. Body from --entry-body or --entry-body-file; --dry-run supported.
fold <issue> --comment-id <id> --action "<label>"Fold one legacy bot comment into the rollup: the entry takes the legacy comment‘s own date and author, every line is left-trimmed, and the legacy comment is deleted only after the append succeeded. Refuses (exit 4) when the comment is the rollup itself. Which comments are foldable, and the action label to use, is the caller’s decision — see status-rollup.md. --dry-run supported.
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.
| 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 / amend-latest). |
| 4 | Refused: amend-latest action mismatch, or fold pointed at the rollup itself. |
| other | gh returned non-zero; the underlying stderr is forwarded. |