diff --git a/packages/reactor/src/cycle/index.ts b/packages/reactor/src/cycle/index.ts index d92936ca..d679b35c 100644 --- a/packages/reactor/src/cycle/index.ts +++ b/packages/reactor/src/cycle/index.ts @@ -28,6 +28,11 @@ export interface ConsumedReceiptEdge { export interface CycleDetectionResult { readonly cycle_checked: true; readonly has_cycle: boolean; + /** + * The detected cycle represented as a closed walk array of node content addresses + * (e.g. `[A, B, C, A]`), where the starting node is repeated at the end to record the closing edge. + * If `has_cycle` is false, this array is empty (`[]`). + */ readonly cycle: readonly ContentAddress[]; } @@ -36,6 +41,9 @@ export interface CycleDetectionResult { * acyclicity check Forme runs over the topology world-model's edges * (architecture.md §6.3, §3.1). Total and order-stable: the same edge set * yields the same cycle regardless of input order. + * + * If a cycle is detected, `cycle` returns a closed walk array (e.g., `[A, B, C, A]`) + * where the final element repeats the initial node to explicitly record the closing edge. */ export function detectReceiptCycles( edges: readonly ConsumedReceiptEdge[], @@ -270,7 +278,7 @@ function visitCycleNode( const existingIndex = path.indexOf(node); if (visiting.has(node) && existingIndex >= 0) { - return [...path.slice(existingIndex), node]; + return path.slice(existingIndex); } visiting.add(node);