This document contains shared persistent memory for LLM assistants across sessions. Store general patterns, conventions, and important system state here; put agent-specific details in the linked child notes.
Navigation: CONTENTS — full index of all notes and projects
Always read README alongside this note — it contains principles for code quality, assumptions, and working conventions.
Read on trigger: TRIGGERS maps situations to the rule notes that govern them. You need not read every rule upfront, but the moment you recognise you are entering a governed area (code, notes, infrastructure), read the mapped note(s) before acting — even mid-task. Re-reading late is correct; pressing on after relevance is clear is the mistake.
Agent-specific memory: Claude-specific memory, Codex-specific memory.
When creating or updating notes, ALWAYS:
1. Read before write — fetch with include_block_ids=true before patching
2. Use if_rev — always pass if_rev on patch/batch to catch concurrent edits
3. Link from parent — immediately update parent page to add link to new child
4. Preserve metadata — keep version, created, title, tags, updated fields
5. Increment version — always increment version number when updating content
6. Add updated date — set updated: YYYY-MM-DD when modifying
7. Preserve links — never remove links to child notes without checking
Critical reference: Avoiding Orphaned Notes and Information Loss
The correct editing model depends on the interface:
• CLI / raw HTTP: GET → edit the local file with normal file-editing tools → PUT the whole document back. This is the primary designed workflow. The cleverness lives in the local editor; whole-document PUT is the norm, not a fallback.
• MCP / agent: no local file, so structured ops (patch/batch/reorder/move) approximate file-editing remotely. These are the constrained substitute, not a richer alternative. Prefer GET→edit-locally→PUT whenever a file and editor are available.
Positional-insert trap: stacked insert_after ops on the same anchor insert in reverse order (each lands immediately after the anchor). Fix: chain each insert off the previous insert's returned block_id, or reconstruct and PUT. Full-document PUT is always safe for reorganisations. See troubleshooting.
{
"title": "Document Title",
"version": 1,
"created": "YYYY-MM-DD",
"updated": "YYYY-MM-DD",
"content": [
{"heading": {"level": 1, "text": "Title"}},
{"para": ["Text with ", {"link": {"href": "key", "text": "link"}}, " inline"]},
{"para": ["\u2022 Bullet point"]},
{"codeblock": {"lang": "python", "body": "code here"}}
]
}
This section is a historical snapshot from 2026-02-12. For current Envoy documentation and status, start at envoy.
Fully operational. All critical bugs resolved. System successfully processing emails with enhanced logging.
• API key source: ~/.bashrcs/api_keys
• Cron schedule: :00, :10, :20, :30, :40, :50 (6-22 hours)
• Test account: envoy_test@critchley.biz → ~/py/envoy/responses/
• Schema: new_envoy_response_schema.json (JSON format)
• Start instructions: envoy/start v7
• envoy (v7) — main page with all links, logging, flags feature, full changelog
The "" (empty string) key is the notes system home page — a general directory document, not Envoy-specific. Links to README, CONTENTS, IMPORTANT, Future, and dev/control-api.
Envoy is not stateless within a task. The email thread is the conversation history — the list of emails and moots in scope persists across cron runs via the continuation email (bundle_key, current_phase, failed_fetches, email/moot list). Replying to an Envoy outbound email is both the trigger and the re-entry mechanism for the next cron run. State is not preserved between separate tasks.
Context bundles (per-thread notes) and per-state instruction notes provide knowledge on each run. IMAP handles persistence within a task; no separate store needed.