memory-attribution-lint
Skill1 starsChanged 39 days agoApache-2.0View on GitHub
Validate and auto-inject the 11-key provenance frontmatter contract on memory files at write time. Use when authoring memory entries, running lint passes on memory directories, or backfilling missing attribution fields. Enforces a uniform provenance schema (name, description, type, source_surface, host, tool, session_id, written_at_utc, source_path, confidence, lifecycle) so every memory entry is traceable to its origin surface, tool, and session.
In this repository12 other files it gives its agents.
- advisor-modeSkill
- brain-setupSkill
- ceo-briefSkill
- cerebro-doctorSkill
- council-modeSkill
- daily-briefSkill
- decisionSkill
- memory-recallSkill
- orchestrator-modeSkill
- sessionendSkill
- sessionstartSkill
- skill-manageSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 14
Write-time validator + auto-injector for memory file frontmatter.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
memory-attribution-lint
Write-time validator + auto-injector for memory file frontmatter. Enforces an 11-key
provenance contract on .md files in memory directories. Closes the "where did this
memory come from?" gap by capturing source surface, tool, host, and session at write
time.
Why provenance matters
Memory entries accumulate across sessions, tools, and surfaces. Without provenance, stale or contradictory entries are hard to triage. The 11-key contract gives every memory file a complete audit trail: who wrote it, from what tool, on what host, in what session, at what time, with what confidence, and at what lifecycle stage.
Contract
Required frontmatter keys:
| Key | Source | Auto-derived |
| name | author | NO |
| description | author | NO |
| type | author (user/feedback/project/reference) | NO |
| source_surface | env CLAUDE_SURFACE or default | YES |
| host | socket.gethostname() | YES |
| tool | env CLAUDE_TOOL or default unknown | YES |
| session_id | env CLAUDE_SESSION_ID or unknown | YES |
| written_at_utc | datetime.now(timezone.utc).isoformat() | YES |
| source_path | author declares | NO |
| confidence | author: high/med/low | NO |
| lifecycle | author: pinned/active/archived/closed/superseded/stale-by:YYYY-MM-DD | NO |
Scripts
scripts/lint.py: validate + auto-inject; exit 0=pass, 1=blocked, 2=injectedscripts/backfill.py: bulk backfill existing memory filesscripts/tests/fixtures/: golden samples for validation cases
Invocation
# Validate single file
python3 scripts/lint.py path/to/memory.md
# Dry-run (report only)
python3 scripts/lint.py --dry-run path/to/memory.md
# Backfill all memory dirs
python3 scripts/backfill.py --dry-run
python3 scripts/backfill.py --executeHook wire (PreToolUse)
See .claude/settings.json hooks.PreToolUse → Write/Edit matching **/memory/*.md.
The hook fires lint on any Write/Edit to a file matching the pattern; exit 1 blocks the
write until missing required keys are supplied, exit 2 auto-injects derivable keys and
allows the write to proceed.
Environment variables consumed
| Variable | Purpose | Default if unset |
CLAUDE_SURFACE | Tool surface label (cc / hermes / etc.) | unknown |
CLAUDE_TOOL | Specific tool that initiated the write | unknown |
CLAUDE_SESSION_ID | Session identifier for cross-reference | unknown |
Set these at session start to capture full provenance automatically. Without them, the
required keys still pass validation (defaulted to unknown) but lose audit value.
Scope Contract (Least-Privilege)
| Dimension | Scope |
| Read paths | Any .md file passed as target argument |
| Write paths | Same file (auto-inject mode only); never writes outside target |
| MCP / tool surface | None — pure Python, stdlib only |
| Network egress | None |
| Surface | Any (hook fires at write-time regardless of surface) |
| Credentials | None |
| Escalation trigger | Exit 1 (blocked write) — operator must add missing required keys manually |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

