Content
# neo-agent-skills
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
```bash
npm install --save-dev neo-agent-skills
```
Then run the materializer from your `postinstall`:
```json
{
"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:
| surface | shape | for |
|---|---|---|
| `.agents/skills` | **one directory symlink** at the whole tree | harness-neutral discovery — Codex, Antigravity, any fork |
| `.claude/skills` | **per-skill links**, manifest-projected | the 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.
**Every pull request bumps this package's version, and every merge publishes it** (see *Authority*). 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
```bash
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
```bash
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 (`'`) 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` at a published release tag (`@vX.Y.Z`): its `Release ref` job fails
a caller at a SHA or a branch, and every publish pushes the matching tag. 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
```bash
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` at a published release tag (`@vX.Y.Z`). **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
```bash
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:
| verdict | meaning |
|---|---|
| `needed` | a dependent in scope still admits a version below the floor; the offending ranges are printed |
| `REDUNDANT` | nothing in scope can resolve below the floor, or nothing declares the package any more: delete the rule |
| `FIGHTING` | a 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
```bash
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.
## Generated `AGENTS.md`
```bash
npx --no-install neo-agent-skills-agents-md --repo neo,neo-agent-brain --out AGENTS.md
```
```js
import {generate} from 'neo-agent-skills/agents-md';
const {text} = generate({audience: 'maintainer', repos: ['neo', 'neo-agent-brain']});
```
The instructions a seat loads every turn are composed from `agents-md/sections/`. Each section declares
the repositories and the audience (`maintainer` or `contributor`) it applies to; nothing is inferred. A
set of repositories composes one file, with every section once, in source order, when any repository
in the set declares it. A peer working in several repositories loads that one file and keeps each
repository's own rules.
Both callers get the same refusals: an undeclared repository or audience, two sections claiming one
numbered rule, and output over the **24,576-byte** budget. The bin writes `--out`, or stdout. The
import writes nothing: Fleet puts the text into each seat's harness home with its own safe write.
## What is in the package
| path | what |
|---|---|
| `.agents/skills/` | the substrate — skills plus `skills.manifest.json` and its schema |
| `scripts/materialize-harness-skills.mjs` | the postinstall linker and its `--check` arm |
| `scripts/check-ticket-archaeology.mjs` | the portable comment/JSDoc archaeology guard |
| `scripts/check-npm-overrides.mjs` | the portable stale-`overrides` guard |
| `scripts/check-substrate-size.mjs` | the 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`, and every merge to `dev` is a release:
- every pull request bumps `package.json` (`scripts/check-version-bump.mjs`);
- `.github/workflows/publish.yml` publishes that version through npm trusted publishing and pushes `v<version>`;
- Dependabot brings it to each consumer.
The version is written once, in `package.json`, and read everywhere else. **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](https://github.com/neomjs/neo/issues/17798) · graduated from
[D#17756](https://github.com/neomjs/neo/discussions/17756).
Connection Info
You Might Also Like
No recommendations available