docs: add journal-spec.md (Phase 1+2 reference + Phase 3+4 roadmap)#25
Conversation
… 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>
📝 WalkthroughWalkthroughAdds 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
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
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
AGENTS.mdCLAUDE.mddocs/journal-spec.md
…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>
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
docs/journal-spec.md
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>
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
docs/journal-spec.md
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>
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
docs/journal-spec.md
| | `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) | |
There was a problem hiding this comment.
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.
|
On the latest comment about §3 common-fields constraints — verified against the actual Summary constraint: the suggestion to use "1–500 chars after trim" doesn't match the code. The runtime validator in Tags constraint: the Happy to be corrected if I'm missing a constraint defined elsewhere — pointer welcome. |
Summary
Adds
docs/journal-spec.md— a sibling document tographspec.mdfocused on the journal subsystem (thetempyr-journalcrate,tempyr journal *CLI,journal_logMCP tool).Two purposes:
Contents
<git-common-dir>/tempyr/journals/, git refs, worktree hashing)open_or_resume,find_active, append atomicitystate.json,publisher.log, CLI + MCP tools[journal]section + init wizard with gh-based visibility detection + auto-fetch refspecjournal fetch)ghfor visibility, Windows path normalization, locked-file readability)Accuracy
Cross-checked every claim against the shipped code:
SCHEMA_VERSION = 1) ✓Entrystruct documented ✓JournalConfigfields with their actual default values ✓Where the spec describes Phase 3+4 it's clearly labeled "Planned" — no aspirational claims of shipped behavior.
Companion changes
CLAUDE.mdandAGENTS.mdboth updated to point at the new spec alongsidegraphspec.md. Mirrored identically per project convention.Test plan
wc -l docs/journal-spec.md→ 449 lines, 13 sectionscargoruns neededcrates/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