diff --git a/apps/app/.eslintrc.cjs b/apps/app/.eslintrc.cjs
index 5d74d343..ee51fb29 100644
--- a/apps/app/.eslintrc.cjs
+++ b/apps/app/.eslintrc.cjs
@@ -306,7 +306,13 @@ module.exports = {
// same `type` so both src/components/forms/** and src/components/Icon.vue
// are captured before the generic `components` catch-all.
{ type: 'components-foundation', pattern: 'src/components/forms/**' },
- { type: 'components-foundation', pattern: 'src/components/Icon.vue' },
+ // mode:'file' is REQUIRED for a single-file pattern. Without it
+ // eslint-plugin-boundaries matches in the default 'folder' mode,
+ // so 'src/components/Icon.vue' never matches and Icon.vue falls
+ // through to the generic `components` catch-all below — breaking
+ // the sanctioned components-v2 → Icon bridge (RFC AD-G5). The
+ // forms/** entry above is a folder glob so it is unaffected.
+ { type: 'components-foundation', pattern: 'src/components/Icon.vue', mode: 'file' },
{ type: 'components-v2', pattern: 'src/components-v2/**' },
{ type: 'components', pattern: 'src/components/**' },
{ type: 'layouts', pattern: 'src/layouts/**' },
diff --git a/apps/app/tests/unit/boundaries-v2.spec.ts b/apps/app/tests/unit/boundaries-v2.spec.ts
index e50ec52a..8b1b7be7 100644
--- a/apps/app/tests/unit/boundaries-v2.spec.ts
+++ b/apps/app/tests/unit/boundaries-v2.spec.ts
@@ -38,6 +38,18 @@ describe('boundaries — v2 zones', () => {
expect(errs).toHaveLength(0)
})
+ it('allows components-v2 → components-foundation (Icon.vue bridge, single-file mode:file)', async () => {
+ // Regression lock: the single-file element needs mode:'file' or
+ // Icon.vue falls through to the generic `components` catch-all and
+ // every v2 shell component's Icon import breaks (RFC AD-G5 bridge).
+ const errs = await boundaryErrors(
+ 'src/components-v2/layout/SidebarNav.vue',
+ '',
+ )
+
+ expect(errs).toHaveLength(0)
+ })
+
it('allows components-v2 → components-foundation (FormField bridge)', async () => {
const errs = await boundaryErrors(
'src/components-v2/forms/Demo.vue',