Use when querying and maintaining the knowledge base for project context, decisions, and architecture documentation on session start.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add oyi77/1ai-skills --skill kb --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Kb?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/oyi77-1ai-skills)More formats (shields.io, HTML) on the badges page.
---
name: kb
category: core
domain: core
author: oyi77
license: Apache-2.0
subdomain: core-platform
version: 2.0.0
description: Use when querying and maintaining the knowledge base for project context, decisions, and architecture documentation on session start.
tags:
- infrastructure
- memory
- self-improvement
- para
- persistence
---
# Knowledge Base (KB)
## Overview
The Knowledge Base (KB) is a PARA-structured persistent memory system for AI agents.
It survives agent compactions, session boundaries, and context window limits by storing
facts, decisions, architecture records, and project state in files on disk.
**PARA stands for:**
- **P**rojects — active deliverables with deadlines
- **A**reas — ongoing responsibilities without end dates
- **R**esources — reference material, templates, cross-references
- **A**rchives — stale content, git-preserved, never deleted
The KB works alongside the `memory` MCP tools (`search_nodes`, `open_nodes`,
`read_graph`, `create_entities`, `add_observations`, `create_relations`) and the
file-based scratchpad pattern. Use all three layers together:
| Layer | Scope | Persistence | Example |
|---|---|---|---|
| KB files | Long-term org memory | Indefinite (git) | `~/kb/projects/foo/facts.yaml` |
| MCP knowledge graph | Relationship graph | Per-session + recall | Entities, relations, observations |
| Scratchpad file | Active session bridge | < 30 min | `~/.kb-session-context.md` |
## Workflow
The KB lifecycle follows a predictable loop across every agent session:
```
Session Start → Load Context → Check Decisions → Work & Capture → Log → Session End
```
### Per-Session Loop
1. **Cold start** — MCP server connects, scratchpad is checked for < 30 min state
2. **Load yesterday** — last session's End-of-Session Summary is retrieved
3. **Open decisions** — all facts with `status: open` across every category
4. **Work** — agent performs tasks, captures facts as they arise
5. **Log decisions** — every resolved decision gets a fact with `status: confirmed`
6. **End-of-Session** — summary written, scratchpad updated, git commit + brain save
### Weekly Loop
1. Archive projects untouched > 90 days
2. Prune stale observations
3. Rebuild entity cross-reference index
4. Review open decisions for closure
5. Verify all code blocks in KB skills parse correctly
---
## Querying the Knowledge Base
### Using MCP Memory Tools
The `memory` MCP server exposes a knowledge graph. Query it with structured tools:
**search_nodes** — find entities by name or pattern:
```python
# Python — via MCP
result = tool.memory_search_nodes(query="client-alpha")
for node in result.nodes:
print(f"{node.name}: {node.entity_type}")
for obs in node.observations:
print(f" - {obs}")
```
**open_nodes** — load full entity details including all observations and relations:
```python
nodes = tool.memory_open_nodes(names=["client-alpha", "website-redesign"])
for node in nodes:
print(f"=== {node.name} ({node.entity_type}) ===")
for obs in node.observations:
print(f" {obs}")
```
**read_graph** — dump the entire knowledge graph for cold-start initialization:
```python
graph = tool.memory_read_graph()
print(f"Entities: {len(graph.entities)}")
print(f"Relations: {len(graph.relations)}")
```
### Using Filesystem grep
When the MCP server is unavailable, fall back to filesystem tools:
```bash
# Find all facts about a specific entity
grep -r "entity: client-alpha" ~/kb/
# List all open decisions across every project
grep -r "status: open" ~/kb/projects/ --include="facts.yaml"
# Quick count of entities per category
for d in projects areas resources; do
count=$(find ~/kb/$d -maxdepth 2 -name "facts.yaml" | wc -l)
echo "$d: $count entities"
done
# Search daily notes for a keyword
rg "blocker" ~/kb/areas/daily/
```
---
## Writing to the Knowledge Base
### Creating Entities
Register a new entity in the knowledge graph:
```python
# Start tracking a project entity
tool.memory_create_entities([
{
"name": "client-alpha-website",
"entityType": "project",
"observations": [
"Client: Alpha Corp",
"Deadline: 2026-09-30",
"Stack: Next.js + Tailwind + Supabase",
"Status: in_progress"
]
}
])
```
### Adding Observations
Add facts to an existing entity as you discover them:
```python
# Attach new facts mid-session
tool.memory_add_observations([
{
"entityName": "client-alpha-website",
"observations": [
"Decided: use Stripe for payments, not Paddle",
"API contract: GET /api/projects returns paginated list",
"Blocker: waiting for client to send brand assets"
]
}
])
```
### Creating Relations
Link entities to model dependencies, influences, and ownership:
```python
# Wire up relationships between entities
tool.memory_create_relations([
{
"source": "client-alpha-website",
"target": "payment-integration",
"relationType": "depends_on"
},
{
"source": "client-alpha-website",
"target": "auth-patterns",
"relationType": "references"
},
{
"source": "alice",
"target": "client-alpha-website",
"relationType": "owns"
}
])
```
### File-Based Storage (YAML)
Canonical writer for per-entity YAML fact files alongside the knowledge graph:
```python
import yaml
from datetime import datetime
from pathlib import Path
KB = Path.home() / "kb"
def save_fact(entity: str, category: str, value: str, **kw):
"""Append one fact to a per-entity YAML file.
Args:
entity: the thing being described (project, tool, client)
category: 'projects', 'areas', or 'resources'
value: the fact text
**kw: optional metadata (status, priority, related, source)
"""
dir_ = KB / category / entity
dir_.mkdir(parents=True, exist_ok=True)
facts_file = dir_ / "facts.yaml"
facts = []
if facts_file.exists():
with open(facts_file) as f:
facts = yaml.safe_load(f) or []
facts.append({
"value": value,
"recorded_at": datetime.now().isoformat(),
**kw
})
with open(facts_file, "w") as f:
yaml.dump(facts, f, default_flow_style=False, sort_keys=False)
return facts_file
```
---
## Maintenance
### Pruning Stale Observations
Knowledge graphs accumulate noise. Run periodic pruning:
```python
def prune_stale_observations(days_threshold=90):
"""Flag observations older than threshold for review."""
from datetime import timedelta
cutoff = datetime.now() - timedelta(days=days_threshold)
stale = []
for category in ["projects", "areas", "resources"]:
for facts_file in (KB / category).rglob("facts.yaml"):
with open(facts_file) as f:
records = yaml.safe_load(f) or []
fresh = []
for rec in records:
recorded = datetime.fromisoformat(rec["recorded_at"])
if recorded < cutoff and rec.get("status") != "archived":
stale.append({
"file": str(facts_file),
"value": rec["value"],
"recorded_at": rec["recorded_at"]
})
else:
fresh.append(rec)
if len(fresh) != len(records):
with open(facts_file, "w") as f:
yaml.dump(fresh, f, default_flow_style=False, sort_keys=False)
return stale
```
### Weekly Review Checklist
- [ ] Move completed projects from `projects/` to `archives/`
- [ ] Delete observations marked "obsolete" or "superseded"
- [ ] Verify all open decisions still need resolution
- [ ] Run `entity-index-gen.py` to rebuild the cross-reference
- [ ] Check that today's daily note has an End-of-Session Summary
### Archiving Stale Content
```bash
#!/usr/bin/env bash
# archive-stale.sh — move projects untouched for 90+ days to archives
KB=~/kb
CUTOFF=$(date -d "90 days ago" +%s)
for dir in "$KB"/projects/*/; do
last=$(git -C "$KB" log -1 --format="%at" -- "$dir" 2>/dev/null || echo 0)
if [ "$last" -gt 0 ] && [ "$last" -lt "$CUTOFF" ]; then
name=$(basename "$dir")
mv "$dir" "$KB/archives/projects/$name"
echo "Archived: $name"
fi
done
```
---
## Session Start Routine
This is the critical cold-start flow every agent session should execute.
### Step 1 — Check the Scratchpad Bridge
```python
from pathlib import Path
from datetime import datetime, timedelta
SCRATCHPAD = Path.home() / ".kb-session-context.md"
def load_session_context():
"""Read the bridge file if it exists and is fresh (< 30 min)."""
if not SCRATCHPAD.exists():
return {"state": "cold_start", "context": {}}
mtime = datetime.fromtimestamp(SCRATCHPAD.stat().st_mtime)
if datetime.now() - mtime > timedelta(minutes=30):
return {"state": "stale", "context": {}}
text = SCRATCHPAD.read_text()
context = {}
for line in text.split("\n"):
if line.startswith("- "):
key, _, val = line[2:].partition(": ")
context[key.lower()] = val
return {"state": "warm", "context": context}
```
### Step 2 — Load the Knowledge Graph
```python
# Re-establish entity context
graph = tool.memory_read_graph()
stale_entities = [e.name for e in graph.entities
if "stale" in (e.observations or [])]
# Open entities related to today's focus
focus = "client-alpha"
related = tool.memory_open_nodes(names=[focus])
for node in related:
print(f"Loaded: {node.name} — {len(node.observations)} observations")
```
### Step 3 — Create Today's Daily Note
```python
def ensure_daily_note():
"""Create today's note if it doesn't exist."""
KB = Path.home() / "kb"
today = datetime.now().strftime("%Y-%m-%d")
note_file = KB / "areas" / "daily" / f"{today}.md"
if note_file.exists():
return note_file
# Load yesterday's summary for continuity
yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
yesterday_file = KB / "areas" / "daily" / f"{yesterday}.md"
yesterday_summary = ""
if yesterday_file.exists():
text = yesterday_file.read_text()
if "## End-of-Session Summary" in text:
yesterday_summary = text.split("## End-of-Session Summary", 1)[1]
content = f"""# Daily Note: {today}
## Session Focus
_(What is the single most important outcome this session?)_
## Continuity Context
{yesterday_summary}
## Open Decisions Needing Input
## Plan
- [ ]
## Decisions Made Today
## End-of-Session Summary
_Write before closing — this bridges the next session._
"""
note_file.parent.mkdir(parents=True, exist_ok=True)
note_file.write_text(content)
return note_file
```
### Step 4 — Load Open Decisions
```python
def load_open_decisions():
"""Return every entity fact with status=open."""
KB = Path.home() / "kb"
decisions = []
for category in ["projects", "areas", "resources"]:
for facts_file in (KB / category).rglob("facts.yaml"):
with open(facts_file) as f:
records = yaml.safe_load(f) or []
for rec in records:
if rec.get("status") in ("open", "pending"):
decisions.append({
"entity": facts_file.parent.name,
"category": category,
"value": rec["value"]
})
return decisions
```
### Full Bash Session Starter
```bash
#!/usr/bin/env bash
# kb-session.sh — run at every agent session start
KB=~/kb
TODAY=$(date +%Y-%m-%d)
YESTERDAY=$(date -d yesterday +%Y-%m-%d)
NOTE=$KB/areas/daily/$TODAY.md
# Step 1: Load yesterday's summary
if [ -f "$KB/areas/daily/$YESTERDAY.md" ]; then
echo "=== Yesterday's Summary ==="
sed -n '/## End-of-Session Summary/,$ p' \
"$KB/areas/daily/$YESTERDAY.md" | head -20
fi
# Step 2: Check open decisions
echo ""
echo "=== Open Decisions ==="
grep -rl "status: open" "$KB"/{projects,areas,resources}/*/facts.yaml 2>/dev/null \
| while read -r f; do
entity=$(basename "$(dirname "$f")")
grep -A1 "value:" "$f" | head -2
echo " (entity: $entity)"
done || echo " None"
# Step 3: Create today's note
if [ ! -f "$NOTE" ]; then
cat > "$NOTE" <<EOF
# Daily Note: $TODAY
## Session Focus
## Decisions Made Today
## End-of-Session Summary
---
EOF
echo ""
echo "Created $NOTE — edit the focus line and begin."
fi
```
---
## Anti-Rationalization Table
| Rationalization | Reality |
|---|---|
| "I remember what happened last session" | Agents lose everything on compaction. Without KB files, you start blank. |
| "The code comments are enough documentation" | Comments describe *what*; KB describes *why* you chose that approach. |
| "YAML facts are too structured for quick notes" | Unstructured daily notes cost nothing. Structure grows as the entity matures. |
| "I'll backfill facts when the project settles" | The gap between "I know this" and "I wrote this" is where information rot begins. |
| "grep is fast enough for recall" | grep finds text. Semantic relationships need the knowledge graph. |
| "My projects are too small for PARA" | PARA scales down to one file per entity. Starting flat means refactoring 200 files later. |
| "The scratchpad file is enough" | The scratchpad handles *active* bridging; the KB handles *permanent* organizational memory. |
| "Daily notes are for humans, not agents" | Agents read more daily notes than humans do — they have zero tacit context. |
| "I don't need relations — tags are fine" | Relations model causality and dependency. Tags model membership. Both are needed. |
| "Archiving is busywork" | Without archiving, every grep finds 3-year-old context about dead projects. |
---
## Verification Checklist
- [ ] `~/kb/{projects,areas,resources,archives}` directory tree exists
- [ ] Today's daily note is present at `~/kb/areas/daily/YYYY-MM-DD.md`
- [ ] Yesterday's daily note contains an End-of-Session Summary section
- [ ] `save_fact()` writes valid YAML re-readable with `yaml.safe_load()`
- [ ] Entity facts contain `recorded_at`, `value`, and `status` fields
- [ ] `load_open_decisions()` returns at least one result before cleanup
- [ ] Knowledge graph has at least 3 entity types registered
- [ ] Scratchpad bridge file is written on session end, checked on session start
- [ ] Scratchpad older than 30 minutes is treated as stale (not loaded)
- [ ] `prune_stale_observations(90)` returns no false positives
- [ ] All Python code blocks parse without syntax errors
- [ ] All bash code blocks pass `bash -n` syntax check
- [ ] Archive script has been run at least once
- [ ] YAML fact files are under git — `git log --oneline` shows fact history
- [ ] Weekly review checklist completed within the last 7 days
---
## When to Use
Use this skill when working with kb. Specifically:
- **Every session start** — load context, check open decisions, create daily note
- **After every decision** — capture as a YAML fact with `status: open` or
`status: confirmed`
- **At session end** — write End-of-Session Summary, update scratchpad, commit
- **During investigations** — store entity facts as you discover them
- **Weekly** — review stale content, archive untouched projects
- **When spawning subagents** — share relevant KB entities via `local://` URIs
so subagents start with context instead of cold
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!