FN-5819: allow shared-group members to merge into group branch with auto-merge off
Allow shared branch-group members to continue member→group integration even when project auto-merge is disabled. - add core helper to detect shared branch-group member integrations and export it - update engine in-review enqueue/handoff/startup flows to permit shared-member integration while still honoring global/engine pause gates - keep self-healing from pulling shared-member in-review tasks backward during auto-merge-off maintenance - expand project-engine and reliability-interaction tests for shared-member autoMerge-off behavior and add FN-5819 backstop docs updates Files changed: AGENTS.md | 2 + docs/architecture.md | 3 +- packages/core/src/__tests__/task-merge.test.ts | 37 +++++++++ packages/core/src/index.ts | 1 + packages/core/src/task-merge.ts | 13 +++ packages/engine/src/__tests__/project-engine.test.ts | 64 ++++++++++++++ packages/engine/src/__tests__/reliability-interactions/branch-group-merge-routing.test.ts | 48 +++++++++++ packages/engine/src/__tests__/reliability-interactions/shared-group-member-integration.test.ts | 97 ++++++++++++++++++++++ packages/engine/src/project-engine.ts | 35 ++++---- packages/engine/src/self-healing.ts | 3 +- 10 files changed, 284 insertions(+), 19 deletions(-) Fusion-Task-Id: FN-5819 Fusion-Task-Lineage: b5eeced7-7c47-4573-9ab4-ca577bec65e1
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
getTaskHardMergeBlocker,
|
||||
getTaskMergeBlocker,
|
||||
isTaskReadyForMerge,
|
||||
isSharedBranchGroupMemberIntegration,
|
||||
resolveEffectiveAutoMerge,
|
||||
resolveEffectiveGroupAutoMerge,
|
||||
resolveTaskMergeTarget,
|
||||
@@ -62,6 +63,42 @@ describe("resolveEffectiveGroupAutoMerge", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("isSharedBranchGroupMemberIntegration", () => {
|
||||
it("returns true for shared members with a resolvable group id", () => {
|
||||
expect(isSharedBranchGroupMemberIntegration({
|
||||
branchContext: {
|
||||
assignmentMode: "shared",
|
||||
groupId: "BG-1",
|
||||
source: "planning",
|
||||
},
|
||||
})).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false for per-task-derived grouped members", () => {
|
||||
expect(isSharedBranchGroupMemberIntegration({
|
||||
branchContext: {
|
||||
assignmentMode: "per-task-derived",
|
||||
groupId: "BG-1",
|
||||
source: "planning",
|
||||
},
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when no group id is present", () => {
|
||||
expect(isSharedBranchGroupMemberIntegration({
|
||||
branchContext: {
|
||||
assignmentMode: "shared",
|
||||
groupId: " ",
|
||||
source: "planning",
|
||||
},
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when branch context is absent", () => {
|
||||
expect(isSharedBranchGroupMemberIntegration({ branchContext: undefined })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveTaskMergeTarget", () => {
|
||||
it("prefers task baseBranch when present", () => {
|
||||
expect(resolveTaskMergeTarget({ baseBranch: "release/1.2", branchContext: undefined })).toEqual({
|
||||
|
||||
@@ -318,6 +318,7 @@ export {
|
||||
getTaskHardMergeBlocker,
|
||||
getTaskCompletionBlocker,
|
||||
isTaskReadyForMerge,
|
||||
isSharedBranchGroupMemberIntegration,
|
||||
resolveEffectiveAutoMerge,
|
||||
resolveEffectiveGroupAutoMerge,
|
||||
resolveTaskMergeTarget,
|
||||
|
||||
@@ -55,6 +55,19 @@ export function resolveEffectiveGroupAutoMerge(
|
||||
return group.autoMerge ?? settings.autoMerge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared-branch-group members perform a soft pre-integration step:
|
||||
* member branch → shared group branch. This path is exempt from the global
|
||||
* `autoMerge:false` in-review terminal gate so member integration can proceed,
|
||||
* but shared-branch → default-branch promotion remains separately gated.
|
||||
*/
|
||||
export function isSharedBranchGroupMemberIntegration(
|
||||
task: Pick<Task, "branchContext">,
|
||||
): boolean {
|
||||
return task.branchContext?.assignmentMode === "shared"
|
||||
&& Boolean(task.branchContext.groupId?.trim());
|
||||
}
|
||||
|
||||
export function resolveTaskMergeTarget(
|
||||
task: Pick<Task, "baseBranch" | "branchContext">,
|
||||
options: MergeTargetResolverOptions = {},
|
||||
|
||||
Reference in New Issue
Block a user