.agents/skills/frontend-large-feature-architecture/references/big-feature-rules.md
Use these rules when a feature keeps growing and the instinct is to add one more state variable, prop, callback, or effect to the same component.
Here, "controller" means a component or hook that owns feature logic: state, effects, data loading, subscriptions, actions, and derived data. Some controller code is necessary. The failure mode is one controller owning too many changing responsibilities and waking too much UI.
actions/*.ts or store actions.useState initializer, not
useMemo. The store is a per-mount instance, not a render-time derived
value.Most large frontend features are not yet in the ideal shape. Traces, observations, experiments, prompts, evals, datasets, and session views all have some controller-heavy surfaces. Do not copy an existing large component just because it works today. Treat it as a migration candidate and move it one state/action/data-preparation boundary at a time.
For the step-by-step path, read controller-migration.md.
A good big-feature PR is intentionally incomplete. It should change one semantic interaction and keep behavior stable: one selection boundary, one action workflow, one pure data-preparation helper, or one render boundary.
Do not bundle file reorganization, state extraction, visual changes, and behavior fixes in the same PR unless the user explicitly asks for that scope. When a reorganization is needed, prefer a rename-only PR first or a later follow-up PR.
Effects are for subscriptions, observers, imperative third-party APIs, one-time initialization, and cleanup. Keep them in containers or feature hooks, not view components. If an effect writes state repeatedly, make the store action idempotent.
Complex actions should be callable without rendering a component. Put workflows
in actions/*.ts or named store actions. Components wire hooks and pass
dependencies; actions own the workflow.
await applyBulkAction({
store,
queryClient,
projectId,
});
Actions must not call React hooks. Pass hook results, query helpers, the local store instance, or narrow callback dependencies into the action. If an action needs substantial data preparation, export a pure helper next to it so the transformation can be tested independently.
Do not pass twenty props through the tree so a button can do feature-level work, and do not leave complex workflows inline in a page controller because that controller happened to have all dependencies in scope.