diff --git a/internal/storage/memory/memory.go b/internal/storage/memory/memory.go index ccf53d3d..c1400718 100644 --- a/internal/storage/memory/memory.go +++ b/internal/storage/memory/memory.go @@ -1063,6 +1063,7 @@ func (m *MemoryStorage) getOpenBlockers(issueID string) []string { } // GetBlockedIssues returns issues that are blocked by other issues +// Note: Pinned issues are excluded from the output (beads-ei4) func (m *MemoryStorage) GetBlockedIssues(ctx context.Context) ([]*types.BlockedIssue, error) { m.mu.RLock() defer m.mu.RUnlock() @@ -1075,6 +1076,11 @@ func (m *MemoryStorage) GetBlockedIssues(ctx context.Context) ([]*types.BlockedI continue } + // Exclude pinned issues (beads-ei4) + if issue.Pinned { + continue + } + blockers := m.getOpenBlockers(issue.ID) if issue.Status != types.StatusBlocked && len(blockers) == 0 { continue diff --git a/internal/storage/sqlite/ready.go b/internal/storage/sqlite/ready.go index ed4a2a22..e6eba19f 100644 --- a/internal/storage/sqlite/ready.go +++ b/internal/storage/sqlite/ready.go @@ -258,11 +258,13 @@ func (s *SQLiteStorage) GetStaleIssues(ctx context.Context, filter types.StaleFi } // GetBlockedIssues returns issues that are blocked by dependencies or have status=blocked +// Note: Pinned issues are excluded from the output (beads-ei4) func (s *SQLiteStorage) GetBlockedIssues(ctx context.Context) ([]*types.BlockedIssue, error) { // Use UNION to combine: // 1. Issues with open/in_progress/blocked status that have dependency blockers // 2. Issues with status=blocked (even if they have no dependency blockers) // Use GROUP_CONCAT to get all blocker IDs in a single query (no N+1) + // Exclude pinned issues (beads-ei4) rows, err := s.db.QueryContext(ctx, ` SELECT i.id, i.title, i.description, i.design, i.acceptance_criteria, i.notes, @@ -279,6 +281,7 @@ func (s *SQLiteStorage) GetBlockedIssues(ctx context.Context) ([]*types.BlockedI AND blocker.status IN ('open', 'in_progress', 'blocked') ) WHERE i.status IN ('open', 'in_progress', 'blocked') + AND i.pinned = 0 AND ( i.status = 'blocked' OR EXISTS ( diff --git a/internal/storage/sqlite/schema.go b/internal/storage/sqlite/schema.go index a433a6ac..9b93321a 100644 --- a/internal/storage/sqlite/schema.go +++ b/internal/storage/sqlite/schema.go @@ -34,6 +34,8 @@ CREATE TABLE IF NOT EXISTS issues ( pinned INTEGER DEFAULT 0, -- NOTE: replies_to, relates_to, duplicate_of, superseded_by removed per Decision 004 -- These relationships are now stored in the dependencies table + -- Workflow fields + pinned INTEGER DEFAULT 0, CHECK ((status = 'closed') = (closed_at IS NOT NULL)) );