Documentation
¶
Overview ¶
Package completioncandidate implements detection rules that surface GTD tasks that appear done but whose status is still pending or in_progress.
Index ¶
- type Candidate
- type Confidence
- type DetectParams
- type PgStore
- func (s *PgStore) DetectAndUpsert(ctx context.Context, p DetectParams) ([]Candidate, error)
- func (s *PgStore) ListPendingCandidates(ctx context.Context, workspaceID *uuid.UUID) ([]Candidate, error)
- func (s *PgStore) PruneResolved(ctx context.Context, olderThan time.Duration) (int64, error)
- func (s *PgStore) UpsertCandidate(ctx context.Context, p UpsertParams) (*Candidate, error)
- func (s *PgStore) WriteAutoApplied(ctx context.Context, taskID uuid.UUID, evidenceRefs []string, ...) error
- type Reason
- type SQLiteStore
- func (s *SQLiteStore) DetectAndUpsert(ctx context.Context, p DetectParams) ([]Candidate, error)
- func (s *SQLiteStore) ListPendingCandidates(ctx context.Context, workspaceID *uuid.UUID) ([]Candidate, error)
- func (s *SQLiteStore) PruneResolved(ctx context.Context, olderThan time.Duration) (int64, error)
- func (s *SQLiteStore) UpsertCandidate(ctx context.Context, p UpsertParams) (*Candidate, error)
- func (s *SQLiteStore) WriteAutoApplied(ctx context.Context, taskID uuid.UUID, evidenceRefs []string, ...) error
- type Status
- type Store
- type UpsertParams
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Candidate ¶
type Candidate struct {
ID uuid.UUID
WorkspaceID *uuid.UUID
TaskID uuid.UUID
RepoName string
Reason Reason
EvidenceRefs []string
Confidence Confidence
SuggestedArtifact string
Status Status
DetectedAt time.Time
ResolvedAt *time.Time
}
Candidate is the domain model for a completion_candidates row.
type Confidence ¶
type Confidence string
Confidence represents how certain the detection rule is about the candidate.
const ( ConfidenceHigh Confidence = "high" ConfidenceMedium Confidence = "medium" ConfidenceLow Confidence = "low" )
type DetectParams ¶
type DetectParams struct {
WorkspaceID *uuid.UUID
StaleThreshold time.Duration // default 24h; hours of inactivity before flagging in_progress task
LookbackDays int // default 7, max 30; days of activity_log to scan
}
DetectParams holds the detection configuration for DetectAndUpsert.
type PgStore ¶
type PgStore struct {
// contains filtered or unexported fields
}
PgStore is the Postgres-backed implementation of Store.
func NewPgStore ¶
NewPgStore creates a Postgres-backed Store.
func (*PgStore) DetectAndUpsert ¶
DetectAndUpsert runs all 4 detection rules and upserts results.
func (*PgStore) ListPendingCandidates ¶
func (s *PgStore) ListPendingCandidates(ctx context.Context, workspaceID *uuid.UUID) ([]Candidate, error)
ListPendingCandidates returns candidates with status='pending' scoped to the store's workspace (or the provided workspaceID override).
func (*PgStore) PruneResolved ¶
PruneResolved deletes candidates whose resolved_at is older than olderThan.
func (*PgStore) UpsertCandidate ¶
UpsertCandidate inserts or refreshes a candidate identified by (task_id, reason).
func (*PgStore) WriteAutoApplied ¶
func (s *PgStore) WriteAutoApplied( ctx context.Context, taskID uuid.UUID, evidenceRefs []string, suggestedArtifact string, ) error
WriteAutoApplied inserts (or refreshes) a completion_candidates row with status='auto_applied' reason='artifact_evidence'. Used by reconcile_merged_prs (sprint feature/gtd-enforce-server-side GTD-fix 9/12) to audit the auto-close.
ON CONFLICT (task_id, reason) the existing row is updated: detected_at refreshed, evidence_refs replaced, suggested_artifact set, AND status forced to 'auto_applied' (in contrast to UpsertCandidate which preserves existing status). This ensures a previously pending candidate flips to auto_applied on the second pass.
type Reason ¶
type Reason string
Reason identifies which detection rule produced the candidate.
const ( ReasonStaleInProgress Reason = "stale_in_progress" ReasonFinishWorkGap Reason = "finish_work_gap" ReasonArtifactEvidence Reason = "artifact_evidence" ReasonCompletionSignal Reason = "completion_signal" // ReasonPRMerged indicates a fuzzy-matched PR likely closes this task. // Surfaced by the Phase 2 reconcile detector (GTD-fix 10/12, sprint // feature/0519-gtd-reconcile-phase2) for tasks whose branch_name and // pr_url linkage are both NULL — i.e. legacy backlog where the GTD-fix // 9/12 exact-match path can never apply. Confidence is always 'medium' // (not 'high') so the candidate enters the manual-accept queue; this // matcher MUST NOT auto-apply because Jaccard similarity false-positives // are common enough that silent task closure would damage trust. ReasonPRMerged Reason = "pr_merged_fuzzy" )
type SQLiteStore ¶
type SQLiteStore struct {
// contains filtered or unexported fields
}
SQLiteStore is the SQLite-backed implementation of Store. It accepts a *sql.DB directly so list queries (sql.Rows) can be used. Wiring in cmd/server/main.go passes the connection extracted from wbtsqlite.DB via its ExecContext-family public methods.
func NewSQLiteStore ¶
func NewSQLiteStore(db *sql.DB, workspaceID string) *SQLiteStore
NewSQLiteStore creates a SQLiteStore backed by the given *sql.DB and optional workspace UUID string. workspaceID may be "" for unscoped mode.
func (*SQLiteStore) DetectAndUpsert ¶
func (s *SQLiteStore) DetectAndUpsert(ctx context.Context, p DetectParams) ([]Candidate, error)
DetectAndUpsert runs all 4 detection rules and upserts results.
func (*SQLiteStore) ListPendingCandidates ¶
func (s *SQLiteStore) ListPendingCandidates(ctx context.Context, workspaceID *uuid.UUID) ([]Candidate, error)
ListPendingCandidates returns candidates with status='pending', scoped to the store's workspace (or the provided workspaceID override).
func (*SQLiteStore) PruneResolved ¶
PruneResolved deletes candidates whose resolved_at is older than olderThan.
func (*SQLiteStore) UpsertCandidate ¶
func (s *SQLiteStore) UpsertCandidate(ctx context.Context, p UpsertParams) (*Candidate, error)
UpsertCandidate inserts or refreshes a candidate identified by (task_id, reason). On conflict (task_id, reason) detected_at, confidence, and evidence_refs are updated.
func (*SQLiteStore) WriteAutoApplied ¶
func (s *SQLiteStore) WriteAutoApplied( ctx context.Context, taskID uuid.UUID, evidenceRefs []string, suggestedArtifact string, ) error
WriteAutoApplied inserts (or refreshes) a completion_candidates row with status='auto_applied' reason='artifact_evidence'. SQLite-side parity for the reconcile_merged_prs flow; see Store interface doc + the Postgres twin.
type Store ¶
type Store interface {
// ListPendingCandidates returns all candidates with status='pending',
// optionally filtered to the given workspace.
ListPendingCandidates(ctx context.Context, workspaceID *uuid.UUID) ([]Candidate, error)
// UpsertCandidate inserts or updates a candidate identified by (task_id, reason).
// On conflict (task_id, reason) the detected_at is refreshed and confidence updated.
UpsertCandidate(ctx context.Context, p UpsertParams) (*Candidate, error)
// PruneResolved deletes resolved candidates older than olderThan. Returns the
// number of rows deleted.
PruneResolved(ctx context.Context, olderThan time.Duration) (int64, error)
// DetectAndUpsert runs all 4 detection rules against the tasks / work_sessions /
// activity_log tables and upserts any matches into completion_candidates.
// Returns all upserted candidates (including previously pending ones that were
// refreshed). Read-only for tasks; writes to completion_candidates only.
DetectAndUpsert(ctx context.Context, p DetectParams) ([]Candidate, error)
// WriteAutoApplied inserts a completion_candidates row recording an auto-apply
// event (status='auto_applied', reason='artifact_evidence'). Used by the
// reconcile_merged_prs flow (sprint feature/gtd-enforce-server-side
// GTD-fix 9/12) to audit-log which task was auto-closed by which PR.
//
// On conflict (task_id, reason) the existing row is refreshed (detected_at
// updated, evidence_refs replaced, suggested_artifact set, status forced to
// auto_applied so a previously-pending candidate is closed). This mirrors
// the UpsertCandidate ON CONFLICT semantics but additionally forces the
// status column.
WriteAutoApplied(ctx context.Context, taskID uuid.UUID, evidenceRefs []string, suggestedArtifact string) error
}
Store is the backend-agnostic interface for the completioncandidate domain. Both SQLite and Postgres stores must satisfy this interface.