feat(FN-4315): add audit recovery pipeline documentation and changeset
Completes FN-4315 by adding a patch changeset for `@runfusion/fusion` and updating project documentation (AGENTS.md and settings reference) to cover the audit recovery pipeline feature. Fusion-Task-Id: FN-4315 Fusion-Task-Lineage: 2646fd86-e525-4b62-a041-616fa7789e84
This commit is contained in:
5
.changeset/fn-4315-audit-recovery-pipeline.md
Normal file
5
.changeset/fn-4315-audit-recovery-pipeline.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Auto-recover from post-merge audit blocks: programmatic per-file survival check, optional AI-driven restoration pass, and an audit-bounce loop (parallel to conflict bounces) before parking a task as failed. Governed by the new `mergeAuditAutoRecovery` setting (default: `ai-assisted`).
|
||||||
@@ -237,6 +237,8 @@ Two rules, learned the hard way (FN-2370 silently reverted three commits' work):
|
|||||||
|
|
||||||
After any squash that auto-resolved conflicts, the merger runs the post-squash audit before auto-completing the task. Outcome depends on `postMergeAuditMode`: `warn` is the default (logs findings and continues), `block` is the stricter opt-in mode (refuses completion on findings), and `off` skips the audit. For rebase-strategy merges, overlap-only findings are also auto-cleared when deterministic verification has already proven the merged tree.
|
After any squash that auto-resolved conflicts, the merger runs the post-squash audit before auto-completing the task. Outcome depends on `postMergeAuditMode`: `warn` is the default (logs findings and continues), `block` is the stricter opt-in mode (refuses completion on findings), and `off` skips the audit. For rebase-strategy merges, overlap-only findings are also auto-cleared when deterministic verification has already proven the merged tree.
|
||||||
|
|
||||||
|
When audit findings still block completion, Fusion now runs an auto-recovery pipeline (Stages 1–5) governed by `mergeAuditAutoRecovery` (`deterministic-only` → `programmatic` → `ai-assisted` → `off`). Stages include deterministic short-circuiting, per-file survival checks, optional single-commit AI restoration, bounded audit-bounce retries, and finally park-with-follow-up if unresolved.
|
||||||
|
|
||||||
Before those auto-resolved squash commits are written, the merger also runs a per-file diff-volume gate: it compares each file's staged squash delta against the branch's net delta vs its merge-base, and blocks the merge in `in-review` when a non-allowlisted file loses too much branch volume. This is the pre-commit guard against FN-3936-style silent drops where fallback resolution kept a branch's commit message but discarded the branch's main file edits.
|
Before those auto-resolved squash commits are written, the merger also runs a per-file diff-volume gate: it compares each file's staged squash delta against the branch's net delta vs its merge-base, and blocks the merge in `in-review` when a non-allowlisted file loses too much branch volume. This is the pre-commit guard against FN-3936-style silent drops where fallback resolution kept a branch's commit message but discarded the branch's main file edits.
|
||||||
|
|
||||||
### Gitignored-path guard on squash merges
|
### Gitignored-path guard on squash merges
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ Features:
|
|||||||
- Sortable columns (ID/title/status/column)
|
- Sortable columns (ID/title/status/column)
|
||||||
- Column visibility toggles and optional hide-done filtering
|
- Column visibility toggles and optional hide-done filtering
|
||||||
- Bulk selection + batch model updates
|
- Bulk selection + batch model updates
|
||||||
|
- Bulk Pause / Unpause / Archive actions from the selection toolbar (`Pause selected`, `Unpause selected`, `Archive selected`) for fast batch task state management.
|
||||||
- Bulk delete from the selection toolbar (`Delete selected`): archived selections are skipped automatically, and dependency-conflict failures can be force-deleted per task after a danger confirmation that removes dependency references.
|
- Bulk delete from the selection toolbar (`Delete selected`): archived selections are skipped automatically, and dependency-conflict failures can be force-deleted per task after a danger confirmation that removes dependency references.
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -193,6 +193,7 @@ Defaults from `DEFAULT_PROJECT_SETTINGS`; key scope from `PROJECT_SETTINGS_KEYS`
|
|||||||
| `mergeDiffVolumeAllowlist` | `string[]` | `[]` | Additional glob patterns skipped by the pre-commit diff-volume gate, beyond the built-in generated-file and lockfile allowlists. |
|
| `mergeDiffVolumeAllowlist` | `string[]` | `[]` | Additional glob patterns skipped by the pre-commit diff-volume gate, beyond the built-in generated-file and lockfile allowlists. |
|
||||||
| `mergeStrategyOverlapBehavior` | `"flip-to-prefer-branch" \| "warn-only" \| "ignore"` | `"flip-to-prefer-branch"` | Safety control for `mergeConflictStrategy="smart-prefer-main"`. Before the Attempt 3 `-X ours` fallback, Fusion checks whether the task branch and recent `main` history overlap on the same files (30-commit lookback, matching the squash audit heuristics). `flip-to-prefer-branch` makes overlapping files prefer the task branch so hardening is not silently discarded (the FN-3936 class of regression). `warn-only` logs the overlap but keeps the legacy main-wins fallback. `ignore` disables the overlap guard and preserves legacy behavior exactly. |
|
| `mergeStrategyOverlapBehavior` | `"flip-to-prefer-branch" \| "warn-only" \| "ignore"` | `"flip-to-prefer-branch"` | Safety control for `mergeConflictStrategy="smart-prefer-main"`. Before the Attempt 3 `-X ours` fallback, Fusion checks whether the task branch and recent `main` history overlap on the same files (30-commit lookback, matching the squash audit heuristics). `flip-to-prefer-branch` makes overlapping files prefer the task branch so hardening is not silently discarded (the FN-3936 class of regression). `warn-only` logs the overlap but keeps the legacy main-wins fallback. `ignore` disables the overlap guard and preserves legacy behavior exactly. |
|
||||||
| `postMergeAuditMode` | `"block" \| "warn" \| "off"` | `"warn"` | Controls the post-merge audit gate. **Warn** (default) logs findings and continues to auto-complete merges. **Block** is the stricter opt-in mode: it refuses auto-completion on duplicate-subject or touched-file overlap findings when you want maximum FN-3936-class drop protection. **Off** skips the audit entirely. Regardless of mode, rebase-strategy overlap-only findings are auto-cleared when deterministic merge verification has already proven the tree (FN-4333). |
|
| `postMergeAuditMode` | `"block" \| "warn" \| "off"` | `"warn"` | Controls the post-merge audit gate. **Warn** (default) logs findings and continues to auto-complete merges. **Block** is the stricter opt-in mode: it refuses auto-completion on duplicate-subject or touched-file overlap findings when you want maximum FN-3936-class drop protection. **Off** skips the audit entirely. Regardless of mode, rebase-strategy overlap-only findings are auto-cleared when deterministic merge verification has already proven the tree (FN-4333). |
|
||||||
|
| `mergeAuditAutoRecovery` | `"deterministic-only" \| "programmatic" \| "ai-assisted" \| "off"` | `"ai-assisted"` | Controls how the engine recovers when the post-merge audit finds risks. **Deterministic only** keeps just the verified-rebase short-circuit. **Programmatic** also diffs each flagged main commit against HEAD and passes when every contribution survives. **AI-assisted** additionally lets the merger write a single restoration commit when programmatic checks find real drops, and bounces the task back to in-progress before parking. **Off** disables all recovery — failed audits park the task immediately. |
|
||||||
|
|
||||||
### Per-task direct-merge override
|
### Per-task direct-merge override
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ describe("collectTaskEvaluationEvidence", () => {
|
|||||||
taskDoneRetryCount: 6,
|
taskDoneRetryCount: 6,
|
||||||
verificationFailureCount: 7,
|
verificationFailureCount: 7,
|
||||||
mergeConflictBounceCount: 8,
|
mergeConflictBounceCount: 8,
|
||||||
|
mergeAuditBounceCount: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const summary = evidence.taskMetadata[0]?.summary ?? "";
|
const summary = evidence.taskMetadata[0]?.summary ?? "";
|
||||||
|
|||||||
@@ -743,8 +743,8 @@ describe("RoadmapStore", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("schema version", () => {
|
describe("schema version", () => {
|
||||||
it("schema version is 40 after init", () => {
|
it("schema version is 73 after init", () => {
|
||||||
expect(db.getSchemaVersion()).toBe(72);
|
expect(db.getSchemaVersion()).toBe(73);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user