Session-orchestrator daily
git clone https://github.com/Kanevry/session-orchestrator
T=$(mktemp -d) && git clone --depth=1 https://github.com/Kanevry/session-orchestrator "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/daily" ~/.claude/skills/kanevry-session-orchestrator-daily && rm -rf "$T"
skills/daily/SKILL.mdDaily Skill
Status
IMPLEMENTED 2026-04-13.
Purpose
Bootstraps today's daily note in the Meta-Vault so the user can start capturing thoughts, scratch work, and "done today" items without yak-shaving YAML frontmatter each morning. The daily note is the anchor of the PKM workflow: it is where the inbox flow starts, where daily momentum is tracked, and where evening reflections land. Every daily note carries the same frontmatter shape (validated by
vaultFrontmatterSchema), which makes Dataview queries and the
vault-sync validator trivial.
Prerequisites
- Must be invoked from inside a Meta-Vault root (cwd contains
) OR with03-daily/
resolved to the vault path (see Resolution Order below).VAULT_DIR
must already exist — the skill fails fast if it does not.03-daily/
+bash
+sed
(always available on macOS/Linux).date
VAULT_DIR Resolution Order
in Session Config (highest precedence)vault-integration.vault-dir
environment variableVAULT_DIR
(fallback when neither is set)$PWD
Claude must read Session Config and export
VAULT_DIR before calling
generate.sh. The canonical pattern (mirrors session-end and evolve):
CONFIG=$(cat .orchestrator/session-config.yaml | yq -o json) VM_DIR=$(echo "$CONFIG" | jq -r '."vault-integration"."vault-dir" // empty') : "${VM_DIR:=$VAULT_DIR}" VAULT_DIR="$VM_DIR" bash /path/to/skills/daily/generate.sh
generate.sh itself reads only VAULT_DIR (pure bash, no Config parser).
Algorithm
- Resolve
. CheckVAULT_DIR
in Session Config first; fall back to thevault-integration.vault-dir
env var; thenVAULT_DIR
. The config field takes precedence — see Prerequisites for the canonical resolution snippet.$PWD
then validates: template exists (exit 2 if not), vault dir exists (exit 3 if not),generate.sh
exists (exit 4 if not).03-daily/ - Compute today's date.
— ISO 8601 date-only, respecting the system timezone (the user is in Vienna, sodate +%Y-%m-%d
via system TZ).Europe/Vienna - Target path.
.$VAULT_DIR/03-daily/YYYY-MM-DD.md - Idempotency check. If the target already exists, print
and exit 0. Never overwrite.Daily note already exists: <path> - Render template. Read
(next to this SKILL.md) and substitutetemplates/daily.md.tpl
,{{date}}
,{{id}}
,{{created}}
,{{updated}}
,{{title}}
via{{weekday}}
. The template is literal markdown; the only shell interpolation happens in thesed
substitutions.sed - Write to target path. Uses
to avoid leaving a half-written file on disk if sed fails.sed … > "$TARGET.tmp" && mv "$TARGET.tmp" "$TARGET" - Validate (recommended but not automatic in
). Callers should run the vault-sync validator over the vault in hard mode to confirm schema compliance:generate.sh
The BATS test suite runs this check on every run — seeVAULT_DIR="$VAULT_DIR" bash ../vault-sync/validator.sh --mode hard
. If validation ever fails, the template has drifted from the canonical Zod schema; fix the template, do not downgrade the gate.tests/daily.bats - Print success.
on stdout, exit 0.Created daily note: <path>
Implementation
The deterministic path is implemented in
generate.sh (pure bash). An
LLM-driven fallback is unnecessary: daily-note creation is a 100%
mechanical transform and a shell script is faster, cheaper, and more
reliable than an LLM round-trip. Recommended invocation:
# Resolve vault dir from Session Config first, env var as fallback: CONFIG=$(cat .orchestrator/session-config.yaml | yq -o json) VM_DIR=$(echo "$CONFIG" | jq -r '."vault-integration"."vault-dir" // empty') : "${VM_DIR:=$VAULT_DIR}" VAULT_DIR="$VM_DIR" bash ~/Projects/session-orchestrator/skills/daily/generate.sh
Or, if
VAULT_DIR is already set in the environment and Session Config has
no vault-integration.vault-dir override:
VAULT_DIR=~/Projects/vault bash ~/Projects/session-orchestrator/skills/daily/generate.sh
Or, if the user's cwd is already the vault:
cd ~/Projects/vault && bash ~/Projects/session-orchestrator/skills/daily/generate.sh
Template Placeholders
| Placeholder | Example | Format |
|---|---|---|
| | ISO 8601 date (), also used inside the |
| | ISO 8601 date () — matches |
| | ISO 8601 date () — matches |
| | Human-readable heading, |
| | Full German weekday name (lookup table keyed on ) |
Note:
{{id}} is not a separate placeholder — the template inlines
id: daily-{{date}} so there is only one date substitution. This keeps
template rendering to a single sed pass and prevents drift between id
and filename.
The German weekday is computed via a hardcoded lookup (1=Montag, 2=Dienstag, ..., 7=Sonntag) rather than
LC_TIME=de_DE.UTF-8 date +%A
because not every macOS install has the de_DE.UTF-8 locale compiled.
Integration with vault-sync
The template must stay in sync with
vaultFrontmatterSchema. The canonical
schema lives at:
~/Projects/projects-baseline/packages/zod-schemas/src/vault-frontmatter.ts
Required fields produced by the template:
id, type, created, updated.
Optional-but-useful fields: title, tags, status. The type is hardcoded
to daily (one of the valid values in vaultNoteTypeSchema). The id is
daily-YYYY-MM-DD which is kebab-case and 16 chars — passes
slugRegex.min(2).max(128).
The BATS suite runs the vault-sync validator end-to-end (
bats tests/daily.bats
→ test 8), so any drift between the template and the schema breaks the build
of this skill, not of the vault that consumes it.
Idempotency Guarantee
Running
generate.sh twice on the same day is a no-op when the existing
file is valid:
- The first run creates
.$VAULT_DIR/03-daily/YYYY-MM-DD.md - The second run finds the file, confirms it is non-empty and starts with
(valid YAML frontmatter opener), prints---\n
, and exits 0.Daily note already exists: <path>
If the existing file is 0 bytes or lacks the
---\n opener (e.g. a previous
run crashed between the $TARGET.tmp write and the mv), the corrupt file
is removed and the note is re-created cleanly.
The file is never re-rendered when intact. This matters because the user edits the daily note throughout the day (ticking checkboxes, filling in the Scratch section, etc.) and re-invoking
/daily from anywhere — a later
session, a different tool, a keybind — must not destroy that work.
Verified by
tests/daily.bats test 5: hash-compares the file before and after
a second generate.sh invocation.
Anti-Patterns
- DO NOT overwrite existing daily notes. Re-running
is routine; losing the day's scratch notes is catastrophic. The idempotency check is load-bearing./daily - DO NOT hardcode the vault path.
is the contract. HardcodingVAULT_DIR
breaks tests, breaks any future multi-vault setup, and couples this skill to one user's machine.~/Projects/vault - DO NOT skip the post-write validation step. If the BATS suite stops running the vault-sync validator, template drift will quietly ship invalid frontmatter into the vault and only be caught at the next session-end gate.
- DO NOT use
for the weekday. The locale is not guaranteed to exist. Use the hardcoded lookup table.LC_TIME - DO NOT add
-unsafe characters to the template. The placeholders usesed
as the sed delimiter; if you add a|
to any substituted value, sed will break. Keep substitutions plain.|
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success (created) or idempotent skip (already exists and valid) |
| 1 | Unexpected runtime failure ( caught an unhandled error) |
| 2 | Infra error: template file not found at |
| 3 | Config error: does not exist as a directory |
| 4 | Vault structure error: directory is missing |
Files
— this file.SKILL.md
— the POSIX bash implementation of the algorithm above.generate.sh
— the daily-note template withtemplates/daily.md.tpl
markers.{{placeholder}}
— 8 BATS test cases covering creation, substitution, idempotency, missing-dir errors, and end-to-end schema validation via vault-sync.tests/daily.bats
Testing
From the skill directory:
bats tests/daily.bats
Expected:
8/8 passing. Test 8 runs the vault-sync validator over a fixture
vault that contains only the freshly-generated daily note, proving end-to-end
schema compliance.