memento-dev — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited memento-dev (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<!-- doc-links: resolve-from-repo-root -->
You are working on the Memento codebase. This skill encodes the rules every change must follow, the verification steps that must pass, and the cadence (ADRs, changesets, docs:generate) that keeps the project coherent across human and AI contributors.
The canonical reference is AGENTS.md at the repo root. This skill is a load-friendly summary. When they conflict, treat AGENTS.md as final and update this skill in the same PR.
Every change is judged against these. They are non-negotiable.
The PR template asks you to address each one explicitly. Default-empty answers are a smell.
Encoded as tests and CI gates where possible. Do not bypass them.
ConfigKey. Adding a magic number in code is a code-review rejection.MemoryEvent for memory changes, ConfigEvent for config changes.{ type: 'local', id: 'self' }. The model is multi-user-ready from day one.id, createdAt, schemaVersion, scope. To "move" a memory between scopes, supersede it with a new memory in the new scope.forgotten memory does not silently become active. Every transition has its own command (forget, restore, archive, supersede).assertNever pattern. A structural test asserts that decay, retrieval, and conflict-detection rules exist for every MemoryKind.conflict.timeoutMs.stored × decayFactor(now − lastConfirmedAt, halfLife). The compact job materializes archives for memories that have decayed below threshold.GitRemoteResolver, WorkspacePathResolver, SessionResolver). Adding a new scope dimension means adding a resolver, not mutating the composite.lastConfirmedAt on Memory is a denormalized cache, validated at write-time and by npx @psraghuveer/memento doctor.supersede to preserve history. The error message points the caller to the right command.memento embedding rebuild is the only way to re-embed memories. Never silent.index.ts. Private paths are an implementation detail.--scrubber.enabled=false in a fixture if you need raw input; do not skip the call site.scripts/ensure-better-sqlite3.mjs (root) and packages/cli/scripts/postinstall.mjs (CLI) cooperate to prevent the "Could not locate the bindings file" trap. The CLI hook early-exits via isWorkspaceCheckout() so it doesn't fight the root heal in dev. Edit them together — editing one in isolation re-introduces the trap for every fresh contributor.preference and decision policies parse the first line of content as topic: value (or topic = value) — that's the structural anchor that makes "I use bun" vs "I use npm" surface as a conflict. Free-prose content silently bypasses detection. New surfaces that auto-write preferences must include the first-line anchor; the assistant skill (skills/memento/SKILL.md) teaches the same pattern. See docs/architecture/conflict-detection.md for the rationale.DO NOT COMMIT file are private working memory. Code, tests, comments, commit messages, and committed docs must not cite, quote, or link them. Rationale lives in the code, the ADR, and the commit message — not in a sidecar. → AGENTS.md §Common pitfalls.packages/schema/src/.packages/core/src/commands/<namespace>/ (e.g. createMemoryCommands, createConflictCommands).packages/core/test/ — every command needs at least one happy-path and one error test.pnpm docs:generate to refresh docs/reference/cli.md and docs/reference/mcp-tools.md.pnpm changeset) if the command is part of the public surface.The contract is ADR-0003. Tool naming is ADR-0010: default rule is noun.verb → verb_noun; declare metadata.mcpName only when overriding the default (e.g. memory.list → list_memories).
defineKey entry to packages/schema/src/config-keys.ts following the JSDoc-style guidance at the top of that file.mutable: false for anything that must not change after server start (storage flags, embedder dimension, etc.).pnpm docs:generate to refresh docs/reference/config-keys.md.packages/core/src/storage/migrations/ (e.g. 0006_<descriptor>.ts).packages/core/test/storage/migrations/.down. Editing a shipped migration is a code-review rejection.docs/adr/template.md as the starting point.Status: Accepted only after the PR merges. Draft PRs use Status: Proposed.pnpm install --frozen-lockfile
pnpm verifypnpm verify runs, in order:
lint (Biome)typecheck (tsc -b)build (per-package tsup)test (Vitest, excludes e2e)test:e2e (builds CLI, drives it over MCP stdio)docs:lint (markdownlint)docs:reflow:check (one paragraph per line, no hard wrap)docs:check (verifies docs/reference/ is in sync with the registry)If docs:reflow:check fails, run pnpm docs:reflow to apply the fix. If docs:check fails, run pnpm docs:generate and commit the regenerated docs/reference/.
Coverage gate is 90% lines + 90% branches (enforced in vitest.config.ts). Coverage trend: also run pnpm test:coverage and confirm the All files row (lines / branches / functions / statements) does not drop vs your starting commit. Per-file drops on a touched file mean missing tests, not a relaxed rule. → AGENTS.md §Verification.
One paragraph per line, no hard wrap. Editor soft-wraps. Enforced by scripts/reflow-md.mjs in pnpm verify. Long lines look ugly in raw form but render correctly and produce reviewable diffs (one diff per paragraph, not one per wrap point).
Conventional Commits — the type prefix matters because the changelog is generated from it:
feat(server): add new command
fix(core): preserve confidence on supersede when not provided
docs(architecture): clarify decay function
chore(deps): bump @modelcontextprotocol/sdk to 1.xFor PRs that change published behavior, add a changeset:
pnpm changesetThen rename the generated file so it sorts chronologically:
.changeset/<UTC-timestamp>-<slug>.mdGet the timestamp with date -u +"%Y-%m-%dT%H%M". Example: .changeset/2026-05-02T1430-fix-init-creates-db-parent-dir.md.
Pure docs / test-only / CI / repo-tooling changes do not need a changeset.
Library packages (@psraghuveer/memento-core, -schema, -embedder-local, -dashboard) follow standard semver on their public exports — minor for new exports, patch for fixes. The CLI (@psraghuveer/memento) bumps minor only for a coherent feature launch (a new capability shipping across packages); everything else — additive commands outside a launch, new bundled packs/skills, polish, README updates that ship in the tarball — is patch. Pre-1.0, breaking changes still bump minor, not major. Default to patch when unsure.
The canonical framework with worked examples is in .changeset/README.md. Follow it instead of judging each PR fresh — that's what makes the choice reproducible across sessions.
These are deliberate omissions, documented in KNOWN_LIMITATIONS.md. Do not add them as part of an incidental PR:
If you believe one of these belongs in the product, open a design proposal issue — do not just implement it.
The PR template is not advisory. Every PR body MUST contain every section in it, in order, without renaming: Problem, Change, Justification against the four principles, Alternatives considered, Tests, Local verification, ADR, AI involvement, Linked issues. Mark genuinely-absent items as N/A with a one-sentence reason — empty is a smell.
Hand-rolling a PR body that omits required sections is the single most common preventable rework. If you are about to open a PR via gh pr create --body "..." or --body-file, copy the template content as the starting structure and fill each section in — don't invent your own headers.
The "AI involvement" section in particular is mandatory for AI-authored PRs. AI-authored PRs are welcome; opaque ones are not.
The same gates apply equally to human and AI contributors. "It looked right" is not verification — pnpm verify is.
When the user is reviewing each commit (pair-programming, multi-PR session, interactive agent mode in any tool):
pnpm verify and pnpm test:coverage, then pause and present a review summary (files changed, tests added, coverage delta, docs touched). Wait for explicit go-ahead before git commit.docs/architecture/, docs/guides/, docs/adr/, and package READMEs for prose that should reflect the change. Update what drifted; do not punt to a follow-up commit.Autonomous batch sessions skip these — they only fire when a human is reviewing commit-by-commit. → AGENTS.md §For AI agents specifically.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.