journal-review — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited journal-review (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
User provides:
Scope parameters:
JOURNAL_BASE: ~/journal/ (hardcoded, matches /journal and /journal-recall skills)REVIEW_CATEGORIES: decisions, learnings, actions, themesDECISION_SIGNALS: "decided", "chose", "went with", "opted for", "tradeoff", "picked", "selected", "decision:"LEARNING_SIGNALS: "learned", "discovered", "figured out", "TIL", "gotcha", "insight", "realization", "aha"ACTION_SIGNALS: "- [ ]", "TODO", "follow up", "need to", "action item", "next step"Action: Parse user input to determine the date range for the review.
Date resolution rules:
Validation:
Category filter:
Tool declarations: Bash (date calculations)
Checkpoint: Review period resolved to concrete start/end dates, categories determined
Action: Read all daily and meeting entries within the review period.
File discovery:
$JOURNAL_BASE/daily/*.mdYYYY-MM-DD from filename, include if within [start, end]$JOURNAL_BASE/meetings/*.mdYYYY-MM-DD prefix from filenameIf no entries found:
PASS: no entries found for review period (searched daily/ and meetings/)Content extraction per file:
Tool declarations: Glob (find files), Read (file content), Bash (date filtering)
Checkpoint: All entries for review period loaded into working memory
Action: Scan loaded entries for each active category using signal-word matching and contextual analysis.
Resilience note: Scan the full file content for signal words using grep-style matching across the entire entry text, not only named sections. Section-scoped matches (e.g., content found under ## Decisions Made) are treated as higher-confidence candidates, but signal matches anywhere in the file are included. If an entry is missing expected sections (e.g., no ## Learnings heading), log a warning but still scan the full content.
Scan strategy:
## Decisions Made sections in daily entries for inline decisions not linked to decisions/ files (matches here are higher-confidence)[[decisions/2026-02-23-worktree-isolation]])Scan strategy:
## Learnings sections and **Learning:** fields in work session blocks[[learnings/project-recovery-strategy]])Scan strategy:
- [ ] (not - [x])## Tomorrow's Priorities, ## Action Items, ## Follow-up, ## Next Steps sections@person in meeting notes)- [x] (completed) in a later daily entry within the vault. If so, mark as "completed" and exclude from candidates.Scan strategy:
projects: field and **Project:** linesTool declarations: Grep (signal-word search), Read (section extraction — files already loaded from Step 1)
Checkpoint: All candidates extracted and categorized
Action: For decision and learning candidates, check whether a formal entry already exists that covers the same topic.
$JOURNAL_BASE/decisions/# ADR: heading or YAML title: field) of each existing decision file$JOURNAL_BASE/learnings/# Learning: heading or YAML title: field) of each existing learning fileTool declarations: Glob (list existing entries), Read (entry titles/content)
Checkpoint: Candidates filtered — only genuinely unlogged items remain; filtered candidates preserved for user audit
Action: Present remaining candidates to the user, grouped by category, and collect approval/dismissal decisions.
Pagination: If any category contains more than 10 candidates, present the top 10 (ranked by signal confidence: section-scoped matches first, then recency) and note: "{N} additional candidates found. Say 'show more {category}' to see them."
Presentation format:
For each active category that has candidates, present a summary block:
## Unlogged Decisions (N candidates)
### 1. {Inferred Topic}
**Source:** daily/{date}.md, line ~{N}
**Signal:** "{signal phrase in context}"
**Context:** {1-3 sentences of surrounding context}
**Recommendation:** Create ADR? [approve / dismiss]
### 2. {Inferred Topic}
...
## Unlogged Learnings (N candidates)
### 1. {Inferred Topic}
**Source:** daily/{date}.md
**Signal:** "{signal phrase in context}"
**Context:** {1-3 sentences of surrounding context}
**Recommendation:** Create learning entry? [approve / dismiss]
...
## Untracked Action Items (N candidates)
### 1. {Action Text}
**Source:** daily/{date}.md
**Status:** Open (not found as completed in later entries)
**Age:** {N days since entry date}
...
## Recurring Themes (N themes)
### 1. {Theme Name}
**Frequency:** Mentioned in {N} entries
**Dates:** {date1}, {date2}, ...
**Snippets:** {representative excerpts}
**Note:** This is informational — no entry created for themes.
...
## Filtered by Cross-Reference (N items)
The following candidates were excluded because they appear to match existing entries.
If any were filtered incorrectly, say "restore {category} {number}" to promote them.
### 1. {Candidate Topic}
**Source:** daily/{date}.md
**Signal:** "{signal phrase in context}"
**Matched to:** {existing entry filename and title}
**Reason:** {one-line explanation of why it was considered a match}
...If no candidates in any category:
PASS: no candidates found (reviewed N entries across N days)Interaction:
Tool declarations: AskUserQuestion (user approval)
Checkpoint: Approval list finalized
Action: For each approved candidate, create a formal journal entry using the same templates and conventions as the /journal skill.
$JOURNAL_BASE/decisions/YYYY-MM-DD-{sanitized-topic}.md.., remove chars outside [a-zA-Z0-9_-], lowercase, limit 100 chars{Decision Name} = inferred topic from Step 2adate = source entry date## Context = extracted context from the daily entry## Decision = the decision text from the signal match## Rationale = any surrounding reasoning from the daily entry, or <!-- Fill in rationale -->**Project:** = project from source entry's YAML frontmatter or session block[[daily/YYYY-MM-DD]]$JOURNAL_BASE/ (traversal protection)$JOURNAL_BASE/learnings/{sanitized-topic}.md{Topic Name} = inferred topic from Step 2bdate = source entry date## Context / **Why I learned this:** = extracted context### What I Discovered = the learning text**Project:** = project from source entry[[daily/YYYY-MM-DD]]Action items are NOT created as new journal entries. Instead, they are reported as a summary list for the user to track manually. The skill does not create a tracking system.
Output for action items:
## Open Action Items Summary
| # | Action | Source | Date | Age |
|---|--------|--------|------|-----|
| 1 | {action text} | daily/{date}.md | {date} | {N} days |
| 2 | ... | ... | ... | ... |
These items were found as open (unchecked) in your daily entries.
Consider adding them to your current daily entry's Tomorrow's Priorities
or closing them with `- [x]` in the source file.Verdict:
PASS: created N entries (M decisions, K learnings) from review of {date range}PASS: all candidates dismissed, no entries created (reviewed N daily entries)FAIL: {reason} (N of M entries written successfully)Tool declarations: Write (new files), Bash (date operations, path sanitization), Glob (check existing files)
Checkpoint: All approved entries created, results reported
The following templates are used for entries created by this skill. They are identical to the /journal skill's embedded templates to ensure consistency across the journal vault. On-disk templates at ~/journal/templates/{type}.md override these if present.
IMPORTANT — template duplication policy: At implementation time, templates were copied character-for-character from /journal SKILL.md v1.0.0 (the authoritative source). Each embedded template includes a version tracking comment. If /journal templates change, re-sync these templates.
<!-- Template source: /journal SKILL.md v1.0.0 — re-sync if /journal templates change -->
---
title: Decision Name
date: YYYY-MM-DD
status: accepted | rejected | superseded | deprecated
tags: [decision, architecture]
projects: []
---
# ADR: {Decision Name}
## Status
**Status:** Accepted
**Date:** YYYY-MM-DD
**Deciders:** <your-name>
**Project:** [[project-name]]
## Context
<!-- What is the issue that we're seeing that is motivating this decision? -->
## Decision
<!-- What is the change that we're proposing? -->
## Rationale
<!-- Why are we making this decision? -->
### Options Considered
1. **Option A:**
- Pros:
- Cons:
### Why We Chose This
## Consequences
### Positive
-
### Negative
-
### Neutral
-
## Implementation
**Implemented in:** [[project-name]]
**Date implemented:** YYYY-MM-DD
**Commits:**
## Related Decisions
- [[decisions/other-decision]]
## References
-<!-- Template source: /journal SKILL.md v1.0.0 — re-sync if /journal templates change -->
---
title: Topic Name
date: YYYY-MM-DD
tags: [learning]
category: technical | pattern | tool
confidence: beginner | intermediate | advanced
---
# Learning: {Topic Name}
## Context
**When:** [[daily/YYYY-MM-DD]]
**Project:** [[project-name]]
**Why I learned this:**
## The Learning
### What I Discovered
### How It Works
### Why It Matters
## Code Example
## Gotchas / Pitfalls
-
## Related Concepts
- [[other-learning]]
## References
-
## Application
**Used in:** [[project-name]]
**Date applied:** YYYY-MM-DD
**Outcome:**Not applicable: Journal review creates permanent journal entries, not workflow artifacts. The review results are communicated directly to the user during the session.
Not applicable: The approval loop is bounded by the number of candidates (finite, extracted from a finite set of entries). There is no revision loop — the user approves or dismisses each candidate once.
Not applicable: Journal entries are the final output, not intermediate artifacts requiring archival.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.