Agent Journal
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 (or you just want to capture a useful note), the journal can push back (for decisions) or simply record tagged notes.
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 everything (journal + the coding agent dora should use on the fly when you later run journal add) with the recommended top-level command:
dora init(You can still use the more focused doraval journal init if you only want the journal part.)
journal init is designed to be low-friction:
- It detects a sensible default for your journal repo from the current git remote (preferred) or your active GitHub account.
- It shows you where the default came from before prompting.
- It remembers the journal repo you used previously, so subsequent projects are faster.
- Fully scriptable via
--repo/--projectflags orDORAVAL_JOURNAL_REPO/DORAVAL_PROJECTenvironment variables.
The command stores the mapping in ~/.doraval/config.yml (never in your project) and fetches the journal files locally. No per-project config files, submodules, or symlinks are required.
Entry format
Section titled “Entry format”## Use "drift" not "score" for rubric deviation
```yamlpushback: 7tags: [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. |
tags | Tags for categorization (decisions or notes): 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:
- Tag filter (cheap): Match the current action’s domain against entry 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 publishes pending entries to the remote and refreshes your local cache. (Advanced maintenance features like projects/_index.md and auto-archiving older entries are planned but not yet implemented.)
Commands
Section titled “Commands”doraval journal init # One-time setup: register project + link to journal repodoraval journal list # View active principles for the current projectdoraval journal update # Pull the latest from the remote GitHub repo into local cachedoraval journal add # Propose a decision/note or capture long rich markdown (--raw-markdown) (stages locally)doraval journal sync # Publish pending entries + refresh cacheTypical workflow
Section titled “Typical workflow”# Start of a session or before using journal-aware toolsdoraval journal update
# Explore current principlesdoraval journal list
# Capture a decision you just madedoraval journal add "Always use 'update' not 'refresh' for cache pulls" \ --pushback 6 \ --tags cli,docs
# At the end of the session (or when ready to share)doraval journal syncupdate keeps the local ~/.doraval/journals/ mirror fresh. sync always refreshes first, then publishes anything in pending/.
journal check and Principle drift integration into skill drift / validate are the major remaining pieces (see the implementation plan).
For a clear explanation of the mental model and why the journal is built this way, see How the Agent Journal Works.
See the individual command pages under Commands (e.g. journal init, journal update) for flag details and examples.
Integration with existing commands
Section titled “Integration with existing commands”doraval skill driftgains Principle drift: flags when a skill contradicts an active journal entry (planned).doraval eval/skill judgecan be extended in the future to incorporate journal entries as additional context for the LLM judge.- Entries with
pushback >= 7surface as warnings indoraval skill validate(planned).
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.