dlqfix

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package dlqfix closes the loop around dead-lettered agent work: every dead-lettered agent task gets ONE autopsy by a second agent, and the autopsy's verdict is executed mechanically — "fixed" rescues the original with a fresh attempt budget, "wontfix" dismisses it with the recorded reason. The agent only contributes the diagnosis; everything downstream (disposition, dedup, loop guarding) is mechanical.

Loop safety is structural: autopsies are only ever minted for dead "agent" tasks (a dead autopsy can never mint another autopsy), each dead task is autopsied at most once (the dlqfix:<task-id> dedup key, forever), and every mint pass runs under the pool's budget guard, which counts autopsy tasks like every other enqueue.

Index

Constants

View Source
const (
	// ConsumerKey is the sweeper's identity in the watermarks table: the
	// persisted cursor shared by every sweeper over the same database, so
	// tasks that dead-lettered while no sweeper was running still get
	// their autopsy when the next pool starts.
	ConsumerKey = "dlqfix-sweeper"

	// DismissedBySweeper names the sweeper in a dismissed task's
	// task.cancelled fact detail (operators dismiss as "operator").
	DismissedBySweeper = "dlqfix-sweeper"
)

Variables

This section is empty.

Functions

func DedupKey

func DedupKey(dead task.ID) string

DedupKey is the dedup identity of the autopsy of one dead task: exactly one autopsy per dead task, forever. A rescued task that dies again does NOT get a second autopsy — the second death is deliberately a human surface (the first verdict and the fresh failure evidence are both in the journal).

Types

type SweepStats

type SweepStats struct {
	// Facts is the number of new facts consumed.
	Facts int
	// FixesEnqueued counts fresh autopsy tasks this sweep created.
	FixesEnqueued int
	// FixesKnown counts dead tasks whose autopsy task already existed
	// (dedup hit — the autopsy ran, or is pending, elsewhere).
	FixesKnown int
	// Rescued counts dead tasks re-queued by a "fixed" verdict.
	Rescued int
	// Dismissed counts dead tasks cancelled by a "wontfix" verdict.
	Dismissed int
	// Skipped counts facts that could not yield work (vanished records,
	// foreign payload shapes, dispositions already executed elsewhere).
	Skipped int
	// AutoDismissed counts dead tasks cancelled by the mechanical
	// gate-artifact dismissal (TODO row 145) — no autopsy was minted for
	// them.
	AutoDismissed int
}

SweepStats summarizes one sweep pass.

type Sweeper

type Sweeper struct {
	// contains filtered or unexported fields
}

Sweeper turns the journal's dead-letter and autopsy-completion facts into DLQ dispositions. It is safe for concurrent use (the cursor serializes sweeps; ticks and the --once drain watcher may call it from different goroutines).

The struct shell deliberately stays per-sweeper (config fields and fact validation differ across the four sweepers); the shared pump is watermark.Cursor.Sweep.

art-dupl:accept mirrored sweeper shell: config fields and fact validation differ per sweeper; the shared pump already lives in watermark.Cursor.

func NewSweeper

func NewSweeper(ctx context.Context, store queue.Store, cfg SweeperConfig) (*Sweeper, error)

NewSweeper returns a sweeper over store. The cursor resumes from the persisted checkpoint — deaths recorded while no sweeper was running are autopsied on the next start. A first run bootstraps at the journal head: dead letters that predate the sweeper are not replayed (same semantics as the review sweeper; rewind with `tq watermarks set dlqfix-sweeper SEQ`).

func (*Sweeper) Sweep

func (s *Sweeper) Sweep(ctx context.Context) (SweepStats, error)

Sweep consumes new facts since the last pass and enqueues autopsy (and executes disposition) work. Idempotent by dedup and transition guards: calling it twice never duplicates work — a replayed page (crash between consumption and checkpoint) re-hits dedup keys and idempotent store transitions instead of minting duplicates or double-disposing.

type SweeperConfig

type SweeperConfig struct {
	// Model, when set, is written into every autopsy payload. Empty (the
	// default) leaves model choice to each repo's crush config.
	Model string
	// Log receives one summary line per mint/disposition. nil logs nothing.
	Log *slog.Logger
	// PageSize bounds one fact-stream page; 0 selects the default.
	PageSize int
	// Scanner attributes footer commits for the gate-artifact shipped-proof
	// check (TODO row 145). nil disables the auto-dismiss path entirely —
	// every dead agent task gets an autopsy as before. The pool wires
	// executor.GitLogScanner{}.
	Scanner executor.GitScanner
}

SweeperConfig controls one Sweeper.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL