Core Concepts
July 11, 2026 · View on GitHub
Forgetful organizes knowledge into nine building blocks. Understanding when to use each one makes the difference between a cluttered knowledge dump and a useful, searchable knowledge graph.
The Building Blocks
Memories
Atomic knowledge units - one concept per note.
Memories are the core of Forgetful. Each memory captures a single fact, decision, preference, or insight. Think of them as the nodes in your knowledge graph.
Important: Memories are the only directly queryable type. Documents and Code Artifacts must be linked to memories to be discoverable through search.
Good memories are:
- Easily titled - if you can't summarize it in ~10 words, it's probably not atomic
- Self-contained - understandable without needing to read other memories
- Linkable - small enough to connect precisely to related concepts
Examples:
- "Chose Stripe over PayPal for lower fees and better webhook support"
- "Use temperature 0.7 for creative tasks, 0.2 for factual queries"
- "Scott prefers explicit error handling over silent fallbacks"
Limits: 200 char title, ~300-400 words content
Provenance tracking: Memories can optionally track their origin for traceability:
source_repo- Repository where the knowledge originatedsource_files- Specific files that informed the memorysource_url- URL to original source materialconfidence- How confident the encoding agent was (0.0-1.0)encoding_agent- Which AI/process created this memoryencoding_version- Version of the encoding processagent_id- Logical identity of the agent (e.g., 'CodeAgentUltra')agent_version- Version of the agentagent_model- LLM model used (e.g., 'claude-sonnet-4-6')
Entities
Real-world things - people, organizations, devices, products.
Entities represent concrete nouns that exist in the world. They can have relationships with each other and link to memories. Use entities when you want to track WHO or WHAT is involved, not just the knowledge itself.
Types: Organization, Individual, Team, Device, System, Other (with custom_type)
Examples:
- Sarah Chen (Individual) - "Backend lead, payments team"
- TechFlow Systems (Organization) - "SaaS platform company"
- Production Server 01 (Device) - "Primary API server, us-east-1"
- GPT-4 (Product) - "OpenAI's flagship model"
Relationships: Entities connect to each other (e.g., "Sarah works_at TechFlow") and to memories (e.g., "Sarah" linked to "Hired Sarah for Stripe integration").
Plans
Containers for structured work - goals, context, and ordered tasks.
Plans represent intent and procedure, not knowledge. While memories capture what you know, plans capture what you intend to do. Each plan lives within a project and decomposes a goal into concrete tasks.
Plans follow a lifecycle: draft → active → completed → archived. A draft plan is being shaped; an active plan is in progress; a completed plan has all its tasks done; an archived plan is retained for reference but no longer actionable.
Good plans have:
- A clear goal - what does "done" look like?
- Context - background information an implementer needs to get started
- Ordered tasks - a breakdown of the work, not a vague wish list
Examples:
- "Migrate payment provider from PayPal to Stripe" (active)
- "Set up CI/CD pipeline for staging environment" (draft)
- "Evaluate and select embedding model" (completed)
Tasks
Work units within plans - assignable, trackable, state-machined.
Tasks are the actionable steps inside a plan. Each task has a service-enforced state machine: todo → doing → done, with two additional terminal/pause states: waiting (blocked on an external dependency) and cancelled (no longer needed).
Tasks support atomic claiming via optimistic locking - when an agent picks up a task, the transition is conflict-safe even with concurrent workers. Each task carries a priority level (P0 = critical, P1 = high, P2 = normal, P3 = low) and an optional agent assignment so multiple agents can coordinate without stepping on each other.
Task dependencies: Tasks can declare dependencies on other tasks within the same plan. A task cannot transition to doing until all of its dependencies are done. The system enforces cycle detection at creation time - if adding a dependency would create a circular chain (A → B → C → A), the request is rejected.
Examples:
- "Create Stripe webhook endpoint" (P1, todo, assigned: backend-agent)
- "Write migration script for subscription records" (P0, doing)
- "Update API documentation for new payment flow" (P2, waiting)
Acceptance Criteria
Boolean conditions on tasks - the definition of done.
Acceptance criteria are first-class children of tasks. Each criterion is a clear, verifiable condition that must be satisfied before a task can transition to done. All criteria on a task must be met for completion.
This enables a clean separation of concerns: a planner defines criteria up front, an implementer does the work and marks criteria as met, and a reviewer validates the results. The workflow becomes planner-sets-criteria → implementer-does-work → reviewer-validates.
Good criteria are:
- Binary - unambiguously true or false, no subjective judgment
- Verifiable - an agent or person can check it without guessing
- Scoped - tied to one observable outcome, not a compound condition
Examples (for a "Create Stripe webhook endpoint" task):
- "Endpoint returns 200 for valid Stripe signature"
- "Invalid signatures return 400 with error detail"
- "Events are persisted to the webhook_events table"
- "Integration test covers payment_intent.succeeded event"
Documents
Long-form reference material - guides, analysis, specifications.
When content exceeds ~300 words or covers multiple related concepts, use a document. Documents are meant to be referenced, not retrieved in full during every query.
Best practice: Create the document, then extract 3-7 atomic memories that link back to it. This gives you both the detailed reference AND searchable knowledge atoms.
Examples:
- "Payment Integration Architecture Guide" - 2000 word technical spec
- "Q4 Planning Meeting Notes" - detailed discussion summary
- "TTS Engine Evaluation Report" - comparison of 5 different engines
Code Artifacts
Reusable code snippets - patterns, templates, examples.
Attach working code to memories so agents can retrieve not just the concept but a concrete implementation.
Examples:
- Stripe webhook handler boilerplate
- FastAPI dependency injection pattern
- React form validation hook
Skills
Procedural knowledge - step-by-step instructions and agent capabilities.
Skills bridge the gap between knowledge (memories) and action. While memories capture WHAT you know, skills capture HOW to do things. Each skill follows the Agent Skills open standard with a kebab-case name, description, and markdown instructions.
Skills have semantic search via embedded descriptions, making them discoverable by capability rather than exact name. They can be imported/exported as SKILL.md files for portability across 30+ agent platforms (Claude Code, Cursor, Gemini CLI, etc.).
Examples:
- "code-review" - Systematic code review process for pull requests
- "deploy-staging" - Deploy application to staging environment
- "data-pipeline-etl" - Extract, transform, and load data from external sources
Fields: kebab-case name (max 64), description (max 1024), content (markdown, max 100KB), license, compatibility, allowed_tools, metadata, tags, importance
Projects
Organizational scope - groups memories by context.
Projects help you filter queries to relevant knowledge. When working on the e-commerce platform, you don't need memories from the trading bot project cluttering your results.
Examples:
- "E-Commerce Platform Redesign" (status: active)
- "Q4 Hiring Initiative" (status: completed)
- "AI Agent Framework" (status: active)
Provenance Tracking
Forgetful supports optional provenance fields on all object types so you can trace where knowledge came from and which agent encoded it. This is particularly useful when multiple agents or tools write to the same knowledge base.
Supported Fields
| Field | Description | Example |
|---|---|---|
source_repo | Repository or project the knowledge came from | "owner/repo" |
source_files | List of file paths that informed this object | ["src/payments.py"] |
source_url | URL to the original source material | "https://github.com/..." |
confidence | Encoding confidence score (0.0–1.0) | 0.9 |
encoding_agent | Software running the agent | "OpenCode" |
encoding_version | Version of the encoding software | "1.3.13" |
agent_id | Logical identity of the agent | "CodeAgentUltra" |
agent_version | Version of the agent | "1.0" |
agent_model | LLM model the agent used | "claude-sonnet-4-6" |
Coverage by Object Type
- All 9 fields: Memories, Projects, Documents, Code Artifacts, Skills, Files, Entities, Plans, Tasks
- 8 fields (no
confidence): Entity relationships — these already carry their own relationship-level confidence - Memories previously had 6 fields;
agent_id,agent_version, andagent_modelwere added to bring them in line with all other types
Environment-Level Defaults
Six environment variables let a server operator set provenance defaults that apply automatically to every create operation, without requiring individual agents to pass these values explicitly:
ENCODING_AGENT, ENCODING_VERSION, AGENT_ID, AGENT_VERSION, AGENT_MODEL, ENFORCE_ENV_OVERWRITE
The apply_provenance_defaults() utility fills in any missing provenance fields from these env values at create time.
ENFORCE_ENV_OVERWRITE
When ENFORCE_ENV_OVERWRITE=true, environment defaults override any provenance values the calling agent provides. This lets a server operator enforce consistent provenance across a shared instance regardless of what individual agents pass in — useful for audit or compliance scenarios where you need to guarantee which tool and model encoded each object.
When false (the default), agent-provided values take precedence and env values only fill gaps.
Decision Flow: What Goes Where?
| Question | Answer |
|---|---|
| Is it a person, org, device, or product? | Entity |
| Is it a goal that decomposes into steps? | Plan |
| Is it a concrete piece of work to be done? | Task |
| Is it a verifiable condition for "done"? | Acceptance Criterion |
| Is it step-by-step procedural knowledge? | Skill |
| Is it detailed analysis or a guide (>300 words)? | Document |
| Is it a single fact, decision, or preference? | Memory |
| Is it reusable code? | Code Artifact |
| Does it help scope/filter other knowledge? | Project |
The Litmus Test
Memory vs Entity
Entity = a thing that EXISTS (noun you could point at) Memory = knowledge ABOUT things (facts, decisions, preferences)
Ask: "Can I point at it?" If yes, probably an entity. If it's abstract knowledge, it's a memory.
- "Sarah Chen" - Entity (she exists)
- "Sarah is great at debugging async issues" - Memory (knowledge about Sarah)
Memory vs Document
Memory = single concept, scannable, <400 words Document = multiple concepts, reference material, >300 words
Ask: "Is this ONE idea or MANY?" One idea = memory. Many related ideas = document (then extract atomic memories from it).
- "Chose XTTS-v2 for voice cloning" - Memory
- "TTS Engine Evaluation comparing 5 engines with benchmarks" - Document
Memory vs Plan
Memory = knowledge about something (retrospective) Plan = intent to do something (prospective)
Ask: "Am I recording what happened, or describing what should happen?" Past/present knowledge = memory. Future work with steps = plan.
- "Chose Stripe for lower fees" - Memory (a decision already made)
- "Migrate payment provider from PayPal to Stripe" - Plan (work to be done)
Skill vs Memory
Skill = how to do something (procedural, reusable steps) Memory = knowledge about something (declarative fact or decision)
Ask: "Is this a procedure someone would follow, or a fact someone would recall?" Steps to follow = skill. Facts to know = memory.
- "How to review pull requests in this project" - Skill
- "We use conventional commits for all PRs" - Memory
Task vs Memory
Task = something to be done, with a state and an owner Memory = something to be known, permanently
Ask: "Will this be 'done' at some point?" If yes, it's a task. Memories don't get completed - they stay true.
- "Write migration script for subscriptions" - Task (it will be done or cancelled)
- "Subscription data lives in the billing schema" - Memory (a fact that persists)
When to Use Projects
Create a project when you have:
- Multiple related memories that should be queried together
- Work context that you'll return to repeatedly
- A need to exclude unrelated knowledge from searches
Worked Example 1: E-Commerce Project
You're building a payment system. Here's how to decompose the knowledge:
Entities:
- Stripe (Product) - "Payment processor API"
- PayPal (Product) - "Alternative payment processor"
- Jordan Taylor (Individual) - "Backend engineer, payments team"
- TechFlow Systems (Organization) - "The company"
Project:
- "E-Commerce Platform v2" (active)
Document:
- "Payment Gateway Evaluation" - 1500 word comparison of Stripe vs PayPal vs Square
Memories (extracted from document + decisions):
- "Chose Stripe over PayPal: better webhooks, lower fees, superior fraud detection"
- "PCI compliance: use Stripe Elements to avoid handling raw card data"
- "Subscription billing requires Stripe Billing API, not one-time charges endpoint"
- "Jordan Taylor owns payment integration - hired specifically for Stripe experience"
Code Artifact:
- Stripe webhook signature verification snippet
Links:
- Memories link to → Stripe entity, PayPal entity, Jordan entity
- Memories link to → Payment Gateway Evaluation document
- Everything scoped to → E-Commerce Platform v2 project
Worked Example 2: AI Agent Project
You're developing a coding assistant agent. Here's the breakdown:
Entities:
- Claude Sonnet (Product) - "Anthropic's fast model"
- Claude Opus (Product) - "Anthropic's reasoning model"
- OpenAI (Organization) - "GPT provider"
- Production Agent Server (Device) - "Hosts the deployed agent"
Project:
- "AI Coding Assistant" (active)
Document:
- "Prompt Engineering Guidelines" - 2000 word guide on system prompts, temperature, context management
Memories (extracted + decisions):
- "Use Claude Sonnet for quick edits, Opus for complex refactoring"
- "Temperature 0.3 for code generation, 0.7 for explanations"
- "System prompt must include repo structure for accurate file references"
- "Context window overflow: summarize conversation history after 50k tokens"
- "Tool calls: prefer specific tools over generic bash when available"
Code Artifact:
- Conversation summarization prompt template
- Tool result truncation logic
Links:
- Model-related memories link to → Claude Sonnet, Claude Opus entities
- Infrastructure memories link to → Production Agent Server entity
- Everything scoped to → AI Coding Assistant project
Quick Reference
| Type | Size | Contains | Links To |
|---|---|---|---|
| Memory | <400 words | One concept | Memories, Entities, Documents, Code Artifacts |
| Entity | N/A | Real-world thing | Other Entities, Memories |
| Plan | N/A | Goal + context | Tasks, Project |
| Task | N/A | Work unit + state | Acceptance Criteria, Plan, Agent |
| Acceptance Criterion | N/A | Boolean condition | Task |
| Document | >300 words | Multiple concepts | Memories |
| Code Artifact | Variable | Working code | Memories |
| Skill | Variable | Procedural instructions | Memories, Projects |
| Project | N/A | Scope/context | Memories, Plans |
The knowledge graph emerges from these connections. Memories are the atoms; entities, documents, skills, and projects provide structure and context. Plans, tasks, and acceptance criteria layer intent on top of knowledge, letting agents coordinate structured work.