Skip to content

Commit e8a6563

Browse files
Fix critical bugs (#273)
* Add .worktrees/ to gitignore * Add AGENTS.md to CLAUDE.md * Fix three P0 bugs: elapsed timer, dynamic image version, memory calc - Fix elapsed time reset in opslevelAppendLogProcessor.go: time.Since(time.Now()) always returns ~0, so elapsed never reset. Changed to `s.elapsed = 0` - Use dynamic ImageTagVersion in k8s.go instead of hardcoded v2024.1.3 for the init container image to prevent version mismatches - Fix memory calculation typo in k8s_config.go: 1024*1204 → 1024*1024 (was allocating ~17% more memory than intended) * Fix P1 bugs: defer placement and leader election race condition - Move defer cleanup after error checks in k8s.go Run() method Previously, defer was called before error check, causing delete attempts on failed/nil resources - Add sync.RWMutex protection for isLeader variable in leaderElection.go The variable was accessed from multiple goroutines without synchronization Added setLeader()/getLeader() functions for thread-safe access * Add tests for P1 bug fixes and defensive nil guards Tests added: - TestSetLeaderGetLeader: basic setLeader/getLeader functionality - TestSetLeaderGetLeader_ConcurrentAccess: race condition verification - TestSetLeaderGetLeader_ConcurrentReadWrite: simulates callback pattern - TestDeleteConfigMap_NilSafe, TestDeletePDB_NilSafe, TestDeletePod_NilSafe - TestGetConfigMapObject, TestGetPBDObject: verify object creation - TestDeleteFunctions_RequireClientset: documents expected behavior Additional fixes: - Add nil guards to DeleteConfigMap, DeletePDB, DeletePod for defensive safety - Fix log message typo in DeletePDB ("configmap" -> "pod disruption budget")
1 parent 92e3906 commit e8a6563

18 files changed

Lines changed: 616 additions & 14 deletions

.beads/.gitignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# SQLite databases
2+
*.db
3+
*.db?*
4+
*.db-journal
5+
*.db-wal
6+
*.db-shm
7+
8+
# Daemon runtime files
9+
daemon.lock
10+
daemon.log
11+
daemon.pid
12+
bd.sock
13+
sync-state.json
14+
last-touched
15+
16+
# Local version tracking (prevents upgrade notification spam after git ops)
17+
.local_version
18+
19+
# Legacy database files
20+
db.sqlite
21+
bd.db
22+
23+
# Worktree redirect file (contains relative path to main repo's .beads/)
24+
# Must not be committed as paths would be wrong in other clones
25+
redirect
26+
27+
# Merge artifacts (temporary files from 3-way merge)
28+
beads.base.jsonl
29+
beads.base.meta.json
30+
beads.left.jsonl
31+
beads.left.meta.json
32+
beads.right.jsonl
33+
beads.right.meta.json
34+
35+
# Sync state (local-only, per-machine)
36+
# These files are machine-specific and should not be shared across clones
37+
.sync.lock
38+
sync_base.jsonl
39+
40+
# NOTE: Do NOT add negation patterns (e.g., !issues.jsonl) here.
41+
# They would override fork protection in .git/info/exclude, allowing
42+
# contributors to accidentally commit upstream issue databases.
43+
# The JSONL files (issues.jsonl, interactions.jsonl) and config files
44+
# are tracked by git by default since no pattern above ignores them.

.beads/README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Beads - AI-Native Issue Tracking
2+
3+
Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
4+
5+
## What is Beads?
6+
7+
Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
8+
9+
**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
10+
11+
## Quick Start
12+
13+
### Essential Commands
14+
15+
```bash
16+
# Create new issues
17+
bd create "Add user authentication"
18+
19+
# View all issues
20+
bd list
21+
22+
# View issue details
23+
bd show <issue-id>
24+
25+
# Update issue status
26+
bd update <issue-id> --status in_progress
27+
bd update <issue-id> --status done
28+
29+
# Sync with git remote
30+
bd sync
31+
```
32+
33+
### Working with Issues
34+
35+
Issues in Beads are:
36+
- **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
37+
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
38+
- **Branch-aware**: Issues can follow your branch workflow
39+
- **Always in sync**: Auto-syncs with your commits
40+
41+
## Why Beads?
42+
43+
**AI-Native Design**
44+
- Built specifically for AI-assisted development workflows
45+
- CLI-first interface works seamlessly with AI coding agents
46+
- No context switching to web UIs
47+
48+
🚀 **Developer Focused**
49+
- Issues live in your repo, right next to your code
50+
- Works offline, syncs when you push
51+
- Fast, lightweight, and stays out of your way
52+
53+
🔧 **Git Integration**
54+
- Automatic sync with git commits
55+
- Branch-aware issue tracking
56+
- Intelligent JSONL merge resolution
57+
58+
## Get Started with Beads
59+
60+
Try Beads in your own projects:
61+
62+
```bash
63+
# Install Beads
64+
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
65+
66+
# Initialize in your repo
67+
bd init
68+
69+
# Create your first issue
70+
bd create "Try out Beads"
71+
```
72+
73+
## Learn More
74+
75+
- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
76+
- **Quick Start Guide**: Run `bd quickstart`
77+
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
78+
79+
---
80+
81+
*Beads: Issue tracking that moves at the speed of thought*

.beads/config.yaml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Beads Configuration File
2+
# This file configures default behavior for all bd commands in this repository
3+
# All settings can also be set via environment variables (BD_* prefix)
4+
# or overridden with command-line flags
5+
6+
# Issue prefix for this repository (used by bd init)
7+
# If not set, bd init will auto-detect from directory name
8+
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
9+
# issue-prefix: ""
10+
11+
# Use no-db mode: load from JSONL, no SQLite, write back after each command
12+
# When true, bd will use .beads/issues.jsonl as the source of truth
13+
# instead of SQLite database
14+
# no-db: false
15+
16+
# Disable daemon for RPC communication (forces direct database access)
17+
# no-daemon: false
18+
19+
# Disable auto-flush of database to JSONL after mutations
20+
# no-auto-flush: false
21+
22+
# Disable auto-import from JSONL when it's newer than database
23+
# no-auto-import: false
24+
25+
# Enable JSON output by default
26+
# json: false
27+
28+
# Default actor for audit trails (overridden by BD_ACTOR or --actor)
29+
# actor: ""
30+
31+
# Path to database (overridden by BEADS_DB or --db)
32+
# db: ""
33+
34+
# Auto-start daemon if not running (can also use BEADS_AUTO_START_DAEMON)
35+
# auto-start-daemon: true
36+
37+
# Debounce interval for auto-flush (can also use BEADS_FLUSH_DEBOUNCE)
38+
# flush-debounce: "5s"
39+
40+
# Git branch for beads commits (bd sync will commit to this branch)
41+
# IMPORTANT: Set this for team projects so all clones use the same sync branch.
42+
# This setting persists across clones (unlike database config which is gitignored).
43+
# Can also use BEADS_SYNC_BRANCH env var for local override.
44+
# If not set, bd sync will require you to run 'bd config set sync.branch <branch>'.
45+
# sync-branch: "beads-sync"
46+
47+
# Multi-repo configuration (experimental - bd-307)
48+
# Allows hydrating from multiple repositories and routing writes to the correct JSONL
49+
# repos:
50+
# primary: "." # Primary repo (where this database lives)
51+
# additional: # Additional repos to hydrate from (read-only)
52+
# - ~/beads-planning # Personal planning repo
53+
# - ~/work-planning # Work planning repo
54+
55+
# Integration settings (access with 'bd config get/set')
56+
# These are stored in the database, not in this file:
57+
# - jira.url
58+
# - jira.project
59+
# - linear.url
60+
# - linear.api-key
61+
# - github.org
62+
# - github.repo

.beads/interactions.jsonl

Whitespace-only changes.

.beads/issues.jsonl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{"id":"opslevel-runner-5kw","title":"Remove redundant client validation in root.go","description":"root.go:56-62 - Dead code after cobra.CheckErr() which exits on error. The second cobra.CheckErr(clientErr) is unreachable.","status":"open","priority":3,"issue_type":"task","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:45.884341-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:33:45.884341-05:00"}
2+
{"id":"opslevel-runner-8tu","title":"Remove redundant slice re-assignment in opslevelAppendLogProcessor.go","description":"opslevelAppendLogProcessor.go:99-101 - Code sets logLines to nil then immediately to empty slice. Either use s.logLines = s.logLines[:0] to reuse backing array, or just s.logLines = nil.","status":"open","priority":4,"issue_type":"task","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:46.38156-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:33:46.38156-05:00"}
3+
{"id":"opslevel-runner-95x","title":"Fix elapsed time reset bug in opslevelAppendLogProcessor.go","description":"In opslevelAppendLogProcessor.go:59-62, time.Since(time.Now()) always returns ~0, so the elapsed counter never actually resets. Should be s.elapsed = 0.","status":"closed","priority":0,"issue_type":"bug","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:44.016053-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:57:30.420415-05:00","closed_at":"2026-01-20T08:57:30.420415-05:00","close_reason":"Closed"}
4+
{"id":"opslevel-runner-9br","title":"Replace busy-wait loops with tickers in LogStreamer","description":"logs.go:53-101 - Both Run() and Flush() use busy-waiting with time.Sleep(). Should use tickers for efficiency and add timeout safety in Flush().","status":"open","priority":1,"issue_type":"task","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:44.515054-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:33:44.515054-05:00"}
5+
{"id":"opslevel-runner-c7f","title":"Fix memory calculation typo (1204 → 1024) in k8s_config.go:46","description":"Memory limits use 1024*1204 instead of 1024*1024, allocating ~17% more memory than intended. This directly impacts resource allocation and could cause pod failures or resource wastage in production.","status":"closed","priority":0,"issue_type":"bug","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:43.49835-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:57:30.423465-05:00","closed_at":"2026-01-20T08:57:30.423465-05:00","close_reason":"Closed"}
6+
{"id":"opslevel-runner-cpt","title":"Add sync.Once to API client singletons for thread safety","description":"api.go:15-37 - REST/GraphQL client singletons could have race conditions during initialization. Use sync.Once to ensure thread-safe initialization.","status":"open","priority":2,"issue_type":"task","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:45.382082-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:33:45.382082-05:00"}
7+
{"id":"opslevel-runner-eya","title":"Fix log typo in DeletePDB - says 'configmap' instead of 'pod disruption budget'","description":"k8s.go:458 - DeletePDB logs 'Deleting configmap' instead of 'Deleting pod disruption budget'. Copy-paste error.","status":"closed","priority":3,"issue_type":"bug","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:45.632702-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T09:21:56.091381-05:00","closed_at":"2026-01-20T09:21:56.091381-05:00","close_reason":"Fixed as part of DeletePDB nil guard addition"}
8+
{"id":"opslevel-runner-gs7","title":"Extract container name constants in k8s.go","description":"k8s.go:226, 338 - Container names 'helper' and 'job' are hardcoded strings. Extract to constants for maintainability.","status":"open","priority":4,"issue_type":"task","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:46.622763-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:33:46.622763-05:00"}
9+
{"id":"opslevel-runner-ifs","title":"Propagate context to K8s operations instead of context.TODO()","description":"K8s operations in k8s.go use context.TODO() instead of propagating parent context. This prevents graceful cancellation during shutdown. Affects: CreateConfigMap, CreatePDB, CreatePod, DeleteConfigMap, DeletePDB, DeletePod, isPodInDesiredState.","status":"open","priority":1,"issue_type":"task","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:44.266878-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:33:44.266878-05:00"}
10+
{"id":"opslevel-runner-lz8","title":"Move defer cleanup after error check in k8s.go","description":"k8s.go:299-324 - Defer statements for cleanup are placed before error checks, meaning cleanup will be called even if resource creation failed. Move defer after the if err != nil check.","status":"closed","priority":1,"issue_type":"bug","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:45.08706-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T09:18:27.188443-05:00","closed_at":"2026-01-20T09:18:27.188443-05:00","close_reason":"Closed"}
11+
{"id":"opslevel-runner-qgb","title":"Fix race condition on isLeader variable in leaderElection.go","description":"leaderElection.go:18-48 - The isLeader package-level variable is accessed without synchronization from multiple goroutines. Add sync.RWMutex protection with setLeader()/getLeader() functions.","status":"closed","priority":1,"issue_type":"bug","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:44.819558-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T09:18:27.190004-05:00","closed_at":"2026-01-20T09:18:27.190004-05:00","close_reason":"Closed"}
12+
{"id":"opslevel-runner-sin","title":"Use dynamic runner image version instead of hardcoded v2024.1.3","description":"In k8s.go:208, the init container image is hardcoded to v2024.1.3 instead of using ImageTagVersion. This causes version mismatches between runner controller and helper binary.","status":"closed","priority":0,"issue_type":"bug","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:43.754131-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:57:30.42223-05:00","closed_at":"2026-01-20T08:57:30.42223-05:00","close_reason":"Closed"}
13+
{"id":"opslevel-runner-t4m","title":"Add context cancellation check in leader election loop","description":"leaderElection.go:51-85 - The infinite loop in OnStartedLeading doesn't check context for cancellation. Use select with ticker instead of time.Sleep for responsive shutdown.","status":"open","priority":2,"issue_type":"task","owner":"jason@opslevel.com","created_at":"2026-01-20T08:33:46.134478-05:00","created_by":"Jason Morrow","updated_at":"2026-01-20T08:33:46.134478-05:00"}

.beads/metadata.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"database": "beads.db",
3+
"jsonl_export": "issues.jsonl"
4+
}

.claude/agents/code-improver.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
name: code-improver
3+
description: "Use this agent when you want to analyze existing code for potential improvements in readability, performance, and best practices. This agent examines code files and provides detailed suggestions with explanations, current code snippets, and improved versions.\\n\\nExamples:\\n\\n<example>\\nContext: User wants to improve a specific file they've been working on.\\nuser: \"Can you review my utils.go file for improvements?\"\\nassistant: \"I'll use the code-improver agent to analyze utils.go and suggest improvements.\"\\n<Task tool call to launch code-improver agent>\\n</example>\\n\\n<example>\\nContext: User has just finished writing a new module and wants feedback.\\nuser: \"I just finished the authentication module, please review it\"\\nassistant: \"Let me launch the code-improver agent to scan your authentication module and identify opportunities for better readability, performance, and adherence to best practices.\"\\n<Task tool call to launch code-improver agent>\\n</example>\\n\\n<example>\\nContext: User asks for general code quality feedback on recent changes.\\nuser: \"Are there any improvements I should make to the files I changed today?\"\\nassistant: \"I'll use the code-improver agent to review your recently modified files and suggest improvements.\"\\n<Task tool call to launch code-improver agent>\\n</example>"
4+
model: sonnet
5+
color: pink
6+
---
7+
8+
You are an expert code quality analyst with deep expertise in software engineering best practices, performance optimization, and clean code principles. You have extensive experience across multiple programming languages and paradigms, with particular strength in identifying subtle issues that impact maintainability, readability, and runtime efficiency.
9+
10+
## Your Mission
11+
12+
You analyze code files to identify opportunities for improvement across three key dimensions:
13+
1. **Readability**: Code clarity, naming conventions, documentation, and structural organization
14+
2. **Performance**: Algorithmic efficiency, resource usage, unnecessary computations, and optimization opportunities
15+
3. **Best Practices**: Language idioms, design patterns, error handling, security considerations, and adherence to established conventions
16+
17+
## Analysis Process
18+
19+
For each file or code section you review:
20+
21+
1. **Initial Assessment**: Read through the entire code to understand its purpose, structure, and context
22+
2. **Systematic Scan**: Examine the code for issues in each of the three dimensions
23+
3. **Prioritization**: Rank findings by impact (critical, moderate, minor)
24+
4. **Solution Development**: Craft improved versions that address identified issues
25+
26+
## Output Format
27+
28+
For each improvement suggestion, provide:
29+
30+
### Issue Title
31+
**Category**: [Readability | Performance | Best Practices]
32+
**Severity**: [Critical | Moderate | Minor]
33+
**Location**: [File path and line numbers]
34+
35+
**Explanation**: A clear description of why this is an issue and the impact it has on the codebase.
36+
37+
**Current Code**:
38+
```[language]
39+
[The problematic code snippet]
40+
```
41+
42+
**Improved Code**:
43+
```[language]
44+
[The refactored/improved version]
45+
```
46+
47+
**Why This Is Better**: Specific explanation of the improvements and their benefits.
48+
49+
---
50+
51+
## Guidelines
52+
53+
### Readability Checks
54+
- Variable and function naming (clarity, consistency, conventions)
55+
- Function length and complexity (single responsibility)
56+
- Code comments (presence, accuracy, necessity)
57+
- Logical grouping and organization
58+
- Consistent formatting and style
59+
- Magic numbers and hardcoded values
60+
- Nested complexity and early returns
61+
62+
### Performance Checks
63+
- Unnecessary iterations or computations
64+
- Inefficient data structures for the use case
65+
- Memory allocation patterns
66+
- Database query optimization opportunities
67+
- Caching opportunities
68+
- Lazy evaluation possibilities
69+
- Algorithmic complexity improvements
70+
71+
### Best Practices Checks
72+
- Error handling completeness and consistency
73+
- Input validation and sanitization
74+
- Resource cleanup (connections, file handles)
75+
- Thread safety considerations
76+
- Security vulnerabilities (injection, exposure)
77+
- Language-specific idioms and patterns
78+
- Testing considerations
79+
- Logging and observability
80+
81+
## Project-Specific Considerations
82+
83+
When reviewing Go code in this codebase:
84+
- Follow the established patterns using Zerolog for structured logging
85+
- Ensure Kubernetes resources are properly cleaned up
86+
- Use context for cancellation and timeouts consistently
87+
- Follow the log processor pipeline pattern for any streaming data
88+
- Adhere to the existing error handling patterns
89+
90+
## Behavioral Guidelines
91+
92+
1. **Be Constructive**: Frame suggestions positively, focusing on improvement rather than criticism
93+
2. **Be Specific**: Always show exact code locations and concrete improvements
94+
3. **Be Practical**: Prioritize suggestions that provide meaningful value over pedantic nitpicks
95+
4. **Be Educational**: Explain the reasoning so developers learn from the feedback
96+
5. **Respect Context**: Consider the project's existing patterns and conventions
97+
6. **Acknowledge Good Code**: When code is well-written, say so
98+
99+
## Quality Assurance
100+
101+
Before presenting each suggestion:
102+
- Verify the improved code is syntactically correct
103+
- Ensure the improvement doesn't change the intended behavior
104+
- Confirm the suggestion aligns with the project's existing patterns
105+
- Check that the explanation clearly communicates the benefit
106+
107+
## Summary Section
108+
109+
After all suggestions, provide a brief summary:
110+
- Total issues found by category and severity
111+
- Top 3 highest-impact improvements to prioritize
112+
- Overall assessment of code quality
113+
- Patterns or themes observed across the suggestions

.claude/settings.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"hooks": {
3+
"PostToolUse": [
4+
{
5+
"matcher": "Write|Edit",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "task lint;"
10+
}
11+
]
12+
}
13+
]
14+
}
15+
}

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
# Use bd merge for beads JSONL files
3+
.beads/issues.jsonl merge=beads

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,5 @@ src/go.work**
2626
# ignore any user-created yaml files that may have been used for tophatting.
2727
src/*.yaml
2828

29-
# agent folders
30-
.beads/
29+
# Git worktrees
3130
.worktrees/

0 commit comments

Comments
 (0)