Files
fusion/packages/engine
gsxdsm b1d2a9ee43 fix(engine): tighten Layer 3 — pass safety constraint into AI prompt + harden Layer 2 restore
Self-review of the recovery cascade surfaced three issues; this commit
addresses all of them.

1. AI didn't actually receive the safety constraint under Layer 3.

The previous commit logged the safety preamble to the task log via
`store.logEntry`, but the merge agent doesn't read task log entries as
prompt context — so the AI was running blind. The "no silent
re-introduction of main's deletions" guarantee was therefore relying
*entirely* on the deterministic verification gate (test + build),
which is correct as a backstop but doesn't help the AI produce a
correct first attempt.

Fixed by threading `preMergeRebaseFallthrough` through
`MergeAttemptParams` → `executeMergeAttempt` → `runAiAgentForCommit` →
`MergePromptParams` → `buildMergePrompt`, where it now injects an
explicit "⚠️ Pre-merge rebase recovery exhausted" preamble at the top
of the user prompt with three concrete rules:
  - Prefer main's deletion when branch re-adds removed lines
  - Prefer main's version on ambiguous hunks
  - Call `fn_report_build_failure` rather than commit a regression
Also includes the original rebase failure message (truncated) so the
AI has diagnostic context.

The truncated-context retry path also forwards the preamble — it's the
safety constraint, not bulk context, so we keep it even when stripping
diff stat / commit log to fit the window.

2. Layer 2's branch-restore could fail with "uncommitted changes".

When a cherry-pick midway through Layer 2's replay fails, the worktree
is in a half-applied state with conflicts in the index. The previous
restore did `git checkout <branch>` (no -f) followed by
`git reset --hard <originalSha>`. The plain checkout would refuse with
"would overwrite local changes" if there were unmerged paths,
preventing the reset from running and leaving the branch at the
half-replayed tip.

Fixed by reordering: hard-reset to the captured original SHA first
(this clears index/working tree of any cherry-pick state), then
`git checkout -f <branch>` to ensure HEAD points at the named branch,
then a final hard-reset to the original SHA as belt-and-suspenders.
Worst case the worktree is at the original branch tip — never worse
than where Layer 2 started.

3. Pre-existing unrelated lint error blocking workspace lint.

`packages/dashboard/src/server.ts` had an unused `resolve` import from
`node:path` left behind by a recent refactor that extracted
`PACKAGE_VERSION` into its own file. The user explicitly asked to
clean it up so workspace lint passes. One-line drop.

Tests + checks:
- Engine: 2886 / 2886 pass (added safety preamble didn't break any
  existing prompt-content assertions)
- Core: 3120 / 3120 pass
- Workspace lint: clean
- Engine typecheck: clean

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 07:20:20 -07:00
..
2026-04-28 22:02:56 -07:00
2026-04-28 22:02:56 -07:00