From 71575f78f57eaa6a336e9644c9ce6b5ec9131cfb Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Thu, 18 Jun 2026 23:51:52 +0530 Subject: [PATCH 1/2] fix: cycle detection returns duplicate closing node in reported cycle path --- packages/reactor/src/cycle/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/reactor/src/cycle/index.ts b/packages/reactor/src/cycle/index.ts index d92936ca..d462becb 100644 --- a/packages/reactor/src/cycle/index.ts +++ b/packages/reactor/src/cycle/index.ts @@ -270,7 +270,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); From 71adabf7025d2db96a49eb81a3eb9bb83fb3f1a5 Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Mon, 3 Aug 2026 00:29:44 +0530 Subject: [PATCH 2/2] docs(cycle): clarify closed walk representation contract --- packages/reactor/src/cycle/index.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/reactor/src/cycle/index.ts b/packages/reactor/src/cycle/index.ts index d462becb..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[],