AI Agent Configuration Overhaul#2287
Conversation
🦋 Changeset detectedLatest commit: 2944ef6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 24 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR overhauls the repository’s AI agent/skills setup by introducing skills-npm configuration, a prepare-time mirroring script for local skills into Claude Code’s discovery path, and a large set of new/expanded AGENTS/skill docs to codify subsystem invariants and ENS concepts.
Changes:
- Add
skills-npm+ a rootpreparehook to install npm skills and symlink local.agents/skills/*into.claude/skills/*. - Expand documentation: new/updated
AGENTS.mdacross apps/packages and skill docs (Omnigraph acceleration, ENS Namespaces, integration-test orchestration, datasource invariants). - Add a perf-testing escape hatch in ENSIndexer to disable ENSRainbow healing via
DISABLE_ENSRAINBOW_HEAL=true.
Reviewed changes
Copilot reviewed 30 out of 32 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| skills-npm.config.ts | Adds repo-wide skills-npm config for “universal” + “claude-code” agents. |
| scripts/link-local-skills.mjs | New script to mirror committed local skills into .claude/skills via symlinks. |
| pnpm-lock.yaml | Locks new dependencies (skills-npm) and updates override resolution metadata. |
| packages/integration-test-env/AGENTS.md | Documents integration-test stack bring-up contract and invariants. |
| packages/ensskills/skills/omnigraph/SKILL.md | Documents Protocol Acceleration behavior and 503/indexing-status contract. |
| packages/ensskills/skills/ens-protocol/SKILL.md | Defines ENS Namespace concept and updates reference table. |
| packages/ensskills/skills/ens-protocol/references/ensv1-and-ensv2.md | Adds ENS Namespaces section framing ENSv1/ENSv2 within a namespace. |
| packages/datasources/AGENTS.md | Documents datasource catalog invariants and cross-package contracts. |
| package.json | Adds prepare hook, skills-npm, and workspace devDependencies for enscli/ensskills. |
| docs/ensnode.io/AGENTS.md | Documents docs-site structure, formatting pipeline, and generation workflows. |
| context7.json | Adds Context7 schema + metadata and rules for docs indexing. |
| apps/fallback-ensapi/AGENTS.md | Documents fallback-ensapi scope, invariants, and secrets model. |
| apps/ensrainbow/AGENTS.md | Documents ENSRainbow CLI-only entrypoint, DB invariants, and operational gotchas. |
| apps/ensindexer/src/lib/graphnode-helpers.ts | Adds DISABLE_ENSRAINBOW_HEAL early return for perf benchmarking. |
| apps/ensindexer/AGENTS.md | Adds detailed ENSIndexer operational invariants and architecture notes. |
| apps/ensapi/AGENTS.md | Adds ENSApi architecture, middleware pipeline, and error-handling conventions. |
| apps/ensadmin/AGENTS.md | Documents ENSAdmin static-export constraints and runtime env injection model. |
| AGENTS.md | Reframes monorepo narrative, adds agent skills conventions, and updates workflow guidance. |
| .mcp.json | Adds MCP server config for Context7. |
| .gitignore | Clarifies Claude directory guidance and ignores **/skills/npm-* outputs. |
| .changeset/omnigraph-skill-acceleration-and-status.md | Changeset for ensskills documentation updates. |
| .agents/skills/fix-audit/SKILL.md | Adds internal skill for pnpm audit fixes + override hygiene. |
| .agents/skills/ensindexer-perf-testing/SKILL.md | Adds internal skill documenting reproducible indexer perf testing flow. |
| .agents/skills/edit-ponder-sync/SKILL.md | Adds internal skill for inspecting/editing Ponder ponder_sync RPC cache. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
📝 Walkthrough🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agents/skills/edit-ponder-sync/SKILL.md:
- Around line 60-62: Update the fenced code block in SKILL.md that currently
shows the fragment id pattern
`log_<chainId>_<address|null>_<topic0|null>_<topic1>_<topic2>_<topic3>_<n>` to
include a language specifier for proper Prettier formatting (change the opening
``` to ```text); edit the block containing that pattern so the fenced code block
is labeled as text.
- Around line 27-40: The fenced code block containing the schema cheat-sheet
(starting with lines describing ponder_sync.blocks, ponder_sync.logs, etc.) is
missing a language specifier; update the opening triple-backtick to include a
language (e.g., ```text) so Prettier/Markdown linting passes and the block is
formatted correctly while preserving the existing content for entries like
ponder_sync.blocks, ponder_sync.transactions, ponder_sync.intervals,
ponder_sync.factories, and ponder_sync.factory_addresses.
- Around line 176-183: Add a short clarifying comment above the RPC, rpchash,
and cachehash definitions explaining that the token "<chainId>" is used in two
different ways: in the RPC environment variable name (used by RPC=$(grep
RPC_URL_<chainId> ...), e.g., RPC_URL_1) and as the numeric chain identifier
used in the SQL query within cachehash (chain_id=<chainId>, e.g., 1); update the
comment to show example substitutions (e.g., replace <chainId> with 1 or
11155111) so future readers know which occurrence is a symbolic env-var suffix
and which is the numeric chain id.
In @.agents/skills/ensindexer-perf-testing/SKILL.md:
- Line 219: The fenced code block in SKILL.md is missing a language identifier;
update the code fence from ``` to a language-specific fence such as ```markdown
(or ```text) so markdownlint and syntax highlighters can correctly parse
it—locate the lone backtick fence in the file (the block containing "**<label>**
— branch/SHA, plugins, namespace") and prepend the chosen language identifier to
that opening fence.
- Around line 242-246: In SKILL.md update the fenced code block shown (the
```bash ... ``` snippet) to add a blank line immediately before the opening
```bash and a blank line immediately after the closing ``` so the block is
separated from surrounding text (fixes MD031); locate the code block by the
exact triple-backtick fence and the
ENSINDEXER_SCHEMA_NAME=ensindexer_perf_<label> pnpm start line and insert the
empty lines around the fences accordingly.
- Around line 195-196: Replace the two incorrect metric names used in the Step 8
queries—ponder_postgres_query_total and ponder_rpc_request_cache_hits—with the
current Ponder metrics referenced in the pitfalls section: use
ponder_indexing_store_queries_total for Postgres QPS by method and use
ponder_indexing_rpc_requests_total (or ponder_indexing_rpc_prefetch_total if you
intend prefetch-only RPCs) for RPC cache/hit rates; update the queries that
reference those symbols so they return data (e.g., sum by (method)
(rate(ponder_indexing_store_queries_total[5m])) and sum by (chain_id)
(rate(ponder_indexing_rpc_requests_total[5m])) or the prefetch variant).
In `@AGENTS.md`:
- Line 118: Add terminal punctuation to the sentence "the OpenAPI doc is a
committed artifact (`docs/ensnode.io/src/data/ensapi-openapi.json`) and CI fails
if it drifts from the ENSApi routes" so it matches surrounding list formatting;
update that paragraph in AGENTS.md by appending a period (or appropriate
punctuation) to the end of the line.
In `@scripts/link-local-skills.mjs`:
- Line 7: Replace the percent-encoded pathname usage for root with a proper
file-system path: import and use fileURLToPath from the 'url' module and call
fileURLToPath(new URL("..", import.meta.url)) instead of new URL("..",
import.meta.url).pathname so the root variable passed into join()/symlink
operations is decoded correctly on Windows and for spaces/unicode.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9c9c3420-7c8f-49f1-a4c0-8f77c68dd98c
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (31)
.agents/skills/edit-ponder-sync/SKILL.md.agents/skills/ensindexer-perf-testing/SKILL.md.agents/skills/fix-audit/SKILL.md.changeset/omnigraph-skill-acceleration-and-status.md.gitignore.mcp.jsonAGENTS.mdapps/ensadmin/AGENTS.mdapps/ensadmin/CLAUDE.mdapps/ensapi/AGENTS.mdapps/ensapi/CLAUDE.mdapps/ensindexer/AGENTS.mdapps/ensindexer/CLAUDE.mdapps/ensindexer/src/lib/graphnode-helpers.tsapps/ensrainbow/AGENTS.mdapps/ensrainbow/CLAUDE.mdapps/fallback-ensapi/AGENTS.mdapps/fallback-ensapi/CLAUDE.mdcontext7.jsondocs/ensnode.io/AGENTS.mddocs/ensnode.io/CLAUDE.mdpackage.jsonpackages/datasources/AGENTS.mdpackages/datasources/CLAUDE.mdpackages/ensskills/skills/ens-protocol/SKILL.mdpackages/ensskills/skills/ens-protocol/references/ensv1-and-ensv2.mdpackages/ensskills/skills/omnigraph/SKILL.mdpackages/integration-test-env/AGENTS.mdpackages/integration-test-env/CLAUDE.mdscripts/link-local-skills.mjsskills-npm.config.ts
Greptile SummaryThis PR overhauling AI agent configuration for the ENSNode monorepo: committing internal skills (previously gitignored), rewriting the root AGENTS.md against the current ENSDb/Unigraph/Omnigraph narrative, adding per-service AGENTS.md files for 8 projects, fleshing out the previously-stub
Confidence Score: 5/5Safe to merge — the only runtime change is a single guarded early-return behind an explicitly undocumented env var intended solely for benchmarking, and all other changes are documentation, skill prose, and tooling configuration. The diff is overwhelmingly documentation and agent configuration. The one functional code change (DISABLE_ENSRAINBOW_HEAL early-return in labelByLabelHash) is minimal, clearly commented, and fully covered by the perf-testing skill's runbook. Previously raised concerns in review threads were all addressed or explicitly acknowledged as intentional. No new issues were found. No files require special attention. scripts/link-local-skills.mjs carries a known-but-accepted silent catch that could obscure permissions errors, but this is in a dev-only setup script with no impact on production. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["pnpm install (prepare)"] --> B["skills-npm --cwd ."]
A --> C["node scripts/link-local-skills.mjs"]
B --> D[".claude/skills/npm-*\n(managed by skills-npm)"]
C --> E[".claude/skills/<name> symlinks\n(mirrors .agents/skills)"]
subgraph committed [".agents/skills (committed)"]
F[fix-audit]
G[edit-ponder-sync]
H[ensindexer-perf-testing]
end
committed --> E
subgraph npm ["ensskills (npm)"]
I[enssdk]
J[enskit]
K[omnigraph]
L[ens-protocol]
end
npm --> D
E --> U["Claude Code agent\ndiscovers skills + context"]
D --> U
Reviews (4): Last reviewed commit: "fix: bot review notes (link-local-skills..." | Re-trigger Greptile |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.agents/skills/ensindexer-perf-testing/SKILL.md (2)
243-247:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd blank lines around fenced code block.
Per past review and markdownlint rule MD031, fenced code blocks should be surrounded by blank lines.
📝 Proposed fix
(`tsx src/index.ts`) does **not** load `.env.local` (no `--env-file`, no in-code dotenv), so source the env and override the schema inline: + ```bash cd apps/ensapi set -a; . ./.env.local; set +a ENSINDEXER_SCHEMA_NAME=ensindexer_perf_<label> pnpm start > /tmp/perf-test/ensapi.log 2>&1 &
- Editing files (restoring env) then no longer disturbs the running ENSApi. A brief gap
</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In @.agents/skills/ensindexer-perf-testing/SKILL.md around lines 243 - 247, The
fenced bash code block (the triple-backtick block containing "cd apps/ensapi ...
ENSINDEXER_SCHEMA_NAME=... pnpm start > /tmp/perf-test/ensapi.log 2>&1 &") needs
a blank line both immediately before the openingbash and immediately after the closing; update the SKILL.md section to insert one empty line above the
opening fence and one empty line below the closing fence so the code block is
properly surrounded per MD031 while keeping the exact commands unchanged.</details> <!-- cr-comment:v1:9cb01fce315007eafab6ab73 --> _Source: Coding guidelines_ --- `220-220`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_ **Add language identifier to fenced code block.** Per past review and markdownlint rule MD040, the fenced code block should specify a language for proper syntax highlighting. <details> <summary>📝 Proposed fix</summary> ```diff -``` +```markdown **<label>** — branch/SHA, plugins, namespace ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In @.agents/skills/ensindexer-perf-testing/SKILL.md at line 220, The fenced code
block in SKILL.md is missing a language identifier; update the opening fence to
include "markdown" (i.e., change "" to "markdown") for the block
containing " — branch/SHA, plugins, namespace" so the snippet is
properly highlighted and linting rule MD040 is satisfied; keep the closing "```"
intact.</details> <!-- cr-comment:v1:e10c5d7f4dd811b5d08ef18a --> _Source: Coding guidelines_ </blockquote></details> </blockquote></details>🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Outside diff comments: In @.agents/skills/ensindexer-perf-testing/SKILL.md: - Around line 243-247: The fenced bash code block (the triple-backtick block containing "cd apps/ensapi ... ENSINDEXER_SCHEMA_NAME=... pnpm start > /tmp/perf-test/ensapi.log 2>&1 &") needs a blank line both immediately before the opening ```bash and immediately after the closing ```; update the SKILL.md section to insert one empty line above the opening fence and one empty line below the closing fence so the code block is properly surrounded per MD031 while keeping the exact commands unchanged. - Line 220: The fenced code block in SKILL.md is missing a language identifier; update the opening fence to include "markdown" (i.e., change "```" to "```markdown") for the block containing "**<label>** — branch/SHA, plugins, namespace" so the snippet is properly highlighted and linting rule MD040 is satisfied; keep the closing "```" intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID:
f3297b54-9cb8-4894-b355-3554e96baedb⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml📒 Files selected for processing (13)
.agents/skills/ensindexer-perf-testing/SKILL.md.changeset/enssdk-enskit-skills.mdexamples/enskit-react-example/README.mdexamples/enssdk-example/README.mdexamples/ensskills-example/README.mdexamples/ensskills-example/package.jsonexamples/omnigraph-graphql-example/README.mdpackages/enskit/README.mdpackages/enssdk/README.mdpackages/ensskills/skills/ens-protocol/references/names-and-hashing.mdpackages/ensskills/skills/enskit/SKILL.mdpackages/ensskills/skills/enssdk/SKILL.mdscripts/link-local-skills.mjs
|
@greptile review |
There was a problem hiding this comment.
♻️ Duplicate comments (2)
scripts/link-local-skills.mjs (2)
7-7:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse
fileURLToPathinstead of.pathnamefor cross-platform compatibility.This issue was flagged in previous reviews but remains unfixed. On Windows, file URLs return incorrect format (e.g.,
/C:/pathinstead ofC:\path), and percent-encoded characters (spaces as%20, etc.) are not decoded. This will cause filesystem operations to fail.🔧 Proposed fix
import { lstatSync, mkdirSync, readdirSync, readlinkSync, symlinkSync, unlinkSync } from "node:fs"; import { join, relative } from "node:path"; +import { fileURLToPath } from "node:url"; -const root = new URL("..", import.meta.url).pathname; +const root = fileURLToPath(new URL("..", import.meta.url)); const source = join(root, ".agents", "skills"); const target = join(root, ".claude", "skills");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/link-local-skills.mjs` at line 7, Replace use of new URL(...).pathname when computing root with Node's fileURLToPath to ensure correct Windows paths and decode percent-encoded chars: import fileURLToPath from 'url' (or use const { fileURLToPath } = require('url') depending on module style) and call fileURLToPath(new URL("..", import.meta.url)) instead of using .pathname; update the declaration of root (the variable assigned from new URL("..", import.meta.url).pathname) to use fileURLToPath so all filesystem ops use a proper platform-native path.
21-21:⚠️ Potential issue | 🟠 Major | ⚡ Quick winNormalize path separators for Windows compatibility.
This issue was flagged in a previous review but remains unfixed. On Windows,
readlinkSync()returns paths with backslashes (e.g.,..\.agents\skills\foo), but the code checks for forward slashes in.agents/skills. This causes the check to fail, preventing stale symlinks from being detected and cleaned up.🔧 Proposed fix
+import { normalize, sep } from "node:path"; import { join, relative } from "node:path"; // ... for (const name of readdirSync(target)) { if (!isLocalSkill(name)) continue; const path = join(target, name); if (!lstatSync(path).isSymbolicLink()) continue; - const linksIntoSource = readlinkSync(path).includes(".agents/skills"); + const linksIntoSource = readlinkSync(path).split(sep).includes(".agents") && + readlinkSync(path).split(sep).includes("skills"); if (linksIntoSource && !localSkills.includes(name)) unlinkSync(path); }Alternative approach using normalize:
- const linksIntoSource = readlinkSync(path).includes(".agents/skills"); + const linksIntoSource = normalize(readlinkSync(path)).includes(join(".agents", "skills"));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/link-local-skills.mjs` at line 21, The check using readlinkSync(path) in the linksIntoSource assignment fails on Windows because backslashes aren't matched; change the logic that computes linksIntoSource (the readlinkSync call used to set linksIntoSource) to normalize separators before the includes check (e.g., convert backslashes to forward slashes or use path.normalize + replace backslashes) so the string comparison against ".agents/skills" works cross-platform; update the readlinkSync(...) handling where linksIntoSource is defined.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@scripts/link-local-skills.mjs`:
- Line 7: Replace use of new URL(...).pathname when computing root with Node's
fileURLToPath to ensure correct Windows paths and decode percent-encoded chars:
import fileURLToPath from 'url' (or use const { fileURLToPath } = require('url')
depending on module style) and call fileURLToPath(new URL("..",
import.meta.url)) instead of using .pathname; update the declaration of root
(the variable assigned from new URL("..", import.meta.url).pathname) to use
fileURLToPath so all filesystem ops use a proper platform-native path.
- Line 21: The check using readlinkSync(path) in the linksIntoSource assignment
fails on Windows because backslashes aren't matched; change the logic that
computes linksIntoSource (the readlinkSync call used to set linksIntoSource) to
normalize separators before the includes check (e.g., convert backslashes to
forward slashes or use path.normalize + replace backslashes) so the string
comparison against ".agents/skills" works cross-platform; update the
readlinkSync(...) handling where linksIntoSource is defined.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6061f45b-91e9-4a2e-a931-d0ec4a487aa0
📒 Files selected for processing (2)
examples/ensskills-example/README.mdscripts/link-local-skills.mjs
Problem & Motivation
validate.tsthat doesn't exist).claude/skillson one machine — valuable, unversioned, unsharedWhat Changed (Concrete)
.agents/skills/is the committed source of truth for internal skills (fix-audit, edit-ponder-sync, ensindexer-perf-testing);scripts/link-local-skills.mjsmirrors them into.claude/skillsonpnpm install;skills-npm.config.tsscopes installs to.agents+.claude(dropped.pientirely)AGENTS.mdfully rewritten against the current narrative: services + complete monorepo map, local runtime (ports, env, startup order, theENSINDEXER_SCHEMA_NAMEcross-app invariant), workflow incl. breaking-changes-are-minor semverAGENTS.md(+CLAUDE.mdsymlinks) for 8 projects — ensindexer, ensapi, ensrainbow, ensadmin, fallback-ensapi, docs/ensnode.io, datasources, integration-test-env — subsystem invariants moved out of root into the subtree where they auto-loadenssdk+enskitskills;omnigraphgained protocol acceleration + indexing-status/503 sections;ens-protocolgained ENS Namespace + Subgraph-Interpreted concepts; changesets included (minor)DISABLE_ENSRAINBOW_HEAL=trueenv short-circuits label healing (benchmarking only); the perf-testing skill uses it instead of patching source; documented inapps/ensindexer/AGENTS.mdcontext7.jsonscoped to docs content + description/rules;.mcp.jsonadds the context7 MCP server (anonymous http, vscode-compatible)integration-options/ensskills.mdxpromotes enssdk/enskit out of the stub list; enssdk/enskit READMEs bumped from the stale 1.13.1 pin to 1.15.2 with durable phrasingskills-npminprepare; pnpm warning fixesDesign & Planning
planned interactively in-session, area by area (analysis → proposal → approval); no standalone design doc. key calls: per-service orientation via nested AGENTS.md (deterministic auto-load when an agent touches the subtree) over "orientation skills" (probabilistic invocation + permanent prompt cost); internal/external placement rule — anything useful to external integrators goes in ensskills or docs, never internal AGENTS.md. considered wrapping internal skills in a workspace package so skills-npm could manage them — rejected (forces
npm-*name prefixes, demotes.agentsto generated symlinks) in favor of the ~40-line link script.Self-Review
apps/ensapi/src/lib/handlers/validate.ts, which doesn't exist — actual validation is@hono/zod-openapiroute schemas + thecreateAppdefaultHook; the new ensapi AGENTS.md documents reality.claude/skills/agent-dx-cli-scalesymlink,.pi/directory; flagged-but-not-fixed:CLOUDFLARE_SECRETenv vsrequire-cloudfront-secret.middleware.tsfilename mismatch in fallback-ensapiCross-Codebase Alignment
ENSINDEXER_SCHEMA_NAME,ENSDB_URL),accelerate,label_set_id,subgraph-interpreted, "coming soon",1.13,tenderlyrelease:postversion— they'll drift again on the next release; small follow-up script if it bothers usDownstream & Consumer Impact
ensskills(published) gains two skills + content — minor bump via changesets.enssdk/enskitpackages unchanged except READMEs.integration-options/ensskills.mdx, enssdk/enskit READMEs, context7 rules served alongside every snippetDISABLE_ENSRAINBOW_HEALis intentionally undocumented outside AGENTS.md + the perf skill; nested AGENTS.md/CLAUDE.md symlink pattern is the cross-agent convention (codex reads AGENTS.md natively, claude reads CLAUDE.md)Testing Evidence
pnpm typecheck,pnpm lint,pnpm testfrom root all green (154 files / 1853 tests). graphnode-helpers suite (14 tests) passes with the new branch in place. enssdk/enskit skill api claims verified against package source + example apps, then spot-checked independently.DISABLE_ENSRAINBOW_HEALearly-return (trivial guarded branch); skill prose accuracy is reviewer-judgment territoryScope Reductions
migrate-to-omnigraph+unigraph-sqlskills remain stubs; worktree qol (port offsets, env copying, un-hardcoding ensadmin's dev port); shared.claude/settings.jsonpermission allowlist; README version-pin sync at release time; cloudfront/cloudflare naming cleanup in fallback-ensapiRisk Analysis
DISABLE_ENSRAINBOW_HEALin production → labels index as unhealable (fix = unset + re-index; mitigated by code comment + AGENTS.md + skill warnings, and it's not in any env example). inaccurate skill content shipping to npm → agents misled (mitigated by source-verified authoring; fixable in a patch release). AGENTS.md drift recurring (mitigated by per-subtree ownership and smaller files).Pre-Review Checklist (Blocking)