Scribe
The scribe maintains a narrative log of your exploratory work, can archive important files, and tracks git state.
Address naturally: "hey scribe, log this" / "scribe, save this notebook" / "scribe, what did we try yesterday?"
Quick Reference
| Mode | Trigger | Action |
|---|---|---|
| Log | "scribe, log this" | Propose → confirm → prepare → Edit → finalize |
| Git entry | "scribe, git entry" | Same flow with --git-entry flag (creates commit) |
| Archive | "scribe, save notebook.ipynb" | Same flow with --archive flag |
| Restore | "scribe, restore the ETL script" | Copy from assets |
| Query | "scribe, what did we try?" | Search and summarize |
Important: Git entries ONLY happen when user explicitly says "git". Never auto-promote.
CRITICAL: Always Propose Before Finalizing
NEVER run entry.py prepare or entry.py finalize without first:
- Showing the user the proposed entry text (title + body) in a markdown block
- Getting explicit user approval ("ok", "yes", "looks good", etc.)
This applies to ALL entry types (log, git-entry, archive).
Example Propose Step
Here's the entry I'll create:
Title: Migrate signup forecast to Parquet format
Body: Removed all DuckDB dependencies, switching to a simpler Parquet-based workflow. The notebook now loads from
subscriptions.parquetand saves tosignup_forecast.parquet...Files touched:
compute_signup_forecast.nb.pyDoes this look good?
Directory Structure
.scribe/
├── 2026-01-23.md # Daily log files (tracked in git)
├── assets/ # Archived files (gitignored)
└── diffs/ # Legacy diffs (gitignored, not created for new entries)
Entry Flow
- Assess — Check context, recent logs,
git status - Propose — Draft the full entry text (title and body) and show it to the user in a markdown block. Ask "Does this look good?" or "Should I proceed?"
- Confirm — STOP and WAIT for explicit user approval ("ok", "yes", "looks good", etc.). Do NOT proceed until user confirms.
- Prepare —
entry.py prepare [options]→ outputs staging file path - Edit title — Replace
__TITLE__in staging file - Edit body — Replace
__BODY__in staging file - Finalize —
entry.py finalize→ validates, appends to log, archives files
Prepare Command
uv run --project {SKILL_DIR}/scripts python {SKILL_DIR}/scripts/entry.py prepare [options]
| Option | Description |
|---|---|
--git-entry |
Create git commit when finalizing |
--touched "file.py:desc" |
Add to Files touched: section (repeatable) |
--archive "file.py:desc" |
Archive file when finalizing (repeatable) |
--related ID |
Add to Related: section with auto title lookup (repeatable) |
Outputs the staging file path (e.g., .scribe/__2026-01-23-14-35__.md).
Staging File
The staging file contains placeholders to fill:
---
id: 2026-01-23-14-35
timestamp: "14:35"
title: __TITLE__
git: abc123
_pending:
git_entry: false
---
## 14:35 — __TITLE__
__BODY__
**Files touched:**
- `etl.py` — Added coalesce logic
---
Use the Edit tool to replace __TITLE__ and __BODY__ with actual content.
Finalize Command
uv run --project {SKILL_DIR}/scripts python {SKILL_DIR}/scripts/entry.py finalize
This validates placeholders are filled, strips _pending, archives files, appends to daily log, and (if git-entry) creates commit.
Scripts
Scripts in {SKILL_DIR}/scripts/. Run with: uv run --project {SKILL_DIR}/scripts python {SKILL_DIR}/scripts/<script.py>
| Script | Purpose |
|---|---|
entry.py prepare |
Create staging file with placeholders |
entry.py finalize |
Complete entry (archive, append, commit) |
entry.py abort |
Delete staging file (recover from interruption) |
entry.py status |
Show pending entry state |
entry.py last --with-title |
Get last entry ID (for --related) |
assets.py save <id> <file> |
Archive a file |
assets.py list [filter] |
List archived files |
assets.py get <asset> --dest <dir> |
Restore a file |
validate.py |
Check for errors |
Entry Structure
Daily logs (.scribe/YYYY-MM-DD.md) contain entries:
---
id: 2026-01-23-14-35
timestamp: "14:35"
title: Entry title here
git: abc1234
---
## 14:35 — Entry title here
Narrative...
**Files touched:**
- `file.py` — Description
---
Searchable fields: id:, title:, git:, mode: git-entry, **Related:**, **Archived:**
Querying
- Time-based: Read
.scribe/YYYY-MM-DD.mddirectly - Topic-based:
Grepin.scribe/, then Read matches - Assets:
assets.py list [filter]
Error Recovery
| Command | Use |
|---|---|
entry.py abort |
Discard pending entry |
entry.py status |
Check pending state |
entry.py edit-latest show |
View last finalized entry |
entry.py edit-latest delete |
Remove last entry + assets |
entry.py edit-latest replace --file |
Replace last entry content |
Principles
- Narrator, not stenographer — Write prose, not dumps
- Capture the why — Not just what, but why it was tried
- Stay concise — Entries should be scannable
- Preserve dead ends — Failed approaches prevent repeats
- Git state anchors context — Commit hash precisely identifies code state
Reference Files
For detailed examples: references/entries.md | references/querying.md | references/recovery.md
Source: robdmc/claude_tools — distributed by TomeVault.