Commit Graph

409 Commits

Author SHA1 Message Date
gsxdsm
51fc826199 fix(engine,core): dedup heartbeat-spawned follow-ups by parent task
Same-agent intake guard now also matches siblings sharing a
sourceParentTaskId, so repeated heartbeats from one parent task
can't bypass dedup just because triage rewrites the title.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 03:05:46 -07:00
gsxdsm
d3ad0641c4 feat(FN-5486): merge fusion/fn-5486 2026-05-22 23:42:44 -07:00
gsxdsm
3a0d179ba2 Fn-5196 2026-05-22 04:09:22 -07:00
Fusion (runfusion.ai)
9a09498397 feat(FN-5196): return 410 Gone for hard-archived task deletions
Implement the hard-archived delete contract: add a typed `ArchivedTaskDeleteError`, map hard-archived task deletes to HTTP 410 Gone at both the store and routes layers, and document the invariant in the soft-delete verification matrix.

Fusion-Task-Id: FN-5196
2026-05-22 02:04:42 -07:00
Fusion (runfusion.ai)
f6f38676b4 feat(FN-5226): add scope auto-widen layer 2.5 to merger for attribution-bas
Merges the Layer 2.5 scope-auto-widen feature (FN-5226) into the merger: a new evaluator module that automatically widens a task's declared file scope based on git attribution prior to the existing scope partition gate, wired into `merger.ts` with full audit taxonomy, persisted task metadata, and re

Fusion-Task-Id: FN-5226
2026-05-21 16:30:31 -07:00
Fusion (runfusion.ai)
0c2416903f feat(FN-5363): enforce strict target lease to prevent merge queue pollution
Enforces strict target-lease behavior on merge queue rows, gates and scrubs polluted entries, enriches no-lease handoff diagnostics, and adds regression tests covering leased-target no-lease and polluted queue reuse paths, with audit registration and docs updates.

Fusion-Task-Id: FN-5363
2026-05-21 13:40:25 -07:00
Fusion (runfusion.ai)
79850b233f feat(FN-5349): add integration branch resolver with auto-recovery fallback
FN-5349 adds a dedicated integration branch resolution module (`packages/engine/src/integration-branch.ts`) replacing ad-hoc dynamic fallbacks, routes merger branch conflict resolution through it, wires auto-recovery handlers (branch-worktree, contamination) to use integration branch fallback, and w

Fusion-Task-Id: FN-5349
2026-05-21 12:04:58 -07:00
gsxdsm
2d425b1e28 fix: scrub queued/blockedBy/overlapBlockedBy on in-review transition
A task that picked up status='queued' or overlapBlockedBy while waiting in
todo (file-scope overlap with a higher-priority peer) was carrying those
todo-dispatch markers into in-review, where the merge gate then permanently
refused with "task is marked 'queued'". Ghost-review → todo → scheduler
re-queue → stranded-completed-todo recovery → in-review formed a steady-
state loop that never let the task merge.

moveTaskInternal now treats queued/blockedBy/overlapBlockedBy as todo-only
dispatch state and clears them on every transition into in-review. failed
and awaiting-* statuses are left untouched (already covered by an existing
test, plus a new regression test for the queued case).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 11:08:14 -07:00
gsxdsm
97e6a0cc0e fix(FN-5256): skip cycle preflight when new task has no deps
The unconditional listTasks() in assertNoDependencyCycle was wasted work
for the common no-dependency write and broke the same-agent duplicate
intake fail-open path: tests that stub listTasks to throw had the cycle
check consume the rejection before _maybeAutoArchiveSameAgentDuplicate's
try/catch could swallow it, propagating the error out of createTask.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 06:40:15 -07:00
Fusion (runfusion.ai)
e12adeb3fa feat(FN-5256): complete Step 2 — enforce cycle checks on writes 2026-05-21 04:15:21 -07:00
gsxdsm
5c15031416 fix(health): re-run integrity check on Refresh health, not just re-read cache
The dashboard's corruption banner refresh action was a no-op for clearing
stale corruption flags after the user repaired the DB. Database.
scheduleBackgroundIntegrityCheck runs the integrity check exactly once at
engine boot and then early-returns forever after, so corruptionDetected
was sticky for the life of the process. POST /api/health/refresh just
read the cached flag back.

Add Database.refreshIntegrityCheck() and TaskStore.refreshDatabaseHealth()
which synchronously re-run the integrity check and update the cached
state, and have the route use them. After REINDEX / fn db --vacuum / any
in-place repair, users can now clear the banner without restarting the
engine.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:02:53 -07:00
gsxdsm
d90da81079 fix(core): default null task.description to empty string on persist
The tasks table description column is NOT NULL, so a task arriving with
description == null/undefined would fail the insert with a constraint
error. Default to "" in getTaskPersistValues, matching the ?? null / ?? 0
treatment of other optional fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 22:25:15 -07:00
Fusion (runfusion.ai)
c60045df22 feat(FN-5223): anchor staleness and stall detectors to engine activation ti
The merge introduces an engine-activation timestamp as the staleness floor for task age calculations, replacing arbitrary wall-clock thresholds with a runtime-relative anchor. Step 1 adds settings defaults, Steps 2–4 wire the floor helper through project engine, in-process runtime, and task store hy

Fusion-Task-Id: FN-5223
2026-05-20 14:29:07 -07:00
gsxdsm
31b403ea3c feat(FN-5363): remove queue-head fallback in acquireMergeQueueLease targetTaskId path
When targetTaskId is passed, the lease attempt must target that task only.
The previous code silently fell back to queue-head selection if the targeted
task was not available — producing a lease for a different task, then
returning it with the wrong taskId.  acquireReuseHandoff would then see
lease.taskId !== input.task.id and emit a misleading 'no-lease' diagnostic
that hid the real cause (queue head was occupied by an unrelated task).

The fix: when targetTaskId is set and the lease for that task returns null,
return null immediately instead of falling through to the queue-head SELECT.
Callers (acquireReuseHandoff) already validate the returned taskId and emit
structured 'no-lease' diagnostics including acquiredTaskId so the polluter
is identifiable in audit logs.

Queue-head fallback is preserved for callers that omit targetTaskId
(backward-compatible).
2026-05-20 12:05:03 -07:00
Fusion (runfusion.ai)
321c170b90 feat(FN-5143): clear agent logs when task is soft-deleted
Clears agent logs when a task is soft-deleted, with new regression tests covering the end-to-end behavior and documentation updated in the storage guide. The core logic lives in `store.ts` while `store-upsert.test.ts` is updated to reflect the new expectations.

Fusion-Task-Id: FN-5143
2026-05-20 09:42:40 -07:00
Fusion (runfusion.ai)
35b2971f54 feat(FN-5216): sanitize duplicate paths in file scope when parsing task sto
The merge adds a file scope sanitizer to the task store that deduplicates and normalizes path entries, with test coverage in `store-parsing.test.ts`; a small documentation fix accompanies the change in AGENTS.md.

Fusion-Task-Id: FN-5216
2026-05-20 06:14:47 -07:00
Fusion (runfusion.ai)
1b49cbc94d feat(FN-5284): surface db corruption via health checks, self-healing, and d
- fix(FN-5284): add db corruption audit mutation type
- feat(FN-5284): complete Step 7 — document corruption surfacing
- feat(FN-5284): complete Step 6 — add db corruption banner
- feat(FN-5284): complete Step 5 — extend health payload
- feat(FN-5284): complete Step 3 — surface db corruption in self-healing
- feat(FN-5284): complete Step 2 — add db corruption notification event
- feat(FN-5284): complete Step 1 — expose integrity check errors

Fusion-Task-Id: FN-5284
2026-05-20 04:13:43 -07:00
Fusion (runfusion.ai)
c9fd41ef26 feat(FN-5175): thread soft-delete audit context and add reconciliation scri
Adds a reconcile script to recover leaked soft-deleted tasks, threads delete audit context through all callers, and records soft-delete audit events with archive column tracking across core/engine/cli/dashboard, with reliability backstop tests covering caller alignment.

Fusion-Task-Id: FN-5175
2026-05-20 02:46:49 -07:00
Fusion (runfusion.ai)
93b11c6c0c feat(FN-5241): add atomic in-review handoff seam with executor/self-healing
The merge introduces an atomic review handoff seam in the core store (`packages/core/src/store.ts`) and migrates executor and self-healing transitions to use it, replacing the previous multi-step mutable-state handoff with a single transactional operation. Extensive reliability backstops and regress

Fusion-Task-Id: FN-5241
2026-05-20 01:01:08 -07:00
Fusion (runfusion.ai)
6b24b56b81 feat(FN-5242): add merge queue storage and lease API to task store
- docs(FN-5242): complete Step 7 — document merge queue storage
- docs(FN-5242): complete Step 5 — add changeset and exports
- fix(FN-5242): order merge queue audit assertions chronologically
- test(FN-5242): complete Step 4 — cover merge queue leasing
- feat(FN-5242): complete Step 2 — add merge queue lease API
- feat(FN-5242): complete Step 1 — add mergeQueue schema v89

Fusion-Task-Id: FN-5242
2026-05-19 21:14:49 -07:00
gsxdsm
87da1cb757 test(dashboard): align github-tracking-documentation phrases with current docs
The doc was rewritten to cover "every task-creation path" (with an
explicit enumeration of surfaces) instead of the older "task creation
flows (including ...)" wording, and uses "best-effort and non-blocking"
instead of "Creation is best-effort and non-blocking". Update the
documentation contract test to match the current phrasing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fusion-Task-Id: FN-5208
2026-05-19 19:23:47 -07:00
Fusion (runfusion.ai)
2c75ac6227 feat(FN-5188): complete Step 2 — persist bootstrappedAt
Fusion-Task-Id: FN-5188
Fusion-Task-Lineage: 6d238ff1-2d69-44e7-8694-ec19e412f8ef
2026-05-19 17:27:20 -07:00
Fusion (runfusion.ai)
1565b6dc52 feat(FN-5188): complete Step 1 — linked worktree refusal
Fusion-Task-Id: FN-5188
Fusion-Task-Lineage: 6d238ff1-2d69-44e7-8694-ec19e412f8ef
2026-05-19 17:27:20 -07:00
gsxdsm
19e2ff0279 fix(core): suppress activity-log writes for polling-emitted events
When multiple TaskStore instances watch the same SQLite DB (dashboard +
engine runtime + per-project stores in one dashboard process), every
column move was recorded once per polling instance — inflating
task:moved rows 3x and amplifying failure noise (146k+ moves and 781
task:failed events in 24h against ~165 real done tasks).

Set suppressActivityLogForPollingEmit while checkForChanges fires
re-emit events, and skip the activity-log listeners when it's set. The
originating instance's in-process emit path remains the sole writer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 16:25:53 -07:00
gsxdsm
abfbbcda1e feat(FN-5140): merge fusion/fn-5140 2026-05-19 10:29:42 -07:00
Fusion (runfusion.ai)
97f46dbad8 test(FN-5115): complete Step 7 — stabilize migrations and verification
Fusion-Task-Id: FN-5115
Fusion-Task-Lineage: 5c3d9d42-9dcd-4ebb-ba10-8a4b14d541dd
2026-05-19 06:51:26 -07:00
Fusion (runfusion.ai)
f36172f564 feat(FN-5115): complete Step 2 — add done pause backfills
Fusion-Task-Id: FN-5115
Fusion-Task-Lineage: 5c3d9d42-9dcd-4ebb-ba10-8a4b14d541dd
2026-05-19 06:51:25 -07:00
Fusion (runfusion.ai)
35b00d2869 feat(FN-5115): complete Step 1 — clear done pause fields
Fusion-Task-Id: FN-5115
Fusion-Task-Lineage: 5c3d9d42-9dcd-4ebb-ba10-8a4b14d541dd
2026-05-19 06:51:25 -07:00
Fusion (runfusion.ai)
e0c0745c00 test(FN-5129): add lineage soft-delete and archive regression coverage
Fusion-Task-Id: FN-5129
Fusion-Task-Lineage: 77519a37-0552-4e8b-8061-ce84012de978
2026-05-19 06:37:56 -07:00
Fusion (runfusion.ai)
bd8bd745d5 feat(FN-5129): complete Step 3 — gate archiveTask lineage references
Fusion-Task-Id: FN-5129
Fusion-Task-Lineage: 77519a37-0552-4e8b-8061-ce84012de978
2026-05-19 06:37:56 -07:00
Fusion (runfusion.ai)
5d9669ad35 feat(FN-5129): complete Step 2 — enforce lineage gate in deleteTask
Fusion-Task-Id: FN-5129
Fusion-Task-Lineage: 77519a37-0552-4e8b-8061-ce84012de978
2026-05-19 06:37:56 -07:00
Fusion (runfusion.ai)
911125f1c9 feat(FN-5129): complete Step 1 — add lineage child guard primitives
Fusion-Task-Id: FN-5129
Fusion-Task-Lineage: 77519a37-0552-4e8b-8061-ce84012de978
2026-05-19 06:37:56 -07:00
Fusion (runfusion.ai)
c3178b564b fix(FN-5127): complete Step 1 — make deleteTask idempotent on re-delete
Fusion-Task-Id: FN-5127
Fusion-Task-Lineage: aafbc6a7-fa26-4dad-ab16-96ea79f8cee2
2026-05-19 06:10:35 -07:00
Fusion (runfusion.ai)
7c9209bba1 test(FN-5105): complete Step 5 — align soft-delete regressions
Fusion-Task-Id: FN-5105
Fusion-Task-Lineage: a876d5eb-d828-415e-b6f0-07bbc8713417
2026-05-19 05:16:37 -07:00
Fusion (runfusion.ai)
44df53c2fb feat(FN-5105): implement soft-delete readers and FTS filtering
Fusion-Task-Id: FN-5105
Fusion-Task-Lineage: a876d5eb-d828-415e-b6f0-07bbc8713417
2026-05-19 05:16:37 -07:00
Fusion (runfusion.ai)
a12047b603 feat(FN-5105): complete Step 1 — add deletedAt schema plumbing
Fusion-Task-Id: FN-5105
Fusion-Task-Lineage: a876d5eb-d828-415e-b6f0-07bbc8713417
2026-05-19 05:16:36 -07:00
Fusion (runfusion.ai)
85bc219279 feat(FN-5093): complete Step 3 — hydrate inReviewStalled in TaskStore
Fusion-Task-Id: FN-5093
Fusion-Task-Lineage: fe96617a-88f8-4a3c-b96c-c516d2206331
2026-05-19 03:54:48 -07:00
Fusion (runfusion.ai)
d192154b2b feat(FN-5034): complete Step 4 — hydrate stale paused todo in TaskStore
Fusion-Task-Id: FN-5034
Fusion-Task-Lineage: 1e315656-30d8-41d2-9802-0d9e155f0ba8
2026-05-19 03:10:25 -07:00
gsxdsm
af7367ab99 feat(FN-5035): merge fusion/fn-5035 2026-05-18 18:07:53 -07:00
gsxdsm
0046fc92e2 feat(FN-4918): merge fusion/fn-4918 2026-05-18 16:23:06 -07:00
gsxdsm
aad1219037 feat(FN-4967): merge fusion/fn-4967 2026-05-18 15:50:48 -07:00
gsxdsm
896ae7a931 feat(FN-5077): merge fusion/fn-5077 2026-05-18 15:01:20 -07:00
Fusion (runfusion.ai)
3ec0d3b82a feat(FN-5052): complete Step 3 — pass autoMerge through stall hydration
Fusion-Task-Id: FN-5052
Fusion-Task-Lineage: 607cd9e6-e4d0-4572-b183-8253d127209f
2026-05-18 08:44:20 -07:00
Fusion (runfusion.ai)
cf9d5f0b76 fix(FN-5051): unblock workspace verification by restoring core typings/exports
Fusion-Task-Id: FN-5051
Fusion-Task-Lineage: a83d5a5a-0211-47ae-9894-0f9a31aaa1bd
2026-05-18 08:31:38 -07:00
Fusion (runfusion.ai)
9eb10fca7e feat(FN-4899): complete Step 2 — support source metadata patches
Fusion-Task-Id: FN-4899
Fusion-Task-Lineage: 2ae24667-6635-4268-a620-d6012266d8f2
2026-05-18 08:02:21 -07:00
Fusion (runfusion.ai)
b692656510 feat(FN-4999): recover completion handoff limbo safely
- Add completion handoff limbo recovery state to task storage and audit events for bounded self-healing retries
- Requeue eligible in-review tasks stuck after "Task marked done by agent" with grace-period, active-task, and merge-blocker safeguards
- Isolate executor run mutation context per task to prevent cross-task runId attribution leaks in scope-leak and completion logs
- Add reliability and executor regression tests covering limbo recovery, run-context isolation, and updated persistence behavior

Fusion-Task-Id: FN-4999
2026-05-18 05:29:10 -07:00
Fusion (runfusion.ai)
dca221829d feat(FN-4990): complete Step 3 — guard out-of-order done updates
Fusion-Task-Id: FN-4990
Fusion-Task-Lineage: 167a6011-d246-45bd-ad7a-1f2fe8b99323
2026-05-18 02:43:33 -07:00
Fusion (runfusion.ai)
77d4a9b466 feat(FN-4892): add same-agent duplicate intake helper and store gate
Fusion-Task-Id: FN-4892
Fusion-Task-Lineage: 6f56b468-a827-416d-ba1f-444e1326d613
2026-05-18 00:53:23 -07:00
Fusion (runfusion.ai)
3037bbf9d6 feat(FN-4908): complete Step 1 — add SQL reliability aggregations
Fusion-Task-Id: FN-4908
Fusion-Task-Lineage: 97d96ea4-8618-43cc-8448-0132cd57974e
2026-05-17 23:21:34 -07:00
Fusion (runfusion.ai)
fc98f46196 feat(FN-4942): complete Step 1 — auto-attach summarizer in createTask
Fusion-Task-Id: FN-4942
Fusion-Task-Lineage: 20865705-e5ec-4261-932c-4d47c2d8dc12
2026-05-17 19:04:18 -07:00