Playbook: Session Notes Workflow
Issue: #2630
Last updated: 2026-07-05
Purpose
Capture decision context, deferred work, and identified risks from agent sessions in a searchable, tamper-evident format. Supports EU AI Act Art.12/13/14 transparency requirements.
When to create a session note
DO create a note when the session:
- Made architectural or operational decisions (even small ones)
- Completed substantive work (PR merged, migration applied, playbook written)
- Identified risks that may affect the platform
- Left work deferred with specific reasoning
DO NOT create a note when:
- Session was read-only research under 5 minutes
- No decisions, no completions, no risks
- Session answered a single factual question
Architecture — Two paths
Path A: Worker sessions (CLAUDE_SESSION_ID present)
Used by AI-Dev-IO1 (vps-i1) and AI-Dev-BMS4-1 (bms-4).
- Run
generate-session-note.pyto write markdown todocs/sessions/YYYY-MM/ - Commit with
git commit --no-verify -m "docs: session note YYYY-MM-DD {topic}" agent-session-end.pyPATCHesdev_r_agent_sessionswith:session_note_path(relative path from repo root)key_decisions[]deferred_items[]risks_identified[]
Path B: Local dev sessions (no CLAUDE_SESSION_ID)
Used by interactive developer sessions on Windows dev machine.
- Run
generate-session-note.pyto write markdown todocs/sessions/YYYY-MM/ - Commit manually
session_note_pathstays NULL in Supabase — known limitation, documented in ADR 002
How to trigger manually
# From repo root (Windows dev machine)
python scripts/generate-session-note.py `
--topic "audit log gap repair" `
--branch feat/2630 `
--worker "local" `
--env "local" `
--session-id "" `
--completed "Added log_op() to 82 playbooks||Opened PR #2741" `
--deferred "CI regeneration for role-context templates" `
--decisions "Used infra_operations not dev_r_rotation_log" `
--risks "infra_operations coverage gap -- P1"# From repo root (Linux worker)
python3 scripts/generate-session-note.py \
--topic "audit log gap repair" \
--branch feat/2630 \
--worker "$P24_WORKER_LABEL" \
--env "$P24_ENVIRONMENT" \
--session-id "$CLAUDE_SESSION_ID" \
--completed "Added log_op() to 82 playbooks||Opened PR #2741" \
--deferred "CI regeneration for role-context templates" \
--decisions "Used infra_operations not dev_r_rotation_log" \
--risks "infra_operations coverage gap -- P1"The script prints the relative file path to stdout on success (e.g. docs/sessions/2026-07/2026-07-05-audit-log-gap-rep-abc12345.md).
It exits 0 on success, 0 with a message on skip (nothing substantive), 1 on error.
How to commit
# Worker (Linux, --no-verify skips hooks that need CLAUDE_SESSION_ID at commit time)
NOTE_PATH=$(python3 scripts/generate-session-note.py --topic "..." ...)
git add "$NOTE_PATH"
git commit --no-verify -m "docs: session note $(date +%Y-%m-%d) {topic}"# Developer (Windows)
$NotePath = python scripts/generate-session-note.py --topic "..." ...
git add $NotePath
git commit -m "docs: session note $(Get-Date -Format yyyy-MM-dd) {topic}"Supabase columns updated by agent-session-end.py (Path A)
| Column | Source | Type |
|---|---|---|
session_note_path | --note-path CLI arg | TEXT |
key_decisions | P24_KEY_DECISIONS env (comma-sep) | TEXT[] |
deferred_items | P24_DEFERRED_ITEMS env (comma-sep) | TEXT[] |
risks_identified | P24_RISKS_IDENTIFIED env (comma-sep) | TEXT[] |
Set these env vars before calling agent-session-end.py:
export P24_KEY_DECISIONS="Used infra_operations table,Deferred IONOS GPU runner"
export P24_DEFERRED_ITEMS="CI regeneration for templates"
export P24_RISKS_IDENTIFIED="infra_operations coverage gap -- P1"
NOTE_PATH=$(python3 scripts/generate-session-note.py --topic "..." ...)
python3 scripts/agent-session-end.py --note-path "$NOTE_PATH" --summary "..."Storage location
docs/sessions/YYYY-MM/YYYY-MM-DD-{slug}-{short-session-id}.md
Monthly subdirectories keep navigation manageable. The .gitkeep in docs/sessions/ ensures the parent directory is tracked even before any notes are written.
Querying session notes (Supabase)
-- All sessions with notes in the last 30 days
SELECT session_id, started_at, session_note_path, key_decisions, risks_identified
FROM dev_r_agent_sessions
WHERE session_note_path IS NOT NULL
AND started_at > now() - interval '30 days'
ORDER BY started_at DESC;
-- Sessions with P1 risks
SELECT session_id, started_at, risks_identified
FROM dev_r_agent_sessions
WHERE array_to_string(risks_identified, ',') ILIKE '%P1%';Escalation
If generate-session-note.py fails: check stderr, verify repo root detection, verify docs/sessions/ write permissions.
If agent-session-end.py PATCH fails: the note still exists in git — the Supabase link is advisory, not critical. Check SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY env vars.
Related
docs/01-architecture/adr-002-session-notes-storage.md— design rationaledocs/templates/session-note.md— manual templatescripts/generate-session-note.py— generator scriptscripts/agent-session-end.py— Supabase PATCHsupabase/migrations/054_session_notes_columns.sql— schema