status

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: 13 Imported by: 0

Documentation

Overview

Package status automates the "done prompt": after every N completed agent tasks in a project, the sweeper mints ONE status task — a headless agent that writes a full status report (docs/status/<timestamp>.md) and closes the loop by appending the next work items to the repo's TODO_LIST.md, where the next harvest tick picks them up.

Loop safety is structural (same rule as internal/review): only completions of "agent" tasks are counted — status tasks never trigger status tasks. The N-completion window is derived from queue state (completed agent tasks updated since the last status task's creation), never from sweeper memory, so restarts cannot desynchronize it. Idempotency is the store's dedup: the window's triggering completion task IDs key the minted tasks.

Index

Constants

View Source
const (
	// ConsumerKey is the sweeper's identity in the watermarks table. One
	// cursor is shared by every status sweeper over the same database:
	// completions recorded while no sweeper ran are counted on the next
	// start (the window query is queue-derived, not cursor-derived).
	ConsumerKey = "status-sweeper"
)

Variables

This section is empty.

Functions

func StatusDedupKey

func StatusDedupKey(project string, trigger task.ID) string

StatusDedupKey is the dedup identity of the report for one window: the project plus the completion that filled the window. Two windows never share a trigger completion; the same window replayed never mints twice.

Types

type SweepStats

type SweepStats struct {
	// Facts is the number of new facts consumed.
	Facts int
	// ReportsEnqueued counts fresh status tasks this sweep created.
	ReportsEnqueued int
	// ReportsKnown counts mints that hit an existing dedup key (the report
	// task already existed — replayed page or a concurrent sweeper).
	ReportsKnown int
	// Skipped counts completions that could not yield a status task
	// (foreign payload shape, vanished task record, window not yet full,
	// or a report already in flight).
	Skipped int
}

SweepStats summarizes one sweep pass.

type Sweeper

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

Sweeper turns the journal's completion facts into periodic status reports. 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.

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; a first run bootstraps at the journal head (completions that predate the sweeper are not replayed as trigger facts — but the window QUERY counts them, so the first N-th completion after start reports on the full backlogged window). Rewind deliberately with `tq watermarks set status-sweeper SEQ`.

func (*Sweeper) Sweep

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

Sweep consumes new facts since the last pass and mints status tasks for full windows. Idempotent by dedup: calling it twice never duplicates work, so a replayed page (crash between consumption and checkpoint) re-hits dedup keys instead of minting duplicates.

type SweeperConfig

type SweeperConfig struct {
	// Every is the number of completed agent tasks per project that mint
	// one status report. Required, >= 1.
	Every int
	// Model, when set, is written into every status payload.
	Model string
	// Log receives one summary line per mint. nil logs nothing.
	Log *slog.Logger
	// PageSize bounds one fact-stream page; 0 selects the default.
	PageSize int
	// AllowDirty mirrors the pool's --allow-dirty: minted status payloads
	// then tolerate an uncommitted tree (RequireClean=false). A
	// multi-agent repo is effectively always dirty; without this the
	// status preflight would requeue forever on an --allow-dirty pool.
	AllowDirty bool
	// TaskTimeout is pinned into minted payloads as TimeoutMinutes (0
	// keeps the executor's default). The executor default (15m) is tuned
	// for stub-y repos; a real done-prompt run PLUS the repo verify gate
	// needs the pool's own task budget.
	TaskTimeout time.Duration
}

SweeperConfig controls one Sweeper.

Jump to

Keyboard shortcuts

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