Skip to content

integration: Add AI-driven conflict resolution#1251

Open
ed-irl wants to merge 4 commits into
ed-irl/integration-merge-driversfrom
ed-irl/integration-auto-resolve
Open

integration: Add AI-driven conflict resolution#1251
ed-irl wants to merge 4 commits into
ed-irl/integration-merge-driversfrom
ed-irl/integration-auto-resolve

Conversation

@ed-irl

@ed-irl ed-irl commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

integration: Add AI-driven conflict resolution

Adds an opt-in fallback that invokes a user-configured shell script
when an integration-rebuild merge conflicts. Rerere and the regenerate
merge driver already handle the mechanical conflicts; this is for
the residue.

The resolver follows a strict JSON protocol on stdout:
{"assumptions": [...], "questions": [...], "unresolved_files": [...]}
Empty (or assumptions-only) means "all resolved." Questions trigger
an interactive Q&A loop whose pairs persist to .integration_resolution.json
at the repo root. unresolved_files with no questions surfaces as an
error for manual investigation. Non-zero exit or invalid JSON falls
through to the existing conflict-surfacing path.

The resolution file accumulates Q&A across rebuilds so the user
doesn't re-answer for already-resolved (ours, theirs) pairs. Entries
are pruned when branches are untracked, deleted, or removed by sync.

Scoped exclusively to gs integration rebuild and the MaybeRebuild
hook on restack — no impact on branch_merge, restack, or any
user-visible merge. Blast radius: one throwaway branch.

Configured via spice.integration.resolver (script) and
spice.integration.autoResolve (default behavior); --auto-resolve /
--no-auto-resolve override per invocation. Iteration cap is 10 to
prevent runaway loops.

integration: AI-driven auto-resolve for merge conflicts

Adds an auto-resolve path for integration-rebuild merge conflicts.
When configured and enabled, git-spice invokes a user-supplied
script on every merge conflict and, if the script reports the
conflict resolved, stages the files and commits the merge without
intervention.

Shared with the rest of git-spice's script-driven features via the
protocol surface on ed-irl/scriptrun:

  • Uses scriptrun.ResolveResponse for the JSON output schema and
    scriptrun.QAPair for resolution-file entries -- no duplicated
    types.
  • Passes the shared GS_OPERATION (always "integration-rebuild" for
    this feature) / GS_BRANCH (the tip being merged) / GS_BASE (the
    integration branch) env via scriptrun.EnvFor.
  • Iteration cap reads spice.scriptResolve.maxIterations
    (default 10) via Handler.MaxResolveIterations, replacing the
    previously private constant. main.go wires it through.
  • Resolution file lives at .spice/resolutions/integration.json via
    spicedir; the old .integration_resolution.json root-level path
    is gone. Save() auto-creates the parent directory.
  • Resolution-file unknown-field rejection is dropped: per the
    shared protocol, extra fields are ignored.
  • Per-protocol details (env contract, JSON schema, persistence,
    iteration cap, fall-through) are documented once in
    doc/src/guide/scripts.md; doc/src/guide/integration.md is
    trimmed to defer there and only documents integration-specific
    UX (Claude Code recipe, the GS_OPERATION value, resolution-file
    key layout).

CLI:

  • gs integration rebuild accepts --auto-resolve /
    --no-auto-resolve, with the default coming from
    spice.integration.autoResolve.
  • The resolver is configured via spice.integration.resolver
    (script body).

Tests:

  • Existing success / disabled / assumptions / invalid_output /
    unresolved_no_questions scripts updated to use the new
    .spice/resolutions/integration.json path.
  • persists_across_rebuilds, prune_on_delete, prune_on_untrack
    learned to mkdir the resolution dir before seeding.
  • Two new scripts (env, iteration_cap) lock the shared env
    contract and the configurable iteration cap (via
    spice.scriptResolve.maxIterations).

@ed-irl

ed-irl commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

@ed-irl ed-irl force-pushed the ed-irl/integration-merge-drivers branch from bced906 to 8dfba8a Compare June 13, 2026 13:40
@ed-irl ed-irl force-pushed the ed-irl/integration-auto-resolve branch from 2744c7a to b0ecc92 Compare June 13, 2026 13:40
@ed-irl ed-irl force-pushed the ed-irl/integration-merge-drivers branch from 8dfba8a to e08f418 Compare June 15, 2026 09:53
@ed-irl ed-irl force-pushed the ed-irl/integration-auto-resolve branch from b0ecc92 to af57956 Compare June 15, 2026 09:53
@ed-irl ed-irl force-pushed the ed-irl/integration-merge-drivers branch from 4b4fe32 to 40200ac Compare June 19, 2026 01:08
ed-irl and others added 3 commits June 23, 2026 11:43
Adds an opt-in fallback that invokes a user-configured shell script
when an integration-rebuild merge conflicts. Rerere and the regenerate
merge driver already handle the mechanical conflicts; this is for
the residue.

The resolver follows a strict JSON protocol on stdout:
  {"assumptions": [...], "questions": [...], "unresolved_files": [...]}
Empty (or assumptions-only) means "all resolved." Questions trigger
an interactive Q&A loop whose pairs persist to .integration_resolution.json
at the repo root. unresolved_files with no questions surfaces as an
error for manual investigation. Non-zero exit or invalid JSON falls
through to the existing conflict-surfacing path.

The resolution file accumulates Q&A across rebuilds so the user
doesn't re-answer for already-resolved (ours, theirs) pairs. Entries
are pruned when branches are untracked, deleted, or removed by sync.

Scoped exclusively to gs integration rebuild and the MaybeRebuild
hook on restack — no impact on branch_merge, restack, or any
user-visible merge. Blast radius: one throwaway branch.

Configured via spice.integration.resolver (script) and
spice.integration.autoResolve (default behavior); --auto-resolve /
--no-auto-resolve override per invocation. Iteration cap is 10 to
prevent runaway loops.
@ed-irl ed-irl force-pushed the ed-irl/integration-merge-drivers branch from 42fe375 to 2fe1405 Compare June 24, 2026 01:32
@ed-irl ed-irl force-pushed the ed-irl/integration-auto-resolve branch from 2cd315d to 572934b Compare June 24, 2026 01:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant