A decision memory with opinions — records project principles and argues back when they're violated.
An agent journal is a structured decision log that lives in a private GitHub repo. It records the decisions, directions, and philosophies behind a project. Both humans and AI coding agents can propose entries. Only the doraval CLI writes to the remote.
When a change conflicts with a recorded principle, the journal pushes back — not as a blocker, but as an argument with calibrated intensity.
The problem
Section titled “The problem”Decisions get lost across Slack threads, commit messages, and agent sessions that start fresh with no memory. An agent makes reasonable choices that accidentally contradict deliberate ones.
The journal is a persistent memory with opinions. It doesn’t block — it argues.
Architecture
Section titled “Architecture”The journal has two layers:
Remote: A private GitHub repo (e.g., saif-shines/saif-shines.md) with global.md for universal principles and projects/<name>.md for project-specific decisions.
Local: doraval maintains a cache at ~/.doraval/ — not in the project directory. No submodules, no symlinks, no config files polluting your repos.
~/.doraval/├── config.yml # Journal repo + project mappings├── journals/ # Cached journal files│ ├── global.md│ └── doraval.md└── pending/ # Proposed entries awaiting sync └── doraval/Register a project once:
doraval journal initThis asks for the journal repo and project name, stores the mapping in ~/.doraval/config.yml, and fetches the journal files. No per-project config needed.
Entry format
Section titled “Entry format”## Use "drift" not "score" for rubric deviation
```yamlpushback: 7scope: [naming, cli]author: humandate: 2026-05-25status: active```
We renamed `score` to `drift` because "score" implies a generic qualityrating. The command measures deviation from a rubric — distance from astandard, not a grade.Fields
Section titled “Fields”| Field | Description |
|---|---|
pushback | 1–10. How hard the journal argues if violated. |
scope | Tags: naming, cli, architecture, testing, ux, api, docs. |
author | human or agent:<name>. |
date | ISO date. |
status | active, superseded, or retired. |
superseded_by | (Optional) Title of the replacing entry. |
The pushback scale
Section titled “The pushback scale”| Range | Label | What it means |
|---|---|---|
| 1–3 | Nudge | ”This diverges slightly. Probably fine, just be aware.” |
| 4–6 | Friction | ”This contradicts a deliberate decision. Reconsider.” |
| 7–10 | Wall | ”Core philosophy conflict. Override explicitly or update the journal.” |
Even pushback 10 is an argument, not a gate.
Conflict detection
Section titled “Conflict detection”Two-stage hybrid approach:
- Scope-tag filter (cheap): Match the current action’s domain against entry scope tags. Fast and deterministic.
- Semantic check (matches only): For entries that pass the filter, the human (v1) or agent (v2) judges whether the change actually contradicts the principle.
Single writer pattern
Section titled “Single writer pattern”Agents and humans propose entries. Only doraval journal sync writes to the remote. No race conditions.
Human/Agent → doraval journal add → ~/.doraval/pending/ → doraval journal sync → GitHubsync also updates projects/_index.md and auto-archives entries older than 1 year when files exceed 300 lines.
Commands
Section titled “Commands”doraval journal init # One-time project registrationdoraval journal list # Show active entriesdoraval journal check # Check work against principlesdoraval journal add <title> # Propose a new entrydoraval journal sync # Push pending, update index, archiveIntegration with existing commands
Section titled “Integration with existing commands”doraval skill driftgains Principle drift — flags when a skill contradicts an active journal entry.doraval skill judgeuses the journal as context for AI assessment.- Entries with
pushback >= 7surface as warnings indoraval skill validate.
What this is NOT
Section titled “What this is NOT”- Not an AGENTS.md replacement. AGENTS.md says how to work. The journal says why decisions were made.
- Not a changelog. Principles and reasoning, not a list of changes.
- Not a linter. Opinions with conviction levels, not pass/fail rules.
- Not a blocker. Every pushback can be overridden — but the conflict must be acknowledged.