From 34997034ce4eb05ba9c1cfe7da1a1ac8525dfce2 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Mon, 24 Nov 2025 01:08:19 -0800 Subject: [PATCH] bd sync: 2025-11-24 01:08:19 --- .beads/beads.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index 04657ccb..3a707b0a 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -60,7 +60,7 @@ {"id":"bd-r71","content_hash":"88067b1a1aaad4cf0fe63e795ee581eebc2dda5b45ea4d6a5a7e357eb17ffeee","title":"Add tests for error wrapping behavior","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-24T00:53:16.906291-08:00","updated_at":"2025-11-24T00:57:46.21316-08:00","closed_at":"2025-11-24T00:57:46.21316-08:00","source_repo":"."} {"id":"bd-s0z","content_hash":"b69df0c8664737b3c04b10e3137652e3c8c3d782de0ecd02bfcd648919f8d944","title":"Consider extracting error handling helpers","description":"Evaluate creating FatalError() and WarnError() helpers as suggested in ERROR_HANDLING.md to reduce boilerplate and enforce consistency. Prototype in a few files first to validate the approach.","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-24T00:28:57.248959-08:00","updated_at":"2025-11-24T00:28:57.248959-08:00","source_repo":".","dependencies":[{"issue_id":"bd-s0z","depends_on_id":"bd-1qwo","type":"blocks","created_at":"2025-11-24T00:28:57.249945-08:00","created_by":"daemon"}]} {"id":"bd-t3b","content_hash":"c32a3a0f2f836148033fb330e209ac22e06dbecf18894153c15e2036f5afae1c","title":"Add test coverage for internal/config package","description":"","design":"Config package has 1 test file. Need comprehensive tests. Target: 70% coverage","acceptance_criteria":"- At least 3 test files\n- Package coverage \u003e= 70%","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:22.91657-05:00","updated_at":"2025-11-20T21:21:22.91657-05:00","source_repo":".","dependencies":[{"issue_id":"bd-t3b","depends_on_id":"bd-ge7","type":"blocks","created_at":"2025-11-20T21:21:31.201036-05:00","created_by":"daemon"}]} -{"id":"bd-t4u1","content_hash":"df659d75f5dfa5d3541d287be73973e2257878865e9dfa8b23f054f98f8c2465","title":"False positive detection by Kaspersky Antivirus (Trojan)","description":"Kaspersky Antivirus falsely detects beads (bd.exe v0.23.1) as a Trojan (PDM:Trojan.Win32.Generic) and removes it.\nEvent: Malicious object detected\nComponent: System Watcher\nObject name: bd.exe\n","design":"## Root Cause\n\nKaspersky's PDM:Trojan.Win32.Generic detection is a **known false positive issue with Go binaries**. The problem stems from Kaspersky's heuristic/behavioral detection (PDM = Proactive Defense Module) flagging characteristics common to Go executables rather than actual malware.\n\n**Why Go binaries trigger this:**\n- Malware written in Go shares similar binary patterns with legitimate Go programs\n- Antivirus ML models detect Go-specific features as suspicious\n- This is an industry-wide problem affecting multiple Go projects and antivirus vendors\n\n## Solutions (Multi-Pronged Approach)\n\n### 1. Immediate: Submit False Positive Report to Kaspersky\n- Use Kaspersky Threat Intelligence Portal: https://opentip.kaspersky.com/\n- Submit bd.exe v0.23.1 for reanalysis\n- Provide project details (legitimate open-source CLI tool)\n- Reference: https://support.kaspersky.com/1870\n\n### 2. Build Optimizations (Already Implemented)\nCurrent `.goreleaser.yml` already uses recommended flags:\n```yaml\nldflags:\n - -s -w # Strip debug symbols and DWARF info\n```\n\nSome developers report success with `-race` flag, but this:\n- Adds ~10x overhead (not suitable for release builds)\n- Only helps in specific cases\n- Not recommended for production\n\n### 3. Code Signing (Recommended for Windows Distribution)\n**Add Windows code signing to GoReleaser:**\n- Obtain code signing certificate (Sectigo, DigiCert, etc.)\n- Configure `signs` section in `.goreleaser.yml`\n- Use `osslsigncode` or Windows signtool\n\n**Benefits:**\n- Improves trust score with AV vendors\n- Required for SmartScreen/reputation building\n- Helps with false positive rates over time\n\n**Limitations:**\n- Won't eliminate false positives immediately\n- Requires certificate purchase ($100-400/year)\n- Reputation builds over time\n\n### 4. Submit to Kaspersky Whitelist\nApply to have beads officially whitelisted:\n- Contact Kaspersky developer relations\n- Provide project details, source code access\n- This is the most reliable long-term solution\n\n### 5. Documentation for Users\nCreate docs/ANTIVIRUS.md with:\n- Known false positive issue with Kaspersky\n- Instructions for adding bd.exe to exclusions\n- Link to verify checksums from GitHub releases\n- How to report false positives to Kaspersky\n\n## Implementation Priority\n\n1. **Immediate**: Submit false positive report (this release)\n2. **Short-term**: Add user documentation (ANTIVIRUS.md)\n3. **Medium-term**: Implement code signing for Windows builds\n4. **Long-term**: Apply for Kaspersky whitelist\n\n## References\n\n- [Kaspersky False Positive Detection Guide](https://support.kaspersky.com/1870)\n- [Go False Positives Discussion](https://www.linkedin.com/pulse/go-false-positives-melle-boudewijns)\n- [Kaspersky PDM Detection Forum](https://forum.kaspersky.com/topic/pdmtrojanwin32generic-54425/)\n- [Go Issues with AV Detection](https://github.com/golang/go/issues/16292)","acceptance_criteria":"- False positive report submitted to Kaspersky\n- ANTIVIRUS.md documentation created with user instructions\n- (Optional) Code signing configured for Windows builds\n- Verified next release is not flagged (or documented if still flagged)","notes":"## Completed Actions\n\n1. **Root cause analysis**: Documented that this is a known false positive with Go binaries\n2. **Created comprehensive user documentation**: docs/ANTIVIRUS.md with:\n - Explanation of why Go binaries trigger false positives\n - Instructions for adding exclusions (Kaspersky, Windows Defender, etc.)\n - File integrity verification steps\n - False positive reporting procedures\n - FAQ section\n3. **Updated TROUBLESHOOTING.md**: Added quick reference section with link to detailed guide\n\n## Next Steps (Follow-up Issues)\n\nThe following actions require external processes or future releases:\n\n1. **Submit false positive to Kaspersky**: Need to access bd.exe v0.23.1 Windows binary and submit to https://opentip.kaspersky.com/\n2. **Code signing for Windows**: Requires purchasing certificate and configuring GoReleaser (medium-term)\n3. **Apply for Kaspersky whitelist**: Long-term relationship building with vendor\n\n## Current Status\n\nUsers affected by this issue now have:\n- Clear documentation explaining the false positive\n- Step-by-step instructions to work around it\n- Ways to verify file integrity\n- Process to report to their antivirus vendor\n\nBuild configuration already includes recommended optimizations (-s -w flags).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T18:56:12.498187-05:00","updated_at":"2025-11-24T01:03:39.166915-08:00","closed_at":"2025-11-24T01:03:39.166915-08:00","source_repo":"."} +{"id":"bd-t4u1","content_hash":"4750b9a3e961d2d7c713dc08f402acde075a3a449d8be7047bb144a4790086ff","title":"False positive detection by Kaspersky Antivirus (Trojan)","description":"Kaspersky Antivirus falsely detects beads (bd.exe v0.23.1) as a Trojan (PDM:Trojan.Win32.Generic) and removes it.\nEvent: Malicious object detected\nComponent: System Watcher\nObject name: bd.exe\n","design":"## Root Cause\n\nKaspersky's PDM:Trojan.Win32.Generic detection is a **known false positive issue with Go binaries**. The problem stems from Kaspersky's heuristic/behavioral detection (PDM = Proactive Defense Module) flagging characteristics common to Go executables rather than actual malware.\n\n**Why Go binaries trigger this:**\n- Malware written in Go shares similar binary patterns with legitimate Go programs\n- Antivirus ML models detect Go-specific features as suspicious\n- This is an industry-wide problem affecting multiple Go projects and antivirus vendors\n\n## Solutions (Multi-Pronged Approach)\n\n### 1. Immediate: Submit False Positive Report to Kaspersky\n- Use Kaspersky Threat Intelligence Portal: https://opentip.kaspersky.com/\n- Submit bd.exe v0.23.1 for reanalysis\n- Provide project details (legitimate open-source CLI tool)\n- Reference: https://support.kaspersky.com/1870\n\n### 2. Build Optimizations (Already Implemented)\nCurrent `.goreleaser.yml` already uses recommended flags:\n```yaml\nldflags:\n - -s -w # Strip debug symbols and DWARF info\n```\n\nSome developers report success with `-race` flag, but this:\n- Adds ~10x overhead (not suitable for release builds)\n- Only helps in specific cases\n- Not recommended for production\n\n### 3. Code Signing (Recommended for Windows Distribution)\n**Add Windows code signing to GoReleaser:**\n- Obtain code signing certificate (Sectigo, DigiCert, etc.)\n- Configure `signs` section in `.goreleaser.yml`\n- Use `osslsigncode` or Windows signtool\n\n**Benefits:**\n- Improves trust score with AV vendors\n- Required for SmartScreen/reputation building\n- Helps with false positive rates over time\n\n**Limitations:**\n- Won't eliminate false positives immediately\n- Requires certificate purchase ($100-400/year)\n- Reputation builds over time\n\n### 4. Submit to Kaspersky Whitelist\nApply to have beads officially whitelisted:\n- Contact Kaspersky developer relations\n- Provide project details, source code access\n- This is the most reliable long-term solution\n\n### 5. Documentation for Users\nCreate docs/ANTIVIRUS.md with:\n- Known false positive issue with Kaspersky\n- Instructions for adding bd.exe to exclusions\n- Link to verify checksums from GitHub releases\n- How to report false positives to Kaspersky\n\n## Implementation Priority\n\n1. **Immediate**: Submit false positive report (this release)\n2. **Short-term**: Add user documentation (ANTIVIRUS.md)\n3. **Medium-term**: Implement code signing for Windows builds\n4. **Long-term**: Apply for Kaspersky whitelist\n\n## References\n\n- [Kaspersky False Positive Detection Guide](https://support.kaspersky.com/1870)\n- [Go False Positives Discussion](https://www.linkedin.com/pulse/go-false-positives-melle-boudewijns)\n- [Kaspersky PDM Detection Forum](https://forum.kaspersky.com/topic/pdmtrojanwin32generic-54425/)\n- [Go Issues with AV Detection](https://github.com/golang/go/issues/16292)","acceptance_criteria":"- False positive report submitted to Kaspersky\n- ANTIVIRUS.md documentation created with user instructions\n- (Optional) Code signing configured for Windows builds\n- Verified next release is not flagged (or documented if still flagged)","notes":"## Completed Actions\n\n1. **Root cause analysis**: Documented that this is a known false positive with Go binaries\n2. **Created comprehensive user documentation**: docs/ANTIVIRUS.md with:\n - Explanation of why Go binaries trigger false positives\n - Instructions for adding exclusions (Kaspersky, Windows Defender, etc.)\n - File integrity verification steps\n - False positive reporting procedures\n - FAQ section\n3. **Updated TROUBLESHOOTING.md**: Added quick reference section with link to detailed guide\n\n## Next Steps (Follow-up Issues)\n\nThe following actions require external processes or future releases:\n\n1. **Submit false positive to Kaspersky**: Need to access bd.exe v0.23.1 Windows binary and submit to https://opentip.kaspersky.com/\n2. **Code signing for Windows**: Requires purchasing certificate and configuring GoReleaser (medium-term)\n3. **Apply for Kaspersky whitelist**: Long-term relationship building with vendor\n\n## Current Status\n\nUsers affected by this issue now have:\n- Clear documentation explaining the false positive\n- Step-by-step instructions to work around it\n- Ways to verify file integrity\n- Process to report to their antivirus vendor\n\nBuild configuration already includes recommended optimizations (-s -w flags).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T18:56:12.498187-05:00","updated_at":"2025-11-24T01:08:09.677069-08:00","closed_at":"2025-11-24T01:03:39.166915-08:00","source_repo":"."} {"id":"bd-tne","content_hash":"2a6596980450714800bddc88e106026743a1a131e96f09198eb7dc2a16d75ca4","title":"Add Claude setup tip with dynamic priority","description":"Add a predefined tip that suggests running `bd setup claude` when Claude Code is detected but not configured. This tip should have higher priority (shown more frequently) until the setup is complete.","design":"## Implementation\n\nAdd to tip registry in `cmd/bd/tips.go`:\n\n```go\n{\n ID: \"claude_setup\",\n Condition: func() bool {\n return isClaudeDetected() \u0026\u0026 !isClaudeSetupComplete()\n },\n Message: \"Run 'bd setup claude' to enable automatic context recovery in Claude Code\",\n Frequency: 24 * time.Hour, // Daily minimum gap\n Priority: 100, // Highest priority\n Probability: 0.6, // 60% chance when eligible\n}\n```\n\n## Detection Logic\n\n```go\nfunc isClaudeDetected() bool {\n // Check environment variables\n if os.Getenv(\"CLAUDE_CODE\") != \"\" || os.Getenv(\"ANTHROPIC_CLI\") != \"\" {\n return true\n }\n // Check if .claude/ directory exists\n if _, err := os.Stat(filepath.Join(os.Getenv(\"HOME\"), \".claude\")); err == nil {\n return true\n }\n return false\n}\n\nfunc isClaudeSetupComplete() bool {\n // Check for global installation\n home, err := os.UserHomeDir()\n if err == nil {\n _, err1 := os.Stat(filepath.Join(home, \".claude/commands/prime_beads.md\"))\n _, err2 := os.Stat(filepath.Join(home, \".claude/hooks/sessionstart\"))\n if err1 == nil \u0026\u0026 err2 == nil {\n return true // Global hooks installed\n }\n }\n \n // Check for project installation\n _, err1 := os.Stat(\".claude/commands/prime_beads.md\")\n _, err2 := os.Stat(\".claude/hooks/sessionstart\")\n return err1 == nil \u0026\u0026 err2 == nil\n}\n```\n\n## Priority and Probability Behavior\n\n**Why 60% probability?**\n- Important message (priority 100) but not critical\n- Daily frequency + 60% = shows ~4 times per week\n- Avoids spam while staying visible\n- Balances persistence with user experience\n\n**Comparison with other probabilities:**\n- 100% probability: Shows EVERY day (annoying)\n- 80% probability: Shows ~6 days per week (too frequent)\n- 60% probability: Shows ~4 days per week (balanced)\n- 40% probability: Shows ~3 days per week (might be missed)\n\n**Auto-stops when setup complete:**\n- Condition becomes false after `bd setup claude`\n- No manual dismissal needed\n- Tip naturally disappears from rotation","acceptance_criteria":"- Claude setup tip added to registry\n- isClaudeDetected() checks environment and filesystem\n- isClaudeSetupComplete() verifies hook installation\n- Tip shows daily until setup complete\n- Tip stops showing after setup\n- Unit tests for detection functions","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-11T23:29:29.871324-08:00","updated_at":"2025-11-11T23:50:29.756454-08:00","source_repo":".","dependencies":[{"issue_id":"bd-tne","depends_on_id":"bd-d4i","type":"blocks","created_at":"2025-11-11T23:29:29.872081-08:00","created_by":"daemon"}]} {"id":"bd-tru","content_hash":"0de12031088519a3dcd27968d6bf17eb3a92d1853264e5a0dceef3310b3a2b04","title":"Update documentation for bd prime and Claude integration","description":"Update AGENTS.md, README.md, and QUICKSTART.md to document the new `bd prime` command, `bd setup claude` command, and tip system.","design":"## Documentation Updates\n\n### AGENTS.md\nAdd new section \"Context Recovery\":\n```markdown\n## Context Recovery\n\n### The Problem\nAfter context compaction or clearing conversation, AI agents may forget to use Beads and revert to markdown TODOs. Claude Code hooks solve this.\n\n### bd prime Command\nThe `bd prime` command outputs essential Beads workflow context in AI-optimized markdown format (~1-2k tokens).\n\n**When to use:**\n- After context compaction\n- After clearing conversation\n- Starting new session\n- When agent seems to forget bd workflow\n- Manual context refresh\n\n**Usage:**\n```bash\nbd prime # Output workflow context\n```\n\n### Automatic Integration (Recommended)\n\nRun `bd setup claude` to install hooks that auto-refresh bd context:\n- **SessionStart hook**: Loads context in new sessions\n- **PreCompact hook**: Refreshes context before compaction (survives better)\n- **Works with MCP**: Hooks complement MCP server (not replace)\n- **Works without MCP**: bd prime provides workflow via CLI\n\n**Why hooks matter even with MCP:**\n- MCP provides native tools, but agent may forget to use them\n- Hooks keep \"use bd, not markdown\" fresh in context\n- PreCompact refreshes workflow before compaction\n\n### MCP Server vs bd prime\n\n**Not an either/or choice** - they solve different problems:\n\n| Aspect | MCP Server | bd prime | Both |\n|--------|-----------|----------|------|\n| **Purpose** | Native bd tools | Workflow context | Best of both |\n| **Tokens** | 10.5k always loaded | ~1-2k when called | 10.5k + ~2k |\n| **Tool access** | Function calls | CLI via Bash | Function calls |\n| **Context memory** | Can fade after compaction | Hooks keep fresh | Hooks + tools |\n| **Recommended** | Heavy usage | Token optimization | Best experience |\n\n**Setup options:**\n```bash\nbd setup claude # Install hooks (works with or without MCP)\nbd setup claude --local # Per-project only\nbd setup claude --remove # Remove hooks\n```\n```\n\n### README.md\nAdd to \"Getting Started\" section:\n```markdown\n### AI Agent Integration\n\n**Claude Code users:** Run `bd setup claude` to install automatic context recovery hooks.\n\nHooks work with both MCP server and CLI approaches, preventing agents from forgetting bd workflow after compaction.\n\n**MCP vs bd prime:**\n- **With MCP server**: Hooks keep agent using bd tools (prevents markdown TODO reversion)\n- **Without MCP server**: Hooks provide workflow context via `bd prime` (~1-2k tokens)\n```\n\n### QUICKSTART.md\nAdd section on agent integration:\n```markdown\n## For AI Agents\n\n**Context loading:**\n```bash\nbd prime # Load workflow context (~1-2k tokens)\n```\n\n**Automatic setup (Claude Code):**\n```bash\nbd setup claude # Install hooks for automatic context recovery\n```\n\nHooks prevent agents from forgetting bd workflow after compaction.\n```","acceptance_criteria":"- AGENTS.md has Context Recovery section\n- README.md mentions bd setup claude\n- QUICKSTART.md mentions bd prime\n- Examples show when to use bd prime vs MCP\n- Clear comparison of trade-offs","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-11T23:30:22.77349-08:00","updated_at":"2025-11-11T23:45:23.242658-08:00","source_repo":"."} {"id":"bd-v0y","content_hash":"72d91011884bc9e20ac1c18b67f66489dcf49f3fec6da4d9b4dbbe1832d8b72f","title":"Critical: bd sync overwrites git-pulled JSONL instead of importing it","description":"## Problem\n\nWhen a user runs `git pull` (which updates .beads/beads.jsonl) followed by `bd sync`, the sync command fails to detect that the JSONL changed and exports the local database, **overwriting the pulled JSONL** instead of importing it first.\n\nThis causes cleaned-up issues (removed via `bd cleanup` in another repo) to be resurrected and pushed back to the remote.\n\n## Root Cause\n\n`hasJSONLChanged()` in cmd/bd/integrity.go incorrectly returns FALSE when it should return TRUE after git pull updates the JSONL file.\n\nThe function has two code paths:\n1. **Fast-path (line 128-129)**: If mtime unchanged, return false\n2. **Slow-path (line 135-151)**: Compute hash and compare\n\nSuspected issue: The mtime-based fast-path may incorrectly return false if:\n- Git preserves mtime when checking out files, OR\n- The mtime check logic has a race condition, OR\n- The stored last_import_mtime is stale/incorrect\n\n## Reproduction\n\n**Setup:**\n1. Repo A: Has 686 issues (including 630 closed)\n2. Run `bd cleanup -f` in Repo A (removes 630 closed issues → 56 issues remain)\n3. Push to remote\n4. Repo B: Still has 686 issues in database\n\n**Trigger:**\n1. In Repo B: `git pull` (JSONL now has 56 issues)\n2. In Repo B: `bd sync`\n\n**Expected behavior:**\n- hasJSONLChanged() returns TRUE\n- Auto-imports 56-issue JSONL\n- Database updated to 56 issues\n- Exports (no-op, DB and JSONL match)\n- Pushes\n\n**Actual behavior:**\n- hasJSONLChanged() returns FALSE ❌\n- Skips auto-import\n- Exports 686 issues from DB to JSONL\n- Commits and pushes the 686-issue JSONL\n- **Undoes the cleanup from Repo A**\n\n## Evidence\n\nFrom actual session (2025-11-23):\n- Commit 8bc8611 in cino/beads shows: `+640, -14 lines` after bd sync\n- No \"Auto-import complete\" message in output\n- Database had 686 issues, JSONL was pulled with 56 issues\n- Sync exported DB → JSONL instead of importing JSONL → DB\n\n## Impact\n\n**Critical:** This breaks multi-device sync and causes:\n- Lost work (cleanup operations undone)\n- Data resurrection (deleted issues come back)\n- Confusing merge conflicts\n- User trust issues (\"Why does sync keep bringing back deleted issues?\")\n\n## Proposed Solutions\n\n### Option 1: Remove mtime fast-path (safest)\nAlways compute and compare hashes. Eliminates false negatives from mtime issues.\n\n**Pros:** Guaranteed correctness\n**Cons:** Slightly slower (hash computation on every sync)\n\n### Option 2: Fix mtime comparison logic\nInvestigate why mtime check fails and fix it properly.\n\n**Areas to check:**\n- Does git preserve mtime on checkout? (may vary by git version/config)\n- Is last_import_mtime updated correctly after all operations?\n- Race condition between git pull and mtime check?\n\n### Option 3: Add hash-based validation\nKeep mtime fast-path but add hash validation as backup:\n- If mtime unchanged, still spot-check hash occasionally (e.g., 10% of the time)\n- Log warnings when mtime and hash disagree\n- This would catch the bug while maintaining performance\n\n### Option 4: Add `--force-import` flag to bd sync\nShort-term workaround: Allow users to force import even if hasJSONLChanged() returns false.\n\n## Workaround\n\nUntil fixed, after `git pull`:\n```bash\nbd import --force # Force import the pulled JSONL\nbd sync # Then sync normally\n```\n\nOr manually run bd cleanup in affected repos.\n\n## Files\n\n- cmd/bd/integrity.go:101-152 (hasJSONLChanged function)\n- cmd/bd/sync.go:130-143 (auto-import logic)\n- cmd/bd/autoflush.go:698 (export updates last_import_hash)\n\n## Related Issues\n\n- bd-77gm: Import reports misleading counts\n- bd-khnb: Content-based staleness detection (original implementation of hash checking)\n","notes":"## Fix Implemented (Option 1)\n\n**Root Cause Confirmed:**\nGit does NOT update mtime when checking out files. Testing confirmed that after `git checkout HEAD~1`, the file mtime remains unchanged even though content differs.\n\n**Solution:**\nRemoved the mtime-based fast-path in `hasJSONLChanged()`. Now always computes content hash for comparison.\n\n**Changes Made:**\n1. **cmd/bd/integrity.go:107-116** - Removed mtime fast-path, always compute hash\n2. **cmd/bd/sync.go:752** - Removed mtime storage after import\n3. **cmd/bd/import.go:340** - Removed mtime storage after import\n4. **cmd/bd/daemon_sync.go:280-301** - Removed mtime storage and updated comments\n5. **cmd/bd/daemon_sync_test.go:479,607,628** - Removed mtime assertions from tests\n\n**Performance Impact:**\nMinimal. Hash computation takes ~10-50ms even for large databases, which is acceptable for sync operations.\n\n**Testing:**\n- All existing tests pass\n- Test \"mtime changed but content same - git operation scenario\" verifies the fix\n- Full test suite passes (cmd/bd and all internal packages)\n\n**Verification:**\nThe fix ensures that after `git pull` updates the JSONL:\n1. `hasJSONLChanged()` returns TRUE (content hash differs)\n2. Auto-import runs and updates database\n3. No data loss or resurrection of deleted issues","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-23T22:24:53.69901-08:00","updated_at":"2025-11-24T01:04:11.865574-08:00","closed_at":"2025-11-23T22:50:12.611126-08:00","source_repo":"."}