FSD Architecture
FSD Architecture
Section titled “FSD Architecture”The fsd_architecture metric evaluates core Feature-Sliced Design signals using your import graph and architecture.layers.
Metric ID
Section titled “Metric ID”fsd_architecture
What It Measures
Section titled “What It Measures”fsd.slice_cross_import_countfsd.slice_cross_import_ratiofsd.public_api_bypass_countfsd.shared_gravity_indexfsd.layer_jump_countfsd.layer_jump_ratiofsd.slice_cycle_countfsd.slices_analyzed_countfsd.edges_analyzed_countfsd.granularity_ok(1= enough graph granularity,0= grouping too coarse for slice checks)
It also emits detail tables:
fsd.slice_cross_imports_tablefsd.public_api_bypass_tablefsd.shared_hotspots_tablefsd.layer_jumps_tablefsd.slice_cycles_table
Required Configuration
Section titled “Required Configuration”fsd_architecture reads layer definitions from architecture.layers (not from shape for legacy).
architecture: layers: - name: app paths: ["src/app/**"] allowed_effects: [] can_depend_on: ["pages", "widgets", "features", "entities", "shared"]
- name: pages paths: ["src/pages/**"] allowed_effects: [] can_depend_on: ["widgets", "features", "entities", "shared"]
- name: widgets paths: ["src/widgets/**"] allowed_effects: [] can_depend_on: ["features", "entities", "shared"]
- name: features paths: ["src/features/**"] allowed_effects: [] can_depend_on: ["entities", "shared"]
- name: entities paths: ["src/entities/**"] allowed_effects: [] can_depend_on: ["shared"]
- name: shared paths: ["src/shared/**"] allowed_effects: [] can_depend_on: []
metrics: - id: fsd_architecture enabled: true config: fsd: slice_roots: ["src/features", "src/entities", "src/widgets", "src/pages"] shared_layer_names: ["shared"] public_api_files: ["index.ts", "index.tsx", "index.js", "index.jsx"] internal_segment_markers: ["model", "ui", "lib", "api", "config", "internal"] thresholds: max_slice_cross_import_ratio: 0.05 max_public_api_bypass_count: 0 max_shared_gravity_index: 0.25 max_layer_jump_ratio: 0.10 max_slice_cycle_count: 0CI Gate Example
Section titled “CI Gate Example”policy: invariants: - metric: fsd.slice_cross_import_ratio op: "<=" value: 0.05 message: "Cross-slice imports are too high"
- metric: fsd.public_api_bypass_count op: "==" value: 0 message: "Do not import slice internals directly"
- metric: fsd.layer_jump_ratio op: "<=" value: 0.10 message: "Layer jumps should stay rare"
- metric: fsd.slice_cycle_count op: "==" value: 0 message: "Slice-level cycles are not allowed"- If
fsd.granularity_ok = 0, increasedata.import_graph.group_depth(usually>= 3) so nodes include slice segments likesrc/features/auth/.... fsd.public_api_bypass_countusesoriginal_importwhen available and falls back to path-based heuristics otherwise.