Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .agents/knowledge/evals/knowledge-checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
id: evals.knowledge-checks
summary: Catalog of the KC checks that knowledge.mts runs on agent knowledge files, with severity and how to fix each failure.
kind: eval
status: active
load_when: A knowledge check fails, or you are changing knowledge.mts or its checks
sources:
- .agents/knowledge/tools/knowledge.mts#runChecks
- .agents/knowledge/taxonomy.yaml#checks
- .github/workflows/microsoft-pr.yml#javascript-tests
verified: 2026-10-29
rules: [fix-not-suppress]
related: [tooling.format-lint]
---

<!-- @format -->

# Knowledge checks

Use when: `knowledge.mts check` reports a failure, or you change a check. Not for: writing conventions; see the organize skill's [conventions](../../skills/rnmacos-organize-knowledge/references/conventions.md).

## Rules

- **evals.knowledge-checks.fix-not-suppress:** Fix the content that fails a check. Change a check's severity in `taxonomy.yaml` only with maintainer approval, and record why in the PR.

## Catalog

Checks are errors unless `checks` in [taxonomy.yaml](../taxonomy.yaml) lowers them. CI runs `check --ci` on tracked files only.

| Check | What it enforces | Typical fix |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| KC-01 | Frontmatter on line 1, required topic keys, no `title`, pragma placement, exactly one H1, a `Use when:` line | Match the topic template |
| KC-02 | Topic and rule IDs are well formed, registered, unique, and not retired; `requires` and `related` resolve | Rename, register the domain, or add a redirect |
| KC-03 | Index tables and path pointers match a fresh generation | `knowledge.mts index --write` |
| KC-04 | Relative links and heading anchors resolve | Fix the path or heading |
| KC-05 | Cited sources and backticked repository paths exist (warning) | Update the citation |
| KC-06 | `yarn <name>` in code is a root script, root binary, or Yarn built-in, and doesn't pass arguments to a script that shadows a binary (warning) | Use a real command, `yarn exec <binary>`, or add it to `yarn_allow` |
| KC-07 | Size budgets; 80% warns | Split, or move detail to a reference |
| KC-08 | Skill name, prefix, description, frontmatter allowlist, reference depth, listing in `AGENTS.md`, and one `.claude/skills` symlink per skill | Follow the skill template |
| KC-09 | Copilot pointer links only to `AGENTS.md`; path pointers have valid `applyTo` globs | Regenerate pointers |
| KC-10 | No `@path` imports | Use a Markdown link |
| KC-11a | No exact duplicate bullets across knowledge files | Keep one copy and link to it |
| KC-11b | Near-duplicate text (advisory, `report --similar`) | Merge or link |
| KC-12 | `AGENTS.md` keeps upstream's first line and one fork block; no fork content in upstream-owned files | Move content into the block or a topic |
| KC-13 | `AGENTS.md` links the index; routes target active topics | Fix the route or link |
| KC-14 | Topic `asserts` hold against the repository (warning) | Re-verify the topic |
| KC-15 | Freshness: verification age and source changes (advisory, `report --stale`) | Re-verify and bump `verified` |

## Verify

```sh
node .agents/knowledge/tools/knowledge.mts check
node --test .agents/knowledge/tools/knowledge.test.mts
```
51 changes: 51 additions & 0 deletions .agents/knowledge/fork/diff-tags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
id: fork.diff-tags
summary: How to mark macOS changes in shared upstream files so merges and audits can find every fork diff.
kind: rules
status: active
load_when: Changing a file that upstream React Native also has, or adding a fork-only file
sources:
- docsite/docs/contributing/diffs-with-upstream.md
- .flowconfig:72-76
- .yarnrc.yml:9
- packages/react-native/ReactApple/Libraries/RCTUIKit/README.md:3
verified: 2026-10-28
rules: [tag-every-change, match-comment-syntax, keep-balanced, tag-new-files]
related: [fork.ownership]
---

<!-- @format -->

# Diff tags

Use when: you change a file that upstream also has, or you add a fork-only file. Not for: deciding who owns a path; see [fork.ownership](ownership.md).

The canonical syntax, with examples, is on the docsite page [How React Native macOS differs from React Native](../../../docsite/docs/contributing/diffs-with-upstream.md). This topic adds agent rules and observed exceptions.

## Rules

- **fork.diff-tags.tag-every-change:** Mark each macOS change in a shared file with `[macOS]` on one line, or `[macOS` … `macOS]` around a block, so `git grep "\[macOS"` finds every fork diff.
- **fork.diff-tags.match-comment-syntax:** Use the file's own comment syntax: `//` in Objective-C, C++, and JS; `#` in Ruby, YAML, and shell; `;` in `.flowconfig`; `<!-- [macOS] -->` in Markdown. Where a file already has tags, match them.
- **fork.diff-tags.keep-balanced:** Every `[macOS` block opener needs a `macOS]` closer. Count both before and after you edit.
- **fork.diff-tags.tag-new-files:** Tag a fork-only file once, near the top, instead of tagging each change in it.

## Facts

- `#if` blocks carry the tag on the directive. macOS-only code uses `#if TARGET_OS_OSX // [macOS` … `#endif // macOS]`. Original iOS-only code uses `#if !TARGET_OS_OSX // [macOS]` with a single-line tag, because the code inside is upstream's.
- `[visionOS]` marks visionOS diffs. Some lines carry both, such as `TARGET_OS_IOS // [macOS] [visionOS]` for APIs that exist only on iOS.
- On 2026-10-28, 675 tracked files contained `[macOS` and 31 contained `[visionOS`.
- `.flowconfig` and `.yarnrc.yml` open blocks with `[macOS] comment` rather than the docsite's `[macOS comment`. Prefer the docsite form in new code.

## Pitfalls

- Don't reformat, reorder, or rewrap upstream lines near your change; every extra changed line can conflict in the next merge.
- Remove a tag only when the code matches upstream again.
- Opener and closer counts can differ legitimately (for example, a tag inside a string). Treat a mismatch as a reason to read the file, not as proof of an error.

## Verify

```sh
git grep -n "\[macOS" -- path/to/file
grep -oE '\[macOS([^]]|$)' path/to/file | wc -l # block openers
grep -oE '(^|[^[])macOS\]' path/to/file | wc -l # block closers
```
48 changes: 48 additions & 0 deletions .agents/knowledge/fork/ownership.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
id: fork.ownership
summary: Which paths the fork owns, which it shares with upstream, and which it must never edit.
kind: rules
status: active
load_when: Adding a file, choosing where fork content goes, or editing configs that upstream also ships
sources:
- .agents/knowledge/taxonomy.yaml#upstream_owned
- docsite/docs/contributing/diffs-with-upstream.md
- https://github.com/react/react-native/blob/main/AGENTS.md
verified: 2026-10-29
rules:
[check-upstream-first, never-edit-upstream-owned, prefer-fork-owned-paths]
related: [fork.diff-tags]
---

<!-- @format -->

# Path ownership

Use when: you add a file, move fork content, or edit a file that upstream also ships. Not for: tag syntax; see [fork.diff-tags](diff-tags.md).

## Rules

- **fork.ownership.check-upstream-first:** Before you edit a path, find out whether upstream has it. If it does, the path is shared: keep the change small and tag it.
- **fork.ownership.never-edit-upstream-owned:** Never put fork content in the paths listed under `ownership.upstream_owned` in [taxonomy.yaml](../taxonomy.yaml). The knowledge checks (KC-12) reject `[macOS`, `rnmacos-`, and `.agents/knowledge` there.
- **fork.ownership.prefer-fork-owned-paths:** Put large macOS-only code and fork tooling in fork-owned paths, so merges never touch it.

## Facts

- Upstream is `react/react-native`, formerly `facebook/react-native`.
- **Fork-owned** paths don't exist upstream: `docsite/`, `.ado/`, `.github/workflows/microsoft-*.yml`, `packages/react-native-macos-init/`, `packages/react-native/ReactApple/Libraries/RCTUIKit/`, `*.macos.js` files, `.agents/`, and the `.claude/skills/rnmacos-*` symlinks.
- **Shared** paths exist in both repositories, including most of `packages/react-native/React/` and `packages/react-native/Libraries/`. Edit them with [diff tags](diff-tags.md).
- **Upstream-owned** paths are shared paths the fork never changes: `__docs__/` architecture notes and the shared lint and format configs.
- Upstream ships a root `AGENTS.md`. The fork's copy keeps upstream's `# React Native` first line and adds a single `[macOS` block, so the 0.88 merge touches as little as possible.

## Pitfalls

- Fork content in an upstream-owned file conflicts with every merge.
- A shared folder can hold fork-only files: `packages/react-native/ReactApple/` exists upstream, but its `RCTUIKit/` subfolder doesn't. Check the exact path.

## Verify

```sh
# Exits 0 if the path exists on upstream main.
gh api "repos/react/react-native/contents/<path>?ref=main" --silent
node .agents/knowledge/tools/knowledge.mts check
```
51 changes: 51 additions & 0 deletions .agents/knowledge/fork/upstream-sync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
id: fork.upstream-sync
summary: Classify local fixes from a version-sync branch before forwarding them to main.
kind: procedure
status: active
load_when: Reviewing a large upstream version merge or deciding which release fixes to forward-port to main
sources:
- docsite/docs/releases/minor-release.md
- https://github.com/microsoft/react-native-macos/pull/3022#discussion_r3719817893
- https://github.com/microsoft/react-native-macos/pull/3022#discussion_r3722730469
- https://github.com/microsoft/react-native-macos/pull/3099
verified: 2026-10-29
rules: [classify-each-fix, verify-target-branch, preserve-branch-config]
related: [fork.diff-tags, fork.ownership, process.pull-requests]
---

<!-- @format -->

# Forward-porting release fixes

Use when: you review local fixes on a version-sync branch and decide what belongs on `main`. Not for: merging upstream itself; follow the [minor-release procedure](../../../docsite/docs/releases/minor-release.md).

## Rules

- **fork.upstream-sync.classify-each-fix:** Classify every locally authored fix against the exact target branch; don't forward-port a whole release branch or infer applicability from a commit subject.
- **fork.upstream-sync.verify-target-branch:** Inspect the target branch's implementation and later merge branches before proposing a forward-port; cite the commit, file, or call site that supports the classification.
- **fork.upstream-sync.preserve-branch-config:** Keep release-specific configuration on its release branch and verify target-branch settings before copying config changes.

## Procedure

1. Identify the locally authored commits in the sync PR, separately from imported upstream history. Use the merge base and inspect the PR's local commits.
2. Classify each local fix as one of:
- Already present on `main`: cite the matching commit or implementation.
- Already fixed in a later merge branch: cite that branch and fix; don't duplicate it.
- Applicable to `main`: propose a separate forward-port PR, and note its dependencies or stack.
- Release-only: keep version bumps and branch-specific release configuration on the stable branch.
- Not applicable: the target has no corresponding file, implementation, or call site; don't invent one just to carry the patch.
3. Split commits that mix categories when needed. For each decision, inspect the target branch itself and any relevant later merge branch; don't treat an open PR as already merged.
4. Verify configuration against the target. For example, Changesets `baseBranch` is `origin/0.83-stable` on that stable branch and `origin/main` on `main`.
5. Run the relevant checks on each forward-port target. Report the classification, evidence, validation, and any unmerged follow-up.

## Facts

- The 0.83 sync review in [#3022](https://github.com/microsoft/react-native-macos/pull/3022) separated changes already in `main`, fixes to forward-port, stable-only changes, fixes already present in later merge branches, and changes with no matching implementation. The review also kept the stable Changesets base branch distinct from `main`.
- In [#3099](https://github.com/microsoft/react-native-macos/pull/3099), shared fixes were submitted separately to `main`; the review tracked that they were not yet merged rather than calling them landed.

## Pitfalls

- A fix present in a later `*-merge` branch may not belong on `main` yet; trace where the behavior first applies and whether it is already guarded.
- An open forward-port PR is not evidence that the fix has landed. Track its status and stack explicitly.
- A stable-only setting such as Changesets `baseBranch` can break `main` if copied without checking its branch-specific value.
42 changes: 42 additions & 0 deletions .agents/knowledge/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# react-native-macos agent knowledge

Start here when [AGENTS.md](../../AGENTS.md) doesn't answer your question. Open only the topics whose "Load when" matches your task, plus the topics they list under `requires`.

To add, change, move, or retire knowledge, use the [`rnmacos-organize-knowledge`](../skills/rnmacos-organize-knowledge/SKILL.md) skill. To search every knowledge home, run `node .agents/knowledge/tools/knowledge.mts find <terms>`.

Vocabulary, budgets, and routes are in [taxonomy.yaml](taxonomy.yaml). The tables below are generated by `knowledge.mts index --write`; don't edit them by hand.

## Topics

<!-- BEGIN GENERATED: topics -->

| Topic | Load when | Summary |
| --- | --- | --- |
| [evals.knowledge-checks](evals/knowledge-checks.md) | A knowledge check fails, or you are changing knowledge.mts or its checks | Catalog of the KC checks that knowledge.mts runs on agent knowledge files, with severity and how to fix each failure. |
| [fork.diff-tags](fork/diff-tags.md) | Changing a file that upstream React Native also has, or adding a fork-only file | How to mark macOS changes in shared upstream files so merges and audits can find every fork diff. |
| [fork.ownership](fork/ownership.md) | Adding a file, choosing where fork content goes, or editing configs that upstream also ships | Which paths the fork owns, which it shares with upstream, and which it must never edit. |
| [fork.upstream-sync](fork/upstream-sync.md) | Reviewing a large upstream version merge or deciding which release fixes to forward-port to main | Classify local fixes from a version-sync branch before forwarding them to main. |
| [process.pull-requests](process/pull-requests.md) | Writing a commit or PR title or body, adding a Changeset, or backporting to a stable branch | PR titles, the PR body template, Changesets, and backport conventions for react-native-macos. |
| [testing.rntester-macos](testing/rntester-macos.md) | Building, running, or debugging RNTester-macOS, or validating a native macOS change | Install Pods for and build RNTester-macOS the way CI does, then run it with Metro. |
| [tooling.commands](tooling/commands.md) | Choosing a command to install, build, test, lint, or format, or when a Yarn command fails | Yarn 4 setup and the root commands for building, testing, linting, and formatting react-native-macos. |
| [tooling.format-lint](tooling/format-lint.md) | Formatting or linting a file, or writing Markdown with frontmatter | Prettier pragma, markdownlint scope, and ESLint and Flow gaps for react-native-macos files, including agent knowledge files. |

<!-- END GENERATED: topics -->

## Skills

<!-- BEGIN GENERATED: skills -->

| Skill | Use when |
| --- | --- |
| [`rnmacos-organize-knowledge`](../skills/rnmacos-organize-knowledge/SKILL.md) | Record, update, move, or retire react-native-macos agent knowledge in AGENTS.md, .agents/knowledge topics, rnmacos-* skills, and path pointers. |

<!-- END GENERATED: skills -->

## Path routes

<!-- BEGIN GENERATED: routes -->

No path routes yet.

<!-- END GENERATED: routes -->
45 changes: 45 additions & 0 deletions .agents/knowledge/process/pull-requests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
id: process.pull-requests
summary: PR titles, the PR body template, Changesets, and backport conventions for react-native-macos.
kind: rules
status: active
load_when: Writing a commit or PR title or body, adding a Changeset, or backporting to a stable branch
sources:
- .github/PULL_REQUEST_TEMPLATE.md
- .github/workflows/microsoft-pr.yml#commitlint-lite
- .github/workflows/microsoft-pr.yml#check-changesets
- docsite/docs/contributing/backporting.md
- docsite/docs/contributing/versioning.md
verified: 2026-10-28
rules: [conventional-title, fill-template, changesets-for-stable]
related: [tooling.commands]
---

<!-- @format -->

# Pull requests

Use when: you write a PR title or body, add a Changeset, or backport a change. Not for: choosing which checks to run; see [tooling.commands](../tooling/commands.md).

## Rules

- **process.pull-requests.conventional-title:** Write PR titles as Conventional Commits, such as `fix(textinput): handle focus correctly`. CI lints the title with `@rnx-kit/commitlint-lite`.
- **process.pull-requests.fill-template:** Fill in the template's `## Summary:` and `## Test Plan:` sections. The Test Plan lists each exact command you ran with its result, plus screenshots for UI changes.
- **process.pull-requests.changesets-for-stable:** Add a Changeset with `yarn change` only when the PR targets a `*-stable` branch. PRs into `main` don't need one.

## Facts

- The template asks contributors to first consider fixing the problem upstream, or in a layer above react-native-macos.
- PR CI (`microsoft-pr.yml`) runs on PRs into `main`, `*-stable`, `release/*`, and `*-merge` branches.
- Backport branches are named `<version>/<branch>`, such as `0.81/fix-text-input`, and titles add the version to the scope, such as `fix(0.81, textinput): …`. The full procedure is in [Backporting](../../../docsite/docs/contributing/backporting.md).
- Minor versions track upstream React Native minor versions; patch versions differ.

## Pitfalls

- A PR from a `changeset-release/` branch is the version bump itself and skips the Changeset check.

## Verify
Comment on lines +37 to +41

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One pitfall is adding "macos" to scope. This is the macOS firk, so nearly all changes have macOS as scope.


```sh
yarn change:check
```
Loading
Loading