neo-agent-skills

September 18, 2026 · View on GitHub

The canonical agent skill substrate for the neomjs organization. Consuming repositories depend on this package; they never carry a copy of it.

How it reaches a repository

npm install --save-dev neo-agent-skills

Then run the materializer from your postinstall:

{
  "scripts": { "postinstall": "neo-agent-skills-materialize" },
  "devDependencies": { "neo-agent-skills": "^0.1.0" }
}

postinstall materializes two surfaces, both as symlinks into node_modules, both untracked:

surfaceshapefor
.agents/skillsone directory symlink at the whole treeharness-neutral discovery — Codex, Antigravity, any fork
.claude/skillsper-skill links, manifest-projectedthe Claude façade

The shapes differ on purpose. The manifest may opt a skill out of the Claude façade, and you cannot opt a skill out of a directory symlink — so the neutral surface links the tree and the façade links each skill. Git-ignore both paths; a tracked entry under either is a shadow copy, which is the thing this package exists to make unnecessary.

Skill changes bump this package's version. Consumers update the dependency like any other. Freshness is whatever npm already tells you — npm outdated, dependabot — and there is deliberately no bespoke lag gate anywhere in this contract.

The check that matters

npx neo-agent-skills-materialize --check

Run it in consumer CI. It answers the questions this transport leaves open: did both projections happen, and does every link point where it should? Existence is not correctness — a link resolving to the wrong skill resolves.

It can silently not happen. npm ci --ignore-scripts skips postinstall and prepare, and is already deliberate practice in several neomjs workflows — that yields a resolved dependency and zero reachable skills. A dependency resolving is not the same as skills being reachable, and only this check tells them apart.

One measured npm behaviour worth knowing: npm install <pkg> does not run your postinstall; a bare npm install does. So the command that bumps this dependency leaves the links stale until the next install. --check is what turns that from silent into loud.

Shared source-comment guard

npx --no-install neo-agent-skills-ticket-archaeology --base origin/dev

The guard scans every changed tracked .mjs file in full. Repository-local issue numbers of any length and review-history markers fail only in comments or JSDoc; executable strings remain valid. A numeric CSS color of 3, 4, 6 or 8 digits passes directly after color syntax (color:, backgroundColor_=, fillStyle=, CSS color), a number with a leading zero is never a ticket, and a numeric HTML entity (&#39;) is a codepoint rather than a reference; anywhere else a bare number stays a ref. A token-scoped [not-ticket-ref: …] marker binds to the one token it follows: css-color on such a color, or any other non-blank reason on a numeric reference the author declares deliberate. A marker binding to neither, or carrying no reason, fails closed. Consumer repositories call the stable Source comment archaeology job in .github/workflows/reusable-pr-baseline.yml through an immutable Skills revision. That job installs its exact guard release outside the caller workspace, so a pull request cannot weaken its own gate by changing the caller lockfile or local binary.

Shared substrate byte-budget guard

npx --no-install neo-agent-skills-substrate-size

Measures what a seat actually loads per turn — AGENTS.md, .agents/ANTIGRAVITY_RULES.md, .claude/CLAUDE.md — against a 24,576-byte per-file limit, and fails the check on a breach.

Loaded bytes, not file bytes: symlinks resolve through realpathSync (an lstat on a symlinked CLAUDE.md reports 12 — the length of ../AGENTS.md), and whole-line @path imports are summed recursively as one unit with a cycle guard keyed on file identity. It reports headroom rather than pass/fail, because this drift is gradual: by the time a file flips to EXCEEDS it is already truncating.

Past the limit the harness silently truncates the BOTTOM of the file, so a seat loses the tail of its own rules with nothing reporting it — the one failure that cannot be observed from inside the seat suffering it.

A missing entry point is not applicable, never a failure. Consumers legitimately differ: only some carry all three. Only ENOENT means absent — a permission denial or an unreadable path is an error and fails the check, because absent is a claim about the repository while unreadable is a claim about the observation, and a failed observation supports neither.

Consumer repositories call the stable Substrate size job in .github/workflows/reusable-pr-baseline.yml through an immutable Skills revision. The limit ships with the guard, not with the caller: the job installs its exact release outside the caller workspace and pins the measurement to the checked-out tree, so a pull request cannot widen the limit it is judged by, drop an entry from the target roster, or move the measurement to a directory where every target is absent and the check greens on nothing.

Shared npm-overrides guard

npx --no-install neo-agent-skills-npm-overrides

An npm overrides rule is a floor: it keeps a dependent whose declared range still admits a vulnerable version from resolving beneath the patched one. Dependabot neither bumps nor removes overrides, so a rule outlives its reason silently. Worse, when a dependent moves to a new major, the stale rule forces it back onto the old one.

The guard judges each rule against the ranges its dependents declare in package-lock.json, with no network. A nested rule ("parent": {"pkg": …}) counts only dependents inside parent's resolved subtree, hoisted ones included:

verdictmeaning
neededa dependent in scope still admits a version below the floor; the offending ranges are printed
REDUNDANTnothing in scope can resolve below the floor, or nothing declares the package any more: delete the rule
FIGHTINGa dependent's range starts above everything the rule permits: delete or raise the rule, or narrow it when another dependent still needs the floor

Holding a package above an exact pin (dompurify: "3.4.8" held at ^3.4.13) is the deliberate security direction, so it reads needed. No overrides is N/A. A missing package.json, or overrides with no v2/v3 lock, is a failed observation and exits 1.

Consumer repositories call the stable npm overrides job in .github/workflows/reusable-pr-baseline.yml. The verdict can only change in a pull request that edits package.json or package-lock.json, so the job runs on every pull request and never reddens one for an upstream release.

Shared credential guard

npx --no-install neo-agent-skills-secrets --all
npx --no-install neo-agent-skills-secrets path/to/file.mjs other/file.md

A committed credential is unrecallable one npm publish later, and a scanner that finds it after the push finds it too late. This guard knows Google API keys and OAuth tokens, OpenAI, Anthropic and GitHub tokens (classic and fine-grained), and AWS access key ids. Each pattern is anchored to the credential's real length, so prose that describes one (AIza…, a placeholder, a short sample) passes.

A finding names file, line and kind, never the match: CI logs are published, and echoing a finding would publish it.

A line that must keep such a literal carries secret-scan-ok: <reason> in whatever comment syntax the file has. The reason runs to the end of the line or to the comment's closer, and it has to say something: <!-- secret-scan-ok: --> is a finding, because a closer is no reason, and so is the credential itself written after the marker. A marker covers its own line only.

Consumer repositories call the stable Secrets job in .github/workflows/reusable-pr-baseline.yml. It scans every tracked file at the pull request's head, not only the diff: a credential already on the base branch still fails, because it is one to revoke whichever pull request finds it.

What is in the package

pathwhat
.agents/skills/the substrate — skills plus skills.manifest.json and its schema
scripts/materialize-harness-skills.mjsthe postinstall linker and its --check arm
scripts/check-ticket-archaeology.mjsthe portable comment/JSDoc archaeology guard
scripts/check-npm-overrides.mjsthe portable stale-overrides guard
scripts/check-substrate-size.mjsthe portable per-turn substrate byte-budget guard

The manifest governs projection: a skill declaring claudeSymlinkRequired: false is a declared opt-out and is correctly absent from the façade. Per-skill links rather than one directory link, because a skill cannot be opted out of a directory symlink.

Authority

Skills are authored on dev. main is release-only via the publish pipeline. Promotion is a version bump and a publish — the package version, the registry tarball integrity, and the consumer's lockfile are the revision authority. There is no receipt file; an earlier design used one to police byte-copies across repositories, and both the copies and the receipt are gone.

Contract: neomjs/neo#17798 · graduated from D#17756.