Skip to content

feat(agents): add AGENTS.md knowledge system and rnmacos-organize-knowledge skill - #3157

Merged
Jason Morse (JasonVMo) merged 4 commits into
mainfrom
user/jasonvmo/agent-knowledge
Nov 10, 2026
Merged

Jason Morse (JasonVMo) merged 4 commits into
mainfrom
user/jasonvmo/agent-knowledge

Conversation

@JasonVMo

@JasonVMo Jason Morse (JasonVMo) commented Oct 29, 2026 •

Copy link
Copy Markdown

Summary:

Coding agents working in this fork have no shared, fork-specific guidance. Nothing tells them how to tag fork diffs for clean upstream merges, which files the fork owns, how CI builds RNTester-macOS, or which yarn commands to run. Ad hoc instruction files also tend to duplicate and contradict each other over time.

This PR adds a small, validated knowledge system:

  • AGENTS.md is the single instruction entry point. All fork content sits in one [macOS] block, so upstream AGENTS.md changes merge cleanly. .github/copilot-instructions.md just points to it.

  • .agents/knowledge/ holds one topic per concern, each with front matter (id, summary, load_when, sources, rules). Topics are listed in taxonomy.yaml and in a generated index.md, so agents load only the topics they need. First topics:

    • fork.diff-tags and fork.ownership
    • tooling.commands and tooling.format-lint
    • testing.rntester-macos
    • process.pull-requests
    • evals.knowledge-checks
  • .claude/skills/rnmacos-organize-knowledge keeps new instructions placed, deduplicated, and indexed. The rnmacos- prefix avoids collisions with skills upstream may add. The skill stays short, and detail lives in references/.

  • .agents/knowledge/tools/knowledge.mts generates the index and checks:

    • structure and front matter
    • links and source paths
    • yarn commands
    • duplicate rules
    • size budgets
    • [macOS] fork-block rules

    microsoft-pr.yml runs the checker, its tests, and markdownlint.

This is agent tooling specific to the fork, so there's no corresponding facebook/react-native PR. It's the base of a stack; #3158 builds the macOS accessibility topics on it.

Test Plan:

Run at the head of this branch (447e205e55), with Node 24.18.0:

Command Result
node .agents/knowledge/tools/knowledge.mts check --ci Passed: 20 files checked: 0 errors, 0 warnings.
node --test .agents/knowledge/tools/knowledge.test.mts Passed: 21 pass, 0 fail
yarn markdownlint-cli2 --no-globs AGENTS.md ".agents/knowledge/**/*.md" ".claude/skills/rnmacos-*/**/*.md" .github/copilot-instructions.md Passed: Summary: 0 error(s)
yarn format-check Passed (exit 0)

The new CI steps in microsoft-pr.yml run the first three commands. No native code changes, so no native build was needed.

@Saadnajmi

Copy link
Copy Markdown
Collaborator

Copilot Could you locally use Matt Pococks retro skill, go through my comments on PRs (in particular, ones doing the big version updates) and make some suggestions (as comments on this PR or the other one Jason has open) for more knowledge?

Copilot AI commented Oct 29, 2026

Copy link
Copy Markdown

Copilot Could you locally use Matt Pococks retro skill, go through my comments on PRs (in particular, ones doing the big version updates) and make some suggestions (as comments on this PR or the othe...

The retro skill wasn’t installed in this environment, so I read Matt Pocock’s public retro skill and applied its categories to your comments on #2824 and #3022 (the large 0.83 syncs), plus #3099. Two durable knowledge candidates emerged:

  1. Add a fork.upstream-sync checklist for large version merges. Diff tags explain how to mark fork changes, but not how to decide what to forward-port. chore(0.83): prepare stable 0.83.0 with React Native 0.83.10 #3022 and chore: merge up to 0.83-stable branch #2824 suggest classifying local fixes as already present upstream/later in the merge stack, stable-only, applicable to main, or inapplicable because the target has no corresponding implementation; verify branch-specific config and cite the evidence. For example, Changesets baseBranch differs between 0.83-stable and main, and the RCTDevLoadingView fix had no corresponding main callsite.
  2. Consider adding an imperative focus check to feat(agents): add macOS accessibility knowledge topics #3158’s testing.ax-probes procedure: exercise JS ref.current.focus()/blur() separately from Tab/Shift-Tab. In chore: merge up to 0.83-stable branch #2824 you explicitly flagged that focus path as something an upstream refactor might affect; the new probe procedure currently covers keyboard focus, not the JS ref path.

The first looks like a new topic; the second could be a small addition to testing.ax-probes if you think it belongs in scope.

Comment thread .agents/knowledge/taxonomy.yaml Resolved

@Saadnajmi Saad Najmi (Saadnajmi) left a comment

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.

Left some comments, mostly ok. I feel I won't "feel" the workflow till I start using it so I'm more wanting to just try it and iterate I think

…wledge skill

Add a structured, validated knowledge system for coding agents:

- AGENTS.md is the single instruction entry point; its fork content lives
  in one [macOS] block so upstream AGENTS.md changes merge cleanly.
  .github/copilot-instructions.md only points to it.
- .agents/knowledge/ holds one topic per concern (fork, tooling, testing,
  process, evals), a taxonomy.yaml, and a generated index.md.
- .claude/skills/rnmacos-organize-knowledge keeps new instructions placed,
  deduplicated, and indexed, with detail in references/.
- .agents/knowledge/tools/knowledge.mts checks structure, links, source
  paths, yarn commands, duplicates, budgets, and fork-block rules, and
  generates the index. CI runs it, its tests, and markdownlint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…inks

Skills now live in .agents/skills, which Copilot and Codex both discover.
.claude/skills/<name> is a relative symlink for Claude Code, and KC-08
requires that link and rejects real files or dangling links there.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JasonVMo
Jason Morse (JasonVMo) force-pushed the user/jasonvmo/agent-knowledge branch from daff2ab to 3ef471e Compare November 10, 2026 16:44
@JasonVMo
Jason Morse (JasonVMo) merged commit 06aadf4 into main Nov 10, 2026
28 checks passed
@JasonVMo
Jason Morse (JasonVMo) deleted the user/jasonvmo/agent-knowledge branch November 10, 2026 23:02
Jason Morse (JasonVMo) added a commit that referenced this pull request Nov 10, 2026
<!-- Thanks for submitting a pull request! We appreciate you spending
the time to work on these changes. Please provide enough information so
that others can review your pull request. The four fields below are
mandatory. -->

<!-- This fork of react-native provides React Native for macOS for the
community. It also contains some changes that are required for usage
internal to Microsoft. We are working on reducing the diff between
Facebook's public version of react-native and our
microsoft/react-native-macos fork. Long term, we want this fork to only
contain macOS concerns and have the other iOS and Android concerns
contributed upstream.

If you are making a new change then one of the following should be done:
- Consider if it is possible to achieve the desired behavior without
making a change to microsoft/react-native-macos. Often a change can be
made in a layer above in facebook/react-native instead.
- Create a corresponding PR against
[facebook/react-native](https://github.com/facebook/react-native)
**Note:** Ideally you would wait for Facebook feedback before submitting
to Microsoft, since we want to ensure that this fork doesn't deviate
from upstream.
-->

## Summary:

> Stacked on #3157. Review only the top commit (`fd13876983`).

macOS accessibility in this fork depends on AppKit behavior that isn't
obvious from headers. For example, a getter can return `AXUnknown` while
AX clients see a different role. Paper and Fabric also resolve roles
differently. Agents and contributors keep rediscovering these details,
or they copy iOS patterns that don't hold on macOS. This PR records the
verified behavior as knowledge topics. It also adds a repeatable way to
check what VoiceOver and other AX clients actually see.

New topics, loaded from a new `AGENTS.md` row for accessibility, focus,
or Tab-order work:

- **`a11y.appkit`:** AppKit AX behavior observed out of process. Rules:
  - Never copy an unset role.
  - Read a control's default role from its cell.
  - Gate state attributes.
  - Target the AX element.
  - Verify out of process.
- **`a11y.roles`:** Role resolution in Paper and in Fabric, side by
side. Rules:
- Resolve `role`, then `accessibilityRole`, then the element's default
role.
  - Restore the default role when both props are unset.
  - Don't import Paper's `RCTConvert` into Fabric.
- **`a11y.state`:** How `accessibilityState` maps to AX attributes and
value words. Rules:
  - Stop advertising state that's been removed.
  - Advertise `AXPress` only when the element handles it.
- **`a11y.text-input`:** `editable={false}` semantics on every platform,
plus the single-line (`RCTUITextField`) and multiline
(`RCTWrappedTextView`) backings.
- **`a11y.keyboard`:** `focusable`, first responder, and the key view
loop, including why a Fabric TextInput takes two Tab stops on `main`.
- **`testing.ax-probes`:** A procedure with a small Swift AX probe. It
dumps elements by `testID`, reports focus, and clicks Fabric views, all
driven with `osascript` keys.

The topics state facts and the open questions in #3136 without
recommending how to resolve them. They watch #3136, so they'll be
updated when it lands.

This PR also corrects `testing.rntester-macos`. `yarn start` fails under
the repository's `nodeLinker: pnpm`, because Yarn resolves the
`react-native-macos` binary under `.yarn/__virtual__`, which the pnpm
linker never creates. Running `cli.js` directly without `NODE_PATH`
starts Metro without its `/status` route, so the app reports "No script
URL provided". The topic now gives a command that works.

Knowledge files only, with no product code changes, so there's no
corresponding facebook/react-native PR.

## Test Plan:

Environment: macOS 27.2 (26B123), Xcode 26.4.1, Node 24.18.0. Run at
`fd13876983`.

**Knowledge checks (the steps CI runs):**

| Command | Result |
| --- | --- |
| `node .agents/knowledge/tools/knowledge.mts check --ci` | Passed: `26
files checked: 0 errors, 0 warnings.` |
| `node --test .agents/knowledge/tools/knowledge.test.mts` | Passed: 21
pass, 0 fail |
| `yarn markdownlint-cli2 --no-globs AGENTS.md
".agents/knowledge/**/*.md" ".claude/skills/rnmacos-*/**/*.md"
.github/copilot-instructions.md` | Passed: `Summary: 0 error(s)` |
| `yarn format-check` | Passed (exit 0) |

**Fact verification:**

- Checked every code claim against `main`. The `asserts` front matter
keeps key lines tied to source, and I confirmed it's enforced: a
deliberately broken assert produced a warning.
- Verified AppKit claims with the probe against small standalone AppKit
apps: `NSView`, `NSTextField`, and `NSTextView`, before and after
setting roles and state.

**Procedure verification in RNTester-macOS on `main`:**

| Step | Result |
| --- | --- |
| `RCT_NEW_ARCH_ENABLED=1 pod install` (Homebrew CocoaPods 1.17.0; local
Ruby couldn't `bundle install`), then `.ado/scripts/xcodebuild.sh
packages/rn-tester/RNTesterPods.xcworkspace macosx Debug RNTester-macOS
build` | `Build Succeeded` |
| `NODE_PATH="$PWD/node_modules" node ../react-native/cli.js start` from
`packages/rn-tester`, then `curl localhost:8081/status` |
`packager-status:running` (without `NODE_PATH`: `Cannot GET /status`) |
| `testing.ax-probes` procedure, run verbatim from a fresh launch |
Navigated APIs → Accessibility; `example_search role=AXTextField
enabled=1` |
| `ax dump` of the TextInput module | Both `secureTextEntry` inputs
report `role=AXUnknown enabled=1`, which matches the
`RCTCopyBackedTextInput` fact |
| Tab from `example_search` in the TextInput module, with
`autorecalculatesKeyViewLoop = YES` added to RNTester's `AppDelegate`
locally (not committed) | Focus alternates `AXScrollArea`,
`AXTextField`, `AXScrollArea`, `AXTextField`…; Shift-Tab returns to
`AXScrollArea`. This matches `a11y.keyboard` |
| Same Tab test without that change | Focus stays on `example_search`,
which matches the `a11y.keyboard.test-recalculated-loop` rule |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants