diff --git a/sdk/src/config.test.ts b/sdk/src/config.test.ts index a4d81749c..37dccf419 100644 --- a/sdk/src/config.test.ts +++ b/sdk/src/config.test.ts @@ -237,6 +237,26 @@ describe('loadConfig', () => { expect(config).toEqual(CONFIG_DEFAULTS); }); + it('maps legacy top-level branching_strategy into git.branching_strategy', async () => { + await writeFile( + join(tmpDir, '.planning', 'config.json'), + JSON.stringify({ branching_strategy: 'phase' }), + ); + + const config = await loadConfig(tmpDir); + expect(config.git.branching_strategy).toBe('phase'); + }); + + it('git.branching_strategy overrides legacy top-level branching_strategy when both are present', async () => { + await writeFile( + join(tmpDir, '.planning', 'config.json'), + JSON.stringify({ branching_strategy: 'phase', git: { branching_strategy: 'milestone' } }), + ); + + const config = await loadConfig(tmpDir); + expect(config.git.branching_strategy).toBe('milestone'); + }); + it('does not mutate CONFIG_DEFAULTS between calls', async () => { const before = structuredClone(CONFIG_DEFAULTS); diff --git a/sdk/src/config.ts b/sdk/src/config.ts index 764777649..1e657c4c7 100644 --- a/sdk/src/config.ts +++ b/sdk/src/config.ts @@ -177,11 +177,16 @@ export async function loadConfig(projectDir: string, workstream?: string): Promi } function mergeDefaults(parsed: Record): GSDConfig { + const legacyBranchingStrategy = typeof parsed.branching_strategy === 'string' + ? parsed.branching_strategy + : undefined; + return { ...structuredClone(CONFIG_DEFAULTS), ...parsed, git: { ...CONFIG_DEFAULTS.git, + ...(legacyBranchingStrategy ? { branching_strategy: legacyBranchingStrategy } : {}), ...(parsed.git as Partial ?? {}), }, workflow: { diff --git a/sdk/src/query/init.test.ts b/sdk/src/query/init.test.ts index 4642d4e5c..11e8f077f 100644 --- a/sdk/src/query/init.test.ts +++ b/sdk/src/query/init.test.ts @@ -330,6 +330,20 @@ describe('initExecutePhase', () => { const data = result.data as Record; expect(data.error).toBeDefined(); }); + + it('honors legacy top-level branching_strategy in config for execute-phase init (#3055)', async () => { + await writeFile(join(tmpDir, '.planning', 'config.json'), JSON.stringify({ + model_profile: 'balanced', + commit_docs: false, + branching_strategy: 'phase', + workflow: { research: true, plan_check: true, verifier: true, nyquist_validation: true }, + })); + + const result = await initExecutePhase(['9'], tmpDir); + const data = result.data as Record; + expect(data.branching_strategy).toBe('phase'); + expect(typeof data.branch_name).toBe('string'); + }); }); describe('initPlanPhase', () => {