When --orphan-handling flag not specified, import was passing empty string
instead of reading config or defaulting to 'allow'. This broke all imports
with hierarchical IDs after git pull.
Fix: Read import.missing_parents config, default to 'allow' if unset.
Priority: flag > config > default
Amp-Thread-ID: https://ampcode.com/threads/T-d089540c-c172-440f-88c9-ff06bde6504d
Co-authored-by: Amp <amp@ampcode.com>
**Problem:**
Closed issues were silently reopening during git sync/import operations.
When importing an issue update, the importer built an updates map with
status='closed' but NO closed_at timestamp. The UpdateIssue() function's
manageClosedAt() would only set closed_at when status was CHANGING to
closed, not when it was already closed. Result: closed_at got cleared,
effectively reopening issues.
**Root Cause:**
1. Importer built updates map without closed_at field (lines 443-451, 519-528)
2. closed_at was not in allowedUpdateFields whitelist
3. manageClosedAt() only managed closed_at for status TRANSITIONS
4. Import of already-closed issue → closed_at lost → issue reopens
**Impact:**
- WASM issues (bd-44d0, bd-8507, etc.) were closed on Nov 4 (commit 0df9144)
- They reopened as 'open' status during sync on Nov 5 (commit 8c9814a)
- Users had to repeatedly close the same issues
- Data integrity violation: status=closed with closed_at=NULL
**Fix:**
1. Add closed_at to allowedUpdateFields whitelist
2. Add closed_at to importer updates maps (both external_ref and ID paths)
3. Update manageClosedAt() to skip auto-management if closed_at explicitly provided
- Preserves import timestamps while maintaining auto-management for CLI operations
**Testing:**
- All internal/importer tests pass
- All internal/storage/sqlite tests pass
- Explicitly tests timestamp preservation in TestImportWithExternalRef
**Files Changed:**
- internal/importer/importer.go: Add closed_at to updates maps
- internal/storage/sqlite/sqlite.go: Allow closed_at updates, respect explicit values
Amp-Thread-ID: https://ampcode.com/threads/T-53ed6e45-9d04-4a35-97e9-d1ec36321ab0
Co-authored-by: Amp <amp@ampcode.com>
This addresses confusion where version bump doesn't trigger release.
The script now supports:
- --commit: Create git commit
- --tag: Create annotated git tag (requires --commit)
- --push: Push commit and tag (requires --tag)
Updated RELEASING.md to use: ./scripts/bump-version.sh X.Y.Z --commit --tag --push
Fixes the gap between version bump and actual release trigger.
- Added OrphanHandling type to sqlite package with 4 modes: strict/resurrect/skip/allow
- Updated EnsureIDs() to accept orphanHandling parameter and implement mode logic
- Added CreateIssuesWithOptions() that passes orphan handling through batch creation
- Made importer.OrphanHandling an alias to sqlite.OrphanHandling
- Importer now respects opts.OrphanHandling during batch issue creation
Next: Add import.orphan_handling config and wire through CLI commands
Amp-Thread-ID: https://ampcode.com/threads/T-bb7ffdd9-f444-4975-b5f7-bfff97cb92ff
Co-authored-by: Amp <amp@ampcode.com>
- Add OrphanHandling enum: strict/resurrect/skip/allow
- Add OrphanHandling field to importer.Options
- Default to 'allow' mode to work around existing system bugs
- Strict mode can be enabled via config for safer imports
Related: bd-8072, bd-b92a
- Add internal/routing package with DetectUserRole and DetermineTargetRepo
- Add routing config schema (mode, default, maintainer, contributor)
- Add --repo flag to bd create for explicit override
- Integrate routing logic into create command
- Test with contributor/maintainer roles and explicit override
Part of bd-8hf (Auto-routing and maintainer detection)
- Add repo_mtimes table to track JSONL file modification times
- Implement HydrateFromMultiRepo() with mtime-based skip optimization
- Support tilde expansion for repo paths in config
- Add source_repo column via migration (not in base schema)
- Fix schema to allow migration on existing databases
- Comprehensive test coverage for hydration logic
- Resurrect missing parent issues bd-cb64c226 and bd-cbed9619
Implementation:
- internal/storage/sqlite/multirepo.go - Core hydration logic
- internal/storage/sqlite/multirepo_test.go - Test coverage
- docs/MULTI_REPO_HYDRATION.md - Documentation
Schema changes:
- source_repo column added via migration only (not base schema)
- repo_mtimes table for mtime caching
- All SELECT queries updated to include source_repo
Database recovery:
- Restored from 17 to 285 issues
- Created placeholder parents for orphaned hierarchical children
Amp-Thread-ID: https://ampcode.com/threads/T-faa1339a-14b2-426c-8e18-aa8be6f5cde6
Co-authored-by: Amp <amp@ampcode.com>
For bd-307: Multi-repo hydration layer
Changes:
- Add MultiRepoConfig to internal/config
- Add GetMultiRepoConfig() to retrieve repos.primary and repos.additional
- Add source_repo field to Issue type to track ownership
- Prepare for hydration logic that reads from N repos
Addresses code review feedback:
✅ P0 (Must Fix):
- Fix JSONL lookup to return LAST match, not FIRST (resurrection.go:160-162)
- Changed from early return to scan all matches and keep last
- Respects JSONL append-only semantics
✅ P1 (Should Fix):
- Add test for multiple JSONL versions
- TestTryResurrectParent_MultipleVersionsInJSONL verifies correct behavior
- Document error message change in CHANGELOG.md
- Old: "parent issue X does not exist"
- New: "parent issue X does not exist and could not be resurrected from JSONL history"
- Marked as breaking change for script parsers
✅ P2/P3 (Nice to Have):
- Add documentation to AGENTS.md explaining auto-resurrection behavior
- Document best-effort dependency resurrection
⏸️ Deferred (P1 - Optimize batch resurrection):
- Caching optimization deferred (no batch use cases currently)
All tests pass:
- Unit tests: internal/storage/sqlite/
- Integration test: TestImportWithDeletedParent
Refactored resurrection functions to accept optional *sql.Conn parameter:
- Added tryResurrectParentWithConn() internal function
- Added tryResurrectParentChainWithConn() internal function
- Updated CreateIssue to use conn-based resurrection
- Updated EnsureIDs to use conn-based resurrection
This eliminates 'database is locked' errors when resurrection
happens inside an existing transaction.
Fixes bd-58c0