From f32c83272934420b4a58bd9c5c1488d1f25a0573 Mon Sep 17 00:00:00 2001 From: real-venus Date: Tue, 14 Jul 2026 08:23:06 -0700 Subject: [PATCH] docs(engine): document the deliberate gate-advisory twin divergence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Record the keep-divergent decision for the gate-decision advisory twins (#4881): src/rules/advisory.ts (host) and packages/loopover-engine/src/advisory/gate-advisory.ts (engine). Add header docs to both explaining that they are intentionally NOT converged — the host copy reaches into the full signals subsystem (isCodeFile, isTestPath, scoring/preview, signals/engine types) while the engine copy is a slimmed re-implementation, precisely so @loopover/engine and its CLI consumers never pull the ~5,800-line signals/engine into their dependency graph. Note that scripts/check-engine-parity.ts keeps the core gate-decision functions in lock-step, and that converging must wait until the dependency-graph constraint is solved. Comments only — no gate-decision behavior changes. Closes #4881 --- .../src/advisory/gate-advisory.ts | 8 ++++++++ src/rules/advisory.ts | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/packages/loopover-engine/src/advisory/gate-advisory.ts b/packages/loopover-engine/src/advisory/gate-advisory.ts index 6c9366c9e9..2f956cf60a 100644 --- a/packages/loopover-engine/src/advisory/gate-advisory.ts +++ b/packages/loopover-engine/src/advisory/gate-advisory.ts @@ -1,3 +1,11 @@ +// Gate-decision advisory logic — ENGINE copy. This is an intentionally-divergent twin of the host +// src/rules/advisory.ts (#4518; keep-divergent decision recorded for #4881). This slimmed re-implementation uses +// predicted-gate-types + ../scoring/label-match and deliberately imports none of ../signals/engine, isCodeFile, or +// isTestPath, so @loopover/engine — and the CLI packages that consume it (packages/loopover-miner, +// packages/loopover-mcp) — never pull the ~5,800-line signals/engine subsystem into their dependency graph. The +// core gate-decision functions are kept structurally in lock-step with the host copy by +// scripts/check-engine-parity.ts (GATE_DECISION_CORE_MARKERS); do NOT converge to a single source until that +// dependency-graph constraint is solved — see #4881. import { randomUUID } from "node:crypto"; import type { Advisory, diff --git a/src/rules/advisory.ts b/src/rules/advisory.ts index f7b8d5b526..380a68d3e3 100644 --- a/src/rules/advisory.ts +++ b/src/rules/advisory.ts @@ -1,3 +1,21 @@ +// Gate-decision advisory logic — HOST copy. This is an intentionally-divergent twin of the engine's +// packages/loopover-engine/src/advisory/gate-advisory.ts (#4518; keep-divergent decision recorded for #4881). The +// two are deliberately NOT converged to a single source. +// +// Why kept divergent: this host copy reaches into the full signals subsystem — `isCodeFile` +// (../signals/local-branch, which transitively pulls the whole review-scoring / GitHub-API graph), `isTestPath` +// (../signals/test-evidence), `labelMatchesPattern` (../scoring/preview), and the CollisionCluster/CollisionReport +// types from the ~5,800-line ../signals/engine. The engine twin is a slimmed re-implementation (slim +// predicted-gate-types + ../scoring/label-match, importing none of signals/engine) precisely so @loopover/engine — +// and the CLI packages that depend on it (packages/loopover-miner, packages/loopover-mcp) — never drag +// signals/engine and its subsystem into their dependency graph. +// +// What keeps this safe: scripts/check-engine-parity.ts (GATE_DECISION_CORE_MARKERS) asserts BOTH files still export +// the core gate-decision functions (evaluateGateCheck / evaluateGateCheckCore / isConfiguredGateBlocker / +// buildPullRequestAdvisory), so the gate *decision* stays in lock-step even though the surrounding types and +// imports diverge. Do NOT converge these into a single shim until the dependency-graph-size constraint is solved +// (e.g. a shared type-only module carrying CollisionReport without dragging the signals implementation along) — see +// #4881. import type { Advisory, AdvisoryConclusion,