AGENTS.md · git:20261011.fdbe38d · 2026-10-11 · sha256 483cb40fcabfca08
AGENTS.md git:20261011.fdbe38dA
Immutable. This exact content never changes and is served at /api/v1/blob/483cb40fcabfca08.
# AGENTS.md Instructions for coding agents working **in** this repository. If you are an agent trying to *use* Mirofy on somebody else's code, you want [`packages/core/SKILL.md`](packages/core/SKILL.md) instead — that is the skill description, and it drives the same CLI a human would run. --- ## What this project is Mirofy points at a repository, reads it into an **evidence graph**, builds a **model**, and compiles that into **one self-contained HTML file**. The whole product rests on one promise: **every relationship it draws can name the file, the line range and the commit it came from, and anything it could not read is listed by name rather than quietly dropped.** Almost every rule below exists to keep that promise true. When a change would make the tool look better by making that claim weaker, the claim wins. ## The rules that are not negotiable 1. **Never guess.** A construct an adapter cannot analyse is a **Gap** — a recorded fact that analysis stopped at a named file and line. It is never an omission, and never a plausible edge. `packages/evidence/src/fact.mjs` enforces this: a scanner may claim `statically-derived` or `config-derived` and nothing else. 2. **Zero runtime dependencies, in every package.** `check:readme` asserts it. If you need something a dependency would give you, write the forty lines. 3. **No fabricated numbers.** Counts carry their denominator; there are no percentages in the coverage report. A number nobody checks is a number that is true until it isn't. 4. **A gate that cannot fail is worse than no gate.** It reads like proof. If you find a check that passes unconditionally, that is a bug. 5. **`packages/core/assets/template.html` is generated, never hand-edited.** It is built from `packages/viewer/`. Run `npm run build:template` after any change under `packages/viewer/`, and `npm run check:template` enforces it. 6. **Never re-baseline a manifest to make a check pass.** `npm run test:golden` and `npm run check:drift` both take `--update`, and both refuse to run it in CI. A re-baseline is a deliberate, reviewable act with a reason in the diff — not a way around a red gate. 7. **Never skip a test to make a suite green.** A test may be skipped only for a platform fact that makes it genuinely unrunnable, and the skip must state that fact at the test. ## Running the gates ```bash npm run check # everything below, in order. This is what CI runs. ``` Individually, when you want a fast loop: ```bash npm run lint # eslint . npm run typecheck # tsc --noEmit npm run test # node:test suites outside the conformance matrix npm run test:golden # digest parity against the recorded golden renders npm run check:template # the built template matches packages/viewer/ npm run check:drift # packages/core/ matches its reviewed manifest npm run test:conformance # the conformance matrix npm run check:artifacts # npm run build reproduces the golden digests npm run check:size # tracked-tree budget npm run check:audit # dependency advisories npm run check:readme # every number in README.md, derived rather than trusted npm run check:changelog # CHANGELOG.md covers the newest code change npm run check:lockfile # the lockfile agrees with the manifests ``` Two of these surprise people: - **`check:readme`** re-derives every number in `README.md` by actually running a scan. Adding a package moves those numbers, and the gate will tell you so. Fix the README or fix the repository — do not delete the claim. - **`check:audit`** asks a live advisory endpoint, so a commit that was green can go red without any code changing. "It passed when I ran it" is not a durable claim about this one. ## Running it ```bash npm run scan # repository -> scan/evidence-graph.json npm run model # evidence graph -> scan/model.json npm run compile # model -> scan/view.json node packages/core/bin/mirofy.mjs map . # the whole pipeline in one command ``` ## Layout | package | does | |---|---| | `scanner` | adapters that read a repository into facts and gaps | | `evidence` | append-only evidence graph, query, honest coverage | | `model` | the system model: stable ids, evidence refs, human overrides | | `compile` | view compiler and the planner seam | | `explain` | graph queries, architecture rules, drift, timeline | | `mcp` | the model as agent context | | `import` | Mermaid into typed documents | | `export` | draw.io and Excalidraw escape hatches | | `layout` | constraint layout: intent to coordinates (dev-time) | | `core` | renderers, schemas, validators, CLI | | `viewer` | the interactive viewer, built into one template | | `benchmark` | first-pass usable rate, over a saved corpus | | `conformance` | the matrix, and the tests every row names | Tests live in `packages/<name>/test/*.test.mjs` and are discovered automatically by `scripts/run-tests.mjs`. Pass explicit file paths to `node --test` — directory mode does not work on the Node versions in the CI matrix, and the runner says why. ## Conventions - **ESM only** (`"type": "module"`), Node 20+. - **Conventional commits**, lowercase, scoped: `fix(viewer): …`, `feat(scanner): …`, `docs: …`. - **Comments explain the decision, not the mechanism.** This codebase is unusually heavily commented on purpose: most comments record *why* a thing is the way it is, often naming the bug that made it necessary. Match that. A comment restating the line below it is noise; a comment naming the failure that line prevents is the point. - **`CHANGELOG.md` records decisions, not diffs.** `git log` already has the diff. An entry that only says what changed is a second copy of something nobody was struggling to find. ## Before you open a PR `npm run check` green locally, and a `CHANGELOG.md` entry if anything under `packages/`, `scripts/`, `.github/`, `fixtures/` or `benchmarks/` changed. If the change genuinely does not deserve an entry, say so in the entry — "no behaviour change" is a fact a reader wants, and an absent line is not.