ADLC
Toolkit

ticket-prune

Reports stale, already-shipped tickets and, with --write, tombstones or archives them so live work is not buried under leftovers.

ticket-prune

ADLC phase: maintenance / cross-phase (C12) · Gate: none. Advisory report; --write tombstones (legacy store) or archives (sharded store) stale tickets, never deletes.

What it defends against

.adlc/tickets.json is a mutable scratchpad, and nothing else prunes it after a ticket ships. Completed tickets accumulate and masquerade as an open backlog. You can't tell live work from leftovers without cross-checking deliverables and merged PRs by hand. ticket-prune reports (and, with --write, tombstones or archives) the tickets it can determine are stale, so the backlog reflects what is actually open.

A ticket is stale when it carries an explicit terminal status (done / closed / complete / completed / archived / shipped, case-insensitive), or — only with --infer-scope — when, absent a status, it declares at least one scope glob and every glob resolves to a file tracked at --base-ref. A ticket with no scope and no status is never inferred stale.

That scope-existence inference is off by default (#779). Scope existence is not evidence that a ticket's work landed: packages/core/** matches a tracked file the moment the ticket is authored on any repo older than its backlog, because the directory was already there. Nothing checks that the scope files changed, that this ticket created them, or that the ticket ever entered a build. Left on by default it classified 179 of this repo's 206 tickets as stale, and --write archived 23 rails-less ones — all open work that had never been completed — while printing a success line and exiting 0. Both the text report and --json state which classifier produced the counts.

Usage

adlc ticket-prune [--tickets path] [--base-ref ref] [--infer-scope] [--write] [--allow-unsigned] [--json]
FlagDescription
--tickets <path>Ticket file to read (default .adlc/tickets.json).
--base-ref <ref>Git ref to check scope globs against (default HEAD). Point at origin/main to audit a branch's tickets against trunk.
--infer-scopeEnable the scope-existence staleness inference (default off, #779). Without it, only an explicit done-shaped status makes a ticket stale.
--writeTombstone rails-less stale tickets: add completed: true in place on the legacy flat-file store (never remove, never mutate any other field); move them to .adlc/ticket-archive/ on the sharded store. Rails-freezing stale tickets are left untouched and reported under needsCeremony.
--allow-unsignedLet a --write against a frozen trust root record its audit entry unsigned when no ADLC_MANIFEST_KEY is set (warns first; the unsigned entry is permanent). Same contract as adlc ticket --allow-unsigned.
--ceremonyDeprecated. Fails closed (exit 1) and redirects to adlc ticket complete <id> --write --authorize --json; rail-freezing tickets are completed per ticket, not in bulk here.
--jsonMachine-readable { baseRef, write, ceremony, inferScope, stale[], active[], tombstoned[], archived[], ceremonyCompleted[], needsCeremony[], blocked[] }.

--json fields: archived[] lists the tickets --write moved out of the active directory store (.adlc/tickets/), so on that store it, not tombstoned[], records what changed; tombstoned[] lists the in-place completed: true tombstones --write adds on the legacy flat-file store (.adlc/tickets.json); blocked[] lists stale tickets left unarchived because a ticket outside the batch still references them; ceremony is always false and ceremonyCompleted[] always empty since --ceremony was deprecated (#208), both retained for compatibility.

Exit codes

0: report or archive succeeded, regardless of how many stale tickets were found. Advisory, not a merge blocker.1: operational error (bad/missing ticket file, invalid JSON, unresolvable --base-ref, or the write lock could not be acquired).

Example

$ adlc ticket-prune --base-ref origin/main --infer-scope
ticket-prune — base ref: origin/main (dry-run, scope-existence inference: on)

Stale tickets (2) — re-run with --write to tombstone them:
  - T3: explicit status: "shipped"
  - T7: inferred: all 2 declared scope glob(s) resolve to tracked files on the base ref

Active tickets (2):
  - T9: no explicit status; declared scope not fully present on the base ref
  - T10: no explicit status and no declared scope — cannot infer, treated as active
exit 0

Go deeper

packages/ticket-prune

On this page