docs(FN-4490): complete Step 5 — add DAG architecture deliverables

Fusion-Task-Id: FN-4490
Fusion-Task-Lineage: 0194e9e4-c49c-4c18-b057-433a58062c75
This commit is contained in:
Fusion
2026-05-14 10:48:16 -07:00
committed by gsxdsm
parent 1c298c9cc2
commit 722efe9227
4 changed files with 164 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# ADR-0001: DAG Orchestration Representation and Scheduling Boundary (v1)
Related tasks: **FN-4487**, **FN-4471**, governance gate **FN-4359**.
See also: [Requirements Matrix](./requirements-matrix.md) · [Failure + Observability Contract](./failure-observability-contract.md)
## Status
**Proposed**
## Context
FN-4471 scoped the multi-agent DAG request into a bounded discovery/prototype arc and highlighted that current orchestration is mostly prompt-driven rather than engine-enforced. FN-4487 converted that scope into Milestones A/B/C and recommended architecture-first work before any runtime prototype.
This ADR is Milestone As binding architecture decision for how DAG semantics integrate with existing Fusion execution primitives without changing reliability-layer behavior during the FN-4359 freeze.
## Decision
Adopt a **first-class DAG model persisted in SQLite** (explicit `dag_runs`, `dag_nodes`, `dag_edges` style records) rather than deriving orchestration only from task `dependencies`.
Use a narrow scheduling boundary: a new logical **DagCoordinator** concept may evaluate graph readiness and then enqueue work only through existing scheduler/executor pathways (no direct task execution path). Integration point is the existing scheduler surface in `packages/engine/src/scheduler.ts`; Milestone B prototype should call into existing queueing/dispatch mechanisms and must not bypass `AgentSemaphore` (`packages/engine/src/concurrency.ts`) or checkout leasing guarantees.
Rationale for this boundary:
- Keeps scheduler internals stable for Milestone B by treating DAG as an upstream producer of eligible task-enqueue intents, not a scheduler replacement.
- Preserves executor ownership and lease semantics in `packages/engine/src/executor.ts`.
- Supports clean restart reconstruction from DB and additive observability.
## Consequences
1. **Storage impact**
- Additive SQLite schema additions are required in `.fusion/fusion.db`.
- No destructive migration or replacement of existing task/blob storage (`docs/storage.md`).
2. **Single-event-loop invariant**
- DAG evaluation and persistence operations must remain non-blocking and aligned with `AGENTS.md` Engine Process Rules.
- No `execSync` for user-configured operations; orchestration logic must use async patterns.
3. **Multi-project/mesh impact**
- Prototype remains single-project/single-node by default.
- Any cross-node DAG semantics are deferred and must align with `docs/multi-project.md` and `docs/multi-project-sequencing.md` identity/routing constraints.
4. **Merge/file-scope path impact**
- DAG-driven execution does not change merge topology: one task still maps to one branch/review flow.
- No cross-task squash semantics introduced; merger audit and file-scope invariant remain authoritative.
## Alternatives Considered
### 1) Use task `dependencies` graph only
Rejected because task dependencies encode coarse task ordering, not DAG-run identity, per-node lifecycle, conditional branch semantics, or node-scoped retry/cancel state. Overloading dependencies would blur existing scheduler semantics and make restart/observability contracts harder to reason about.
### 2) External orchestrator service
Rejected for Milestone A/B because it adds network/distributed coordination complexity before proving local fit, conflicts with current single-process engine assumptions, and increases failure surface around auth/routing across nodes. A local additive model gives lower blast radius and cleaner governance under FN-4359.
## Governance
Reliability freeze text from `AGENTS.md`:
> "Reliability mechanism changes are currently under freeze pending FN-4359 governance hardening; treat new reliability-layer behavior changes as blocked unless explicitly approved in task scope."
Milestone B implementation is gated on freeze lift or explicit carve-out approval. DAG retry/replay behavior MUST NOT regress `SelfHealingManager` (`packages/engine/src/self-healing.ts`), `RestartRecoveryCoordinator` (`packages/engine/src/restart-recovery-coordinator.ts`), or merger audit/file-scope protections (`packages/engine/src/merger.ts`).
## Open Questions
1. Node identity model: reuse task IDs directly or introduce DAG-node IDs that reference tasks?
2. Fan-in semantics: how should `blockedBy` and multiple-parent completion be represented?
3. Retry budgeting: per-node, per-run, or hybrid budget with `retriesBurned` attribution?
4. Cancellation precedence: how should operator cancel interact with in-flight executor retries?
5. DAG/task document linkage: should run evidence live only in DB/audit logs or mirror key summaries into task documents?
6. Prototype flag scope: project-level feature flag only, or per-task override allowed?

View File

@@ -0,0 +1,74 @@
# DAG Failure Model + Observability Contract (Milestone A)
Related tasks: **FN-4487**, **FN-4471**, governance/policy dependencies **FN-4359**, **FN-3973**, **FN-4488**, retry context **FN-4398**.
See also: [Requirements Matrix](./requirements-matrix.md) · [ADR v1](./adr-0001-dag-orchestration.md)
## 1) Failure taxonomy
- **Per-node failure**: a node reaches failed terminal state due to execution error/timeouts.
- **Edge failure (dependency unsatisfied)**: downstream node cannot enqueue because one or more required predecessor outcomes are missing/invalid.
- **Partial-DAG abort**: DAG run transitions to aborted with a subset of nodes complete and remainder marked skipped/blocked.
- **Whole-DAG cancel**: operator/system cancellation transitions all non-terminal nodes to canceled/skipped with audit trail.
- **Retry-exhausted**: bounded retries consumed for node/run; record retry budget burn (align with FN-4398 `retriesBurned` concepts).
- **Governance-blocked**: execution path denied by policy gate (spawn/approval restrictions, e.g., FN-3973 and FN-4488 governance).
## 2) Interaction contract with existing reliability layers
Milestone B implementation MUST preserve all behaviors below:
1. **SelfHealingManager (`packages/engine/src/self-healing.ts`)**
- No new reliability-layer code paths are required for Milestone B prototype.
- DAG state machine must remain additive and not alter existing self-healing recovery semantics.
2. **RestartRecoveryCoordinator (`packages/engine/src/restart-recovery-coordinator.ts`)**
- DAG run/node state must be reconstructible from SQLite alone after process restart.
- Recovery should not require ephemeral in-memory DAG state as source of truth.
3. **Merger post-squash audit + file-scope invariant (`packages/engine/src/merger.ts`)**
- DAG orchestration must not alter one-task/one-branch merge assumptions.
- Existing audit and file-scope gating remain unchanged and mandatory.
4. **Workflow steps `gateMode` semantics (`docs/workflow-steps.md`)**
- `gate` failures continue blocking merge; `advisory` remains non-blocking.
- DAG path cannot silently downgrade or bypass configured workflow gates.
5. **Executor checkout leasing (409 contention semantics)**
- Lease conflicts remain hard conflicts (409) and are not auto-retried by DAG coordinator logic.
- DAG scheduler logic must respect existing ownership/checkout contracts.
## 3) Observability contract
### Structured logger prefix
Use a dedicated prefix aligned to existing conventions (`[executor]`, `[scheduler]`, `[stuck-detector]`):
- **`[dag-coordinator]`** for DAG orchestration lifecycle logs.
### Minimum event vocabulary
- `dag:run:start`
- `dag:node:enqueue`
- `dag:node:complete`
- `dag:node:fail`
- `dag:run:complete`
- `dag:run:abort`
Each event should include (at minimum): `runId`, `dagRunId`, `taskId` (when applicable), `nodeId`, `status`, `reasonCode` (for fail/abort/block), and timestamp.
### Run-audit linkage
DAG lifecycle mutations must emit auditable events consistent with the run-audit contract (`AGENTS.md` Run Audit section):
- database domain for DAG state transitions,
- git domain unchanged (normal task branch/merge flow),
- filesystem domain only when writing normal task artifacts.
### Dashboard surfacing
Operator-facing DAG views are **deferred to Milestone C**. Milestone B only requires machine-usable structured logs/audit evidence and minimal debug visibility.
## 4) Out of scope (explicit)
- Cross-node DAG execution beyond existing mesh model constraints.
- Multi-tenant orchestration isolation redesign.
- Time-travel/replay engine semantics.
- Autoscaling/orchestration-level capacity management.

View File

@@ -0,0 +1,18 @@
# DAG Orchestration Requirements Matrix (Milestone A)
Related tasks: **FN-4487** (mission proposal), **FN-4471** (upstream scoping), governance gate **FN-4359**.
See also: [ADR v1](./adr-0001-dag-orchestration.md) · [Failure + Observability Contract](./failure-observability-contract.md)
| Capability | Operator need | Engine constraint | Existing Fusion mechanism it must compose with | Milestone A deliverable | Milestone B in-scope? | Out of scope for the mission |
|---|---|---|---|---|---|---|
| DAG definition / authoring | Define a small, explicit graph (nodes, edges, metadata) without replacing current task UX. | Engine is single-event-loop; representation must be lightweight and non-blocking (`AGENTS.md` Engine Process Rules). | `docs/storage.md`; `packages/engine/src/scheduler.ts`; `packages/engine/src/executor.ts`; `packages/core/src/ai-engine-loader.ts` boundary rule. | ADR section: representation choice + storage boundary. | Yes (minimal prototype graph). | Full visual workflow builder and template marketplace. |
| Node-to-node edges (data + control) | Express dependency sequencing and basic payload handoff semantics between nodes. | Must preserve checkout lease ownership and not bypass task execution flow. | `packages/engine/src/scheduler.ts`; `packages/engine/src/executor.ts`; checkout leasing contract in `AGENTS.md`. | Requirements matrix mapping + failure contract for unsatisfied edges. | Yes (single dependency edge in prototype). | Arbitrary cross-task artifact buses or shared mutable global state. |
| Conditional branches | Route execution based on node outcome/approvals without custom ad hoc scripts. | Branch evaluation cannot block loop; must fit existing gating and approval patterns. | `docs/workflow-steps.md` (`gateMode`); `packages/engine/src/agent-heartbeat.ts`; `packages/engine/src/concurrency.ts`. | ADR semantics: bounded condition model and evaluation timing. | Yes (simple pass/fail branch only). | Full DSL/expression language and nested policy engine. |
| Retry semantics | Operators need bounded retry and clear retry-exhausted outcomes per node/run. | Must not regress reliability layers during FN-4359 freeze. | `packages/engine/src/self-healing.ts`; `packages/engine/src/restart-recovery-coordinator.ts`; retry context from FN-4398 (`retriesBurned`). | Failure taxonomy + governance section in ADR. | Yes (bounded prototype retries, additive). | Global replay/time-travel and automatic adaptive retry tuning. |
| Partial-failure handling | Continue/abort policy must be explicit when one node fails and others are pending. | Preserve deterministic task terminal states and existing merge gating assumptions. | `packages/engine/src/executor.ts`; `packages/engine/src/merger.ts`; workflow pre-merge/post-merge model in `docs/workflow-steps.md`. | Failure contract state machine + abort semantics. | Yes. | Cross-DAG compensating transactions and distributed sagas. |
| Cancellation | Support operator/system cancel of a DAG run with auditable state. | Must respect 409 checkout conflict semantics; no auto-retry takeover. | Checkout leasing rules in `AGENTS.md`; `packages/engine/src/executor.ts`; `packages/engine/src/scheduler.ts`. | Failure contract cancellation section and log vocabulary. | Yes. | Force-cancel across remote nodes with unilateral lease revocation. |
| Observability / log surface | Operators need per-run and per-node lifecycle visibility and reasons for block/fail states. | Must follow structured logger conventions and run-audit linkage. | `packages/engine/src/logger.ts`; `AGENTS.md` Engine Diagnostic Logging; Run Audit section. | Failure + observability contract event schema. | Yes (debug-level telemetry). | Full dashboard productization (deferred to Milestone C). |
| Multi-project / mesh scope | Understand if/when DAG spans projects/nodes and auth boundaries. | Current system is project-scoped with central registry; node APIs require apiKey and explicit routing. | `docs/multi-project.md`; `docs/multi-project-sequencing.md`; node sync endpoints in `AGENTS.md`. | ADR consequences + explicit scoping constraints. | No (prototype is single-project/single-node). | Cross-node DAG scheduling, multi-tenant routing, global consistency protocol changes. |
| Persistence | DAG run state must survive restart and be reconstructible from DB. | Additive schema only; no destructive migrations; hybrid storage model must remain intact. | `docs/storage.md`; `.fusion/fusion.db` contracts; `packages/engine/src/restart-recovery-coordinator.ts`. | ADR storage decision + failure contract restart expectations. | Yes. | Event-sourcing rewrite or replacement of current task/blob storage model. |
| Governance / approval gating | Operators need clear policy boundary for what can ship under reliability freeze. | FN-4359 freeze blocks reliability-layer behavior changes absent explicit carve-out. | `AGENTS.md` Reliability Mechanism Governance; `packages/engine/src/self-healing.ts`; `packages/engine/src/restart-recovery-coordinator.ts`; merger file-scope invariant in `packages/engine/src/merger.ts`. | ADR Governance section + open questions for Milestone B gate. | Yes (architecture gates only; runtime gated). | Bypassing governance with silent reliability changes or hidden scheduler overrides. |