maubot-plugins/docs/adr-0002-alfred-nextcloud-store.md
2026-09-22 14:51:11 +02:00

76 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ADR 0002 — Alfred's store is Nextcloud, not the git vault
**Status:** accepted 2026-09-22 (supersedes the "Store" part of ADR 0001)
**Owner:** padreug
**Code:** `~/Work/tries/2026-09-20-alfred-vm/` (`pkgs/vault-*.py`, `vm.nix`, `workspace/AGENTS.md`)
## Context
ADR 0001 started the Alfred trial with the operator's zk vault
(`padreug/brain-chateaudufaune`, git) as the store: tasks as `- [ ]` lines,
journal as daily Markdown, the bot committing and pushing. Two days of live
use showed three things.
1. **The vault is invisible to the community.** It is edited with nvim/zk on
one laptop, synced by git, with no phone, share or web path. "What needs
doing" answered a question nobody but the operator could see, and the
journal (meant as the record newcomers read) was equally hidden.
2. **Free-form file writes were the failure class.** Every Alfred failure came
from `file_write` + `git`: wrong paths, ten tool iterations burnt on a
commit, a task turned into cron reminders, and `contacts.md` invented in
the vault three times (last: `785a9ea`, 2026-09-22) despite explicit
instructions. The CLI verbs with one action each (`vault-cal add`,
`vault-contacts add`) succeeded whenever the model chose them.
3. **The community already lives on Nextcloud.** `cloud.ariege.io` (Nextcloud
33) holds Coco's 2025 Deck boards (seven domain boards, a label taxonomy,
stacks, assignees; archived 2026-01-29), shared calendars, Talk rooms, Notes,
a `chateau` task list. Contacts and appointments had already moved there on
2026-09-21.
## Decision
Nextcloud is the system of record; Alfred's only actions are four commands:
| concern | app / protocol | command | collection |
|---|---|---|---|
| tasks | Tasks (CalDAV VTODO) | `vault-todos` | task list `chateau-1` |
| appointments | Calendar (CalDAV) | `vault-cal` | calendar `chateau` |
| people | Contacts (CardDAV) | `vault-contacts` | address book `Chateau` |
| journal, inbox notes, chat log | Files / Notes app (WebDAV, plain `.md`) | `vault-notes` | folder `Notes/Chateau/{Journal,Inbox,Chatlog}` |
- Tasks (VTODO) over Deck: standard, phone-synced (Tasks.org, DAVx5, Nextcloud
Tasks), shows in the Calendar app, and its fields map onto the spec:
STATUS ↔ §3.2 lifecycle, PRIORITY 1/3/5/7/9 ↔ §3.3.1 levels 1–5, CATEGORIES
↔ domain tags (vocabulary borrowed from the 2025 Deck labels), `X-ALFRED-SRC`
↔ `src:explicit|llm`, `X-ALFRED-BY` ↔ `author`. Deck stays an option if the
group revives its boards.
- Alfred runs as a dedicated Nextcloud user `alfred` that only receives the
four château shares; `file_write`/`file_edit`/`git` are excluded from the
agent; `allowed_commands` is exactly the four verbs; 60 actions/hour.
- No bulk verb exists; every delete takes one uid, and `vault-cal` exposes
`move` instead of delete to the model.
- The git repo `brain-chateaudufaune` is frozen for the bot (final commit
"moved to Nextcloud", deploy key removed); it remains the operator's zk
vault. A daily export backup (ics/vcf/notes) into that repo restores git
history for the community store.
## Consequences
- The whole group sees and edits the same tasks, events, contacts and journal
on phone and web the day they land; the operator syncs `Notes/Chateau` to the
laptop and keeps using zk on it.
- Undo is Nextcloud trash/versions plus the daily backup, weaker than git
history for in-place edits; mitigated by single-uid verbs and the rate cap.
- Still not spec-conformant (no §4 events, no §5 community scoping, no §7
signing), but VTODO is a projection away from NIP-52: a future bridge maps
fields 1:1 instead of parsing Markdown.
- One more account and app password to manage; Nextcloud app passwords are
full-account, hence the dedicated user.
## Revisit when
- The trial holds up: promote to cfaun as a `services.zeroclaw` instance
(sops for env files), and decide whether `tracker` is retired or bridged.
- The agent stays unreliable: the deterministic maubot plugin path from ADR
0001 now has an even simpler shape (four HTTP clients, no git).
- The group revives Deck: add a `vault-deck` verb or mirror VTODOs to cards.