Memory onboard
Self-hosted AI coding factory — sandboxed agents deliver tickets to merged code, gated by a human in a dashboard. Local-first, cost-transparent, human-in-the-loop.
npx -y skills add tmj-90/gaffer --skill memory-onboardAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use this skill when the user types `/memory-onboard` (or asks "set up memory for this repo" / "onboard this repo to memory" / "what should be in lore for this repo?"). It runs a repo-aware onboarding interview that produces DRAFT lore records grounded in concrete repo signals (README, ADRs, recent commits, deprecation markers, in-flight migrations). Requires the memory-mcp MCP server to be configured. Uses these MCP tools: search_lore / get_lore / suggest_lore (core), and optionally report_conflict (when a candidate item contradicts existing lore) and record_absence (when the user confirms a topic has no team policy yet). All suggest_lore / report_conflict output lands as drafts — the human approves via `memory review` afterwards. record_absence markers self-expire (default 14 days) and don't need review.
SKILL.md
14.2 KB, ~3.4k tokens by cl100k_base, as published. Nobody here has run it
/memory-onboard — repo-aware onboarding for memory
This skill is the way to seed a repo with lore. It earns its keep by reading the repo first (README, ADRs, recent commits, deprecation markers, in-flight migrations) so the proposed drafts are specific to this codebase, with source citations — rather than inventing memory or mechanically chunking every bullet in the docs (which produces mostly noise and floods the review queue).
Output: DRAFT records with source citations, plus optional absence
markers and boundary edges. Everything lands in memory review for a
human to ratify — the skill never promotes its own records.
Hard rules
- Every lore record this skill produces is a DRAFT. Call
suggest_lore(orreport_conflictfor counter-claims — also drafts), never any approval path. The human reviews withmemory review. Exception:record_absencedoes NOT create a draft — it records a self-expiring "we checked, no policy" marker. Different primitive, different gate (see rule 6). - Every draft carries the tag
inductionso it can be filtered later. Layer topic-specific extras as appropriate (security,conventions,migrations,incident-lessons,invariants, etc.).report_conflictcounter-drafts are auto-taggedconflict-reportby the server. - Cite sources in the body. When a draft comes from a file or commit,
include a one-line reference at the top of the
body— e.g.Source: README.md L42–55orSource: commit abc1234 "migrate accounts → organisations". This is the trust signal a reviewer needs. - Never put secrets, credentials, personal data, regulated data, or anything that looks like a token into any lore record. If a candidate item contains something like that, skip it and tell the user why.
- Skip the obvious. "We use TypeScript", "run the tests before
committing", and other things a model already knows about a typical
codebase belong in
CLAUDE.md(or nowhere), not in lore. Aim for non-obvious, high-consequence knowledge. - Use
record_absencesparingly. If the user explicitly confirms "we don't have a policy on X yet, and that's intentional", that's a legitimate absence marker — callrecord_absence({ query: "<topic>", reason: "<why no policy>", repo: <repo> }). Don't infer absence from "I didn't find anything in the README"; the user has to confirm it. Markers self-expire (14 days default) so they fade automatically if the team takes a stance later. - Use
report_conflictwhen you find a contradiction, not when you find a duplicate. Ifsearch_lorereturns an existing record and the source-of-truth you just read disagrees with it (e.g. README says "Argon2id", existing lore says "scrypt"), that's areport_conflictmoment. If the existing record just covers the same topic without contradicting, leave it alone —possibleConflictsin search results handles benign overlap.
Procedure
Follow these steps in order. Confirm with the user as the comments indicate.
Step 1 — confirm scope
Detect the current repo's short name (from git config --get remote.origin.url
or, failing that, from the working directory name). Confirm with the user:
"I'll onboard
<repo-name>to memory. Anything I should add to that, or remove? (e.g.payments-svc, auth-svcfor cross-repo notes)"
Capture the final repos array — every draft created in this session
will carry it.
Step 2 — survey the repo
Read these sources, in this order. Stop short of full-file reads when you can — skim for signals.
CLAUDE.md/AGENTS.md/.claude/CLAUDE.md(any of these agent-instruction files): highest-priority source. These already contain content the team has hand-curated for agents — sections like "Things That Catch People Out", "Conventions", "Gotchas", "Architectural decisions", "Migrations", and similar are designed for exactly the kind of content memory captures. Treat each H2/H3 subsection (or each bullet under such a heading) as a candidate. Your job is to triage durability — not just transcribe the file verbatim. If a bullet reads as task-specific or transient, skip it; if it reads as "this is how things are here and will be in six months", capture it.README.md— flag anything mentioning: "deprecated", "DO NOT USE", "WARNING", "legacy", "see also <ADR>", "incident", architectural choices, naming conventions, env vars with surprising defaults.docs/,docs/adrs/,docs/architecture/,ADRs/,decisions/,.architecture/— if any exist, scan titles and final-decision sections. ADRs are the cleanest source of "decisions that aren't obvious from code".MIGRATIONS.md/migrations//db/migrations/— in-flight migrations are gold for lore. Look for "TODO", recent file dates, companion code that handles both old + new schemas.- Top-level
package.json/pyproject.toml/go.mod/Cargo.toml— service name, peer-repo dependencies that suggest cross-repo conventions worth capturing. git log --oneline -50— recent commit subjects often hint at: in-flight migrations ("migrate X to Y"), deprecations ("remove legacy Z"), incident fixes ("fix INC-NNN: …"), policy decisions.- Grep for
// DEPRECATED,// TODO: remove,// WARNING:,// HACK:— these often mark non-obvious project knowledge.
Step 3 — surface candidate drafts
Build a list of 5–10 candidate drafts grounded in what you found. Present them to the user as a numbered list with the source citation:
Found these candidate items. Want me to draft any of them as lore?
- Don't touch
legacy/auth.tsexcept for security fixes. UserequireSession()for new auth gates. (Source: README.md L42–55; grep finds 12 active call sites ofrequireSession.)- In-flight migration: accounts → organisations. New code uses
org_id; reporting still joins onaccount_id. (Source: commit a4f12c0 + migrations/0017_accounts_to_orgs.sql.)- Webhook retries cap at 2h backoff to avoid downstream DoS. (Source: docs/adrs/0009-webhook-retry-cap.md, INC-411.) …
Reply with the numbers to draft (e.g.
1, 3, 5) or skip withnone. I can also propose more items if I missed anything.
Skip items that are:
- generic programming advice the model already knows
- obvious from a single file's contents
- task-specific or session-specific
- anything containing apparent secrets / PII / regulated data
- already covered by an existing lore record (run
search_lorefor near-duplicate titles before proposing)
Step 4 — draft via suggest_lore
For each item the user picks, call suggest_lore with this shape:
suggest_lore({
title: "<short title — what is the rule / fact?>",
summary: "<one-paragraph summary, stands alone>",
body: "Source: <file/line or commit sha or doc path>\n\n<full detail / reasoning / evidence>\n\n(onboarded via /memory-onboard, <iso date>)",
repos: <array confirmed in Step 1>,
tags: ["induction", <topic-specific extras>],
source: <PR/ADR/incident URL if you found one>,
confidence: <"medium" if source URL is present, else "low">,
team: <if obvious from CODEOWNERS or similar>
})
Drafts can't claim high confidence regardless — that invariant is
enforced server-side. Don't try.
After each call, note the returned id and any possibleDuplicates
the server flagged. If possibleDuplicateCount > 0 or
possibleDuplicates is non-empty, tell the user before continuing:
"Draft
<new-id>created. Memory flagged 2 possible duplicates:<id1>,<id2>. Worth reviewing those alongside this one."
Step 5 — wrap up
When the user is done picking, output a final summary:
Created N drafts in
<repo>:
<id1><title1><id2><title2> …Counter-drafts (from
report_conflict, if any):
<id3>challenges<existingId><one-line observation>Absence markers (from
record_absence, if any):
<query>—<reason>(expires in 14 days)Next steps:
memory review— interactive triage of the draftsmemory hooks install— opt-in: a Stop-hook nudges you to review pending drafts at session end so they don't rot in the queue (one-time-per-session, never nags)Drafts are invisible to default search until approved. Absence markers surface only on zero-hit searches matching the same normalised query.
If the user wants to keep iterating, loop back to Step 3 with a different angle (e.g. "now let's look at the test suite for authoritative-checks lore", or "let's scan for incident-lesson signals in the issues tracker").
Step 6 — (when invoked mid/end-of-session) ground in THIS session's work
The repo survey in Step 2 is a cold read. The higher-signal source, when you have it, is the work the current session just did — what you learned debugging, migrating, or fixing something here over the last hour is exactly the non-obvious knowledge the next agent will lack.
If this skill is invoked after real work in the session (not a first-touch cold start), before wrapping up ask yourself:
- Did I hit a gotcha that wasted time and will bite again? (a non-obvious constraint, a surprising default, an ordering rule)
- Did I discover a convention by reading code that isn't written down? (naming, auth, timezone, data-modelling)
- Did I steer away from a deprecated pattern after spotting it?
- Did I learn why a past decision was made that the code alone doesn't explain?
For each "yes", propose it as a candidate draft (same numbered-list +
confirm flow as Step 3) with the session as the citation — e.g.
Source: discovered while implementing <task> this session. Only
durable, project-specific findings; skip anything transient or
already-obvious (same Step 3 skip rules apply).
When a finding is already captured in a commit you made this session, tell the user the cheaper path instead of re-drafting it by hand:
"I committed the rationale in
a4f12c0. You can draft that straight from the message withmemory suggest --from-commit a4f12c0(it auto-derives the commit permalink as the source) rather than me retyping it."
This session-grounded pass is the difference between transcribing a repo and capturing what was actually learned working in it.
Step 7 — (optional) map cross-repo boundaries
While surveying the repo (Step 2) you'll often spot integration points: an event this service publishes, an endpoint it serves, a queue or table another team owns. These are boundary edges — the substrate of the cross-repo impact map.
- When you find a producer/consumer relationship, check the map first
with
find_dependents({ contract }), then record what's missing withdeclare_boundary({ repo, contract, role: "provides" | "consumes", kind?, detail?, source? }). Like lore, edges land as drafts — the human ratifies viamemory boundary review. - Use
provideswhen this repo OWNS / produces the contract;consumeswhen it depends on one owned elsewhere. - Don't invent edges. Only declare integration points you actually saw
in code/config (publish calls, route definitions, client calls, schema
references). Cite the evidence in
detailorsource.
This is how the "change this contract, what does it affect?" query gets
populated — one onboarding at a time, per repo, aggregated via sync.
A note on search results
When you call search_lore during onboarding to check for
near-duplicates, the server ranks hits by relevance adjusted for trust
(sourced, higher-confidence, non-stale records first), so the top hits
are the ones most worth comparing against. If a response includes a
truncated: { shown, total } block, more records matched than were
returned — narrow the query or raise limit before concluding a topic
is uncovered.
Out of scope for this skill
- Don't promote, deprecate, or supersede records. Those are CLI-only by design.
- Don't bulk-import existing docs as lore. Onboarding is
selective — the value is judgement about what's durable and
non-obvious, not volume. Transcribing every bullet of a doc floods the
review queue with noise and degrades the trust gate. Propose a focused
set; let the human ratify via
memory review. - Don't enable restricted records (
includeRestricted/ settingrestricted: true). If the user wants restricted lore, they author it via the CLI withmemory add --restricted. - Don't claim contradictions you can't prove. If
search_lorereturns existing records that overlap (possibleConflictspopulated), that's the runtime overlap heuristic — surface it but let the human decide. Only callreport_conflictwhen a source-of-truth you just read explicitly disagrees with the existing record (see Hard rule 7). - Don't blanket-record absences. A
record_absencemarker is only warranted when the user confirms "the team has intentionally not taken a stance on X". Inferring absence from "I didn't find anything" would seed wrong markers that mislead the next agent. - Don't install the Stop-hook on the user's behalf. Mention it
exists at wrap-up so they can opt in (
memory hooks install), but installing it silently changes their.claude/settings.json— that's their decision.