feat(FN-709): store branch name on tasks for reliable merge recovery

- Add 'branch' field to Task and ArchivedTaskEntry types with DB migration
- Executor stores branch name on task after worktree assignment
- Merger reads branch from task metadata instead of relying on worktree state
- Implement non-destructive conflict recovery in prepareForTask with reset/clean
- Add tests for branch storage, merger branch reading, and worktree recovery
This commit is contained in:
gsxdsm
2026-04-02 14:08:31 -07:00
parent 932a45a862
commit 321feb0b8d
10 changed files with 241 additions and 78 deletions

View File

@@ -86,7 +86,7 @@ describe("Database", () => {
});
it("seeds schema version", () => {
expect(db.getSchemaVersion()).toBe(5);
expect(db.getSchemaVersion()).toBe(6);
});
it("seeds lastModified", () => {
@@ -109,7 +109,7 @@ describe("Database", () => {
it("is idempotent - calling init() twice does not fail", () => {
expect(() => db.init()).not.toThrow();
expect(db.getSchemaVersion()).toBe(5);
expect(db.getSchemaVersion()).toBe(6);
});
it("does not overwrite existing config on re-init", () => {
@@ -704,7 +704,7 @@ describe("schema migrations", () => {
db.init();
// Verify version bumped to 5 (includes v1→v2, v2→v3, v3→v4, and v4→v5 migrations)
expect(db.getSchemaVersion()).toBe(5);
expect(db.getSchemaVersion()).toBe(6);
// Verify new columns exist and existing data is intact
const cols = db.prepare("PRAGMA table_info(tasks)").all() as Array<{ name: string }>;
@@ -729,11 +729,11 @@ describe("schema migrations", () => {
const db = new Database(kbDir);
db.init();
expect(db.getSchemaVersion()).toBe(5);
expect(db.getSchemaVersion()).toBe(6);
// Re-init should not fail
db.init();
expect(db.getSchemaVersion()).toBe(5);
expect(db.getSchemaVersion()).toBe(6);
db.close();
});
@@ -828,13 +828,14 @@ describe("schema migrations", () => {
db.init();
// Verify version bumped to 5
expect(db.getSchemaVersion()).toBe(5);
expect(db.getSchemaVersion()).toBe(6);
// Verify new columns exist and existing data is intact
const cols = db.prepare("PRAGMA table_info(tasks)").all() as Array<{ name: string }>;
const colNames = cols.map((c) => c.name);
expect(colNames).toContain("missionId");
expect(colNames).toContain("sliceId");
expect(colNames).toContain("branch");
// Existing task should still be readable
const task = db.prepare("SELECT * FROM tasks WHERE id = 'KB-2'").get() as any;
@@ -1037,7 +1038,7 @@ describe("createDatabase factory", () => {
const db = createDatabase(kbDir);
db.init();
expect(db.getSchemaVersion()).toBe(5);
expect(db.getSchemaVersion()).toBe(6);
expect(db.getLastModified()).toBeGreaterThan(0);
db.close();