Load local rules only where they apply. Keep shared project instructions short enough to read.
Add "Rules by file path" from ntent to this repo.
Fetch https://ntent.app/r/f/path-scoped-rules as plain text. Write it verbatim to .claude/rules/copy-a-sibling.md. Then one file per concern, named after the rule. Then make exactly these edits and no others: It is a template. Set the paths it applies to and write the rule in this repo’s own terms. It needs AGENTS.md. If this repo does not have it, stop and tell me.
Then check it: Open a file the rule’s paths cover and ask the assistant to state the rule. It answers without being shown the file.Reads https://ntent.app/r/f/path-scoped-rules
Read the code
copy-a-sibling.md.claude/rules/copy-a-sibling.md · one file per concern, named after the rule
67 lines
---
title: Copy the nearest sibling before writing a new screen
paths:
- "src/app/**/*.tsx"
- "src/components/**/*.tsx"
---
# Copy the nearest sibling before writing a new screen
Before building a new page, panel, dialog or empty state, open the nearest
existing one of the same kind and copy its structure. No check catches an
assembly that is wrong; every value in it is legal on its own. This is the
cheapest rule in the playbook and the one most often skipped, because skipping
it is invisible until a batch of screens has already shipped.
## Incorrect
A settings page written from the description alone. Every token is real, every
string is a key, lint passes — and the page puts its save control in a place no
other settings page in the product puts it, groups fields under headings nothing
else uses, and invents an empty state.
```tsx
export default function NotificationSettings() {
return (
<div className="p-6">
<div className="flex justify-end">
<Button>Save</Button>
</div>
<h2 className="text-lg">Preferences</h2>
{rows.length === 0 && <p>Nothing here yet.</p>}
{/* ...fields... */}
</div>
)
}
```
## Correct
The same page, built by opening `src/app/settings/profile/page.tsx` first and
keeping its shape: the same page wrapper, the same section primitive, the same
footer placement for the commit action, the same empty state component.
```tsx
import { SettingsPage, SettingsSection, EmptyState } from '@/components/settings'
export default function NotificationSettings() {
return (
<SettingsPage title={t('settings.notifications.title')}>
<SettingsSection title={t('settings.notifications.channels')}>
{rows.length === 0 ? <EmptyState kind="settings" /> : rows.map(renderRow)}
</SettingsSection>
{/* SettingsPage owns the footer and the save control, as it does everywhere else */}
</SettingsPage>
)
}
```
The pull request says which sibling it copied. That sentence is the whole
enforcement mechanism, and it costs the author nothing to write.
## Reference
- The judgement chapter, on why this section exists and how to add to it.
- Extend it to everything with a sibling: before adding a dialog, open the
nearest sibling dialog; before a route handler, the nearest route handler.
Success check: Open a file the rule’s paths cover and ask the assistant to state the rule. It answers without being shown the file.