{
  "$schema": "https://raw.githubusercontent.com/fallow-rs/fallow/main/config-schema.json",
  "entry": [
    "packages/producer/src/**/*.test.ts",
    "packages/aws-lambda/src/**/*.test.ts",
    "packages/gcp-cloud-run/src/**/*.test.ts",
    "packages/producer/src/regression-harness.ts",
    "packages/producer/src/regression-harness-distributed.test.ts",
    "packages/producer/src/regression-harness-lambda-local.ts",
    "packages/producer/src/transparency-test.ts",
    "packages/producer/src/parity-harness.ts",
    "packages/producer/src/parity-fixtures.ts",
    "packages/producer/src/perf-gate.ts",
    "packages/producer/src/runtime-conformance.ts",
    "packages/producer/src/benchmark.ts",
    "packages/producer/scripts/generate-font-data.ts",
    "packages/producer/we-render.mjs",
    "packages/producer/scripts/validate-fast-video.ts",
    "packages/cli/scripts/generate-font-data.ts",
    "packages/engine/scripts/test-fitTextFontSize-browser.ts",
    "packages/aws-lambda/scripts/*.ts",
    // Built as standalone IIFE for the browser-side sandbox runtime;
    // referenced by file path (not import) in build-hyperframes-runtime-artifact.ts.
    "packages/core/src/runtime/entry.ts",
    // Bundled as a standalone IIFE by the position-edits render artifact
    // generator; referenced by file path rather than imported by TypeScript.
    "packages/core/stubs/position-edits-render-entry.ts",
    // In-page audit scripts read as raw strings and injected via
    // page.addScriptTag (see layout.ts / validate.ts) — referenced by file
    // path, never imported, so they have no import-graph referrer.
    "packages/cli/src/commands/layout-audit.browser.js",
    "packages/cli/src/commands/contrast-audit.browser.js",
    "packages/cli/src/commands/motion-sample.browser.js",
    // Worker entry points loaded dynamically by their *Pool.ts companions.
    "packages/producer/src/services/pngDecodeBlitWorker.ts",
    "packages/producer/src/services/shaderTransitionWorker.ts",
    // Off-main-thread /health endpoint, spawned by path from healthWorker.ts.
    "packages/producer/src/services/healthWorkerThread.ts",
    // Test fixture worker, spawned by path via the pools' workerEntryPath
    // option from the crash-recovery tests; has no import-graph referrer.
    "packages/producer/src/services/__fixtures__/crashOnMessageWorker.mjs",
    "scripts/*.{ts,mjs,js}",
    "scripts/*/run.mjs",
    // Keyframe UI components — wired dynamically via EaseCurveSection/MotionPanel.
    "packages/studio/src/components/editor/KeyframeDiamond.tsx",
    "packages/studio/src/components/editor/SpringEaseEditor.tsx",
    // NLE notice — rendered conditionally via NLELayout when timeline is first shown.
    "packages/studio/src/components/nle/TimelineEditorNotice.tsx",
    // Zoom hook extracted for downstream razor-blade PRs (#1330, #1331).
    "packages/studio/src/player/components/useTimelineZoom.ts",
    // Cached O(1) GSAP target lookup, replacing O(n²) inline checks.
    // Consumers migrate in a follow-up once useDomGeometryCommits adopts it.
    "packages/studio/src/hooks/gsapTargetCache.ts",
    // Preview helper consumed dynamically from the studio iframe bridge.
    "packages/studio/src/hooks/gsapRuntimePreview.ts",
    // TEMP(studio-dnd): shipped unwired ahead of the NLE integration;
    // the app-shell swap PR (studio-dnd/pr22) wires the consumers and removes this block.
    "packages/studio/src/components/editor/CanvasContextMenu.tsx",
  ],
  "ignorePatterns": [
    "docs/**",
    // Chrome browser binaries downloaded by puppeteer — not project source.
    "chrome/**",
    // Standalone spike scripts and benchmark runners used during R&D.
    "packages/engine/spikes/**",
    "packages/producer/de-*.mjs",
    "packages/producer/tests/**",
    "packages/player/tests/**",
    "packages/engine/tests/**",
    "skills/**/test-corpus/**",
    "skills/**/scripts/**",
    // Agent-invoked motion-graphics tools co-located with their docs (run via
    // `node <path>` per grounding/PROTOCOL.md / categories/maps/module.md
    // prose), not import-graph reachable.
    "skills/motion-graphics/grounding/**",
    "skills/motion-graphics/categories/**",
    // Agent-invoked reference materials (template + motion-primitive HTML, catalogs),
    // forked by path by the frame-worker per SKILL.md prose, not import-graph reachable.
    "skills/music-to-video/references/**",
    // Bundled @font-face data (read at runtime via fs.readFileSync, invisible
    // to the import graph) + its manual rebuild tool.
    "skills/**/fonts/**",
    // Golden snapshot files: data consumed by toMatchFileSnapshot, not importable modules.
    "packages/**/__goldens__/**",
    "registry/**",
    "examples/**",
    "packages/sdk/examples/**",
    ".github/workflows/fixtures/**",
    // Auto-generated TS client for the HeyGen cloud API. Regenerated by
    // experiment-framework/scripts/generate_hyperframes_cli_client.py via
    // the sync-hyperframes-codegen.yml workflow; complexity/dead-code
    // findings on this file are not actionable from this repo.
    "packages/cli/src/cloud/_gen/**",
  ],
  "ignoreExports": [
    // TEMP(studio-dnd): consumers land later in the stack; removed by studio-dnd/pr22.
    {
      "file": "packages/studio/src/components/editor/canvasContextMenuZOrder.ts",
      "exports": ["readEffectiveZIndex"],
    },
    // drawElementService is the bottom of the fast-capture Graphite stack
    // (#1917): its consumers (frameCapture in #1919) land two PRs upstack, so
    // a per-PR audit diffing against the merge base sees these exports as
    // unused. Consumed for real once the stack merges; safe to drop this
    // entry after #1919 lands.
    {
      "file": "packages/engine/src/services/drawElementService.ts",
      "exports": [
        "instrumentAcceleratedCanvases",
        "injectDrawElementCanvas",
        "captureDrawElementFrame",
        "initDrawElementWorkerEncode",
        "cleanupDrawElementWorkerEncode",
        "produceDrawElementFrame",
      ],
    },
    // CLI command files: every command exports a const `examples` per the
    // convention documented in CLAUDE.md. This is a namespace barrel, not a
    // collision.
    { "file": "packages/cli/src/commands/*.ts", "exports": ["examples"] },
    // Options type for the render-queue hook's public startRender callback —
    // consumed structurally by callers (StudioRightPanel), not by import.
    {
      "file": "packages/studio/src/components/renders/useRenderQueue.ts",
      "exports": ["StartRenderOptions"],
    },
    // Independent ML model managers each declare their own DEFAULT_MODEL /
    // MODELS_DIR / ensureModel for their model namespace.
    {
      "file": "packages/cli/src/{background-removal,tts,whisper}/manager.ts",
      "exports": ["DEFAULT_MODEL", "MODELS_DIR", "ensureModel"],
    },
    // `isPathInside` is documented as exported-for-tests only in fileServer.ts;
    // it has different semantics (symlink resolution) from utils/paths.ts.
    {
      "file": "packages/producer/src/services/fileServer.ts",
      "exports": ["isPathInside"],
    },
    // Studio telemetry: consumed by useRenderQueue.ts / StudioFeedbackBar.tsx
    // (deep relative imports) but fallow's static analyzer doesn't trace
    // them. Same path-resolution quirk — trackStudioSessionStart from the
    // same file resolves fine.
    {
      "file": "packages/studio/src/telemetry/events.ts",
      "exports": ["trackStudioRenderStart", "trackStudioFeedback"],
    },
    // domEditingLayers: these exports are consumed via the browser iframe
    // runtime context (not traceable by static import analysis from the
    // studio entry point) or re-exported through the domEditing barrel but
    // have no downstream consumers yet.
    {
      "file": "packages/studio/src/components/editor/domEditingLayers.ts",
      "exports": [
        "isEditableTextLeaf",
        "collectDomEditTextFields",
        "buildElementLabel",
        "refreshDomEditSelection",
      ],
    },
    // domEditing barrel: re-exports consumed throughout the studio but
    // fallow's static analyzer can't trace re-exports through barrel files.
    {
      "file": "packages/studio/src/components/editor/domEditing.ts",
      "exports": ["*"],
    },
    // Exported for render.test.ts (exported-for-tests pattern).
    {
      "file": "packages/cli/src/commands/render.ts",
      "exports": ["resolveBrowserGpuForCli", "renderLocal", "checkRenderResolutionPreflight"],
    },
    // initThreeDProjectionInPage: passed to page.evaluate() for browser-side execution —
    // Puppeteer serializes it at runtime, not an import-graph consumer.
    {
      "file": "packages/engine/src/services/threeDProjection.ts",
      "exports": ["initThreeDProjectionInPage"],
    },
    // captureCost.ts: constants and helpers consumed by the runCaptureCalibration
    // orchestration function and tests, but the entry-point graph doesn't
    // reach them because the orchestrator's caller resolves them dynamically.
    {
      "file": "packages/producer/src/services/render/captureCost.ts",
      "exports": [
        "CAPTURE_CALIBRATION_TARGET_MS",
        "MAX_MEASURED_CAPTURE_COST_MULTIPLIER",
        "CAPTURE_CALIBRATION_PROTOCOL_TIMEOUT_MS",
        "measureCaptureCostFromSession",
        "logCaptureCalibrationResult",
        "createFailedCaptureCalibrationEstimate",
      ],
    },
    // gsapParserExports.ts is the public-API barrel that re-exports constants,
    // types, and utilities from gsapConstants, gsapSerialize, and springEase.
    // The re-exports are intentional public API consumed by callers outside the
    // changed-file set (e.g. studio, aws-lambda) and therefore appear unused
    // to fallow's static analysis of the PR diff.
    {
      "file": "packages/parsers/src/gsapParserExports.ts",
      "exports": [
        "PROPERTY_GROUPS",
        "classifyPropertyGroup",
        "classifyTweenPropertyGroup",
        "SPRING_PRESETS",
        "generateSpringEaseData",
        "GsapMethod",
        "GsapKeyframesData",
        "GsapKeyframeFormat",
        "PropertyGroupName",
        "SpringPreset",
      ],
    },
    // Shared test helpers consumed by gsapParser.test.ts (same file,
    // fallow doesn't trace intra-file test consumption).
    {
      "file": "packages/parsers/src/gsapParser.test-helpers.ts",
      "exports": [
        "expectKeyframe",
        "expectKeyframesFormat",
        "convertAndReparse",
        "parseSplitAndAssert",
      ],
    },
    // hfIds: EXCLUDED_TAGS is consumed by tests (htmlParser.test.ts) and
    // hfIdPersist.ts but fallow's static analyzer may not trace all consumers.
    {
      "file": "packages/parsers/src/hfIds.ts",
      "exports": ["EXCLUDED_TAGS", "mintHfId"],
    },
    // Shared timeline components extracted for downstream PRs in the
    // razor-blade stack (#1330, #1331). Consumers live on those branches.
    {
      "file": "packages/studio/src/player/components/timelineCallbacks.ts",
      "exports": ["*"],
    },
    // Shared timeline DOM barrel for downstream consumers; fallow does not
    // trace all re-export-only modules.
    {
      "file": "packages/studio/src/player/lib/timelineDOM.ts",
      "exports": ["*"],
    },
    // gsapTargetCache: cached O(1) GSAP target lookup, consumed by
    // useDomEditCommits and intended to replace the local copy in
    // useDomGeometryCommits once callers migrate.
    {
      "file": "packages/studio/src/hooks/gsapTargetCache.ts",
      "exports": ["isElementGsapTargeted"],
    },
    // Re-exports from useDomEditCommits: barrel-style re-exports
    // consumed by downstream studio code.
    {
      "file": "packages/studio/src/hooks/useDomEditCommits.ts",
      "exports": ["GSAP_CSS_FALLBACK_BLOCKED_MESSAGE", "PersistDomEditOperations"],
    },
    {
      "file": "packages/studio/src/utils/timelineElementSplit.ts",
      "exports": ["buildPatchTarget", "readFileContent"],
    },
    // freezeUrl and freezeLocalFile are public API re-exported from the figma
    // barrel (index.ts) for Task 4 manifest flow and the /figma skill integration;
    // not yet imported by current code outside the module.
    {
      "file": "packages/core/src/figma/freeze.ts",
      "exports": ["freezeUrl", "freezeLocalFile"],
    },
    // mediaDir, typeDirPath, isFigmaManifestRecord: re-exported from the figma
    // barrel (index.ts) via manifest.ts per Task 8 wiring. Consumed only by the
    // /figma skill integration, not by code in the current codebase.
    {
      "file": "packages/core/src/figma/manifest.ts",
      "exports": ["mediaDir", "typeDirPath", "isFigmaManifestRecord"],
    },
  ],
  "ignoreDependencies": [
    // Runtime/dynamic deps not visible to static analysis: tsup `external`,
    // dynamic require() resolution, peer/static-file consumption in tests,
    // and bun-hoisted workspace devDeps (e.g. happy-dom in root package.json
    // resolves for every workspace, so workspaces don't redeclare it).
    // Required by @puppeteer/browsers and puppeteer-core at runtime; listed
    // as a direct dep to guarantee installation even when transitive
    // resolution fails (corrupted cache, dedup edge cases).
    "debug",
    "puppeteer",
    "puppeteer-core",
    "esbuild",
    "giget",
    "gsap",
    "happy-dom",
    "ffmpeg-static",
    "ffprobe-static",
    "@hyperframes/core",
    "@hyperframes/studio",
    "@hyperframes/producer",
    "@fontsource/archivo-black",
    "@fontsource/eb-garamond",
    "@fontsource/ibm-plex-mono",
    "@fontsource/inter",
    "@fontsource/jetbrains-mono",
    "@fontsource/league-gothic",
    "@fontsource/montserrat",
    "@fontsource/nunito",
    "@fontsource/oswald",
    "@fontsource/outfit",
    "@fontsource/space-mono",
    "@fontsource/lato",
    "@fontsource/noto-sans-jp",
    "@fontsource/open-sans",
    "@fontsource/playfair-display",
    "@fontsource/poppins",
    "@fontsource/roboto",
    "@fontsource/source-code-pro",
  ],
  "duplicates": {
    // Raise from the default 5 to 6 lines so trivially short Hono route-handler
    // preambles (resolveProject + 404 + body-parse) are below the threshold.
    // The three 5-line groups in files.ts / render.ts are structural boilerplate
    // that naturally converges and is unlikely to diverge; extraction would
    // require intrusive middleware changes beyond this PR's scope.
    "minLines": 6,
    "ignore": [
      // sourcePatcher.ts: pre-existing internal clones between the inline-style
      // and attribute tag-patchers; only the PatchOperation type gained two
      // optional fields here, but the line shift makes fallow re-flag them.
      "packages/studio/src/utils/sourcePatcher.ts",
      // gsapParser.ts: recast/babel GSAP writer — intentional duplication between
      // recast and acorn parallel implementations (pre-existing, moved from core).
      "packages/parsers/src/gsapParser.ts",
      // hfIds.ts: 7-line clone with sdk/engine/mutate.ts — pre-existing duplication
      // from when hfIds lived in packages/core/src/parsers/. Moving the file to the
      // new package makes fallow see it as a fresh finding; the underlying clone
      // predates this refactor.
      "packages/parsers/src/hfIds.ts",
      // Parser test files: parallel arrange/act/assert test cases — pre-existing
      // duplication moved from packages/core/src/parsers/.
      "packages/parsers/src/gsapParser.test.ts",
      "packages/parsers/src/gsapParser.test-helpers.ts",
      "packages/parsers/src/gsapWriter.parity.test.ts",
      "packages/parsers/src/gsapWriterParity.corpus.test.ts",
      "packages/parsers/src/gsapWriterParity.acorn.test.ts",
      "packages/parsers/src/htmlParser.roundtrip.test.ts",
      "packages/parsers/src/htmlParser.test.ts",
      // @hyperframes/studio-server test files: parallel arrange/act/assert test cases
      // (pre-existing structure from when studio-api lived in packages/core/src/studio-api/).
      "packages/studio-server/src/routes/files.test.ts",
      "packages/studio-server/src/routes/render.test.ts",
      "packages/studio-server/src/routes/lint.test.ts",
      "packages/studio-server/src/routes/preview.test.ts",
      "packages/studio-server/src/routes/projects.test.ts",
      "packages/studio-server/src/helpers/backupJournal.test.ts",
      "packages/studio-server/src/helpers/finiteMutation.test.ts",
      "packages/studio-server/src/helpers/hfIdPersist.test.ts",
      "packages/studio-server/src/helpers/manualEditsRenderScript.test.ts",
      "packages/studio-server/src/helpers/mediaValidation.test.ts",
      "packages/studio-server/src/helpers/previewAdapter.test.ts",
      "packages/studio-server/src/helpers/safePath.test.ts",
      "packages/studio-server/src/helpers/sourceMutation.test.ts",
      "packages/studio-server/src/helpers/studioMotionRenderScript.test.ts",
      "packages/studio-server/src/helpers/subComposition.test.ts",
      // @hyperframes/lint rule test files: parallel arrange/act/assert test cases
      // (pre-existing structure from when lint lived in packages/core/src/lint/).
      "packages/lint/src/rules/adapters.test.ts",
      "packages/lint/src/rules/captions.test.ts",
      "packages/lint/src/rules/composition.test.ts",
      "packages/lint/src/rules/core.test.ts",
      "packages/lint/src/rules/fonts.test.ts",
      "packages/lint/src/rules/gsap.test.ts",
      "packages/lint/src/rules/media.test.ts",
      "packages/lint/src/rules/slideshow.test.ts",
      "packages/lint/src/rules/textures.test.ts",
      "packages/lint/src/hyperframeLinter.test.ts",
      // slideshowPanelHelpers.ts: setSlideNotes/addFragment/addHotspot share an
      // intentional parallel shape (signature + mapSlidesIn → exists-check →
      // map/append); the per-slide mutation differs, so a shared abstraction
      // would obscure more than it dedupes.
      "packages/studio/src/components/panels/slideshowPanelHelpers.ts",
      // SlideshowPanel.test.ts: parallel arrange/act/assert test cases — collapsing
      // them would hurt readability of what each case verifies.
      "packages/studio/src/components/panels/SlideshowPanel.test.ts",
      // hyperframes-player.test.ts: parallel arrange/act/assert test cases verifying
      // distinct behaviors (same-origin vs realm media, audio-locked permutations,
      // seek bridge variants). Each case is self-contained for readability;
      // extracting the iframe / mock-audio setup helpers would over-couple
      // unrelated scenarios under a shared fixture.
      "packages/player/src/hyperframes-player.test.ts",
      // present.ts mirrors play.ts's server startup + console-output block. The
      // shared low-level pieces (resolve*/injectRuntime/listenOnFreePort) are in
      // utils/compositionServer.ts; the remaining clone is per-command logging text
      // (different labels/help lines) — extracting it would over-abstract.
      "packages/cli/src/commands/present.ts",
      // skillsManifest.test.ts: parallel arrange/act/assert cases for locateInstall
      // (project vs global scope, per-agent host conventions, claude-code priority).
      // Each case seeds a dir then asserts the resolved location/agent; collapsing
      // the shared seed/assert shape would obscure what each scope/host verifies.
      "packages/cli/src/utils/skillsManifest.test.ts",
      // skills.test.ts: parallel prune cases (removed-in-global vs project, non-slug
      // rejection, --source/--dir plumbing) share a mock-checkSkills → runSkillsUpdate
      // → assert-remove-spawn shape; each verifies a distinct prune behavior, so
      // extracting the shared scaffold would obscure what each case asserts.
      "packages/cli/src/commands/skills.test.ts",
      // figma test files: freeze.test.ts and manifest.test.ts share a common
      // arrange/act/assert setup preamble (file creation + test dir handling) that
      // is minimal boilerplate; collapsing it into a shared fixture would reduce
      // readability of each test's independent setup.
      "packages/core/src/figma/freeze.test.ts",
      "packages/core/src/figma/manifest.test.ts",
      // layout-audit.browser.test.ts: parallel arrange/act/assert cases per audit
      // rule (overflow / overlap / occlusion) that each install their own mocked
      // geometry + computed-style before asserting. The clone groups are this
      // pre-existing per-rule scaffold; adding a clip-path case shifts lines and
      // re-flags it. Collapsing the per-rule installers would obscure each case.
      "packages/cli/src/commands/layout-audit.browser.test.ts",
      // gsapParserAcorn.motionEval.test.ts: parallel arrange/act/assert cases for
      // the staggered-collection honesty pass (.from reveal vs .to landing on the
      // rest pose). Each asserts a distinct keyframe shape; collapsing the shared
      // parse/keyframes-extraction scaffold would obscure what each case verifies.
      "packages/core/src/parsers/gsapParserAcorn.motionEval.test.ts",
      // Studio UX-review sweep (148 findings fixed across ~90 studio files):
      // heavily-edited files re-flag line-shifted inherited complexity, and the
      // new small handlers (a11y keydown/menu/dialog/error-state paths, mostly
      // 5-6 cyclomatic) trip the CRAP threshold absent coverage data. Reviewed
      // individually in the studio-ux PR stack rather than refactored here.
      "packages/studio/src/player/components/TimelineClipDiamonds.test.tsx",
      "packages/studio/src/hooks/useFileManager.ts",
      "packages/studio/src/captions/hooks/useCaptionSync.ts",
      "packages/studio/vite.adapter.ts",
      "packages/studio/src/components/sidebar/AudioRow.tsx",
      "packages/studio/src/components/sidebar/AssetsTab.tsx",
      "packages/studio/src/components/editor/propertyPanelFill.tsx",
      "packages/studio/src/captions/store.ts",
      "packages/studio/src/captions/components/CaptionOverlay.tsx",
      "packages/cli/src/server/studioServer.ts",
      // Sub-composition html/body scoping fix: inlineSubCompositions.ts has a
      // pre-existing head-vs-content script-extraction clone, and the scoping
      // test file has pre-existing parallel arrange/act/assert cases. Adding the
      // scopeRootSelectors handling shifts lines and re-flags both.
      "packages/core/src/compiler/inlineSubCompositions.ts",
      "packages/core/src/compiler/compositionScoping.test.ts",
    ],
  },
  "health": {
    // useGsapTweenCache.ts: pre-existing large React-effect hooks (the populate
    // and runtime-scan effects, the per-element animations memo) whose
    // complexity pre-dates the computed-timeline work. Exempted at file level
    // rather than refactored as scope creep.
    "ignore": [
      // TEMP(studio-dnd): coexistence-window complexity flare (inherited/CRAP-no-coverage);
      // removed by studio-dnd/pr22 when the final config lands.
      "packages/studio/src/player/hooks/useTimelineSyncCallbacks.ts",
      "packages/studio/src/components/editor/CanvasContextMenu.tsx",
      "packages/studio/src/components/editor/canvasContextMenuZOrder.test.ts",
      "packages/studio/src/player/components/timelineCollision.test.ts",
      "packages/studio/src/player/components/timelineStackingSync.test.ts",
      // sourcePatcher.ts: resolveSourceFile / splitInlineStyleDeclarations /
      // patch*InTag pre-date this PR; only the PatchOperation type gained two
      // optional fields, but the line-shift fingerprint re-flags the inherited
      // complexity.
      "packages/studio/src/utils/sourcePatcher.ts",
      // timeline.ts: collectRuntimeTimelinePayload (CRITICAL) pre-dates this PR;
      // only an import line changed here (slideshow/sceneId → slideshow/index),
      // but the line-shift fingerprint makes fallow re-flag inherited complexity.
      "packages/core/src/runtime/timeline.ts",
      // sceneId.ts: trivial 5-cyclomatic guard, moved verbatim from
      // packages/core/src/slideshow/ into parsers; flagged only because the move
      // makes fallow treat it as a fresh finding.
      "packages/parsers/src/slideshow/sceneId.ts",
      // assetPaths.ts / rewriteSubCompPaths.ts: pure URL/asset-path helpers moved
      // verbatim from packages/core/src/compiler/ into parsers. The move makes
      // fallow score them as fresh (high CRAP = inherited complexity with no
      // coverage mapping yet); the logic is unchanged.
      "packages/parsers/src/assetPaths.ts",
      "packages/parsers/src/rewriteSubCompPaths.ts",
      // gsapParser.ts: the recast/babel GSAP writer is a 2500-line legacy parser;
      // moved from packages/core/src/parsers/ — same complexity rationale.
      "packages/parsers/src/gsapParser.ts",
      // htmlParser.ts has pre-existing complexity (moved from packages/core).
      "packages/parsers/src/htmlParser.ts",
      // studio-server files: pre-existing complexity (moved from packages/core/src/studio-api/).
      // files.ts: executeGsapMutationRecast/Acorn are CRITICAL; excluded as files.ts
      // was already in health.ignore at the old path (packages/core/src/studio-api/routes/files.ts).
      "packages/studio-server/src/routes/files.ts",
      "packages/studio-server/src/routes/render.ts",
      "packages/studio-server/src/routes/thumbnail.ts",
      "packages/studio-server/src/helpers/manualEditsRenderScript.ts",
      "packages/studio-server/src/helpers/studioMotionRenderScript.ts",
      "packages/studio-server/src/helpers/subComposition.ts",
      // lint rule implementations and project linter: pre-existing complexity
      // (moved from packages/core/src/lint/). File-level exemption avoids the
      // line-shift fingerprint problem for inherited findings.
      "packages/lint/src/rules/media.ts",
      "packages/lint/src/rules/textures.ts",
      "packages/lint/src/rules/gsap.ts",
      "packages/lint/src/project.ts",
      // SlideshowPanel.tsx: top-level editor panel that wires several independent
      // sections (slides/inspector/branches/hotspot). Its cyclomatic count comes
      // from that fan-out; splitting it would scatter shared state without
      // reducing real complexity. File-level exemption (not an inline comment)
      // avoids the line-shift fingerprint problem noted above.
      "packages/studio/src/components/panels/SlideshowPanel.tsx",
      // play.ts / present.ts: CLI command entrypoints whose cyclomatic count is
      // browser/arg validation + server wiring (same shape as preview.ts). The
      // serving logic is factored into utils/compositionServer.ts; the remaining
      // body is linear validation that reads clearly inline.
      "packages/cli/src/commands/play.ts",
      "packages/cli/src/commands/present.ts",
      // sync-agent-dirs.ts: a build-time codegen that regex-parses upstream
      // agents.ts. parseAgents/resolveGlobalExpr are branchy by nature (literal
      // vs base-var args, validation throws) but small and well-tested via the
      // generated table's shape test; this is dev tooling, not shipped runtime.
      "packages/cli/scripts/sync-agent-dirs.ts",
      // Files modified only for import-path updates (one-line changes to switch
      // from @hyperframes/core/* subpaths to the new packages). Their complexity
      // is pre-existing; the line-shift fingerprint problem makes fallow treat
      // the violations as new even though no logic changed.
      "packages/cli/src/server/studioServer.ts",
      "packages/core/src/core.types.ts",
      "packages/core/src/generators/hyperframes.ts",
      "packages/producer/src/services/htmlCompiler.ts",
      "packages/studio/src/hooks/gsapRuntimeBridge.ts",
      "packages/studio/src/hooks/gsapShared.ts",
      "packages/studio/src/hooks/gsapDragPositionCommit.ts",
      "packages/studio/src/hooks/gsapKeyframeCacheHelpers.ts",
      "packages/studio/vite.config.ts",
      "packages/cli/src/commands/lint.ts",
      "packages/cli/src/commands/preview.ts",
      "packages/cli/src/commands/publish.ts",
      "packages/cli/src/server/studioServer.ts",
      // set-version.ts: compareSemver helper has pre-existing complexity from
      // semver string parsing logic; line-shift fingerprint problem from new
      // packages added to PACKAGES array makes fallow treat it as new.
      "scripts/set-version.ts",
      // gsapRuntimeReaders.ts: pre-existing complexity in readAllAnimatedProperties;
      // line-shift fingerprint from import-path updates triggers the violation.
      "packages/studio/src/hooks/gsapRuntimeReaders.ts",
      // In-page audit scripts: single large browser-side IIFE wrappers
      // (auditLayout/__contrastAudit) with pre-existing CRITICAL helpers
      // (textOverflowFixHint, selectorFor, the WCAG walk). Adding the small
      // clip-path probe helpers shifts every function below it, so the line-shift
      // fingerprint re-flags inherited complexity even though the new helpers are
      // all at the lowest tier (<=5 cyclomatic).
      "packages/cli/src/commands/layout-audit.browser.js",
      "packages/cli/src/commands/contrast-audit.browser.js",
      // lottie.ts: the flagged `seek` handler (lottie-web/dotLottie dual-API
      // dispatch, unchanged by the duration-auto-inference work in this PR)
      // pre-dates this PR's scope. New functions added earlier in the file
      // (getInferredDurationSeconds + helpers) shifted its line numbers,
      // breaking fallow's inherited-detection fingerprint. File-level
      // exemption avoids the line-shift problem for this inherited finding.
      "packages/core/src/runtime/adapters/lottie.ts",
      // info.ts: the flagged `run` command handler pre-dates the keyframes-cli
      // PR; that PR only added the orientation()/durationFromHtml() helpers and
      // swapped a few `maxEnd` reads for the new `duration` variable, without
      // adding branches. The line-shift fingerprint re-flags the inherited
      // complexity even though the logic is unchanged.
      "packages/cli/src/commands/info.ts",
      // gsapParserAcorn.ts: the flagged `sameMemberAccess` (structural equality
      // of two member-access nodes) pre-dates this PR's motion-eval work
      // (added in #1760, unchanged since). The new const-folding / set-seeding /
      // label-position code added earlier in the file shifted its line number,
      // so the line-shift fingerprint re-flags this inherited finding.
      "packages/parsers/src/gsapParserAcorn.ts",
      // isFigmaManifestRecord: type guard with 19 cyclomatic due to chained
      // field validation (id/type/path/source types + value shape guards).
      // This is the correct shape for a discriminating type guard; refactoring
      // into smaller guards would obscure the unified validation contract.
      "packages/core/src/figma/manifest.ts",
      // Studio UX-review sweep (148 findings fixed across ~90 studio files):
      // heavily-edited files re-flag line-shifted inherited complexity, and the
      // new small handlers (a11y keydown/menu/dialog/error-state paths, mostly
      // 5-6 cyclomatic) trip the CRAP threshold absent coverage data. Reviewed
      // individually in the studio-ux PR stack rather than refactored here.
      "packages/studio/src/App.tsx",
      "packages/studio/src/captions/components/CaptionAnimationPanel.tsx",
      "packages/studio/src/captions/components/CaptionOverlay.tsx",
      "packages/studio/src/captions/components/CaptionOverlayUtils.ts",
      "packages/studio/src/captions/components/CaptionPropertyPanel.tsx",
      "packages/studio/src/captions/components/shared.tsx",
      "packages/studio/src/captions/hooks/useCaptionSync.ts",
      "packages/studio/src/components/AskAgentModal.tsx",
      "packages/studio/src/components/editor/BlockParamsPanel.tsx",
      "packages/studio/src/components/editor/DomEditOverlay.tsx",
      "packages/studio/src/components/editor/FileTree.tsx",
      "packages/studio/src/components/editor/FileTreeNodes.tsx",
      "packages/studio/src/components/editor/LayersPanel.tsx",
      "packages/studio/src/components/editor/MotionPathNode.tsx",
      "packages/studio/src/components/editor/PropertyPanel.tsx",
      "packages/studio/src/components/editor/propertyPanelFont.tsx",
      "packages/studio/src/components/editor/propertyPanelMediaSection.tsx",
      "packages/studio/src/components/editor/propertyPanelStyleSections.tsx",
      "packages/studio/src/components/editor/Transform3DCube.tsx",
      "packages/studio/src/components/LintModal.tsx",
      "packages/studio/src/components/MediaPreview.tsx",
      "packages/studio/src/components/nle/NLELayout.tsx",
      "packages/studio/src/components/nle/NLEPreview.tsx",
      "packages/studio/src/components/sidebar/AudioRow.tsx",
      "packages/studio/src/components/sidebar/BlocksTab.tsx",
      "packages/studio/src/components/sidebar/CompositionsTab.tsx",
      "packages/studio/src/components/sidebar/LeftSidebar.tsx",
      "packages/studio/src/components/storyboard/StoryboardLoaded.tsx",
      "packages/studio/src/components/StudioPreviewArea.tsx",
      "packages/studio/src/components/StudioRightPanel.tsx",
      "packages/studio/src/components/StudioToast.tsx",
      "packages/studio/src/components/ui/Tooltip.tsx",
      "packages/studio/src/components/ui/useDialogBehavior.ts",
      "packages/studio/src/hooks/useAppHotkeys.ts",
      "packages/studio/src/hooks/useCaptionDetection.ts",
      "packages/studio/src/hooks/useFileManager.ts",
      "packages/studio/src/hooks/useFrameCapture.ts",
      "packages/studio/src/hooks/usePanelLayout.ts",
      "packages/studio/src/player/components/menuKeyboardNav.ts",
      "packages/studio/src/player/components/Timeline.tsx",
      "packages/studio/src/player/components/TimelineCanvas.tsx",
      "packages/studio/src/player/components/TimelineClip.tsx",
      "packages/studio/src/player/components/TimelineClipDiamonds.tsx",
      // Sub-composition html/body scoping fix: these files carry pre-existing
      // CRITICAL/HIGH functions (inlineSubCompositions, bundleToSingleHtml,
      // mountCompositionContent/loadExternalCompositions, scopeSelector/
      // replaceAuthoredRootIdSelectors) that pre-date this PR. The change only
      // threads a scopeRootSelectors option through the existing scoping calls;
      // the line-shift fingerprint re-flags the inherited complexity.
      "packages/core/src/compiler/compositionScoping.ts",
      "packages/core/src/compiler/inlineSubCompositions.ts",
      "packages/core/src/compiler/htmlBundler.ts",
      "packages/core/src/runtime/compositionLoader.ts",
    ],
  },
}
