aedee4b8231bf050c3240a00ab6645ede5d87ee9
426 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
87e673baf7 |
feat(merge): remove the pre-commit diff-volume gate
The gate blocked approved clean-room squashes on per-file shrinkage with no
override path ("AI merge diff-volume gate blocked the approved squash").
Removed by operator decision: delete checkDiffVolume/DiffVolumeRegressionError,
the merge:diff-volume-blocked audit event, the runDiffVolumeGate call sites in
every legacy squash finalizer, the AI-merge pre-land check, and the
mergeDiffVolume* settings. File scope remains the pre-land guard; the
post-squash audit policy remains the shrinkage backstop.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
2a9ae0aca3 |
FN-9109: add resilient cross-runtime Cursor fallback
Route eligible CLI fallback failures into one bounded, auditable Cursor runtime handoff. - defer cursor-cli fallback selection until a retryable primary prompt failure - serialize concurrent swaps, retry the primary after failed handoffs, and dispose replacements safely - transfer text-only conversation context within strict turn and total character limits - document routing behavior and cover provider, runtime, concurrency, and failure cases Files changed: .../fn-9109-cross-runtime-cursor-fallback.md | 7 + AGENTS.md | 2 + docs/cursor-cli-contract.md | 8 + .../src/__tests__/cli-provider-routing.test.ts | 18 +- .../cli-runtime-routing-conformance.test.ts | 64 ++++- .../src/__tests__/cross-runtime-fallback.test.ts | 146 +++++++++++ .../engine/src/agents/agent-session-helpers.ts | 211 ++++++---------- packages/engine/src/agents/cli-provider-routing.ts | 4 +- .../engine/src/agents/cross-runtime-fallback.ts | 277 +++++++++++++++++++++ packages/engine/src/util/run-audit.ts | 8 + 10 files changed, 602 insertions(+), 143 deletions(-) Fusion-Task-Id: FN-9109 Fusion-Task-Lineage: 30664371-8410-4d6f-a263-cc86c8e0dc72 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9fa8b386ee |
FN-9059: add durable workspace coordination leases
Prevent overlapping multi-node workspace operations and duplicate repository landings. - Add durable coordination leases, fence tokens, and land-intent persistence. - Fence workspace merge dispatches and repository publication across engine nodes. - Reconcile expired coordination state safely and cover lease lifecycle behavior. Files changed: .../fn-9059-workspace-durable-coordination.md | 7 + AGENTS.md | 1 + docs/architecture.md | 2 + docs/multi-project.md | 48 ++++ .../workspace-coordination-leases.pg.test.ts | 56 ++++ .../__tests__/postgres/workspace-leases.pg.test.ts | 112 ++++++++ packages/core/src/engine-node-identity.ts | 22 ++ packages/core/src/index.ts | 3 + .../0060_fn_9059_workspace_coordination_leases.sql | 10 + packages/core/src/postgres/schema-applier.ts | 13 +- packages/core/src/postgres/schema/project.ts | 31 ++ packages/core/src/store.ts | 18 ++ packages/core/src/task-store/workspace-leases.ts | 261 +++++++++++++++++ packages/core/src/tasks/workspace-lease-types.ts | 24 ++ .../engine/src/__tests__/project-engine.test.ts | 69 ++++- .../src/__tests__/self-healing-workspace.test.ts | 63 ++++- .../workspace-durable-coordination.test.ts | 49 ++++ .../src/__tests__/workspace-merger-lease.test.ts | 312 ++++++++++++++++++++- packages/engine/src/merge/merger-ai.ts | 277 ++++++++++++++++-- packages/engine/src/merge/workspace-fence-ref.ts | 171 +++++++++++ packages/engine/src/project-engine.ts | 175 ++++++++++-- packages/engine/src/runtimes/in-process-runtime.ts | 4 +- packages/engine/src/self-healing.ts | 191 ++++++++++++- packages/engine/src/util/run-audit.ts | 2 + .../engine/src/worktree/worktree-acquisition.ts | 43 ++- 25 files changed, 1901 insertions(+), 63 deletions(-) Fusion-Task-Id: FN-9059 Fusion-Task-Lineage: e51e3f54-69ee-4337-a218-4895d87474aa Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
43889bc684 |
FN-9058: block workspace main-checkout edits
Prevent workspace tasks from completing after task-era edits in configured sub-repository main checkouts. - Detect dirty and recent commit evidence across every workspace main checkout before invariant checks. - Block attributable edits with bounded retries while warning safely for inconclusive evidence. - Add audit telemetry, documentation, changeset, and real-git regression coverage. Files changed: .../fn-9058-workspace-main-checkout-guard.md | 7 + AGENTS.md | 1 + docs/architecture.md | 1 + .../engine/src/__tests__/_workspace-fixture.ts | 3 +- .../executor-workspace-main-checkout-guard.test.ts | 164 +++++++++++++++++++++ packages/engine/src/executor/execution-prompt.ts | 3 +- .../src/executor/workspace-main-checkout-guard.ts | 128 ++++++++++++++++ .../src/executor/worktree-verify-invariants.ts | 45 +++++- packages/engine/src/util/run-audit.ts | 2 + 9 files changed, 351 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-9058 Fusion-Task-Lineage: b5dd58bd-4bd9-41fd-b3d5-e07270f3abca Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
db8e715452 |
FN-9056: reclaim safe terminal workspace worktrees
Reclaim safely abandoned workspace worktrees and canonical task branches without disrupting live or recoverable tasks. - Tear down eligible complete, idle failed, and soft-deleted per-repository worktrees with bounded retries. - Veto live, paused, scheduled-recovery, ambiguous, and unsafe-path cleanup candidates. - Verify failed-task landing evidence against each repository integration branch before deleting canonical branches. - Cover liveness and stale landed-SHA safety regressions. Files changed: .changeset/fn-9056-workspace-terminal-teardown.md | 7 + AGENTS.md | 2 +- docs/architecture.md | 1 + .../src/__tests__/self-healing-workspace.test.ts | 319 ++++++++++++++++++++- .../engine/src/executor/cleanup-task-worktree.ts | 8 +- packages/engine/src/self-healing.ts | 268 ++++++++++++----- packages/engine/src/util/run-audit.ts | 7 +- 7 files changed, 525 insertions(+), 87 deletions(-) Fusion-Task-Id: FN-9056 Fusion-Task-Lineage: 4353f7d9-063b-442b-88d3-6f3da1c9aae8 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
c9e283ae0d |
FN-9049: distinguish unavailable workspace branch evidence
Prevent transient Git probe failures from being treated as missing workspace branches. - Classify branch evidence as present, absent, or unavailable using show-ref probes - Defer unavailable evidence with bounded retries before parking a task - Cover probe outcomes and partial-land recovery with workspace tests - Add a patch changeset and document the workspace reconciliation contract Files changed: .changeset/fn-9049-workspace-branch-evidence.md | 7 ++ AGENTS.md | 2 +- .../src/__tests__/self-healing-workspace.test.ts | 134 +++++++++++++++++++-- packages/engine/src/self-healing-git-evidence.ts | 59 +++++++-- packages/engine/src/self-healing.ts | 71 +++++++---- 5 files changed, 234 insertions(+), 39 deletions(-) Fusion-Task-Id: FN-9049 Fusion-Task-Lineage: 1a77d5af-3c06-4229-b61e-30a3891870ca Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d6da58d89a |
FN-9054: reclaim archived workspace land leases
Reclaim stale workspace land leases when their owners are terminal. - Treat archived and soft-deleted workspace task owners as terminal after the existing staleness floor. - Preserve active and merge-pending lease protections while recording terminal reclaim reasons. - Cover archived, renamed archive lane, deleted, missing, and protected-owner lease cases. Files changed: AGENTS.md | 2 +- .../src/__tests__/self-healing-workspace.test.ts | 150 +++++++++++++++++++++ packages/engine/src/self-healing.ts | 50 ++++--- packages/engine/src/util/run-audit.ts | 2 +- 4 files changed, 185 insertions(+), 19 deletions(-) Fusion-Task-Id: FN-9054 Fusion-Task-Lineage: 747e62f2-732a-4640-8d49-c08869a47964 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5134a55b77 |
FN-8958: fence orphaned merge-body writes
Prevent cancelled merge generations from writing stale task state. - Add a signal-aware merge write fence with orphan audit reporting. - Fence merge finalization, post-push metadata, and recovery-branch task logs. - Cover durable write callsites and cancellation behavior with tests and guidance. Files changed: .changeset/fn-8958-orphan-merge-write-fence.md | 7 + AGENTS.md | 1 + .../reliability/orphan-merge-body-write-fence.md | 68 ++ .../__tests__/_merge-durable-write-callsites.ts | 4 + .../merge-orphan-durable-write-inventory.json | 982 +++++++++++---------- .../merge-orphan-body-durable-writes.test.ts | 38 +- .../engine/src/__tests__/merge-write-fence.test.ts | 39 + .../engine/src/merge/auto-merge-finalization.ts | 9 + packages/engine/src/merge/merge-write-fence.ts | 92 ++ packages/engine/src/merge/merger-ai.ts | 173 ++-- 10 files changed, 875 insertions(+), 538 deletions(-) Fusion-Task-Id: FN-8958 Fusion-Task-Lineage: 5f398c44-4320-4f0c-be15-707184f66aa8 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6ae9299576 |
FN-8953: defer terminal wedge alerts during recovery
Hold terminal wedge alerts until their recovery window has elapsed. - Persist and settle pending wedge notifications across restarts. - Clear pending alerts on task progress and reconcile expired holds during self-healing. - Expose the settle window in notification settings with coverage for store and notification flows. Files changed: .changeset/fn-8953-wedge-settle-window.md | 7 + AGENTS.md | 1 + docs/architecture.md | 3 +- docs/settings-reference.md | 1 + .../core/src/__tests__/store-wedge-pending.test.ts | 56 +++++ packages/core/src/config/settings-schema.ts | 1 + packages/core/src/store.ts | 46 ++++ packages/core/src/types/settings/settings-scope.ts | 2 + packages/core/src/types/task/task-core.ts | 15 ++ .../app/components/settings/save-split.ts | 1 + .../sections/NotificationsSection.search.ts | 9 + .../settings/sections/NotificationsSection.tsx | 15 ++ .../settings-default-descriptions.test.tsx | 1 + ...self-healing-pending-wedge-notification.test.ts | 148 ++++++++++++ .../__tests__/notification-service.test.ts | 7 +- .../__tests__/task-wedge-notification.test.ts | 258 ++++++++++++++++++++- .../src/notification/notification-service.ts | 260 +++++++++++++++++++++ packages/engine/src/self-healing.ts | 38 +++ packages/i18n/locales/en/app.json | 2 + 19 files changed, 850 insertions(+), 21 deletions(-) Fusion-Task-Id: FN-8953 Fusion-Task-Lineage: fd5b5827-c69d-409f-86d5-01ff23405ee3 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
eef68fe0b9 |
FN-8933: capture semantic memory from completed work
Add inferred graph relationships and detached recall capture across completed-work memory surfaces. - Validate and persist deterministic inferred semantic edges with audit outcomes. - Capture completed tasks, research findings, and insights as bounded recall entries. - Wire memory semantics through engine, research APIs, and coverage tests. Files changed: .changeset/fn-8933-memory-semantics-capture.md | 7 + AGENTS.md | 1 + docs/knowledge-graph.md | 10 +- .../src/__tests__/memory/recall-capture.test.ts | 111 +++++++++++++ .../__tests__/postgres/insight-store.pg.test.ts | 25 +++ .../postgres/research-execution.pg.test.ts | 38 +++++ .../__tests__/research-feature-promotion.test.ts | 39 +++++ .../core/src/async-stores/async-insight-store.ts | 23 ++- packages/core/src/index.ts | 1 + .../__tests__/graph-builder-incremental.test.ts | 28 ++++ .../__tests__/inferred-edge-writer.test.ts | 74 +++++++++ packages/core/src/knowledge-graph/graph-builder.ts | 27 ++- .../src/knowledge-graph/graph-serialization.ts | 2 +- packages/core/src/knowledge-graph/graph-store.ts | 12 ++ packages/core/src/knowledge-graph/graph-types.ts | 2 +- packages/core/src/knowledge-graph/index.ts | 1 + .../src/knowledge-graph/inferred-edge-writer.ts | 96 +++++++++++ packages/core/src/memory/index.ts | 1 + packages/core/src/memory/recall-capture.ts | 184 +++++++++++++++++++++ .../src/research/research-feature-promotion.ts | 23 ++- packages/core/src/task-store/task-store-helpers.ts | 13 +- .../src/__tests__/research-routes.test.ts | 80 ++++++++- packages/dashboard/src/research-routes.ts | 27 ++- .../src/__tests__/agent-mission-tools.test.ts | 60 ++++++- .../src/__tests__/in-process-runtime.pg.test.ts | 28 +++- .../memory-consolidation-heartbeat-hook.test.ts | 8 +- .../__tests__/memory-consolidation-ports.test.ts | 17 +- .../src/__tests__/memory-semantics-pass.test.ts | 115 +++++++++++++ .../engine/src/__tests__/project-engine.test.ts | 65 +++++++- packages/engine/src/agent-heartbeat.ts | 14 +- packages/engine/src/agent-tools.ts | 12 +- packages/engine/src/agents/agent-reflection.ts | 9 +- packages/engine/src/memory/index.ts | 1 + .../src/memory/memory-consolidation-adapters.ts | 18 +- packages/engine/src/memory/memory-consolidation.ts | 13 +- packages/engine/src/memory/memory-semantics.ts | 67 ++++++++ packages/engine/src/project-engine.ts | 3 + .../engine/src/research/research-orchestrator.ts | 20 ++- packages/engine/src/runtimes/in-process-runtime.ts | 12 ++ packages/engine/src/util/run-audit.ts | 11 ++ 40 files changed, 1250 insertions(+), 48 deletions(-) Fusion-Task-Id: FN-8933 Fusion-Task-Lineage: b75a6b23-906f-4255-92f1-7684beb742b8 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
f1fe399184 |
FN-8991: add runtime skill-loader drift gate
Enforce the intentional Claude-to-Grok runtime skill-loader clone relationship across verification lanes. - Add an exact rename-diff validator with fixture and live-loader coverage. - Run the validator in pretest, fast verification, and static merge-gate checks. - Document the loader duplication contract and expanded static-validator inventory. Files changed: AGENTS.md | 2 + docs/testing.md | 4 +- package.json | 7 +- .../check-runtime-skill-loader-drift.test.mjs | 113 +++++++++++++++++++++ scripts/__tests__/run-static-gate-checks.test.mjs | 1 + scripts/__tests__/verify-fast.test.mjs | 1 + scripts/check-runtime-skill-loader-drift.mjs | 113 +++++++++++++++++++++ 7 files changed, 236 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-8991 Fusion-Task-Lineage: a3b67752-0043-4336-9a2a-ff391672b31f Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
637854ad36 |
FN-8932: add durable memory consolidation agent
Add a provisioned memory agent that consolidates durable recall material through idempotent heartbeat ticks. - Provision and configure the durable memory agent with an enabled workflow setting. - Add consolidation adapters, material collection, recall graph references, and run-audit metadata. - Expose the setting in the dashboard and document the memory-agent behavior. - Cover provisioning, heartbeat, consolidation, audit, and recall graph behavior with tests. Files changed: .changeset/fn-8932-memory-agent.md | 7 ++ AGENTS.md | 1 + docs/agents.md | 10 ++ docs/settings-reference.md | 1 + docs/storage.md | 2 +- .../memoryConsolidationEnabled-default.test.ts | 22 ++++ .../memory-recall-graph-cross-reference.pg.test.ts | 115 +++++++++++++++++++++ .../__tests__/memory-agent-provisioning.test.ts | 31 ++++++ packages/core/src/agents/agent-store.ts | 85 +++++++++++++++ packages/core/src/agents/memory-agent-defaults.ts | 30 ++++++ packages/core/src/index.gate.ts | 2 + packages/core/src/index.ts | 9 ++ packages/core/src/memory/recall/index.ts | 1 + packages/core/src/memory/recall/recall-dedup.ts | 3 + packages/core/src/memory/recall/recall-store.ts | 35 ++++++- .../src/workflows/builtin-workflow-settings.ts | 14 +++ .../src/workflows/workflow-settings-resolver.ts | 12 ++- .../__tests__/WorkflowSettingsPanel.test.tsx | 8 ++ .../__tests__/workflow-setting-display.test.ts | 6 ++ .../app/components/workflow-setting-display.ts | 5 + .../memory-consolidation-heartbeat-hook.test.ts | 92 +++++++++++++++++ .../__tests__/memory-consolidation-ports.test.ts | 34 ++++++ ...memory-consolidation-run-audit-metadata.test.ts | 19 ++++ .../__tests__/memory-consolidation-tick.test.ts | 62 +++++++++++ packages/engine/src/agent-heartbeat.ts | 55 ++++++++++ packages/engine/src/index.ts | 1 + packages/engine/src/memory/index.ts | 3 + .../src/memory/memory-consolidation-adapters.ts | 29 ++++++ .../src/memory/memory-consolidation-material.ts | 22 ++++ packages/engine/src/memory/memory-consolidation.ts | 41 ++++++++ packages/engine/src/util/run-audit.ts | 10 ++ 31 files changed, 764 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-8932 Fusion-Task-Lineage: b4fdec50-1f42-4120-af17-0b6f3a94586e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
cef07527f6 |
FN-8948: reconcile mission state from task ground truth
Centralize mission and feature state repair around deterministic task lifecycle evidence. - Add a reusable mission reconciliation authority with task-move, API, tool, and maintenance callers. - Repair unambiguous title links while preserving terminal, validation, and audit safeguards. - Route scheduler moves through the authority and reject duplicate feature-title ownership. - Expose reconcile controls and document the operator workflow. Files changed: .changeset/fn-8948-mission-auto-reconcile.md | 7 + AGENTS.md | 1 + docs/missions.md | 8 +- packages/cli/skill/fusion/SKILL.md | 2 +- .../cli/skill/fusion/references/extension-tools.md | 9 + .../skill/fusion/references/fusion-capabilities.md | 1 + .../extension-experiment-finalize.test.ts | 2 + .../__tests__/extension-gitlab-tracking.test.ts | 2 + .../cli/src/__tests__/extension-web-fetch.test.ts | 2 + packages/cli/src/extension.ts | 14 + packages/dashboard/src/mission-routes.ts | 24 +- .../src/__tests__/agent-mission-tools.test.ts | 2 +- .../engine/src/__tests__/mission-autopilot.test.ts | 8 +- .../src/__tests__/mission-state-reconcile.test.ts | 67 +++++ packages/engine/src/agent-tools.ts | 6 + .../engine/src/execution/gating-classifications.ts | 1 + packages/engine/src/index.ts | 6 + packages/engine/src/missions/index.ts | 8 +- packages/engine/src/missions/mission-autopilot.ts | 106 +------ .../engine/src/missions/mission-feature-sync.ts | 1 + .../engine/src/missions/mission-state-reconcile.ts | 169 +++++++++++ packages/engine/src/runtimes/in-process-runtime.ts | 4 +- packages/engine/src/scheduler.ts | 331 +++++---------------- packages/engine/src/util/run-audit.ts | 2 + 24 files changed, 426 insertions(+), 357 deletions(-) Fusion-Task-Id: FN-8948 Fusion-Task-Lineage: 0fbccef3-eeac-46d2-b3d8-aca679b3657e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3143f9536f |
FN-8908: auto-recover terminal task failures
Recover generic terminal task failures through a bounded, durable retry budget before escalating them to operators. - add fenced task-store recovery claims, retries, budget resets, and audit events - defer terminal-failure notifications until recovery is exhausted while preserving a single escalation - expose operator retry budget reset and cover recovery lifecycle behavior Files changed: .../fn-8908-terminal-failure-auto-recovery.md | 7 + AGENTS.md | 1 + docs/agents.md | 2 + docs/architecture.md | 2 + packages/cli/src/commands/task.ts | 2 + packages/cli/src/extension.ts | 2 + ...terminal-failure-auto-recovery-store.pg.test.ts | 108 +++++++++ .../terminal-failure-auto-recovery.test.ts | 60 +++++ packages/core/src/index.gate.ts | 1 + packages/core/src/index.ts | 1 + packages/core/src/store.ts | 179 ++++++++++++++- .../core/src/task-store/archive-lifecycle-2.ts | 15 ++ packages/core/src/task-store/moves.ts | 48 +++- packages/core/src/task-store/persistence.ts | 18 +- packages/core/src/task-store/project-store-ops.ts | 4 +- .../src/task-store/workflow-task-create-ops.ts | 4 +- packages/core/src/tasks/index.ts | 1 + .../src/tasks/terminal-failure-auto-recovery.ts | 114 ++++++++++ packages/core/src/types/task/task-core.ts | 24 ++ .../src/routes/register-task-workflow-routes.ts | 2 + ...-healing-terminal-failure-auto-recovery.test.ts | 199 ++++++++++++++++ .../__tests__/notification-service.test.ts | 86 ++++++- .../__tests__/task-wedge-notification.test.ts | 2 +- .../src/notification/notification-service.ts | 103 +++++++-- .../src/notification/task-wedge-notification.ts | 30 ++- packages/engine/src/self-healing.ts | 251 ++++++++++++++++++++- packages/engine/src/util/run-audit.ts | 7 + 27 files changed, 1240 insertions(+), 33 deletions(-) Fusion-Task-Id: FN-8908 Fusion-Task-Lineage: 99e96b16-0306-41f1-87da-8623d69735f7 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
27cb2d2621 |
FN-8921: add deterministic knowledge graph tooling
Add a committable, provenance-tagged knowledge graph layer with CLI generation and query support. - Extract TypeScript, Markdown, and FNXC knowledge into deterministic graph nodes and edges. - Persist recoverable graph artifacts outside ignored Fusion state and expose build/query CLI commands. - Document configuration and add core and CLI coverage for graph structure, serialization, and recovery. Files changed: .changeset/fn-8921-knowledge-graph.md | 7 + .gitattributes | 3 + AGENTS.md | 1 + docs/README.md | 2 + docs/cli-reference.md | 4 + docs/knowledge-graph.md | 37 +++++ docs/settings-reference.md | 4 + docs/storage.md | 2 + packages/cli/package.json | 3 +- .../__tests__/knowledge-graph-bundle-shape.test.ts | 4 + .../src/__tests__/knowledge-graph-command.test.ts | 115 ++++++++++++++ packages/cli/src/bin.ts | 19 +++ packages/cli/src/commands/knowledge-graph.ts | 79 ++++++++++ packages/cli/tsup.config.ts | 2 + packages/core/package.json | 4 +- packages/core/src/config/settings-schema.ts | 2 + packages/core/src/index.ts | 1 + .../__tests__/derive-modules.test.ts | 11 ++ .../__tests__/extract-file-composition.test.ts | 20 +++ .../knowledge-graph/__tests__/extract-fnxc.test.ts | 33 ++++ .../__tests__/extract-markdown.test.ts | 21 +++ .../__tests__/extract-typescript.test.ts | 30 ++++ .../__tests__/file-discovery.test.ts | 26 ++++ .../graph-artifact-not-gitignored.test.ts | 15 ++ .../__tests__/graph-builder-equivalence.test.ts | 76 ++++++++++ .../__tests__/graph-builder-incremental.test.ts | 52 +++++++ .../__tests__/graph-identity.test.ts | 11 ++ .../knowledge-graph/__tests__/graph-query.test.ts | 13 ++ .../__tests__/graph-serialization.test.ts | 29 ++++ .../__tests__/graph-store-recovery.test.ts | 106 +++++++++++++ .../__tests__/resolve-imports.test.ts | 10 ++ .../core/src/knowledge-graph/derive-modules.ts | 4 + packages/core/src/knowledge-graph/extract-file.ts | 6 + packages/core/src/knowledge-graph/extract-fnxc.ts | 168 +++++++++++++++++++++ .../core/src/knowledge-graph/extract-markdown.ts | 9 ++ .../core/src/knowledge-graph/extract-typescript.ts | 107 +++++++++++++ .../core/src/knowledge-graph/file-discovery.ts | 85 +++++++++++ packages/core/src/knowledge-graph/graph-builder.ts | 141 +++++++++++++++++ .../core/src/knowledge-graph/graph-manifest.ts | 4 + packages/core/src/knowledge-graph/graph-query.ts | 126 ++++++++++++++++ .../src/knowledge-graph/graph-serialization.ts | 134 ++++++++++++++++ packages/core/src/knowledge-graph/graph-store.ts | 97 ++++++++++++ packages/core/src/knowledge-graph/graph-types.ts | 54 +++++++ packages/core/src/knowledge-graph/index.ts | 14 ++ .../core/src/knowledge-graph/resolve-imports.ts | 4 + packages/core/src/types/settings/settings-scope.ts | 2 + pnpm-lock.yaml | 12 +- 47 files changed, 1700 insertions(+), 9 deletions(-) Fusion-Task-Id: FN-8921 Fusion-Task-Lineage: 7014d0f1-fc47-454b-afe5-5f0d9b229f33 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
51437558ac |
fix(workflow): give a stranded planning hold a retry owner, and stop status erasure
FN-8923 sat silent in Todo for 7+ hours with zero run-audit rows. Its plan node held on principal routing, triage correctly recorded `needs-replan`, and then dependency auto-unblock nulled that status when its blocker completed. From that moment the card was invisible to both lanes: triage saw a fully-written spec with no replan flag and skipped it, while the executor's `isUnplannedForExecution` refused to dispatch because no capacity-boundary continuation existed. Not stuck in a retry loop -- unowned. - Dependency auto-unblock clears only the `queued` marker it owns, at all four sites (scheduler.ts plus three in self-healing.ts). `status` is a shared lifecycle channel and `needs-replan` is the only signal that re-admits a hold-column card whose PROMPT.md is already a real spec. - New self-healing sweep `reconcilePrincipalHeldPlanningContinuations` re-queues planning for a card whose sole active continuation is a principal-routing hold. A planning hold otherwise has no retry owner at all. Gated on the planning lane, effective auto-merge, an owned (null) status, and the shared planning lifecycle lock, so it cannot clobber a triage claim or launder a `failed` / `stuck-killed` / `queued` card into a replan. - Workflow node-instance-id materialization is idempotent across foreach, loop, and optional-group containers. It re-wrapped its own output on every dispatch, so FN-8869 grew a ~1.8 KB `run_id` of ~30 repeated segments on a hot indexed column and every retry read as a distinct run. - An unresolvable node instance or absent IR now fails closed instead of being treated as an edited-away override -- the previous shape would have discarded a real reviewer fence and handed a named review to the pool. - Mirror the routing exports into the gate-safe core barrel; the reduced barrel resolved them to `undefined`, a latent trap for any suite reaching the router. Findings from a multi-reviewer pass; 9 of 11 confirmed by an independent validator. Each fix carries a regression asserting the invariant across its surfaces, not the single reported case -- the optional-group accretion test was verified to fail without the fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6bd8004ba1 |
FN-8915: document agent activity API contract
Publish an inspectable contract for durable agent-activity history and pagination. - Define the route wire shape, cursor semantics, retention, and SSE recovery behavior. - Add PostgreSQL and dashboard coverage for documented pagination and truncation guarantees. - Link architecture and diagnostics guidance to the canonical contract and validate its prerequisite lineage. Files changed: .changeset/fn-8864-agent-activity-events.md | 2 +- AGENTS.md | 1 + docs/agent-activity-contract.md | 94 ++++++++++++++++++++++ docs/architecture.md | 2 +- docs/diagnostics.md | 2 +- .../agent-activity-cursor-contract.pg.test.ts | 90 +++++++++++++++++++++ .../src/__tests__/agent-activity-route.test.ts | 10 +++ .../src/__tests__/sse-agent-activity.test.ts | 12 ++- scripts/check-fn-8864-ancestry.sh | 35 ++++++++ 9 files changed, 244 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-8915 Fusion-Task-Lineage: da3f8c96-3b58-4e6d-a413-c51bdd643f26 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3d6a908b95 |
FN-8898: document inert prerebase settings
Clarify that legacy prerebase settings are inert on the production merge path. - Mark retained prerebase configuration and audit events as legacy-only. - Add a static validator and tests preventing new prerebase callers. - Update merge architecture, testing, and settings documentation. Files changed: AGENTS.md | 2 +- docs/architecture.md | 3 +- docs/settings-reference.md | 6 +- docs/testing.md | 2 +- package.json | 6 +- packages/core/src/types/settings/settings-scope.ts | 32 +++-- .../src/errors/transient-merge-error-classifier.ts | 12 +- packages/engine/src/merge/merger-auto-prerebase.ts | 12 +- packages/engine/src/util/run-audit.ts | 2 + scripts/__tests__/check-prerebase-inert.test.mjs | 73 +++++++++++ scripts/__tests__/run-static-gate-checks.test.mjs | 1 + scripts/__tests__/verify-fast.test.mjs | 1 + scripts/check-prerebase-inert.mjs | 146 +++++++++++++++++++++ scripts/lib/source-projection.mjs | 87 ++++++++++++ 14 files changed, 359 insertions(+), 26 deletions(-) Fusion-Task-Id: FN-8898 Fusion-Task-Lineage: 9cfd836d-17c2-44a0-a076-56fef0917935 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
7745c59e63 |
FN-8880: align shared-member recovery consent tests
Align recovery expectations with the shared-member consent policy. - Hold non-opted-in shared members when project auto-merge is off. - Cover explicit per-task auto-merge opt-in during startup and self-healing recovery. - Document the project-off consent rule for branch-group members. Files changed: AGENTS.md | 2 +- docs/architecture.md | 4 +- packages/engine/src/__tests__/project-engine.test.ts | 41 +++++++++++------ packages/engine/src/__tests__/self-healing.test.ts | 51 +++++++++++++++++++--- 4 files changed, 75 insertions(+), 23 deletions(-) Fusion-Task-Id: FN-8880 Fusion-Task-Lineage: 3118064d-59ca-4c2e-89a8-442ee8876cf8 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
dd40691ca2 |
fix: make workflow continuation writes atomic, not conflict-recovery
Code review of
|
||
|
|
5b2b31d2c9 |
FN-8762: extract Todo Lists into bundled plugin
Move Todo Lists into a bundled, project-enabled plugin package. - Move Todo UI, client API, and server routes into the plugin package. - Register and bundle Todo as an enabled plugin dashboard view rather than a static host feature. - Preserve Todo route validation and server-error semantics, including task assignment agent lookup. - Keep disabled and legacy Todo views out of project navigation and main content. Files changed: .changeset/fn-8762-todos-plugin.md | 7 + AGENTS.md | 3 +- docs/PLUGIN_AUTHORING.md | 4 + docs/dashboard-guide.md | 4 + docs/todo-view.md | 151 +---- .../cli/src/plugins/staged-bundled-plugin-ids.ts | 1 + packages/cli/tsup.config.ts | 8 + .../core/src/board/mobile-nav-primary-items.ts | 2 - .../__tests__/bundled-plugin-install.test.ts | 2 + .../core/src/plugins/bundled-plugin-install.ts | 1 + packages/dashboard/app/App.tsx | 18 +- .../app/__tests__/lazy-loaded-views-docs.test.ts | 9 +- packages/dashboard/app/api/legacy.ts | 15 - packages/dashboard/app/api/system/index.ts | 1 - packages/dashboard/app/api/system/todo.ts | 85 --- packages/dashboard/app/components/Header.tsx | 23 +- .../dashboard/app/components/LeftSidebarNav.tsx | 1 - packages/dashboard/app/components/MobileNavBar.tsx | 4 - .../dashboard/app/components/SettingsModal.tsx | 2 - .../app/components/__tests__/App.test.tsx | 7 - .../app/components/__tests__/Header.test.tsx | 42 -- .../app/components/__tests__/RightDock.test.tsx | 18 +- ...skDetail.mobile-transition.board-panel.test.tsx | 1 - .../__tests__/TaskDetail.swipe-back.test.tsx | 1 - .../__tests__/TodoView.mobile-css.test.ts | 66 --- .../app/components/__tests__/TodoView.test.tsx | 649 --------------------- .../__tests__/navigation-history.test.tsx | 3 - .../__tests__/overflowViewRegistry.test.tsx | 118 +--- .../app/components/dashboard/MainContent.tsx | 27 +- .../dashboard/app/components/dashboard/types.ts | 6 +- .../app/components/overflowViewRegistry.tsx | 21 +- .../app/hooks/__tests__/useTodoLists.test.ts | 291 --------- .../app/hooks/__tests__/useViewState.test.ts | 11 + packages/dashboard/app/hooks/useAppSettings.ts | 5 - packages/dashboard/app/hooks/useViewState.ts | 5 + .../__tests__/registerBundledPluginViews.test.tsx | 14 + packages/dashboard/app/plugins/bundled-todos.d.ts | 5 + .../app/plugins/registerBundledPluginViews.ts | 18 + packages/dashboard/app/plugins/types.ts | 4 + .../src/__tests__/todo-documentation.test.ts | 68 --- .../dashboard/src/__tests__/todo-routes.test.ts | 577 ------------------ packages/dashboard/src/registry-manifest.json | 101 +++- packages/dashboard/src/routes.ts | 1 - .../src/routes/plugin-bundled-runtimes.ts | 1 + .../src/routes/register-integrated-routers.ts | 2 - packages/dashboard/src/shared/dashboard-views.ts | 6 - packages/dashboard/src/todo-routes.ts | 342 ----------- packages/dashboard/vite.config.ts | 8 + packages/dashboard/vitest.config.ts | 8 + packages/desktop/scripts/workspace-tools.ts | 1 + plugins/fusion-plugin-todos/README.md | 20 + plugins/fusion-plugin-todos/manifest.json | 6 + plugins/fusion-plugin-todos/package.json | 38 ++ .../fusion-plugin-todos/src/dashboard-interop.d.ts | 12 + plugins/fusion-plugin-todos/src/dashboard-view.tsx | 4 + .../src/dashboard/LoadingSpinner.tsx | 1 + .../src/dashboard}/TodoView.css | 0 .../src/dashboard}/TodoView.tsx | 16 +- plugins/fusion-plugin-todos/src/dashboard/api.ts | 15 + .../src/dashboard/projectStorage.ts | 3 + .../fusion-plugin-todos/src/dashboard/swrCache.ts | 6 + .../src/dashboard/useConfirm.ts | 1 + .../src/dashboard}/useTodoLists.ts | 4 +- plugins/fusion-plugin-todos/src/index.ts | 4 + .../fusion-plugin-todos/src/todo-routes.test.ts | 46 ++ plugins/fusion-plugin-todos/src/todo-routes.ts | 156 +++++ plugins/fusion-plugin-todos/tsconfig.json | 28 + plugins/fusion-plugin-todos/vitest.config.ts | 9 + pnpm-lock.yaml | 64 +- pnpm-workspace.yaml | 1 + 70 files changed, 671 insertions(+), 2531 deletions(-) Fusion-Task-Id: FN-8762 Fusion-Task-Lineage: 3beb502c-3793-451b-b357-50c243395410 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
19e9f5bc88 |
chore(release): require interactive confirm; drop authorized/--yes skips
Remove the typed authorization phrase and the --yes/-y auto-confirm path so every real release must confirm y/N in an interactive terminal. Reject --yes with a clear error so old muscle memory cannot skip the proceed prompt. |
||
|
|
1e7f510ee2 |
fix: stop blocking tasks on open-PR file claims — board tasks are the only blockers
Remove the FN-8700 PR/file-claim blocking mechanism end to end (operator decision after FN-8728 parked on unrelated PR #2398): - Drop the AGENTS.md claim-check rule and scripts/check-file-claimed.mjs - Executor prompt + fn_task_done no longer accept pr:N refs or treat open PRs as blocked-exit reasons - execution-block-classifier classifies on Fusion task dependencies only; legacy pr refs are discarded, reason prose never makes a block durable - Remove the session-log BLOCKED promotion and the gh-backed reconcile-external-pr-blockers self-healing sweep - Legacy file-claim parks are no longer honored, so previously PR-blocked rows recover via normal paths Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
04c2bb4707 |
FN-8654: rotate credential instances after provider limits
Retry provider-limit failures with eligible credential instances before falling back to existing pauses and backoff. - Add a runtime-shared credential rotator with cooldown, exhaustion, and audit handling. - Wire credential rotation into executor and heartbeat retry lanes while preserving user pause controls. - Document the behavior and cover rotation, recovery, and retry paths. Files changed: .changeset/fn-8654-credential-instance-rotation.md | 7 + AGENTS.md | 1 + docs/architecture.md | 2 +- docs/settings-reference.md | 4 + .../__tests__/credential-instance-rotation.test.ts | 88 +++++++++++ .../__tests__/credential-rotation-lanes.test.ts | 20 +++ .../__tests__/credential-rotation-recovery.test.ts | 19 +++ .../__tests__/credential-rotation-wiring.test.ts | 15 ++ .../__tests__/rate-limit-retry-rotation.test.ts | 50 ++++++ .../src/__tests__/usage-limit-detector.test.ts | 14 ++ packages/engine/src/agent-heartbeat.ts | 102 +++++++++++- .../engine/src/credential-instance-rotation.ts | 175 +++++++++++++++++++++ packages/engine/src/executor.ts | 141 +++++++++++++++-- packages/engine/src/index.ts | 7 + packages/engine/src/project-engine.ts | 5 + packages/engine/src/rate-limit-retry.ts | 32 +++- packages/engine/src/runtimes/in-process-runtime.ts | 29 +++- packages/engine/src/usage-limit-detector.ts | 18 ++- 18 files changed, 699 insertions(+), 30 deletions(-) Fusion-Task-Id: FN-8654 Fusion-Task-Lineage: 44d63441-270c-4949-8c34-47ec4c9992e4 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
8a6949dd24 |
FN-8661: resolve selected credential instances for sessions
Resolve requested provider credential instances before creating agent sessions. - Thread lane credential instance selections through planning, validation, execution, review, and merge sessions. - Resolve selected instances into runtime credential stores while retaining provider-default fallback behavior. - Preserve selected credentials for mission validation, executor retries, and spawned child agents. Files changed: .../fn-8661-credential-instance-resolution.md | 7 ++ AGENTS.md | 1 + docs/architecture.md | 2 +- docs/secrets.md | 2 + docs/settings-reference.md | 1 + .../dashboard/src/__tests__/routes-auth.test.ts | 80 +++++++++++++++++++ .../dashboard/src/routes/register-model-routes.ts | 78 +++++++++++++++++++ .../src/__tests__/agent-session-helpers.test.ts | 16 ++++ .../credential-instance-resolution.test.ts | 49 ++++++++++++ packages/engine/src/agent-heartbeat.ts | 1 + packages/engine/src/agent-runtime.ts | 9 ++- packages/engine/src/agent-session-helpers.ts | 67 +++++++++++----- packages/engine/src/auth-storage.ts | 90 ++++++++++++++++++---- packages/engine/src/executor.ts | 29 ++++++- packages/engine/src/merger-ai.ts | 2 + packages/engine/src/merger.ts | 5 ++ packages/engine/src/mission-execution-loop.ts | 4 +- packages/engine/src/pi.ts | 7 +- packages/engine/src/pr-response-run-ops.ts | 1 + packages/engine/src/reviewer.ts | 7 ++ packages/engine/src/triage.ts | 2 + 21 files changed, 420 insertions(+), 40 deletions(-) Fusion-Task-Id: FN-8661 Fusion-Task-Lineage: 1e34a3ce-0857-4619-9746-ce0dc12dc2ba Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
cced31208e |
FN-8672: document observed suite-only flakes
Record first-sighting evidence for three suite-only flakes while preserving their substantial test coverage. - Define the narrow first-sighting observed-register exception and second-sighting quarantine escalation. - Add reproduction data for the core and engine PostgreSQL-adjacent flakes. - Validate register metadata, paths, hierarchy segments, and escalation guidance. Files changed: AGENTS.md | 4 ++ .../suite-only-flakes-observed-register.md | 74 ++++++++++++++++++++++ docs/testing.md | 4 ++ scripts/__tests__/observed-flake-register.test.mjs | 61 ++++++++++++++++++ 4 files changed, 143 insertions(+) Fusion-Task-Id: FN-8672 Fusion-Task-Lineage: b52c74fb-aa7b-49e3-9f1d-a2c8c577f9c7 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
500f40e65b |
fix: descriptive waiting badges (Queued to revise / Queued behind FN-X) + dependency-free blocked exits replan calmly
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7acfaf6c10 |
docs(agents): date -u is the only rule safe from every timezone — #3277's new instruction inverts it (#3281)
#3277 fixed the gate correctly and I have no argument with the code: `today = max(localToday, utcToday)`, so a stamp is future only if ahead of **both** calendars. That is the right shape for a fleet spread across timezones. It reversed the **authoring rule** along with it, and that part is backwards: > **Write your own local date and a real clock time.** … Do NOT reach for `date -u` Under #3277's own comparison, that reintroduces the failure it just fixed. ## Measured against the merged gate, on current main ``` stamp 2026-08-02 (a UTC+2 author's local date at 22:00 UTC) gate exit=1 REJECTED stamp 2026-08-01 (the same author using date -u) gate exit=0 ACCEPTED ``` Run today, 2026-08-01, with the runner in PDT. Probe file added and removed; tree clean after. ## Why `date -u` is the only safe rule The bound is `max(localToday, utcToday)`, and **UTC only moves forward between writing a stamp and checking it**. So a `date -u` stamp has already been passed by the bound at check time, from every timezone, always. No other rule has that property. Writing your own local date is safe *only if you are not east of UTC*. During a UTC+2 author's evening their local date is already tomorrow in UTC, and the stamp is rejected until UTC catches up hours later — which is exactly the "five reds in two hours" incident #3277 diagnosed. The gate change widens the window enough that CI usually catches up before anyone looks, but "usually, after a delay" is a race, not a rule, and it fails hardest for the authors furthest east. The prior instruction (`date -u`) was correct; what was wrong was its stated *rationale* ("validates against UTC"), which is what I was fixing in #3276 before #3277 landed. This PR keeps #3277's both-directions history — the part that explains why neither naive rule works on its own — and restores the prescription. ## Why not just comment on #3277 It is merged, and AGENTS.md is the file every agent reads before writing a stamp. Leaving the inverted rule in place for a review cycle means every east-of-UTC author in the fleet follows it. Filed as a PR so it can be judged on the measurement rather than on my say-so — if the numbers above are wrong, this should be closed. **Supersedes #3276**, which documented the pre-#3277 mechanism and is now stale. I will close it once this is judged. Docs only; no changeset (AGENTS.md is excluded). |
||
|
|
1e7e6baef1 |
fix(fnxc): the gate compared author stamps against ONE machine's calendar — five reds in two hours (#3277)
Root-cause fix for tonight's repeated red `main`, instead of repointing stamps one at a time — **four PRs across three lanes did that in ninety minutes** (#3261, #3269, and my #3263 and #3272, two of which I closed as superseded by concurrent work). ## The defect The fleet writes stamps from **many** machines; this gate evaluates them on **one**. #2941 fixed the case where the author sits **west** of the runner — a correct 5pm-in-California stamp read as "tomorrow" under a UTC comparison — by switching to the runner's **local** calendar. The mirror case was left open, and that is what broke `main`: | commit | landed (PDT) | = UTC | stamp written | |---|---|---|---| | `9094d1640e` | 16:12 | 23:12 Jul 31 | `2026-08-01-00:20` | | `e52da740a5` | 16:32 | 23:32 Jul 31 | `2026-08-01-00:50` | | `3f95c6d53e` | 16:40 | 23:40 Jul 31 | `2026-08-01-01:05` | Those are **neither** the runner's local date **nor** UTC. They are the *author's* local date in a UTC+1 container — and they are **correct** by this project's own convention ("authors write the local date"). The gate, running in PDT, called all three "tomorrow" and reddened `main` for every other lane. ## The fix A stamp is future only if it is ahead of **both** the local and UTC calendar dates. - Accepts both honest directions (author east or west of the runner). - **Preserves #2941**, doesn't revert it — west of Greenwich the local date is the earlier of the pair, so the 5pm-in-California case still passes. - Still catches an invented date: `scheduler.ts`'s `2026-08-06` stamp (six days out) remains counted, and a mutation probe at `2026-09-15` fails the gate. ## AGENTS.md corrected in the same commit It still instructed **`date -u`**, which describes the *pre-#2941* gate. That instruction is now the one that **produces** the failure from any machine east of the runner — I followed it myself earlier tonight and repointed stamps that were already correct. Rewritten to say: write your own local date; the gate accepts anything not ahead of both calendars. ## Baseline Auto-tightened for **37 files** — the gate's no-author drop path. Those allowances were false positives carried since the UTC-only era, so this **strengthens** the ratchet rather than widening it (`scheduler.ts` 2 → 1, keeping the genuinely-invented stamp counted). ## Verification ``` check-fnxc-future-dates green check-inert-sync-lane-conversions green check-lane-wiring green check-sql-column-literals green census --strict green MUTATION: FNXC:MutationProbe 2026-09-15-10:00 → gate fails (real future dates still caught) ``` No changeset: tooling/gate + internal docs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
79a292b57c |
docs(agents): take FNXC timestamps from date -u, not the local clock (#3174)
I have patched this same breakage **three times today**, and it is not a per-file defect — the convention is under-specified. `check-fnxc-future-dates` validates against **UTC**. A stamp written from a clock **behind** UTC is a future stamp the moment UTC rolls over, and `pnpm lint` passes locally because the local date agrees with what was written. Nothing in the authoring loop can catch it. It surfaces only as a **red main for everybody else**. ## The evidence Four separate breakages in one day, four files, at least two authors: | file | stamps | |---|---| | `packages/engine/src/scheduler.ts` | 7 dated 2026-08-01 → 08-06 | | the scheduler PG test | 1 | | `packages/core/src/task-store/task-update.ts` | 2, fixed by two different people | Every one was a **real time on the wrong day** — nobody was careless, they read their own clock. ## What changed `AGENTS.md` already specifies the *format* (`yyyy-MM-dd-hh:mm`) and says nothing about the *clock*, so every worker reasonably used their own. This adds the one missing sentence, plus the impossible-hour rule the gate also enforces — which produced its own main-red earlier today (#3006 normalized four hour-26 stamps). Docs only; no changeset, per the AGENTS.md rule for internal docs. ## Note This PR will show red on Gate until **#3173** merges — main's inert-sync-lane allowance is stale (11 → 7, never re-recorded), unrelated to this change and inherited by every open PR. |
||
|
|
b8bfcd031b |
tooling: answer "is this file claimed?" in one command (#3175)
Addresses the root cause of a pattern I have now measured four times. ## The finding **Every fleet worker pushes as the same GitHub account.** `gh pr list --author "@me"` returns **all 17 open PRs** — mine and teammates' are indistinguishable. So "is this file already being converted?" can only be answered by fetching every open PR's file list by hand: 25+ API calls that no worker makes before starting. I didn't either. ## The measured cost | PR | Outcome | Landed instead as | |---|---|---| | #3096 | shrank to a test | teammate's serialisation + union | | #3116 | shrank to a test | `preExecLiveColumns`, `starvedWaitingColumns`, … | | #3140 | shrank to a test | #3137 | | #3125 | **shrank to nothing — closed** | #3135 | Plus #3118, a teammate independently writing the same coverage I wrote for #3112. **In every case both implementations were correct and independently reached the same design** — #3137 chose payload-first-with-sync-fallback for the same reason I did. This is not carelessness; the fleet is doing correct work twice and discovering coverage gaps by accident, when rebases collide. ## What this adds ``` $ node scripts/check-file-claimed.mjs packages/engine/src/self-healing.ts CLAIMED packages/engine/src/self-healing.ts #3152 fix(self-healing): 18 recovery rebounds hardcoded `todo` … ``` **On its first run it reported `self-healing.ts` claimed by #3152 — which I had no way to know a moment earlier.** Exits non-zero when claimed, so it can gate work: `node scripts/check-file-claimed.mjs <path> && start-work`. ## Deliberate limits - **It cannot see unpushed work**, so it narrows the collision window rather than closing it. Two workers starting the same file minutes apart still collide. Closing that needs **distinguishable authorship** — a per-worker `Co-Authored-By` or a title prefix — which is a coordination decision, not a script. - **A `gh` failure exits 2 and says UNKNOWN, not unclaimed.** A claim check that fails open is worse than none, which is the same false-green shape this program keeps finding elsewhere. Also adds a short AGENTS.md pointer next to the other standing rules. ## Verification Run against a claimed and an unclaimed path; both answers correct, exit codes as documented. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a command-line check for open pull requests that may already be modifying specified files. * Reports matching pull request details and clearly indicates whether each file is claimed. * Returns distinct statuses for claimed files, unclaimed files, and unavailable GitHub checks. * **Documentation** * Added guidance for checking file ownership before beginning conversion work. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3bf9bf5f74 |
collapse the plan-admission-throttle payload to one gate (+ AGENTS.md) (#2562)
The cross-project semaphore is deleted, so `task:plan-admission-throttled` was describing a gate that no longer exists. Nothing wires `options.semaphore` any more, which left three things dead-but-visible: - `semaphoreAvailable` was permanently `Infinity`, so `Math.min(projectRoom, …)` was a no-op keeping a deleted limiter in the arithmetic - `blockedBy` was a **discriminator** between `"running-agent cap"` and `"global semaphore"`; only the first can occur - four `semaphore*` metadata fields were always `undefined`, and two more terms in the dedupe signature were constant ## `blockedBy` is kept, not dropped Even though it is now a constant. The event exists (FN-8600) to answer *“why did this card sit queued to plan?”* after the fact — a named reason answers that even when there is one gate, whereas a payload with **no** reason field reads as “unknown”. It costs nothing and preserves the shape if a second gate is ever added. The dedupe signature drops the two semaphore terms and keeps the eligible task IDs — that term is what stops a **new** card’s stall being swallowed when the counts land on an unchanged tuple, which is the property the event depends on. ## AGENTS.md It documented the removed field names verbatim, so it is updated in the same commit. Leaving docs describing a payload the code cannot emit is exactly the readable-but-wrong artifact this program keeps deleting. ## Verification `pnpm lint` clean · engine `tsc` clean · `pnpm test:gate` green · triage suites **234/234**. --- **Correction I owe on `concurrency.ts`, measured rather than estimated.** I earlier told the coordinator ~75% of its 886 lines could go with the cross-project cap. That was line-range arithmetic and it was wrong. With the cap now fully removed, `concurrency.ts` is **still 886 lines**, because `AgentSemaphore` has four consumers unrelated to it — `verification-concurrency` (maxConcurrentVerifications), `research-orchestrator` (research runs), `experiment-executor` (maxConcurrentExperiments), `step-session-executor` (parallel steps) — plus `ProjectAdmissionCoordinator`, which is FN-8453 oldest-first **ordering**, not a limiter. The real remaining win there is the pre-held-slot bookkeeping and the idle-semaphore leak recovery, which existed to service the global instance; I will measure that as its own slice rather than quote a fraction. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Updated plan admission throttling to consistently use the project’s running-agent capacity. * Improved throttle audit events by reporting stable capacity details and removing obsolete semaphore information. * Preserved accurate deduplication for repeated throttling events, including changes in stalled tasks. * **Documentation** * Updated run-audit guidance to match the revised throttling event format. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
d193dcdbb0 |
chore(lint): ban React components declared inside another component
Adds fusion-react/no-nested-component-definitions, a custom rule in the house style of the existing detached-spawn guard. A component declared in render is a new element type every render, so React remounts its subtree on each parent update and destroys focus, scroll, and local state. This pattern shipped three times without review or tests catching it: FN-8606's ModalShell left Planning Mode and Settings untypable, and MailboxModal's ReplyContextExpandable collapsed expanded reply rows. Tests missed it because fireEvent.change sets a value without needing the node to stay mounted. The rule reports PascalCase functions (including memo()/forwardRef()-wrapped) that return JSX and are declared inside another JSX-returning function. Lowercase render helpers are deliberately allowed — they are the sanctioned fix. Escape hatch: // nested-component-allowlist: <reason>. Scoped to production .tsx, with a vitest guard for the rule itself. Hoists the two pre-existing violations (ProviderStatusBadge, GitHubStatusBadge in ModelOnboardingModal) to module scope so the rule lands clean at "error". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2d263acc49 |
fix(FN-8600): keep self-healing from pausing live planners and unstick queued planning
Planning moved into the task's own worktree but never published that path to activeSessionRegistry, so the self-owned-branch reclaim sweep's FN-4819 liveness guard was blind to a live planner. A zero-commit task branch trivially reads as tip-already-merged, so the sweep ran `git worktree remove --force` on the tree a planning session was using, the removal failed, and the failure escalated to branch-conflict-unrecoverable — parking a healthy card paused with no operator action. Planning now claims its worktree through acquireActiveSessionPath (new "planning" session kind) and releases it only while it still owns the record, so a live executor that took over the same path mid-teardown is never cleared. Also fixes planning starvation and its diagnosability: - admitOldest walks past candidates whose lane declines instead of ending the pass on candidates[0], unwinding each declined attempt's pre-held executor slot and reservation exactly so a decline cannot leak capacity past maxConcurrent. - Withheld planning admission emits a deduped task:plan-admission-throttled run-audit event (ids/counts only), written fire-and-forget with the dedupe marker set only after the write lands. Previously the binding gate lived only in a log line that is persisted nowhere, so "why did this card sit queued to plan?" was unanswerable after the fact. Reviewed by 8 review agents; every finding acted on or recorded. A proposed STALE_SEMAPHORE_EXCESS_REPAIR_MS 600s->180s reduction was reverted under review — nested runs are already excluded from the reclaim floor, so the window guards uncounted top-level holders such as a merge body, and shortening it would trade a bounded visible stall for an unbounded silent cap breach. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fd073e287f |
FN-8592: self-heal stranded hold continuations
Restore graph-owned plan-review continuations for eligible hold-column cards stranded after planning cancellation. - Detect real-spec hold cards with no active workflow continuation and re-seed Plan Review safely. - Serialize workflow continuation seeding, review-result writes, and lease claims to prevent duplicate recovery. - Add recovery diagnostics, release warnings, regression coverage, and a patch changeset. Files changed: .changeset/fn-8592-stranded-hold-continuation.md | 7 + AGENTS.md | 1 + docs/architecture.md | 4 + .../workflow-task-serialization-protocol.test.ts | 119 +++++++++++++ .../workflow-work-items-conditional-seed.test.ts | 191 +++++++++++++++++++++ packages/core/src/store.ts | 5 +- .../src/task-store/async-workflow-workitems.ts | 123 +++++++++---- packages/core/src/task-store/project-store-ops.ts | 14 ++ .../src/task-store/workflow-task-create-ops.ts | 16 +- .../src/task-store/workflow-workitems-ops-2.ts | 91 ++++++---- .../src/__tests__/pre-release-plan-review.test.ts | 17 ++ ...self-healing-stranded-hold-continuation.test.ts | 171 ++++++++++++++++++ packages/engine/src/hold-release.ts | 57 +++++- packages/engine/src/plan-review-continuation.ts | 94 ++++++++++ packages/engine/src/runtimes/in-process-runtime.ts | 30 +--- packages/engine/src/self-healing.ts | 100 ++++++++++- 16 files changed, 945 insertions(+), 95 deletions(-) Fusion-Task-Id: FN-8592 Fusion-Task-Lineage: fe7ffd34-96e4-4418-a879-7418e6293d30 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b5707318b5 |
feat(engine): add force to fn_task_promote for agent-native override parity
fn_task_promote can now pass force:true to start execution when a task is still waiting on planning or plan review, matching the dashboard's promote override. The rejection message names the flag so a caller that hits the gate can decide, and a forced release says the pending replan was cancelled rather than burying it. Force stays opt-in per explicit promote request: the hold-release sweep and the webhook event release have no force parameter, so FN-7648 still holds for every automatic surface. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
41d60f0355 |
feat(board): explain the unplanned promote rejection and let operators force past it
Promote on a held card printed the raw i18n key `board.rejection.unplannedForExecution`:
FN-8471 added the server-side code without a client case or catalog entry, so
translateRejection fell through to `t(messageKey, messageKey)`.
- Add the explicit rejection case (both translate helpers) plus the en catalog
entry and secondary-locale stubs.
- promoteHeldTask(..., { force }) waives ONLY the unplanned-for-execution gate;
hold membership, capacity and slot reservation still arbitrate. It clears a
needs-replan/plan-review-unavailable status so triage rediscovery cannot pull
the card back into the waived replan, and emits task:promote-forced-unplanned.
- POST /tasks/:id/promote accepts { force: true }; the board asks for explicit
confirmation first and only offers the override for this rejection.
Force stays operator-only — the sweep, the webhook release and fn_task_promote
never set it, so FN-7648 still holds for every automatic surface.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
0c085bf444 |
fix(engine): pushAfterMerge no longer strands approved merges when the remote diverges (#2407)
## Problem
With `pushAfterMerge` enabled (and `mergeStrategy` other than
`pull-request`), if `origin/<integration-branch>` advances externally
between the local squash-merge and the push, the divergence path opens a
clean-room `git pull --rebase` and an AI agent resolves and stages the
conflicts — but the flow could end there: no `git rebase --continue`, no
push, and no surfaced error.
Because finalize runs *before* the push, the task is already `done`, so
a reviewed, approved merge is silently left container-only, and every
subsequent merge on the project stalls the same way. Separately, an
abort mid-push (`MergeAbortedError`) was swallowed with only a
process-log warning — no task-log entry, no run-audit event.
## Change
- **Deterministic regression coverage** for the conflicting-divergence
path (real-git fixture) proving the rebase runs to completion and the
push lands (refs converge), plus abort/termination scenarios.
- **Recovery-branch safety net:** before the clean-room rebase starts,
the pre-rebase local squash is force-pushed to a per-task remote branch
`fusion/<task-id>-stranded`, so approved content is never container-only
— even across process death or abort. Deleted after a successful target
push; retained on failure/abort as the recovery source.
- **Never-silent outcomes:** every non-pushed outcome (failure or abort)
writes a durable task-log entry and a `push:origin` run-audit event. The
audit contract now documents `push:origin` as polymorphic (dashboard
Smart Push vs. automated post-merge push) and enumerates the automated
path's outcomes, including the new `"aborted"` shutdown case.
- **Cleanup hardening:** `isRebaseInProgress` now probes Git's
worktree-specific `rebase-merge`/`rebase-apply` state directories
(async, timeout-guarded) so a completed rebase can't receive a spurious
second `--continue`; unfinished rebases are cleaned up.
Out of scope by design: withholding the "merge confirmed" state until
the push succeeds — the `FNXC:MergePush` invariant ("a push problem can
never park or roll back a landed merge") is deliberate; the recovery
branch + surfacing satisfy the data-preservation intent without breaking
it.
## Files
`packages/engine/src/merger-ai.ts`, `packages/engine/src/merger.ts`,
`packages/engine/src/run-audit.ts`, new/updated tests under
`packages/engine/src/__tests__/`, `docs/settings-reference.md`,
`docs/dashboard-guide.md`, `AGENTS.md`, and a labeled changeset.
## Validation
`tsc --noEmit` clean; engine divergence + merger suites pass (41 tests);
rebased onto current `main` with no conflicts.
---
_Developed with Claude Code, under human supervision and review._
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Prevented approved post-merge pushes from becoming stranded when the
remote diverges by using a recovery-branch workflow and safer cleanup.
* Improved behavior and reporting when pushes are aborted or fail after
merge, including clearer non-fatal status and audit outcomes.
* **Documentation**
* Expanded push-after-merge and dashboard Smart Push documentation with
recovery-branch and `push:origin`/`push:recovery-branch` outcome
semantics.
* **Tests**
* Added end-to-end regression tests for divergent/conflicting AI
push-after-merge flows, including abort and worktree cleanup
verification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Victor Cano <victortroz@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
1dd36ed4c6 |
fix(FN-8492): mark orphaned pending step results failed instead of deleting them
Code-review follow-up on
|
||
|
|
4413699de0 |
fix(FN-8492): clear orphaned pending workflow-step results at startup
An engine restart that kills an in-flight pre-merge step session (FN-8492's Code Review) left its pending workflowStepResult behind with no live session. The merge gate read it as incomplete pre-merge steps, surfaced an identical stall every 30 minutes, and the deadlock disposer parked the task failed two hours later. resolveOrphanedPendingStepResults existed for exactly this but shipped with no caller (same U9 gap as the adoption table). Wire it: a startup sweep right after legacy adoption clears pending results whose task has no live session (activeSessionRegistry / executingTaskLock / isTaskActive), emitting task:reconcile-orphaned-pending-step-results with ids/counts-only metadata. User pauses and live resumed sessions are never disturbed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
ccb7d4e8ff |
FN-8367: enforce bounded engine shellouts
Enforce bounded synchronous shellout use across the engine. - Audit every production synchronous shellout against a call-site allowlist. - Bound data-dependent git diff commands by timeout and output size. - Document the async shellout invariant and align focused command guards. Files changed: AGENTS.md | 2 +- docs/architecture.md | 1 + .../__tests__/engine-no-blocking-shellout.test.ts | 135 +++++++++++++++++++++ .../user-configured-command-no-execsync.test.ts | 5 +- packages/engine/src/merger-git-parse.ts | 16 ++- .../engine/src/merger-workspace-test-commands.ts | 27 ++++- 6 files changed, 181 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-8367 Fusion-Task-Lineage: 976384e6-f283-4464-9f74-f328f2be3430 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
e0e395a715 |
FN-8365: enforce dashboard route registrar mount order
Keep dashboard API registration modular while preserving Express route precedence. - Route all top-level dashboard registrars through a runtime-checked canonical mount sequence - Add mount-order and inline-route-ratchet coverage with CI enforcement - Document registrar ownership and mount-order conventions Files changed: .github/workflows/pr-checks.yml | 3 + AGENTS.md | 2 + package.json | 5 +- packages/dashboard/src/routes.ts | 136 +++++----- packages/dashboard/src/routes/README.md | 276 ++++++++++----------- packages/dashboard/src/routes/__tests__/create-api-routes-mount-order.test.ts | 66 +++++ packages/dashboard/src/routes/create-api-routes-mount-sequence.ts | 54 ++++ scripts/__tests__/check-routes-modular.test.mjs | 28 +++ scripts/check-routes-modular.mjs | 65 +++++ scripts/lib/routes-modular-baseline.json | 3 + 10 files changed, 433 insertions(+), 205 deletions(-) Fusion-Task-Id: FN-8365 Fusion-Task-Lineage: 9c36a263-ed5e-4524-8ea5-71ed3f3e34d9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3f7c32c95c |
refactor(cutover 2/3): engine — graph-owned lifecycle, legacy execution deleted (#2342)
Part **2 of 3** of the IR-driven lifecycle cutover (stacked on #2341; top is #2335). **Scope (80 files, packages/engine + cli/pi skill docs + AGENTS/architecture):** graph-driven column moves via the column-boundary controller (R1), single-mover scheduler/hold-release trait cutover (KTD-2/KTD-9), trait re-keyed self-healing + merger with the R7b confirmed-merge-must-finalize guarantee, graph-exclusive Plan Review with leased dedup (R4/R5), the executeCore body-lift — zero legacy re-entry — with fn_review_step + interceptor machinery deleted and tombstone-ratcheted (R9), builtin workflow runtime fixes (missing hold handler, unseamed-node column inheritance, no-merge completion mover), the 6-column benchmark acceptance suite (11 tests) + 12-builtin lifecycle sweep (94 assertions), and the executor test-harness modernization. Also retires core's interpreter-cutover scaffolding whose last consumer (the authoritative driver) dies here. **Merge order:** #2341 → this → #2335. After #2341 merges, retarget this to main. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
0dbe67c851 |
FN-8356: clear stale duplicate decision pauses
Clear inactive duplicate markers so eligible tasks resume planning instead of showing a stranded decision badge. - Reconcile stale triage-marker duplicate pauses during self-healing and record audit events. - Clear inactive canonical markers during triage while preserving user and unrelated pauses. - Cover missing, deleted, completed, and archived canonical states with regression tests. Files changed: .changeset/fn-8356-stale-duplicate-decision.md | 7 ++ AGENTS.md | 1 + docs/architecture.md | 1 + .../explicit-duplicate-marker-sweep.test.ts | 43 ++++++-- .../self-healing-stale-duplicate-decision.test.ts | 109 +++++++++++++++++++++ .../triage-explicit-duplicate-marker.test.ts | 32 ++++-- packages/engine/src/run-audit.ts | 2 + packages/engine/src/self-healing.ts | 87 ++++++++++++++-- packages/engine/src/triage.ts | 41 ++++++-- 9 files changed, 298 insertions(+), 25 deletions(-) Fusion-Task-Id: FN-8356 Fusion-Task-Lineage: 8df8f0ee-d73e-41d6-8abe-a4b33662c9da Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b61311baa8 |
FN-8305: add durable PostgreSQL symbol locks
Introduce durable project-scoped symbol locks backed by PostgreSQL. - Add normalized lease-based lock acquisition, renewal, release, and reconciliation APIs with audit events. - Add PostgreSQL schema migrations and self-healing reconciliation coverage. - Document the lock model and test migration and lock behavior. Files changed: AGENTS.md | 1 + docs/architecture.md | 1 + docs/storage.md | 7 + .../src/__tests__/postgres/schema-applier.test.ts | 115 +++++++++- packages/core/src/__tests__/symbol-locks.test.ts | 91 ++++++++ packages/core/src/index.ts | 17 ++ .../core/src/postgres/migrations/0000_initial.sql | 25 +++ .../src/postgres/migrations/0025_symbol_locks.sql | 63 ++++++ packages/core/src/postgres/schema-applier.ts | 18 +- packages/core/src/postgres/schema/project.ts | 29 +++ packages/core/src/store.ts | 23 ++ packages/core/src/symbol-lock-types.ts | 60 +++++ packages/core/src/task-store/symbol-locks.ts | 244 +++++++++++++++++++++ .../__tests__/symbol-lock-reconciliation.test.ts | 19 ++ packages/engine/src/self-healing.ts | 35 +++ 15 files changed, 745 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-8305 Fusion-Task-Lineage: efd95c73-23e3-4359-8204-dfad374a39bc Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9a37415887 |
fix(engine): add honest blocked exit to fn_task_done so impossible tasks park failed instead of laundering to done (#2256)
## What & why
FN-8141 ("Update pi SDK to latest and verify Kimi K3 end to end") was
impossible as specced — pi 0.80.x removed `AuthStorage`/`ModelRegistry`
APIs, so every SDK bump broke the build. The executor correctly reverted
its work and filed follow-up FN-8145 — but had **no sanctioned way to
end the task in a blocked state**. `fn_task_done` only expressed
success: the bulk-completion gate refused it, the requeue budget re-ran
the doomed task 5 times, and the only remaining affordance (mark every
step `skipped`, then complete) made `isTaskComplete()` return true.
Self-healing then promoted the "complete" todo to in-review and the AI
merger finalized the empty diff as `done`. **The honest path must be
cheaper than the laundering path.**
This adds a first-class **blocked** outcome to the executor's
`fn_task_done` tool.
## Change
- `fn_task_done` gains `outcome: "completed" | "blocked"` (default
`"completed"`), optional `blockedBy: string[]`, and `reason` (required
when blocked).
- `outcome="blocked"` runs **before** every completion gate (completion
blocker, verdict providers, worktree invariants, bulk-completion
refusal) — blocked is not a completion claim, so none of those gates
apply.
- Parks the task `failed` with `error = "BLOCKED: <reason>"`, following
the FN-7863 `EXECUTION_DISPATCH_LOOP_EXHAUSTED` park convention: **steps
keep their true statuses** (no auto-done, no auto-skip), worktree/branch
preserved. It does **not** call `onDone()`, so the executor's existing
`status === "failed"` post-loop branch honors the park instead of
handing off to review.
- `blockedBy` is recorded as real `task.dependencies` edges (unioned
with existing) so the task requeues behind the blocker.
- Emits run-audit `task:execution-blocked-parked` with ids/outcomes-only
metadata (`taskId`, `blockedBy` ids, `hasReason` boolean — **never** the
reason prose).
- Executor + core prompt guidance and the
`bulk-step-completion-without-review` refusal message now name the
blocked exit as **the** correct action when work cannot proceed,
replacing skip-and-done. `PREMISE STALE:` skip guidance is preserved for
genuinely-stale premises.
## Surface enumeration
- **fn_task_done tool schema + handler**
(`packages/engine/src/executor.ts`): blocked branch added at the top of
`execute`, before all gates.
- **Refusal/requeue machinery**: `formatTaskDoneRefusal` for
`bulk-step-completion-without-review` now points at the blocked exit;
the requeue-budget path is untouched (blocked never enters it).
- **Executor prompt text**: turn-ending rules, the "Cannot proceed"
section, the preflight/stale-premise escape hatch (now explicitly
distinguishes stale-premise skip from blocked).
- **Core prompt mirror** (`packages/core/src/agent-prompts.ts`): same
turn-ending + cannot-proceed guidance.
- **Tool reference doc**
(`packages/cli/skill/fusion/references/engine-tools.md`): `fn_task_done`
params updated. (grep for `fn_task_done` confirmed the only executable
tool schema is in executor.ts; CLI/pi surfaces re-export it, no separate
schema copy.)
- **Self-healing**: verified a blocked-parked row is NOT auto-recovered
by `recoverStrandedCompletedTodoTasks` — its steps are not all
done/skipped and `task.error` is set (both are hard filters in the
sweep).
- **Run Audit inventory** (`AGENTS.md`): documented the new event.
## Test evidence
New `packages/engine/src/__tests__/executor-task-done-blocked.test.ts`
(8 tests) asserts the invariant across surfaces:
```
pnpm --filter @fusion/engine exec vitest run \
src/__tests__/executor-task-done-blocked.test.ts \
src/__tests__/executor-task-done-invariant.test.ts \
src/__tests__/gating-classifications.test.ts \
src/__tests__/reliability-interactions/execute-requeue-loop-guard.test.ts --reporter=dot
→ Test Files 3 passed | Tests 138 passed (0 failed)
```
Coverage: blocked parks failed with `BLOCKED:` error and does **not**
trip the bulk-completion refusal or requeue to todo; `blockedBy` unioned
into `dependencies`; `task:execution-blocked-parked` emitted with
metadata that excludes the reason prose; steps left untouched; empty
`reason` rejected without parking; `completed` outcome unchanged (still
marks steps done, no blocked audit); and
`recoverStrandedCompletedTodoTasks` never promotes a blocked-parked row.
### Note on `pnpm verify:fast`
`verify:fast` currently fails at the workspace build step due to
**pre-existing** type errors in `packages/engine/src/auth-storage.ts`,
`pi.ts`, and `provider-registration.ts` — the exact FN-8142 pi SDK API
break that FN-8145 will fix. These are present on the base branch and
untouched by this PR. Verified instead that this change introduces
**zero** new type errors (`tsc` diff before/after, engine and core both
clean) and that all scoped tests are green.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus <noreply@anthropic.com>
|
||
|
|
ca7a5a7106 |
FN-8144: remove workspace worktrees on archive
Archive workspace task worktrees synchronously and safely across archive entry points. - Add store-scoped workspace disposal planning, reservations, and quarantine handling. - Install baseline and executor disposers that remove per-repository worktrees and branches without shell interpolation. - Cover disposal-plan deduplication and document the archive cleanup behavior. Files changed: .../fn-8144-archive-removes-workspace-worktrees.md | 7 ++ AGENTS.md | 1 + docs/task-management.md | 4 + .../archive-removes-workspace-worktrees.test.ts | 59 +++++++++++ packages/core/src/archive-worktree-disposer.ts | 52 ++++++++++ packages/core/src/index.gate.ts | 8 ++ packages/core/src/index.ts | 8 ++ .../core/src/task-store/archive-lifecycle-2.ts | 29 ++++-- packages/core/src/task-store/archive-lifecycle.ts | 114 ++++++++++++++++++++- .../src/archive-worktree-disposer-install.ts | 27 ++++- packages/engine/src/executor.ts | 25 ++++- 11 files changed, 319 insertions(+), 15 deletions(-) Fusion-Task-Id: FN-8144 Fusion-Task-Lineage: 1c4b65f3-a1d2-4a5c-a4b6-c263f9e6f61d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d870878a23 |
FN-7998: add executor alternate model escalation
Add opt-in executor escalation after same-model tool-failure retries are exhausted. - Persist escalation settings and one-shot task state across SQLite and PostgreSQL stores. - Retry once on a configured alternate model or scheduler node and audit escalation outcomes. - Expose escalation controls, documentation, translations, migration, and regression coverage. Files changed: .changeset/fn-7998-executor-escalation.md | 7 ++ AGENTS.md | 1 + docs/settings-reference.md | 13 ++- .../core/src/__tests__/settings-defaults.test.ts | 23 ++++- packages/core/src/in-review-stall.ts | 29 ++++++ packages/core/src/index.gate.ts | 3 +- packages/core/src/index.ts | 3 +- packages/core/src/manual-retry-reset.ts | 1 + .../0014_executor_escalation_attempt.sql | 2 + packages/core/src/postgres/schema-applier.ts | 17 ++++ packages/core/src/postgres/schema/project.ts | 1 + packages/core/src/settings-schema.ts | 4 + packages/core/src/store.ts | 2 +- packages/core/src/task-store/persistence.ts | 2 + packages/core/src/task-store/remaining-ops-2.ts | 2 +- packages/core/src/task-store/remaining-ops-3.ts | 2 +- packages/core/src/task-store/remaining-ops-6.ts | 2 +- packages/core/src/task-store/serialization.ts | 1 + packages/core/src/task-store/task-update.ts | 2 + packages/core/src/types.ts | 13 +++ .../dashboard/app/components/SettingsModal.tsx | 12 +++ .../app/components/settings/section-keys.ts | 4 + .../settings/sections/SchedulingSection.search.ts | 36 +++++++ .../settings/sections/SchedulingSection.tsx | 6 ++ .../settings-default-descriptions.test.tsx | 4 + .../__tests__/executor-tool-failure-retry.test.ts | 91 +++++++++++++++++- packages/engine/src/executor.ts | 104 +++++++++++++++++++-- packages/i18n/locales/en/app.json | 8 ++ 28 files changed, 376 insertions(+), 19 deletions(-) Fusion-Task-Id: FN-7998 Fusion-Task-Lineage: bbce767d-c61a-4667-be62-abc0cc54d8be Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
60b6e3e048 |
FN-7996: add configurable executor tool-failure retries
Add bounded, durable same-model retry handling for qualifying consecutive executor tool errors. - Persist retry claims, cursors, and audit markers with PostgreSQL migrations. - Expose project retry count, backoff, and failure threshold settings in the dashboard. - Cover retry, exhaustion, reset, and stale-run safety behavior with tests. Files changed: .changeset/fn-7996-executor-tool-failure-retry.md | 7 + AGENTS.md | 1 + docs/architecture.md | 1 + docs/settings-reference.md | 10 ++ .../executor-tool-failure-retry-claim.test.ts | 17 +++ .../core/src/__tests__/manual-retry-reset.test.ts | 3 + .../core/src/__tests__/settings-defaults.test.ts | 15 +- packages/core/src/in-review-stall.ts | 20 +++ packages/core/src/index.gate.ts | 6 + packages/core/src/index.ts | 6 + packages/core/src/manual-retry-reset.ts | 3 + .../0013_executor_tool_failure_retry.sql | 4 + packages/core/src/postgres/schema-applier.ts | 17 +++ packages/core/src/postgres/schema/project.ts | 3 + packages/core/src/settings-schema.ts | 3 + packages/core/src/store.ts | 10 +- packages/core/src/task-store/persistence.ts | 7 + packages/core/src/task-store/remaining-ops-2.ts | 2 +- packages/core/src/task-store/remaining-ops-3.ts | 2 +- packages/core/src/task-store/remaining-ops-6.ts | 65 ++++++++- packages/core/src/task-store/serialization.ts | 3 + packages/core/src/task-store/task-update.ts | 6 + packages/core/src/types.ts | 16 +++ .../dashboard/app/components/SettingsModal.tsx | 15 ++ .../app/components/settings/section-keys.ts | 3 + .../settings/sections/SchedulingSection.search.ts | 27 ++++ .../settings/sections/SchedulingSection.tsx | 4 + .../settings-default-descriptions.test.tsx | 3 + .../__tests__/executor-tool-failure-retry.test.ts | 160 +++++++++++++++++++++ packages/engine/src/executor.ts | 87 ++++++++++- packages/i18n/locales/en/app.json | 6 + 31 files changed, 523 insertions(+), 9 deletions(-) Fusion-Task-Id: FN-7996 Fusion-Task-Lineage: d1682ef8-534c-410e-b74c-1f2cf176eac2 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
beae12a4bf |
FN-8034: enforce component and token reuse
Document standing guidance that keeps UI implementations consistent with existing systems. - Require reuse of components, primitives, hooks, and helpers before creating alternatives. - Require dashboard styling to use design tokens and component-scoped CSS. - Link the styling guide, token source, and documented solution patterns. Files changed: AGENTS.md | 8 ++++++++ 1 file changed, 8 insertions(+) Fusion-Task-Id: FN-8034 Fusion-Task-Lineage: f0435e22-8e8e-471e-b188-7e1a732c2e41 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |