Structured Activity Logging — HoffDesk Spec v1.0
Status: Draft
Adopted: 2026-04-23
Purpose
Replace freeform daily notes with structured, queryable activity logs. Preserve the file-based, sovereign architecture. Add run grouping and metrics.
File Structure
memory/
├── 2026-04-22.md # Legacy format (preserved)
├── 2026-04-23.md # New structured format
├── runs/
│ └── 20260423_wv_001.md # Run detail files (optional)
└── LOGGING.md # This spec
Entry Format
Each activity is a markdown list item with JSON frontmatter:
- <!-- {"type": "task.started", "run_id": "20260423_wv_001", "title": "Draft structured logging spec", "agent": "wadsworth", "time": "2026-04-23T02:18:00Z", "tokens": 450} --> Started drafting spec at Matt's request
Required Fields
| Field | Type | Description |
|---|---|---|
type |
enum | task.started, task.progress, task.completed, task.failed |
run_id |
string | Grouping identifier for related actions |
title |
string | Brief headline, ≤80 chars |
agent |
string | Agent handle: wadsworth, socrates, daedalus |
time |
ISO8601 | UTC timestamp |
Optional Fields
| Field | Type | Description |
|---|---|---|
state |
enum | thinking, working, idle, done, error |
detail |
string | What specifically happened |
tokens |
number | Approximate tokens used |
duration_ms |
number | Time elapsed |
tool |
string | Tool name invoked |
tool_input |
string | Brief summary, ≤200 chars |
tool_output |
string | Brief result, ≤200 chars |
progress |
number | 0-100 for multi-step tasks |
Run ID Format
YYYYMMDD_AGENT_SEQ
| Segment | Meaning | Example |
|---|---|---|
YYYYMMDD |
Date | 20260423 |
AGENT |
2-letter code | wv = wadsworth, sc = socrates, dd = daedalus |
SEQ |
Sequence number | 001, 002... |
Examples
20260423_wv_001— Wadsworth's first run today20260423_sc_003— Socrates' third run today20260423_dd_001— Daedalus' first run today
Usage Patterns
Starting a Run
- <!-- {"type": "task.started", "run_id": "20260423_wv_001", "title": "Content Pipeline v2 integration", "agent": "wadsworth", "time": "2026-04-23T02:00:00Z", "state": "working"} --> Starting integration test for v2 pipeline
Progress Update
- <!-- {"type": "task.progress", "run_id": "20260423_wv_001", "title": "Fixed uvicorn binding", "agent": "wadsworth", "time": "2026-04-23T02:15:00Z", "progress": 60, "detail": "Killed old process, restarted on 0.0.0.0"} --> Uvicorn now accessible via Tailscale
Completion
- <!-- {"type": "task.completed", "run_id": "20260423_wv_001", "title": "v2 pipeline integration complete", "agent": "wadsworth", "time": "2026-04-23T02:30:00Z", "state": "done", "duration_ms": 1800000} --> ✅ Pipeline test successful
Failure (with recovery)
- <!-- {"type": "task.failed", "run_id": "20260423_wv_001", "title": "Model hallucinated output", "agent": "wadsworth", "time": "2026-04-23T02:20:00Z", "state": "error", "detail": "phi4:14b generated fever dream content"} --> ❌ Content rejected, escalating to Matt
Querying Logs
Find All Runs Today
grep -o '"run_id": "[^"]*"' memory/2026-04-23.md | sort | uniq
Find Specific Run
grep "20260423_wv_001" memory/2026-04-23.md
Find Failed Tasks
grep '"type": "task.failed"' memory/2026-04-23.md
Find Tool Usage
grep '"tool": "memory_search"' memory/2026-04-23.md
Duration Analysis
grep -o '"duration_ms": [0-9]*' memory/2026-04-23.md | awk '{sum+=$2; count++} END {print "Avg:", sum/count/1000, "s"}'
Migration Path
Phase 1: Dual Format (Now)
- New entries use structured format
- Legacy entries preserved as-is
- Both coexist in same file
Phase 2: Backfill (Optional)
- Convert high-value legacy entries
- Leave routine entries as-is
Phase 3: Tooling (Later)
log_activity()helper function- Query CLI for memory files
- Dashboard view (optional)
Example Full Day
# 2026-04-23 — Session Log
## Morning
- <!-- {"type": "task.started", "run_id": "20260423_wv_001", "title": "Content Pipeline v2 integration test", "agent": "wadsworth", "time": "2026-04-23T14:00:00Z", "state": "working"} --> Starting Phase 1.5/2 integration
- <!-- {"type": "task.progress", "run_id": "20260423_wv_001", "title": "Verified Socrates backend", "agent": "wadsworth", "time": "2026-04-23T14:30:00Z", "progress": 25} --> All 8 API endpoints responding
- <!-- {"type": "task.progress", "run_id": "20260423_wv_001", "title": "Deployed Daedalus templates", "agent": "wadsworth", "time": "2026-04-23T15:00:00Z", "progress": 50, "tool": "file_write", "tool_input": "3 pipeline templates to shared/"} --> Templates now served by API
- <!-- {"type": "task.progress", "run_id": "20260423_wv_001", "title": "Fixed uvicorn binding", "agent": "wadsworth", "time": "2026-04-23T15:30:00Z", "progress": 75, "detail": "Switched from 127.0.0.1 to 0.0.0.0 for Tailscale access"} --> Port 8000 now accessible
- <!-- {"type": "task.completed", "run_id": "20260423_wv_001", "title": "v2 pipeline integration complete", "agent": "wadsworth", "time": "2026-04-23T16:00:00Z", "state": "done", "duration_ms": 7200000} --> ✅ Both agents Phase 1.5/2 complete
## Evening
- <!-- {"type": "task.started", "run_id": "20260423_wv_002", "title": "Content quality assessment", "agent": "wadsworth", "time": "2026-04-23T01:40:00Z", "state": "thinking"} --> Matt reports generated content is "fever dream hallucination"
- <!-- {"type": "task.progress", "run_id": "20260423_wv_002", "title": "Analyzed model output", "agent": "wadsworth", "time": "2026-04-23T02:00:00Z", "detail": "phi4:14b over-indexed on struggle pattern, hallucinated details"} --> Root cause: model + prompt mismatch
- <!-- {"type": "task.completed", "run_id": "20260423_wv_002", "title": "Delivered assessment options", "agent": "wadsworth", "time": "2026-04-23T02:10:00Z", "state": "done"} --> Options A (fix), B (upgrade), C (hybrid) presented to Matt
Validation
Before appending, validate:
- JSON is valid
- Required fields present
run_idformat correcttimeis valid ISO8601typeis in allowed enum
Invalid entries fall back to legacy format (no JSON comment).
Version: 1.0
Last Updated: 2026-04-23
Next Review: After 7 days of usage