Skip to content

docs: add journal-spec.md (Phase 1+2 reference + Phase 3+4 roadmap)#25

Merged
cleak merged 4 commits into
masterfrom
claude/journal-spec
Apr 28, 2026
Merged

docs: add journal-spec.md (Phase 1+2 reference + Phase 3+4 roadmap)#25
cleak merged 4 commits into
masterfrom
claude/journal-spec

Conversation

@cleak
Copy link
Copy Markdown
Owner

@cleak cleak commented Apr 28, 2026

Summary

Adds docs/journal-spec.md — a sibling document to graphspec.md focused on the journal subsystem (the tempyr-journal crate, tempyr journal * CLI, journal_log MCP tool).

Two purposes:

  1. Reference for what's shipped across Phase 1 (capture, #20) and Phase 2 (publish + ticker + config + init, PRs #22/#23/#24). Captures schema, lifecycle, atomicity guarantees, hardening choices, and operational surface.
  2. Roadmap for Phase 3 (search) and Phase 4 (auto-emit + polish) so a future contributor can pick up implementation without re-deriving design choices from PR threads.

Contents

§ Topic
1 Executive summary + phase map (1+2 ✅, 3+4 📋)
2 Storage (filesystem layout under <git-common-dir>/tempyr/journals/, git refs, worktree hashing)
3 Entry schema — 8 kinds, common + per-kind required fields, redaction rules
4 Session lifecycle — open_or_resume, find_active, append atomicity
5 Publisher pipeline — commit + push + cleanup, idempotency on crash, phase tracking, hardening, pack-refs cadence, in-process tokio ticker
6 Operational surface — state.json, publisher.log, CLI + MCP tools
7 Configuration — [journal] section + init wizard with gh-based visibility detection + auto-fetch refspec
8 Multi-machine sync (auto-fetch refspec + journal fetch)
9 Roadmap — slices 3a (index foundation), 3b (hybrid retrieval), 3c (auto-emit + hooks), v2 backlog
10 Known edge cases & design decisions (why orphan commits, why second-precision IDs, why single-publisher, why no SQLite yet, why gh for visibility, Windows path normalization, locked-file readability)
11 Open questions for Phase 3
12 References (code paths + PR links)

Accuracy

Cross-checked every claim against the shipped code:

  • Schema version (SCHEMA_VERSION = 1) ✓
  • All 28 fields in the Entry struct documented ✓
  • Per-kind validation rules (decision needs chosen/rationale/reversible + 50+ char detail; dead_end needs approach/failure_mode + 50+ char detail; assumption needs polarity) ✓
  • All 9 redaction rule names listed ✓
  • All 5 JournalConfig fields with their actual default values ✓
  • All 5 CLI subcommands (log/flush/status/logs/fetch) with current flags ✓

Where the spec describes Phase 3+4 it's clearly labeled "Planned" — no aspirational claims of shipped behavior.

Companion changes

  • CLAUDE.md and AGENTS.md both updated to point at the new spec alongside graphspec.md. Mirrored identically per project convention.

Test plan

  • wc -l docs/journal-spec.md → 449 lines, 13 sections
  • No code changes; no cargo runs needed
  • Spec content cross-checked against:
    • crates/tempyr-journal/src/entry.rs (schema)
    • crates/tempyr-journal/src/kind.rs (validation)
    • crates/tempyr-journal/src/redact.rs (rule names)
    • crates/tempyr-journal/src/config.rs (config defaults)
    • crates/tempyr-cli/src/main.rs (CLI surface)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Updated AI agent guidance to reference the new journal subsystem specification.
    • Added a comprehensive journal specification describing append-only reasoning logs, session lifecycle (open/resume/finalize), append/publish semantics and coordination, publication pipeline and reliability guarantees, operational state/logging contract, CLI/tooling surfaces and initialization behavior, configuration options, and planned indexing/search phases.

… 3+4 roadmap

Sibling document to graphspec.md focused on the journal subsystem
(`tempyr-journal` crate, `tempyr journal *` CLI, `journal_log` MCP
tool). Captures both shipped behavior and the planned trajectory so a
future contributor (human or agent) can pick up Phase 3 without
re-deriving design choices from PR threads.

Sections:

1. Executive summary + phase map
2. Storage architecture (filesystem + git refs + worktree hash)
3. Entry schema (8 kinds, per-kind validation, redaction)
4. Session lifecycle (open/resume/finalize, append atomicity)
5. Publisher pipeline (commit + push + cleanup, idempotency, phase
   tracking, hardening, pack-refs cadence, in-process ticker)
6. Operational surface (state.json, publisher.log, CLI + MCP tools)
7. Configuration ([journal] section, init wizard with gh-based
   visibility detection, auto-fetch refspec)
8. Multi-machine sync
9. Roadmap — slices 3a (index foundation), 3b (hybrid retrieval),
   3c (auto-emit + hooks), and v2 backlog
10. Known edge cases & design decisions (why orphan commits, why
    second-precision IDs, why single-publisher, why no SQLite yet,
    why gh for visibility, Windows path normalization, locked file
    readability)
11. Open questions for Phase 3
12. References (code paths + PR links)

Cross-checked against the actual code: schema version, entry struct
field set, kind validation rules, redaction rule names, config
defaults, and CLI surface all reflect what's shipped, not aspirational.

CLAUDE.md and AGENTS.md updated to point at the new spec alongside
graphspec.md (mirrored identically per project convention).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

Adds a new journal subsystem specification document and updates agent-facing docs to reference it; the spec defines an append-only JSONL reasoning journal, git-backed storage layout and refs, session lifecycle and append atomicity, publisher pipeline for creating parent-less commits and pushing archives, CLI/operational surfaces, and a roadmap for indexing and auto-emit features.

Changes

Cohort / File(s) Summary
Agent Guidance Documentation
AGENTS.md, CLAUDE.md
Updated agent-facing guidance to reference the new docs/journal-spec.md in addition to the existing docs/graphspec.md.
Journal Subsystem Specification
docs/journal-spec.md
New comprehensive spec describing on-disk layout for open sessions under <git-common-dir>/tempyr/journals/open/, archived refs under refs/tempyr/journals/archive/..., JSONL entry schema with versioning/validation/redaction modes, session open/resume/finalize semantics, append atomicity and publisher.lock, publisher pipeline (blob/tree/parent-less commit/update-ref/push), state/log contracts (state.json, publisher.log), CLI/MCP surfaces, config wiring ([journal], tempyr init/gh detection), and Phase 3/4 roadmap for indexing and auto-emit enhancements.

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant JournalFS as Journal Filesystem
  participant Publisher
  participant Git as Git (local)
  participant Remote as Remote (origin)

  Agent->>JournalFS: append JSONL entry (acquire append lock)
  JournalFS-->>Agent: ack (entry written)
  Note over JournalFS,Publisher: entries accumulate under .../open/<session>/
  Publisher->>JournalFS: acquire publisher.lock
  Publisher->>Git: write blobs/trees, create orphan commit
  Git-->>Publisher: commit created (refs update candidate)
  Publisher->>Remote: push refs/tempyr/journals/archive/...
  Remote-->>Publisher: push ack
  Publisher->>JournalFS: record progress in state.json and rotate publisher.log
  Publisher->>JournalFS: cleanup open files and release publisher.lock
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • cleak/outline-playground#52: Modifies agent-facing docs to adjust journaling/bootstrap guidance; directly related to the AGENTS.md/CLAUDE.md changes.
  • cleak/outline-playground#70: Updates agent instructions with journal-related guidance and agent flows; related to the new journal spec reference.

Poem

🐰 I hop through lines of JSON and ink,

Appending thoughts before you blink,
Commits tuck secrets in a tidy nest,
Publisher hums and does its best,
A rabbit cheers: journals blessed! 🥕📜

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a new comprehensive documentation file for the journal subsystem with both reference material and roadmap information.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/journal-spec.md`:
- Around line 185-189: The docs contradict the meaning of the `.ready` marker:
update the append/finalize semantics so the `.ready` marker is consistently
defined and used—specifically, ensure `session.is_ready()` denotes a
finalized/ready-for-publisher state and that `entry.is_final` does not "drop"
the `.ready` marker during append; instead, clarify that finalizing an entry
should set (or leave) the `.ready` marker and that only an explicit
finalize/publisher-consume action removes it. Update the lines describing step 2
(`session.is_ready()`), step 5 (`entry.is_final` behavior), and any lifecycle
section referencing `.ready` so they all describe the same lifecycle transition.
- Line 24: Update compound-adjective hyphenation: change instances where
compound modifiers precede nouns to use hyphens — e.g., in the sentence
containing journal_search "auth middleware" change "finds the dead end someone
hit two weeks ago" to "finds the dead-end someone hit two weeks ago" (or
rephrase to "finds the dead end that someone hit..." if post-nominal), and
change any "Two layered detectors" occurrences (line ~141) to "two-layered
detectors" (or "two-layer detectors" if preferred). Ensure both occurrences of
these compound adjectives are consistently hyphenated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0782b692-7995-4d47-9273-dfefab2bea4c

📥 Commits

Reviewing files that changed from the base of the PR and between 25db36f and 83b775d.

📒 Files selected for processing (3)
  • AGENTS.md
  • CLAUDE.md
  • docs/journal-spec.md

Comment thread docs/journal-spec.md Outdated
Comment thread docs/journal-spec.md Outdated
…modifiers

Two findings:

1. **`.ready` marker semantics in append step 5 were ambiguous.** "drop
   the `.ready` marker" could be read as either "create one" or "remove
   one", and the actual code (`session.finalize()`) creates it via
   touch. Rewrote step 5 to say "**create** the `.ready` marker via
   `session.finalize()`" matching the verb already used on line 178
   ("touches"), and explicitly stated that the publisher is the only
   actor that ever **removes** the marker (after a successful commit +
   push or `--no-push` cleanup, per §5). Also expanded step 2 to make
   `is_ready()` semantics — the **finalized-and-handed-off** signal —
   explicit so steps 2 and 5 obviously describe the same lifecycle
   transition.

2. **Compound-adjective hyphenation inconsistent.** Five "dead end"
   prose usages (decisions/dead-ends list, "the dead-end someone hit",
   "Most dead-ends trace back", path-scoped queries) and one "Two
   layered detectors" all hyphenated for consistency with the
   already-hyphenated "dead-end rate" later in the doc and the
   `dead_end` snake-case kind name in code.

Verified all `.ready`/`finalize` references in the doc now agree:
filesystem layout (line 50: "publisher may commit"), finalize helper
(line 178: "touches"), append step 2 (line 185: "finalized-and-
handed-off"), append step 5 (line 188: "create"), publisher cleanup
(line 206: "removed last").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/journal-spec.md`:
- Line 381: Typo in the "Cross-encoder reranking" bullet: replace the malformed
word "rerunlp" with "rerun through" (or "rerun through a small reranker") in the
bullet that begins "Cross-encoder reranking" so the line reads e.g.
"**Cross-encoder reranking** — top-k from RRF rerun through a small reranker for
higher precision on close calls."; locate the bullet by its text "Cross-encoder
reranking" and update the phrase accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b0db7999-b426-41da-9027-67021182a2ae

📥 Commits

Reviewing files that changed from the base of the PR and between 83b775d and e1df998.

📒 Files selected for processing (1)
  • docs/journal-spec.md

Comment thread docs/journal-spec.md Outdated
Was clearly a fingers-tangled artifact of typing "rerun" + something else.
Now reads "top-k from RRF rerun through a small reranker for higher
precision on close calls."

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/journal-spec.md`:
- Line 336: Update the description for
`<git-common-dir>/tempyr/journals/index.db` in docs/journal-spec.md to remove
the misleading term "gitignored" and instead state that the file is derived and
rebuildable and not part of repository content (e.g., "derived and rebuildable;
not part of repository content"). Locate the occurrence of the path
`<git-common-dir>/tempyr/journals/index.db` and replace the phrase "gitignored"
with the clearer wording.
- Around line 330-374: The docs mix phase scopes: the "Phase 3: Search and
Retrieval" header contains "Slice 3c — Auto-emit + hooks + polish" which belongs
to Phase 4; fix by moving the "Slice 3c — Auto-emit + hooks + polish" block out
of the Phase 3 section into the Phase 4 section (or rename it to "Phase 4a" and
adjust subsequent slice numbers), and update any cross-references so "Phase 3:
Search and Retrieval", "Slice 3a/3b", and the auto-emit/hooks material are
consistently assigned to Phase 3 vs Phase 4.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9e138e0c-975d-479e-862e-8113ddb0721b

📥 Commits

Reviewing files that changed from the base of the PR and between e1df998 and af0a3ae.

📒 Files selected for processing (1)
  • docs/journal-spec.md

Comment thread docs/journal-spec.md
Comment thread docs/journal-spec.md Outdated
Two findings, both real:

1. **"gitignored" was misleading.** The index.db lives at
   `<git-common-dir>/tempyr/journals/index.db` — i.e., inside `.git/`,
   which isn't part of the repo content tree at all. There's nothing to
   gitignore (gitignore only governs files in the work tree). Reworded
   to "rebuildable; lives inside `.git/`, so it's not part of
   repository content and never tracked".

2. **Roadmap contradicted §1 phase map.** Section 1's phase map
   assigns auto-emit + hooks + MCP annotations + docs to Phase 4
   ("Polish"), but the Roadmap section had a "Slice 3c" with exactly
   that content under Phase 3, and labeled the v2 backlog as Phase 4.
   Restructured:
   - Phase 3: Search and Retrieval = slices 3a + 3b only (index +
     hybrid retrieval)
   - Phase 4: Auto-Emit, Hooks, and Polish (was "Slice 3c" content) —
     now matches §1's Phase 4 scope
   - Beyond Phase 4: v2 Backlog (was "Phase 4: v2 Backlog") — items
     that aren't planned for the four-phase rollout but are tracked

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/journal-spec.md`:
- Around line 96-104: The spec's field constraints for the journal entry must
match the Entry contract: update the `summary` field to the Entry-defined
constraint (1–500 chars after trim) instead of 20–200, and replace the loose
“free-form” description for `tags` with the same bounded format rules used by
Entry (the tag format/length/character rules from the Entry contract). Locate
the `summary` and `tags` rows in the table (and any nearby descriptions) and
make them identical to the Entry contract wording so CLI/MCP callers and
validators use the same constraints.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7a11b9fb-2deb-408c-a809-903f8cf5ff8a

📥 Commits

Reviewing files that changed from the base of the PR and between af0a3ae and 2c2ad20.

📒 Files selected for processing (1)
  • docs/journal-spec.md

Comment thread docs/journal-spec.md
Comment on lines +96 to +104
| `v` | u32 | yes | Schema version, currently `1` |
| `id` | string | yes | `j-<uuid_v4>` |
| `ts` | RFC3339 datetime | yes | UTC wall-clock at write time |
| `agent` | string | yes | Default `"claude"`; identifies which agent wrote this |
| `kind` | enum | yes | One of `plan` / `finding` / `assumption` / `question` / `decision` / `dead_end` / `risk` / `outcome` |
| `summary` | string | yes | 20–200 chars after trim |
| `detail` | string | optional* | Required for `decision` and `dead_end` (50+ chars after trim) |
| `tags` | string[] | optional | Free-form labels |
| `files` | string[] | optional | Repo-relative paths (forward slashes, even on Windows) |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Align field constraints in the spec with the Entry contract.

Line 101 and Line 103 currently over-constrain/describe fields differently than the implementation contract: summary is documented as 20–200, and tags as “free-form,” while the Entry contract documents summary as 1–500 and tags with bounded format constraints. This can mislead CLI/MCP callers and downstream validators.

📌 Suggested doc correction
-| `summary` | string | yes | 20–200 chars after trim |
+| `summary` | string | yes | 1–500 chars after trim |
@@
-| `tags` | string[] | optional | Free-form labels |
+| `tags` | string[] | optional | Structured labels; each tag 1–40 chars, `[a-z0-9_-]` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/journal-spec.md` around lines 96 - 104, The spec's field constraints for
the journal entry must match the Entry contract: update the `summary` field to
the Entry-defined constraint (1–500 chars after trim) instead of 20–200, and
replace the loose “free-form” description for `tags` with the same bounded
format rules used by Entry (the tag format/length/character rules from the Entry
contract). Locate the `summary` and `tags` rows in the table (and any nearby
descriptions) and make them identical to the Entry contract wording so CLI/MCP
callers and validators use the same constraints.

@cleak
Copy link
Copy Markdown
Owner Author

cleak commented Apr 28, 2026

On the latest comment about §3 common-fields constraints — verified against the actual Entry contract and not applying the requested change, because applying it would put the spec out of sync with the shipped code.

Summary constraint: the suggestion to use "1–500 chars after trim" doesn't match the code. The runtime validator in kind.rs:127–132 uses (20..=200).contains(&len) and emits the exact error string "summary length {len} out of bounds (must be 20..=200 chars)". The struct doc comment at entry.rs:118 also says validated 20..=200 chars at write time. The spec line already says "20–200 chars after trim", which is the faithful description.

Tags constraint: the Entry contract doesn't define format/length/character rules for tags. The field is pub tags: Vec<String> with a doc comment that only notes the "tool" tag convention; validate_entry doesn't touch tags at all. "Free-form labels" is accurate.

Happy to be corrected if I'm missing a constraint defined elsewhere — pointer welcome.

@cleak cleak merged commit 4b4ea58 into master Apr 28, 2026
1 check passed
@cleak cleak deleted the claude/journal-spec branch April 28, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant