-
Notifications
You must be signed in to change notification settings - Fork 0
Memory Model
Zeref OS stores everything in plain markdown under memory/, with append-only event logs and snapshots. Single-writer enforced via memory-keeper agent (per shared rule R1). v2.6.1 adds PATTERNS.jsonl event schema validation (L5 + L15).
memory/
├── hot.md ← last 3 sessions, ≤500 words (read FIRST per AGENTS.md §0)
├── index.md ← domain index (read if hot insufficient)
├── MEMORY.md ← agent-written session notes (NOT human-edited)
├── DECISIONS.md ← confirmed decisions w/ provenance + evidence grade
├── OPEN_QUESTIONS.md ← unresolved questions w/ owner
├── RISKS.md ← identified risks w/ severity
├── CONFLICTS.md ← contradiction queue (user arbitrates)
├── glossary.md ← project-specific term definitions
├── projects/ ← per-sub-project context (if multi-project repo)
├── patterns/
│ └── PATTERNS.jsonl ← append-only event log; 11-event schema (v2.6.1)
├── snapshots/<iso>/ ← point-in-time wiki state + manifest
├── archive/ ← superseded snapshots (never deleted per R2)
├── raw/ ← untouched source material
└── sync/
├── outbound/ ← staged parent updates
└── parent/ ← received parent updates
The "boundary file" pattern prevents unbounded reads:
-
First: read
memory/hot.md(≤500 words, current context) -
Second: read
memory/index.mdif hot is insufficient — find the relevant domain row - Third: read only the named section of the named page
- Never: load a full page just to scan it
This caps always-on context to ~3-4k tokens regardless of project age.
All writes flow:
skill output
↓
memory-keeper (conflict detect, advisory lock via zeref/lock.py)
↓
privacy-guardian (PRIVACY.md mode + REDACT.md classes + SHARING_POLICY.md allowlist)
↓
disk (with PII scrub per v2.5 L11)
No skill writes to memory/ directly. Concurrent writes blocked by zeref/lock.py::MemoryLock (v2.5 L9). Atomic write semantics via atomic_write / atomic_append (v2.5 L10).
When memory-keeper detects a conflict:
- Halt write
- Subject/predicate/value fingerprint match against DECISIONS / OPEN_QUESTIONS / RISKS
- Append both sides to
memory/CONFLICTS.md - Surface to user immediately OR snooze until
/done(user choice) - User arbitrates (via
contradiction-resolutionskill) — never silent - Resolved entry moves to
memory/DECISIONS.mdwith both-sides provenance
4 anti-patterns refused: recency-wins · grade-wins · silent-drop · indefinite-snooze.
Append-only event log. Every event is a single JSON line:
{"ts":"2026-06-08T14:00:00Z","agent":"memory-keeper","event":"wiki-write","target":"memory/DECISIONS.md","payload":{"summary":"..."},"hash":"sha256:...","evidence_grade":"high"}11 allowlisted event types (validated by scripts/zeref-validate.py::lint_patterns_log()):
| Event | Required payload | Optional payload |
|---|---|---|
wiki-write |
summary | — |
session-start |
— | trigger, scope, budget_ceiling_usd, team, force_multipliers |
memory-drift-detected |
finding | — |
budget-gate (v2.6) |
weight, tier, match | est_cost_usd, budget_remaining_usd, override_reason |
skill-route (v2.6) |
domain, lead, support, qa | ext |
tool-probe (v2.6) |
tool, reachable | path, fallback, marker_verified |
prompt-gate (v2.6) |
classification | restructured, brief_tokens, stripped_context_tokens, injection_detected |
handoff-compress (v2.6) |
original_tokens, compressed_tokens, ratio | model_from, model_to, harness_from, harness_to |
tier-change |
from, to | — |
grep-with-context |
— | action |
log-cutover |
— | from, to, note |
Value enums (enforced):
-
weight∈ {CRITICAL, HIGH, MEDIUM, LOW} -
tier∈ {OPUS, SONNET, HAIKU, OPUS-equivalent, SONNET-equivalent, HAIKU-equivalent}
Hard constraints (L14 stack cap + Core Principle 14):
-
skill-routewithlen(support) + 2 > 5→ lint error -
budget-gatewith(CRITICAL, HAIKU)or(LOW, OPUS)unlessmatch=OVERRIDE→ lint error
Background scan of PATTERNS.jsonl over rolling 48–80h window:
- Task signature: verb + subject + 3-gram qualifiers
- Jaccard similarity ≥ 0.8 over qualifier 3-gram sets
- Union-find clustering; discard clusters < 3 members
- Scoring:
frequency × (1 / recency_span_hours) - Top-3 by score per scan; rest logged as suppressed
- Emits candidates →
pattern-to-skill(review-first)
Activation: /done, /stop, /status, manual. Background only — never blocks active work.
On /done, full memory/ state copied to memory/snapshots/<iso>/ with manifest.json. Never deleted (R2 non-deletion). Used by parent-sync for rollback + by memory-import-export for backup.
Per parent-sync skill (v4.1 origin, v2.6.1 R6-aware):
- STAGE: filter via
evidence-curator(≥medium); pass throughprivacy-guardian; write tomemory/sync/outbound/<iso>/withmanifest.json - APPROVE: explicit user confirmation with preview
- PUSH: copy to
<parent_path>/memory/sync/parent/<child_id>/<iso>/; chmod 444; log PUSHED - PARENT INGEST: parent's
/startruns conflict detection on incoming entries - ROLLBACK: via provenance pointers
- R6 (v2.6.1): every staged entity must survive verbatim into parent; re-diff after privacy-abstraction
local-only privacy mode blocks all parent sync.
Per budget-governor (v2.6 rewrite):
| Tier | Per-skill cap | Behavior |
|---|---|---|
| HAIKU | 4 000 tok | Aggressive compaction, minimal wiki writes |
| SONNET | 8 000 tok | Normal operation, full wiki writes |
| OPUS | 16 000 tok | Full parent-child sync, deep conflict analysis |
warn_at_tokens (default 50000) → consolidation suggested. hard_cap_tokens → blocks writes; forces /done.
python3 scripts/zeref-validate.py
# Skills: 14/14 (from zeref-registry.json)
# Memory layout: flat
# PATTERNS lint: 0 finding(s)
# ✔ Validation passed- Privacy-Model — modes + classes + connectors
- Pattern-Detection — Two-Strikes Rule + drafting
- Architecture — agents + skills + 4-gate chain
- Glossary — boundary file, evidence grade, R6, gate event types
-
_shared/rules.md— R1-R6
Getting Started
Architecture
- Architecture · 14 skills · 4 gates
- Memory-Model · flat + PATTERNS schema
- Privacy-Model · 3 modes + R6
- Team-Packs · 6 on-demand
- Pattern-Detection · Two-Strikes
Reference