1161 lines
45 KiB
Markdown
1161 lines
45 KiB
Markdown
---
|
|
title: "Château du Faune — Tracker / Journal pilot review"
|
|
subtitle: "Findings from the first week of !journal, !goals, !tasks usage across four Signal rooms"
|
|
date: 2026-06-02
|
|
author: aiolabs / Château du Faune
|
|
---
|
|
|
|
# Executive summary
|
|
|
|
For the past two weeks, members of the Château du Faune have been
|
|
"going through the motions" of using `!journal`, `!tasks`, `!goals`,
|
|
`!reminder`, `!buy`, `!sidequest`, and related commands across four
|
|
Signal rooms — Operations, Animals, Gardens & Food, Events, and the
|
|
general castle room. Nothing was hooked up yet: the chats are mirrors
|
|
of what the maubot stack on the new Matrix homeserver will eventually
|
|
capture. The point was to *generate signal* — to find out which
|
|
verbs people actually reach for, how they phrase entries, where the
|
|
syntax gets in the way, and which features the protocol spec is
|
|
quietly missing.
|
|
|
|
This document reads that signal. It is written for both the chateau
|
|
members (who will see their words quoted back and choices made about
|
|
how the bot will treat their phrasing) and for the
|
|
[aiolabs/maubot-plugins][repo] developers (who will turn the
|
|
recommendations into code and spec changes). The
|
|
[community-organizer spec][spec] is the contract; the
|
|
[`tracker/`][tracker] and [`journal/`][journal] plugins are the
|
|
reference implementation; the data we collected over the past two
|
|
weeks is the field test.
|
|
|
|
**Top-line findings:**
|
|
|
|
1. **The capture habit is sticking.** The bot doesn't exist yet, and
|
|
people are still using the syntax — sometimes correcting each
|
|
other on it. The most surprising data point is that Coco told
|
|
Helena *"`!journal` is the required format"* unprompted. Social
|
|
enforcement of a syntax we haven't actually shipped is the best
|
|
possible adoption signal.
|
|
|
|
2. **The vocabulary the community reaches for is broader than the
|
|
spec.** The current spec lists `!task`, `!sidequest`, `!journal`,
|
|
`!remind`, `!add`, `!done`, `!list`, `!setup`. The chats show
|
|
people typing `!buy`, `!need`, `!goals`, `!stewards`, `!tasks`,
|
|
`!task` (singular), `!reminders` (plural), `!idea`, `!plans`,
|
|
`!priority` (inline), `!side quests`, and a few more. Some of
|
|
these are per-room shortcuts the spec already accommodates;
|
|
others want a small protocol-level addition.
|
|
|
|
3. **The 5-level priority scheme came directly from this pilot.**
|
|
Coco proposed "1 urgent / 2 crucial / 3 important / 4 future / 5
|
|
frequent/ongoing" in the operations chat on May 24. It is now
|
|
§3.3.1 of the spec, exactly as proposed. This loop — observe →
|
|
spec → implement → re-observe — is the one we want to keep
|
|
running.
|
|
|
|
4. **The bot will need to be more grammar-tolerant than the spec
|
|
currently implies.** Multiple verbs per message, edited messages
|
|
that add content, `!`-words inside bullet points used as
|
|
priority markers, pinning as a "this is the current list"
|
|
signal, no-prefix journals — these are all behaviors the bot
|
|
doesn't catch today but should.
|
|
|
|
5. **The community is already designing the bot's voice.** Alfred
|
|
got named on May 24 ("we trusted him with resource management,
|
|
safety, tool use, etc."). Photos got captioned, journals got
|
|
pinned, Cocopis explained what `!tags` are *to other members*.
|
|
The chateau is treating the bot as a collaborator before it
|
|
exists. We should lean into that — bot personality is now a
|
|
design surface.
|
|
|
|
The rest of this report:
|
|
|
|
- **§1** What we observed, by room and by pattern
|
|
- **§2** What the existing spec + plugins handle well
|
|
- **§3** Spec changes proposed
|
|
- **§4** Plugin changes proposed
|
|
- **§5** New ideas the data surfaced
|
|
- **§6** How this fits the larger omnixy / aiolabs ecosystem
|
|
- **§7** A phased plan
|
|
- **§8** Open questions for the chateau
|
|
|
|
[repo]: https://git.atitlan.io/aiolabs/maubot-plugins
|
|
[spec]: ../docs/community-organizer-spec.md
|
|
[tracker]: ../tracker/
|
|
[journal]: ../journal/
|
|
|
|
---
|
|
|
|
# 1 — What we observed
|
|
|
|
## 1.1 Verbs in actual use
|
|
|
|
A frequency-sorted list of every `!verb` we saw across the four rooms
|
|
(case-folded), grouped by what the spec or current shortcut config
|
|
covers:
|
|
|
|
| Verb seen | Already in spec | Status |
|
|
|---|---|---|
|
|
| `!journal` | Yes (universal) | Heavy use across all four rooms |
|
|
| `!reminder` / `!reminders` | Spec verb is `!remind` | Mismatch — see §3.1 |
|
|
| `!tasks` / `!task` | Spec verb is `!task` | `!tasks` plural also appears |
|
|
| `!goals` | No | New — see §3.2 |
|
|
| `!stewards` | No (per-room shortcut candidate) | Used as a list/backlog, not a one-off task |
|
|
| `!buy` | Per-room shortcut, fits cleanly | Should ship pre-configured for cdf rooms |
|
|
| `!need` | No | Distinct from `!buy` in usage — see §3.2 |
|
|
| `!sidequest` / `!side quests` | Yes | Used; "side quests" with space appeared once |
|
|
| `!idea` / `!plans` | No | Speculative / design-phase items |
|
|
| `!priority` (inline) | No (priority is a tag) | Used as a bullet-level marker — see §1.4 |
|
|
| `!move` | Mentioned by Ulo as a future verb | Not in spec |
|
|
|
|
And a usage example per verb so the design instinct is grounded in
|
|
actual phrasing rather than imagined phrasing:
|
|
|
|
**`!journal` — past-tense daily log, multi-line is the dominant
|
|
form:**
|
|
|
|
> `!journal`
|
|
> `- opened/closed, watered and fed hens, babies & pacas`
|
|
> `- put insulators on the rebars so they're ready to go for fence`
|
|
> `- mentally plotted potential hidden-in-plain-sight stable locations. I want opinions next`
|
|
> `- should scrape clean duck babes straw tmrw`
|
|
> `- should clean and dry very well sapphis wound again`
|
|
|
|
Note the mix of past-tense ("opened/closed") and forward-looking
|
|
("should scrape clean tmrw") bullets in the same `!journal`. People
|
|
do not bucket their day cleanly. §3.4 addresses this.
|
|
|
|
**`!goals` — a *list of current intentions*, often nested with
|
|
sub-categories:**
|
|
|
|
> `!goals & notes next week for garden/kitchen crew`
|
|
>
|
|
> `GARDEN`
|
|
> `- documentation & journaling process`
|
|
> `- prepping & starting the Lady Godiva pumpkin patch.`
|
|
> `…`
|
|
>
|
|
> `KITCHEN`
|
|
> `- forage, harvest & food processing resource improvements (ex. cherries into vinegars…)`
|
|
> `- filling the shop up (& soon looking into certifying our kitchen/lab)`
|
|
> `…`
|
|
|
|
`!goals` lists evolve over days — Coco's gardens `!goals` on May 27
|
|
and June 2 are *the same list*, refined. This is the strongest
|
|
argument we found for **replaceable-event semantics** (§3.3).
|
|
|
|
**`!reminder` — a future-pointed list, often with embedded
|
|
@-mentions and `!priority` markers inside bullets:**
|
|
|
|
> `!goals this week/soon`
|
|
> `- attempt to secure alpaca deposit & arrival of the boys`
|
|
> `- !priority confirm if teeth & nails will also be done by the shearer 'sometime in july'`
|
|
> `- !priority diagnosis of sapphis skin condition be made by a vet in person.`
|
|
> `!reminder following shearing, immediately start sapphis skin infection protocol`
|
|
> `- fencing add in doors & handles. Start soon on setting up 2nd stable paddock`
|
|
|
|
Look at that message carefully: it is *one* `!goals` entry, with
|
|
`!priority` and `!reminder` appearing **inside bullets as inline
|
|
markers**, not as new commands. This is the single most important
|
|
parser decision we have to make — see §4.1.
|
|
|
|
**`!buy` — shopping list, sometimes added-to over days via edit:**
|
|
|
|
> `!buy`
|
|
> `- roll out flypaper for stable(s)`
|
|
> `- door handles for electric (or from laura)`
|
|
> `- la fourche order, sesame & produce will be thursday, 28th`
|
|
> `- buy more pans & x2 induction adapters`
|
|
|
|
**`!need` — semantically distinct from `!buy`. Means "stock is
|
|
low" rather than "purchase this":**
|
|
|
|
> `!need puppy & cat food, hay & straw soon`
|
|
|
|
Coco used both in the same week. The distinction matters because
|
|
`!need` items become `!buy` items only after someone agrees to act
|
|
on them, where `!buy` is already a decision.
|
|
|
|
## 1.2 Cadence patterns — the recurring chore problem
|
|
|
|
The operations chat opened with a chores list dominated by
|
|
*recurring* items with fuzzy intervals:
|
|
|
|
> `pacas:`
|
|
> `- every ~3 days scoop manure`
|
|
> `- every ~3 days fluff bedding`
|
|
> `- every 2 wks to 1 month - change out whole bedding`
|
|
> `- daily fresh water`
|
|
> `- daily light green/yellow hay`
|
|
> `- training - max 1x/day - approach with treats in a bucket…`
|
|
>
|
|
> `hens & ducks:`
|
|
> `- am let out, pm close in`
|
|
> `- every ~3 days fresh water & food`
|
|
> `- every 1 week change out straw`
|
|
> `- spend time with the puppies every day`
|
|
|
|
Coco flagged the problem herself: *"weird thing is tasks that are
|
|
every few days or variable timeframes?"*
|
|
|
|
The spec partially anticipates this with `priority:5` ("frequent /
|
|
ongoing"), but `priority:5` is a marker, not a cadence. "Every 3
|
|
days" and "daily" are different cadences and the bot should know.
|
|
RFC 5545 `RRULE` is the canonical answer; NIP-52 doesn't yet
|
|
codify recurrence (§11 of the spec lists this as open). A
|
|
lightweight stopgap is proposed in §3.5.
|
|
|
|
## 1.3 Multi-verb messages
|
|
|
|
Helena posted in the Gardens & Food room:
|
|
|
|
> `!journal`
|
|
> `• bigger Team meet and on board of Marta what we did the last weeks…`
|
|
> `• weeding`
|
|
> `• getting fresh alpaca manure and distributing`
|
|
> `• collecting seeds for next year planting`
|
|
>
|
|
> `!task`
|
|
> `- research thing for rain tank`
|
|
> `- update online garden map`
|
|
> `- check on sprouting pumpkin seeds and plant when ready`
|
|
|
|
This is one Matrix message but **two distinct entries** — a
|
|
`!journal` and a `!task` list. The current tracker dispatch regex
|
|
matches the first verb at start-of-message and stops. The plugin
|
|
will silently drop Helena's `!task` block.
|
|
|
|
This is a real bug, not a theoretical one — Helena was the first
|
|
person who naturally typed in this shape, and the bot would have
|
|
lost the task list. §4.2 fixes it.
|
|
|
|
Skye independently did the same thing on the same day:
|
|
|
|
> `!goals !tasks`
|
|
> `- [ ] organise conversation about image ai making with pat and coco`
|
|
> `- [ ] Look into creation of the funding via our socials…`
|
|
> `- [ ] For flyers/posters the !goals is to make one for pats new events app for ariege…`
|
|
|
|
`!goals !tasks` on one line is yet another shape: two verbs sharing
|
|
one body. Likely "this entry belongs to both lists" — but the spec
|
|
needs to say so explicitly.
|
|
|
|
## 1.4 Inline `!priority` and `!reminder` markers
|
|
|
|
Returning to Coco's May 27 `!goals`:
|
|
|
|
> `- !priority confirm if teeth & nails will also be done by the shearer 'sometime in july'`
|
|
> `- !priority diagnosis of sapphis skin condition be made by a vet in person.`
|
|
> `!reminder following shearing, immediately start sapphis skin infection protocol`
|
|
|
|
`!priority` and `!reminder` are appearing **inside body content** as
|
|
bullet-level annotations, not as commands. A naïve parser that
|
|
matches `!\w+` anywhere in a message would interpret these as new
|
|
commands and produce four entries from one message.
|
|
|
|
The fix is the rule the journal plugin already enforces: a `!verb`
|
|
counts as a verb **only** if it is at the very start of the message
|
|
(or, with §4.2 in place, at the very start of a top-level block).
|
|
Everything else is body content with inline tags.
|
|
|
|
But "inline tags" is itself a feature worth keeping: a bullet
|
|
starting with `!priority` is a natural way to mark *that bullet*
|
|
as urgent within a larger list. The bot can:
|
|
|
|
1. Treat the inline `!priority` as a *tag on the bullet body*
|
|
(preserves the user's intent).
|
|
2. Leave the parent entry's priority alone (the user didn't priority
|
|
the *list*; they priority'd one item in it).
|
|
|
|
A renderer can then surface that bullet as priority-1 within the
|
|
parent entry. This is a richer model than the spec currently
|
|
sketches, but it matches what users are actually doing. §3.3
|
|
proposes the wire format.
|
|
|
|
## 1.5 Pinning as state
|
|
|
|
Across all four rooms, the dominant `!goals` / `!tasks` / `!stewards`
|
|
messages are **pinned to the room**. When the list evolves, the new
|
|
version is pinned and the old one is unpinned. Matrix has native
|
|
support for this (`m.room.pinned_events`).
|
|
|
|
We propose treating "the latest pinned message matching `!goals`
|
|
from a given room" as the **current state of that group's working
|
|
list**. This gives every room a queryable "what's on our plate
|
|
right now" view without requiring users to remember an item id.
|
|
|
|
§3.3 + §4.5 develop this.
|
|
|
|
## 1.6 Implicit subjects — animals, people, places
|
|
|
|
The animals room is full of entries like:
|
|
|
|
> `- thinking of long-term solutions for pups barking and neighbors.`
|
|
> `- 45 min in the alpaca paddock with both pups, no electricity.`
|
|
> `- carefully choose feeding station(s) so they are isolated and don't compete with any other animals`
|
|
>
|
|
> *(and elsewhere)*
|
|
>
|
|
> `lets clean sapphis wound again soon?`
|
|
> `also just realized the shearer will come in july`
|
|
|
|
The community has named entities — *Sapphi*, *Loki*, *Leia*,
|
|
*Tango*, *Morrigan*, *the alpacas*, *the pups*, *the hens*, *the
|
|
south paddock*, *the orchard*, *the coop* — that recur across many
|
|
entries. A useful query is "show me everything mentioning Sapphi
|
|
this month" or "what tasks involve the south paddock?".
|
|
|
|
NIP-52 already supports `["p", "<pubkey>"]` for *people*. Animals
|
|
and places need a convention — see §3.6.
|
|
|
|
## 1.7 Inline @-mentions = informal assignment
|
|
|
|
> `- location & plans for stable, cont. @coco`
|
|
> `- closing the main property gate? guardian dogs sign @coco`
|
|
> `- pruning & landscaping @Thomasss**]`
|
|
> `- following a budget per person for food orders, picking up produce @Skye 🌟`
|
|
|
|
People mention each other inline to mean "this bullet is yours". The
|
|
bot can extract these into structured `["p", …]` tags and a
|
|
renderer can surface a per-person "your bullets" view. §4.6.
|
|
|
|
## 1.8 Cross-group routing ambiguity
|
|
|
|
Skye said in the Events room:
|
|
|
|
> *"organise a mini meeting to talk about ai image making etc with
|
|
> pat/coco …. I'm not sure which chat to put these social things in
|
|
> hehe"*
|
|
|
|
Some items belong to multiple groups. The current 1-room ↔
|
|
1-community mapping makes this expensive — you'd have to type the
|
|
same entry twice. Coco's answer (*"i think events would be the
|
|
fitting place"*) is the human workaround; the bot should help.
|
|
§5.2 proposes optional multi-room fan-out.
|
|
|
|
## 1.9 No-prefix journal-shaped content
|
|
|
|
Lots of messages look like journals without using any command:
|
|
|
|
> `today plan for me:`
|
|
> `- working in other groups on animals and operations`
|
|
|
|
> `Today's plan for me:`
|
|
> `- making bulk buckwheat zucchini burgers some for today and rest in freezer`
|
|
|
|
> `journal`
|
|
> `started but did not complete: bathroom clean, mapping stables, fencing the internal 150m paddock`
|
|
|
|
The chateau is explicitly standardizing on `!journal` (Coco
|
|
corrected Helena on this in real time). So we **should not** make
|
|
the bot fuzzy-match — they want explicit syntax. But the data
|
|
suggests an opt-in *"capture every non-command message in this
|
|
specific room"* mode could be valuable for very-low-friction rooms
|
|
(e.g. a private journal room per member). Default: off. §5.1.
|
|
|
|
## 1.10 Capitalization, punctuation, language
|
|
|
|
The same intent appears as `!journal`, `Journal:`, `journal`, `!journal:`,
|
|
`Today plan for me`, `today plan:`, sometimes mixed with French.
|
|
|
|
The bot's regex needs to be:
|
|
- case-insensitive on the verb (`!Journal` == `!journal`)
|
|
- tolerant of a trailing colon (`!journal:` is fine)
|
|
- bilingual on body content (already true — body is opaque text)
|
|
|
|
The current `_CMD_RE = re.compile(r"^!(\w+)(?:[ \t\r\n]+(.*))?$", re.DOTALL)`
|
|
in `tracker.py:52` *does* match `!Journal` because `\w` is
|
|
case-insensitive in unicode mode, and the dispatch already calls
|
|
`.lower()`. But it does **not** match `!journal:` because the colon
|
|
follows the verb with no whitespace. One-line fix in §4.3.
|
|
|
|
## 1.11 Edits matter
|
|
|
|
Two distinct edit patterns appeared:
|
|
|
|
**A. Edit-to-append.** Coco edited a `!journal` post-hoc and
|
|
commented: *"just added that i also fed puppies 2x today"*. The
|
|
intent is "this is the same entry, with more content".
|
|
|
|
**B. Edit-to-correct.** Coco scheduled a vet appointment for "June
|
|
5 @ 14h", then edited the same entry to "May 30 @ 15h" with the
|
|
note *"updated to May 30 @ 15h because they need the vaccination
|
|
within the month"*.
|
|
|
|
The tracker's current known-quirks note (`tracker/README.md:133`)
|
|
says:
|
|
|
|
> *"Edited messages don't re-trigger the bot. Matrix sends edits
|
|
> as a separate `m.replace` event that maubot doesn't pass to
|
|
> handlers. Type a fresh message instead of editing."*
|
|
|
|
This is solvable — `m.replace` events *are* visible to maubot; the
|
|
handler just needs to be wired. §4.4.
|
|
|
|
---
|
|
|
|
# 2 — What the existing spec and plugins handle well
|
|
|
|
Before proposing changes, let's mark what's already right. The pilot
|
|
*validates* a lot of the design.
|
|
|
|
## 2.1 The split between universal verbs and per-room shortcuts
|
|
|
|
The spec says: every implementation must recognize the universal
|
|
verbs (`!task`, `!journal`, etc.); per-room shortcuts (`!buy`,
|
|
`!harvest`, …) expand to them. The data agrees: every room developed
|
|
its own dialect (animals uses `!journal` heavily, operations uses
|
|
`!buy` and `!stewards`, events uses `!goals`). A single plugin
|
|
serves all of them.
|
|
|
|
We just need to **pre-configure** the cdf rooms with sensible
|
|
shortcuts so members don't have to `!setup add buy task #buy` on day
|
|
one. §4.7.
|
|
|
|
## 2.2 The passive regex / multi-line story
|
|
|
|
The journal plugin's switch to `@command.passive` with a regex was
|
|
right. Every multi-line entry we observed (and many one-line ones)
|
|
would have been silently dropped under `@command.new`. The CLAUDE.md
|
|
footgun is real and the plugin avoided it.
|
|
|
|
## 2.3 The 5-level priority scheme
|
|
|
|
`priority:1..5` with the labels urgent / crucial / important / future
|
|
/ frequent-ongoing came out of the pilot. The renderer plan is to
|
|
surface labels rather than numbers; the wire tag stays `priority:N`
|
|
for sort stability. The data didn't push back on this — Coco's
|
|
proposal landed exactly as written.
|
|
|
|
## 2.4 Sidequests as a separate kind
|
|
|
|
`!sidequest` (with a `🎯` emoji ack) gives a distinct surface for
|
|
"would be cool to do" items. Coco's *"`!side quests` lists which are
|
|
different from the rest of the tasks"* is exactly the use case. The
|
|
spec already excludes sidequests from default `!list` output, which
|
|
is the right default.
|
|
|
|
## 2.5 The Matrix-only Phase 1 posture
|
|
|
|
The tracker is `matrix-only` for v1 — no Nostr publishing yet. This
|
|
turns out to be the right call: the four-week dataset shows the
|
|
community is still finding its vocabulary. Publishing to a public
|
|
relay before the vocabulary stabilizes would make schema migrations
|
|
visible to anyone subscribed. Stay matrix-only until the verb set is
|
|
stable, then bridge.
|
|
|
|
## 2.6 The journal plugin's append-only stance
|
|
|
|
The spec's "`!done` on a journal entry is undefined behavior;
|
|
implementations SHOULD reject it" matches the data: nobody tried to
|
|
close a journal. They edit, they re-journal, they pin — they don't
|
|
close. Good call.
|
|
|
|
---
|
|
|
|
# 3 — Spec changes proposed
|
|
|
|
These are protocol-level additions to `docs/community-organizer-spec.md`.
|
|
Each is small. None breaks existing conformance — they extend, they
|
|
don't refactor.
|
|
|
|
## 3.1 Plural aliases for universal verbs
|
|
|
|
`!reminders` and `!tasks` should be accepted as equivalents of
|
|
`!remind` and `!task`. `!sidequests` likewise. This is a one-line
|
|
parser change; it costs nothing and removes a footgun (users will
|
|
naturally pluralize when a list is multi-item).
|
|
|
|
> *Spec change:* in §3.1, add a row:
|
|
> *"Implementations MUST accept the bare plural form of each verb
|
|
> (`!tasks`, `!sidequests`, `!reminders`) as equivalent."*
|
|
|
|
## 3.2 New universal verbs: `!goals` and `!need`
|
|
|
|
Both verbs got real, repeated, distinct-from-existing usage. Both
|
|
deserve protocol-level status, not per-room shortcut status, because:
|
|
|
|
- They had identical meaning across all four rooms. A bakery co-op
|
|
reading this spec should be able to use them without re-configuring.
|
|
- The shortcut mechanism is for *vocabulary the community invented*
|
|
(e.g. `!harvest`, `!brewery`). `!goals` and `!need` are not
|
|
vocabulary inventions — they're a category the spec missed.
|
|
|
|
| New verb | Purpose | Underlying kind |
|
|
|---|---|---|
|
|
| `!goals <text>` | A list of current intentions for the author/group/period. Replaceable per `(author, room, period?)`. | 31922 with `["t", "goals"]` |
|
|
| `!need <text>` | A supply that is running low. Distinct from `!buy` (which is "I will purchase this"). Default lifecycle: open → `!buy` (converts to task) or `!done`. | 31922 with `["t", "need"]` |
|
|
|
|
`!goals` deserves §3.3 (replaceable semantics) since the goals lists
|
|
visibly evolved over days in the pilot.
|
|
|
|
## 3.3 Replaceable-event semantics for `!goals` (and stewards lists)
|
|
|
|
NIP-52 kind 31922 is a *parameterized replaceable event* keyed by
|
|
`d`-tag. Today the tracker assigns a unique `d` per entry. For
|
|
`!goals` (and the per-room `!stewards` list pattern), we want the
|
|
opposite: the latest `!goals` from a given `(author, room)` pair
|
|
should *replace* the previous one.
|
|
|
|
> *Spec change:* in §3.3, add:
|
|
> *"Implementations MAY designate certain verbs as replaceable per
|
|
> `(author, room, period?)`. When a verb is replaceable, the bot
|
|
> reuses the same `d`-tag for successive captures, so the relay
|
|
> retains only the latest version. Recommended replaceable verbs:
|
|
> `goals`, `stewards`."*
|
|
|
|
The `period` qualifier lets `!goals this week` and `!goals next week`
|
|
coexist. Suggested encoding: a `period:` tag (e.g. `period:2026-w22`).
|
|
For v1 we keep it simple — no period qualifier, latest wins.
|
|
|
|
The pinning UX hooks straight in: when a `!goals` message is the
|
|
latest replaceable entry from its author, the bot can ask Matrix to
|
|
pin it (and unpin the previous one). This makes the room's pinned
|
|
message a live mirror of the relay state.
|
|
|
|
## 3.4 Forward + retrospective in a single `!journal`
|
|
|
|
The data shows people blend "did X" and "will do Y tomorrow" in the
|
|
same `!journal`. The spec currently says journals are past-tense and
|
|
append-only. Rather than fight the user, we accept the blend.
|
|
|
|
> *Spec change:* in §3.1, clarify:
|
|
> *"`!journal` is append-only; implementations MUST NOT close
|
|
> journals. Bodies MAY contain forward-looking statements; the
|
|
> classifier MAY surface these as candidate tasks at review time but
|
|
> MUST NOT auto-create derived task entries."*
|
|
|
|
The "candidate task" idea is a v2 nicety: a weekly digest that pulls
|
|
"should…" bullets out of journals and offers them as `!task`
|
|
candidates. Not in v1.
|
|
|
|
## 3.5 Recurrence tags (lightweight, pre-RRULE)
|
|
|
|
For the chore-list problem (`every ~3 days scoop manure`, `daily
|
|
fresh water`), we propose a `frequency:` tag namespace that lives
|
|
inside the existing `["t", …]` mechanism. Renderers parse it.
|
|
|
|
Suggested values:
|
|
|
|
| Tag | Meaning |
|
|
|---|---|
|
|
| `frequency:daily` | Once per day |
|
|
| `frequency:weekly` | Once per week |
|
|
| `frequency:3d` | Every 3 days |
|
|
| `frequency:2w` | Every 2 weeks |
|
|
| `frequency:as-needed` | No fixed cadence; on demand |
|
|
|
|
This is a stopgap. When NIP-52 or a sibling NIP defines proper
|
|
recurrence, we migrate. For now, the eink renderer can group
|
|
`frequency:daily` items into a "today" panel and `frequency:weekly`
|
|
into a "this week" panel without parsing RRULE.
|
|
|
|
> *Spec change:* in §3.3, add:
|
|
> *"`frequency:<spec>` is reserved for recurrence hints. Recommended
|
|
> values: `daily`, `weekly`, `Nd` (every N days), `Nw` (every N weeks),
|
|
> `monthly`, `as-needed`. Implementations MAY define additional
|
|
> values."*
|
|
|
|
## 3.6 Subject tags — animals and places, not just people
|
|
|
|
NIP-52 has `["p", <pubkey>]` for people but no convention for
|
|
non-human subjects. We propose a namespaced `t`-tag:
|
|
|
|
| Tag | Meaning |
|
|
|---|---|
|
|
| `subject:animal/sapphi` | Animal named Sapphi |
|
|
| `subject:animal/loki` | Animal named Loki |
|
|
| `subject:place/south-paddock` | A named place on the property |
|
|
| `subject:object/electric-fence` | A named asset/object |
|
|
|
|
A community can define its own subject vocabulary via `!setup`:
|
|
|
|
```
|
|
!setup subjects animal/sapphi animal/loki animal/leia
|
|
!setup subjects place/south-paddock place/orchard
|
|
```
|
|
|
|
When typing, members can reference subjects with a `@`-prefix as
|
|
shorthand:
|
|
|
|
```
|
|
!journal cleaned @sapphi's wound, fed @hens at noon
|
|
```
|
|
|
|
The bot expands `@sapphi` to `subject:animal/sapphi` tags and
|
|
preserves the original text in the body. Renderers can then offer
|
|
"recent entries about Sapphi" without the bot needing to do NLP.
|
|
|
|
For *people* the existing `["p", "<mxid-or-pubkey>"]` already works;
|
|
inline `@person:name` (or just `@`-mentions resolved through the
|
|
Matrix room's member list) feeds straight into that.
|
|
|
|
## 3.7 Inline `!verb` markers within a body are tags, not commands
|
|
|
|
This is half a spec change, half a clarification:
|
|
|
|
> *Spec change:* in §3.3, add:
|
|
> *"A `!verb` occurring at the start of a message (or, with multi-verb
|
|
> support, at the start of a top-level block) is a command. A `!verb`
|
|
> appearing inside body content is body content and MAY be extracted
|
|
> by the bot as an `inline:<verb>` tag on the parent entry. This
|
|
> preserves user intent without spawning ghost entries."*
|
|
|
|
So Coco's `- !priority diagnosis of sapphis skin condition…` bullet
|
|
gets recorded as part of the parent `!goals` entry, *and* the parent
|
|
gets an `inline:priority` tag. A renderer can surface that bullet
|
|
with priority styling.
|
|
|
|
## 3.8 Multi-line entries with sub-headers
|
|
|
|
A small content-format convention so renderers can do something
|
|
sensible with Coco's `GARDEN` / `KITCHEN` sub-headers:
|
|
|
|
> *Spec change:* in §10, add:
|
|
> *"Bodies MAY use Markdown-style headers (`#`, `##`) as in-body
|
|
> section markers. Renderers MAY surface them as visual groupings.
|
|
> The body remains a single content blob; sub-headers do not split
|
|
> the entry."*
|
|
|
|
---
|
|
|
|
# 4 — Plugin changes proposed
|
|
|
|
These are concrete edits to `tracker/`, `journal/`, and a small
|
|
amount of `wiki/` if we want cross-plugin discovery. Each maps to a
|
|
specific file path so the work is sized.
|
|
|
|
## 4.1 Parse inline `!verb` markers as tags, not commands
|
|
|
|
`tracker/tracker.py:184` — the `dispatch` handler matches a verb at
|
|
start-of-message. Today, anything else is unmatched and the message
|
|
is dropped (correct). We extend: after dispatching the top-level
|
|
verb, scan the body for inline `!verb` occurrences and add them as
|
|
`inline:<verb>` tags on the recorded entry. Implementation is a
|
|
single pass over the body before recording.
|
|
|
|
This makes Coco's `- !priority …` bullets actually do something
|
|
useful at the entry level without inventing ghost entries.
|
|
|
|
## 4.2 Split multi-verb messages
|
|
|
|
`tracker/tracker.py:52` — the `_CMD_RE` regex anchors at
|
|
start-of-string and captures everything to end-of-string. We change
|
|
to a *two-pass* parse:
|
|
|
|
1. Split the message at every line that starts with `!verb` (and
|
|
only such lines — bullets like `- !priority …` are NOT split
|
|
points).
|
|
2. Each split block becomes its own captured entry.
|
|
|
|
Helena's `!journal … !task …` message becomes two entries. Skye's
|
|
`!goals !tasks` on a single line stays as one entry but gets *both*
|
|
tags applied. This requires a second regex for the multi-verb-one-line
|
|
case.
|
|
|
|
The order matters: split first on newline-prefixed `!verb`s, then on
|
|
the single-line multi-verb case.
|
|
|
|
## 4.3 Tolerate trailing colon and case on verb
|
|
|
|
`tracker/tracker.py:52` — change the regex to allow an optional
|
|
trailing colon and explicit case-insensitive flag:
|
|
|
|
```python
|
|
_CMD_RE = re.compile(r"^!(\w+):?(?:[ \t\r\n]+(.*))?$", re.DOTALL | re.IGNORECASE)
|
|
```
|
|
|
|
(The `.lower()` already happens in `dispatch`; the regex flag is for
|
|
unicode `\w` consistency. Trailing colon is the visible change.)
|
|
|
|
Apply the same change to `journal/journal.py:34` for `_JOURNAL_RE`.
|
|
|
|
## 4.4 Handle Matrix edits
|
|
|
|
`tracker/tracker.py` — register a handler for `m.room.message` events
|
|
with `rel_type == "m.replace"`. The handler:
|
|
|
|
1. Looks up the original event id in the items table (we need to
|
|
start recording it — schema change below).
|
|
2. If the original is a captured entry, treat the edit as a body
|
|
update on that entry. Bump a `last_edited_ts`.
|
|
3. Reply with a small ack ("✏️ Updated entry `42`").
|
|
|
|
Schema change: add `mx_event_id TEXT` column to `items`, indexed.
|
|
This is a real change to `upgrade_table` — add as `upgrade_v2`.
|
|
|
|
`tracker/README.md:133` — strike the "Edited messages don't
|
|
re-trigger the bot" caveat.
|
|
|
|
This is the single change that unlocks the most observed user
|
|
behavior. People *do* edit, and treating edits as no-ops loses
|
|
substantial information.
|
|
|
|
## 4.5 Detect pin events; mark replaceable verbs as pinned
|
|
|
|
`tracker/tracker.py` — subscribe to `m.room.pinned_events`. When a
|
|
captured entry's source Matrix message becomes pinned, mark the
|
|
entry as `pinned=true`. When a `!goals` entry is recorded, the bot
|
|
*itself* asks Matrix to pin the message (and unpin the previous
|
|
`!goals` from the same author).
|
|
|
|
This makes the pinned-message UX a transparent mirror of the relay
|
|
state, without users needing to manually pin/unpin.
|
|
|
|
(This requires the bot to have pin-event permission in the room. The
|
|
admin can grant it via Element. Document in the README.)
|
|
|
|
## 4.6 Extract inline @-mentions as `p`-tags
|
|
|
|
`tracker/tracker.py` — alongside the existing `_TAG_RE` extraction
|
|
for `#tag`, add an `_MENTION_RE` extraction for `@user`. Resolve
|
|
against the Matrix room's member list (best-effort; if it doesn't
|
|
resolve, store the literal string).
|
|
|
|
The recorded entry gets `["p", "<mxid>"]` tags for each resolved
|
|
mention, *and* keeps the `@user` substring in the body for human
|
|
readability. A renderer can then offer a "your bullets" view per
|
|
person.
|
|
|
|
## 4.7 Ship sensible default shortcuts for the cdf rooms
|
|
|
|
`tracker/tracker.py` — add a one-time bootstrap that, on first
|
|
`!setup` (or first capture) in a room whose name matches a known
|
|
chateau room, pre-populates shortcuts. Suggested defaults:
|
|
|
|
| Room name | Shortcuts |
|
|
|---|---|
|
|
| Animals | `!buy task #buy`, `!chores task #priority:5`, `!vet task #vet`, `!need need` |
|
|
| Gardens | `!buy task #buy`, `!harvest task #harvest`, `!plant task #plant`, `!need need` |
|
|
| Operations | `!buy task #buy`, `!steward task #steward`, `!repair task #repair`, `!need need` |
|
|
| Events | `!host task #host`, `!ticket task #ticket` |
|
|
|
|
These are starting points, not a final list. Communities edit them
|
|
via `!setup` once they're in.
|
|
|
|
A safer way to ship this is a `default_shortcuts.yaml` config the
|
|
plugin reads, so changes don't need a code redeploy.
|
|
|
|
## 4.8 New universal verbs implementation
|
|
|
|
`tracker/tracker.py:56` — add to `UNIVERSAL_VERBS`:
|
|
|
|
```python
|
|
UNIVERSAL_VERBS = {
|
|
"add", "task", "tasks", "sidequest", "sidequests",
|
|
"remind", "reminders", "done", "list", "setup",
|
|
"goals", "need", "needs",
|
|
}
|
|
```
|
|
|
|
(Plural aliases per §3.1.)
|
|
|
|
Add `_handle_goals` and `_handle_need` handlers. `!goals` uses
|
|
replaceable-event semantics (§3.3) — for the matrix-local v1, this
|
|
means *upserting* on `(user, room, kind='goals')` rather than
|
|
inserting. One row per author per room.
|
|
|
|
`!need` records a `kind='need'` item that stays open until
|
|
either `!done` (we got some) or another verb explicitly converts it
|
|
to a `!buy` task.
|
|
|
|
## 4.9 Frequency tag parsing in `!list`
|
|
|
|
`tracker/tracker.py:302` — when listing items, group by
|
|
`frequency:` tag so the chore-list renders as:
|
|
|
|
```
|
|
**Daily (3):**
|
|
- `5` fresh water for alpacas
|
|
- `7` fresh water for ducks
|
|
- `12` open & close hens
|
|
|
|
**Every 3 days (2):**
|
|
- `19` scoop alpaca manure
|
|
- `23` fluff alpaca bedding
|
|
|
|
**Weekly (1):**
|
|
- `4` change out hen straw
|
|
```
|
|
|
|
This is rendering, not protocol — the spec just stores tags.
|
|
|
|
## 4.10 Replace the `tracker/README.md` quirk note
|
|
|
|
After §4.4 lands, strike the edit caveat. Add a paragraph on the
|
|
new pin behavior, the new universal verbs, and the multi-verb
|
|
splitting.
|
|
|
|
---
|
|
|
|
# 5 — New ideas the pilot surfaced
|
|
|
|
## 5.1 Opt-in "private journal room" mode
|
|
|
|
For a per-user *private* journal room (one bot account, one human
|
|
member), the prefix friction adds nothing — every message is
|
|
journal content by definition. We can add a per-room flag
|
|
`auto_journal: true` (default `false`) that records every plain
|
|
message as a `!journal` entry. This is *opt-in per room* and the
|
|
bot acks loudly the first time it activates so nobody is surprised
|
|
by it.
|
|
|
|
For shared rooms — which is everywhere in the pilot — the default
|
|
stays explicit-prefix-only, matching Coco's "`!journal` is the
|
|
required format" enforcement.
|
|
|
|
## 5.2 Multi-room fan-out
|
|
|
|
Skye's "I'm not sure which chat to put these social things in"
|
|
suggests an entry can sometimes belong to multiple rooms. We
|
|
propose a `+#room` syntax:
|
|
|
|
```
|
|
!task +#events +#general organize image-AI brainstorm with pat and coco
|
|
```
|
|
|
|
This records the entry in *both* communities. The same entry has
|
|
two `a`-tags (one per NIP-72 community). Renderers in either room
|
|
see it. `!done` closes it in both.
|
|
|
|
Implementation: parse `+#<roomname>` tokens out of the body, resolve
|
|
to room ids the bot is also a member of, and insert one row per
|
|
target room with a shared `link_id`. v2 work, not v1.
|
|
|
|
## 5.3 Photo / link / media in entries
|
|
|
|
Helena's "checked feathered babies" entry was actually a photo +
|
|
caption. Thomas shares YouTube links. Coco shared a PDF on toxic
|
|
plants. The body field today is text; the bot can capture media
|
|
attachments by storing their `mxc://` URI in a `media` JSON column.
|
|
A renderer can fetch and display.
|
|
|
|
Especially valuable for the eink panel — a photo of the daily chores
|
|
list, a graph of fed/watered checkmarks, the duck-pool-water-runoff
|
|
diagram.
|
|
|
|
## 5.4 Calendar feed for timed entries
|
|
|
|
Pat already saw the vet appointment on the castle calendar — *"nice
|
|
i already see it on the castle calendar"*. This integration should
|
|
be documented: where it lives, what feeds it. If it's manual, it
|
|
should be automated; if it's automated, it should be tested for
|
|
all `kind 31923` timed entries.
|
|
|
|
The natural shape: an iCalendar feed at
|
|
`https://docs.ariege.io/calendar.ics` produced from the bot's
|
|
timed-entry table. Castle members subscribe in their calendar app
|
|
of choice.
|
|
|
|
## 5.5 Daily / weekly digests
|
|
|
|
The pilot showed the value of *summary*. Coco pins a current
|
|
`!goals`. Ulo posts meeting summaries. Helena writes "homework"
|
|
recaps. The bot can produce these on a cron:
|
|
|
|
- **Morning digest** (per room): "Yesterday's journal entries (3),
|
|
Open tasks this week (12), Goals pinned (1)."
|
|
- **Weekly digest** (Sunday evening): "This week's completed tasks
|
|
(28), Open carry-over (15), Journal highlights (a sampling)."
|
|
|
|
This is a content surface, not protocol. The data is already there.
|
|
Implementation = a cron handler + a markdown template + posting to
|
|
the room. Maubot has cron support via `asyncio` + `croniter`.
|
|
|
|
## 5.6 Bot personality — Alfred
|
|
|
|
The community named the bot Alfred (the butler). Replies should
|
|
match: a slightly formal, helpful, occasionally dry tone.
|
|
|
|
Concretely:
|
|
- Current acks: `📥 Logged for @alice.`
|
|
- Alfred-flavored: `Very good, @alice. Logged.`
|
|
|
|
A `personality` config field with `default | alfred | minimal`
|
|
lets other adopting communities pick. Keep `default` deadpan and
|
|
neutral.
|
|
|
|
This is low-priority but it costs nothing and the data shows the
|
|
community will engage with the bot more if it feels like a
|
|
collaborator. "What should we name our assistant?" — *"Alfred would
|
|
be my go to"* — *"doiittt"* is a community taking ownership of the
|
|
tool before it exists.
|
|
|
|
## 5.7 LLM fallback inside the chateau network
|
|
|
|
The spec's classifier conformance level 2 is LLM fallback. The
|
|
chateau has an existing Ollama setup or can run one on the same
|
|
host as maubot. The fallback fires only when:
|
|
|
|
- The user typed `!add` (explicit ambiguity),
|
|
- The rules classifier returned `unclassified`,
|
|
- The LLM is reachable.
|
|
|
|
If any condition fails, the entry stays in the inbox until
|
|
human-sorted (level 0 fallback). The architecture stays
|
|
self-hostable.
|
|
|
|
Smallest reasonable model for this is in the `llama3:1b` /
|
|
`phi3:mini` size range — runs comfortably on the maubot host.
|
|
|
|
## 5.8 Wiki / docs lookup inside the tracker context
|
|
|
|
The wiki plugin already exists. Inside a tracker reply, if an entry
|
|
mentions e.g. *"recycling"*, the bot could surface a `[?]` hint:
|
|
"Related: `docs.ariege.io/spaces/waste-recycling`". One-line link,
|
|
ignorable.
|
|
|
|
This makes the chateau's docs site organically discoverable from
|
|
chat without anyone needing to remember URLs. Implementation:
|
|
inside the tracker's record path, fire a quick keyword query at the
|
|
wiki plugin's index and append top-1 result if confidence is high.
|
|
|
|
---
|
|
|
|
# 6 — How this fits the larger omnixy / aiolabs ecosystem
|
|
|
|
The Château pilot is one community using one piece of the stack. The
|
|
broader picture:
|
|
|
|
## 6.1 The protocol survives the implementation
|
|
|
|
The community-organizer spec is CC0 and references only open
|
|
standards (RFC 5545 VTODO, NIP-52, NIP-72, ActivityStreams). If the
|
|
maubot plugin disappears tomorrow, the events on the relay are still
|
|
readable by any NIP-52 client. The chateau's organizational memory
|
|
is not coupled to maubot. That's the design property we're
|
|
protecting.
|
|
|
|
## 6.2 Nostr bridge (Phase 2)
|
|
|
|
Today the tracker is matrix-only. When the vocabulary stabilizes
|
|
(probably 2-4 more weeks of pilot), Phase 2 bridges to Nostr:
|
|
|
|
- Bot writes captured entries to a community Nostr relay.
|
|
- The relay can be private (auth-gated) or public per the
|
|
`publish` posture config.
|
|
- Renderers (the eink panel, a future webapp dashboard) subscribe
|
|
to the relay and surface the data.
|
|
|
|
This is the unlock for the *inky-impression* panel in the foyer —
|
|
the data shape it consumes is exactly the events the bot will be
|
|
producing.
|
|
|
|
## 6.3 Identity — the signer abstraction
|
|
|
|
Today everything is signed by the bot. The spec's §7.2 / §12
|
|
develop the per-user-signing endgame: a sidecar
|
|
`nsecbunkerd` on the same host, the bot holding only scoped NIP-46
|
|
connection tokens.
|
|
|
|
At chateau scale (10-20 members), this is overkill for v1. We run
|
|
v1 (trust the bot, `author` tag carries the human MXID) for as long
|
|
as the community is small and physical-trust-bounded. We migrate to
|
|
per-user signing when:
|
|
|
|
- More than one community is using the same bot account, *or*
|
|
- An external party (visitor, woofer, neighbor) needs to write
|
|
entries without being a fully-trusted member, *or*
|
|
- LNbits #18 (the bunker integration) ships and we want a single
|
|
identity story across the stack.
|
|
|
|
The signer abstraction is *already* in the spec, so the migration
|
|
is design-for-it-now, do-it-later.
|
|
|
|
## 6.4 LNbits / Lightning
|
|
|
|
Two Lightning hooks the pilot suggests:
|
|
|
|
**Marketplace / payable buy items.** A `!buy` item could optionally
|
|
carry a price and produce a Lightning invoice via LNbits when
|
|
clicked through. "Roll-out flypaper — €12 — pay" with the invoice
|
|
generated against the chateau's funding wallet. Useful for outside
|
|
contributors who want to chip in a specific item.
|
|
|
|
**Visa funding stream.** Coco's alpaca funding stream (€23k over
|
|
time) is exactly the kind of recurring-pledge use case LNbits has.
|
|
This is a partnership channel between the tracker and the LNbits
|
|
extension at the marketplace level, not v1.
|
|
|
|
## 6.5 Events app
|
|
|
|
Coco's events-app side-project is in the pilot data:
|
|
*"developing the app & biz plan for tech company of an
|
|
ariege-wide calendar of events app"*. The tracker's NIP-52 31923
|
|
events are the right shape to feed that calendar. The webapp
|
|
consumes NIP-52 already (per the bunker spec discussion). One data
|
|
shape, two surfaces: the bot records, the events app displays.
|
|
|
|
## 6.6 Continuwuity homeserver
|
|
|
|
The Matrix homeserver running this is Continuwuity, deployed via
|
|
`deploy/server-deploy/modules/services/matrix.nix`. The maubot
|
|
daemon registers via the admin-room token flow (see
|
|
`~/dev/CLAUDE.md` Matrix-homeserver section). All bot accounts in
|
|
this report (`@journalbot`, future `@trackerbot`, `@wikibot`, etc.)
|
|
are regular Matrix users on that homeserver.
|
|
|
|
The bot-as-user pattern means a chateau member can DM the bot
|
|
privately (e.g. for personal `!journal` entries the public room
|
|
shouldn't see). The current journal plugin already supports this —
|
|
just invite the bot to a 1-1 room.
|
|
|
|
## 6.7 Wiki cross-cutting
|
|
|
|
The wiki plugin (`!ask`, `!doc`) reads `docs.ariege.io`. The
|
|
chateau's documentation should grow alongside the tracker — when a
|
|
new community-life protocol gets agreed on at a meeting (e.g.
|
|
"who feeds the cat"), it should land in `docs.ariege.io/spaces/...`
|
|
and be `!ask`-able. The pilot showed several decisions that would
|
|
benefit from durable documentation: the chickens' opening time, the
|
|
puppy training schedule, the vet's number.
|
|
|
|
This argues for a small `tracker → wiki` integration: when a
|
|
`!journal` entry contains a *decision* (heuristically: contains
|
|
"we decided" / "rule" / "from now on"), the bot pings the room with
|
|
"This looks like a durable decision — would you like to file it
|
|
as a docs page?". One-click → wiki page draft.
|
|
|
|
---
|
|
|
|
# 7 — Phased plan
|
|
|
|
A 5-phase rollout that keeps each step small, deployable, and
|
|
reversible.
|
|
|
|
## Phase 0 — Verb normalization and edit handling (next 1-2 weeks)
|
|
|
|
Small parser / dispatch changes. No schema migrations beyond
|
|
`mx_event_id`.
|
|
|
|
- §4.1 inline `!verb` markers as tags
|
|
- §4.2 multi-verb-per-message splitter
|
|
- §4.3 trailing-colon + case
|
|
- §4.4 edit handling (schema v2: add `mx_event_id`)
|
|
- §4.8 new universal verbs (`!goals`, `!need`, plural aliases)
|
|
- §4.10 README updates
|
|
|
|
After Phase 0, the bot won't drop any of the entries we observed.
|
|
|
|
## Phase 1 — Replaceable goals and pinning (2-4 weeks)
|
|
|
|
- §3.3 replaceable-event semantics in spec
|
|
- §4.5 pin/unpin behavior on `!goals` recording
|
|
- §4.7 default shortcuts for cdf rooms
|
|
- §4.9 `!list` grouping by frequency
|
|
|
|
After Phase 1, `!goals` becomes a living list per author and the
|
|
chore-recurrence model is at least visible to renderers.
|
|
|
|
## Phase 2 — Subjects, mentions, recurrence (4-6 weeks)
|
|
|
|
- §3.5 `frequency:` tag in spec
|
|
- §3.6 subject tags (animals, places)
|
|
- §4.6 inline `@`-mention extraction
|
|
- §3.7, §3.8 grammar clarifications in spec
|
|
- §5.5 daily/weekly digests
|
|
|
|
After Phase 2, the eink panel can render meaningful views without
|
|
needing protocol changes.
|
|
|
|
## Phase 3 — Nostr bridge (6-10 weeks)
|
|
|
|
- Wire the tracker's local SQLite to a Nostr publisher.
|
|
- Subscribe to events tagged with the bot's communities for
|
|
bidirectional sync.
|
|
- Eink panel goes live against the relay.
|
|
|
|
## Phase 4 — Per-user signing and identity (when LNbits #18 ships)
|
|
|
|
- Operator-IdP + sidecar bunker per spec §12.
|
|
- Chat-handle ↔ pubkey binding via LNbits.
|
|
- Bot acquires scoped NIP-46 tokens per member.
|
|
- `BotSigner` becomes the fallback only.
|
|
|
|
---
|
|
|
|
# 8 — Open questions for the Château
|
|
|
|
Things the team should weigh in on before we lock the next phase:
|
|
|
|
1. **Verb names.** Is `!goals` the right word, or `!intentions` /
|
|
`!focus` / `!agenda`? Same for `!need` vs `!stock` vs `!low`. The
|
|
bot will accept what the community uses — but the spec name will
|
|
stick.
|
|
|
|
2. **Default shortcuts per room.** §4.7 lists candidates. Anything
|
|
missing? Anything wrong? Specifically: does the Animals room
|
|
want `!vet` and `!med` as separate kinds, or one `!health`?
|
|
|
|
3. **Subject vocabulary.** Which animals, places, and assets are
|
|
worth naming as subjects? Suggested first pass: **animals** —
|
|
Sapphi, Loki, Leia, Tango, Morrigan, plus group names
|
|
(alpacas, hens, ducks, pups, hatchlings). **Places** — orchard,
|
|
south-paddock, coop, garage, kitchen, lab, dependence. **Assets** —
|
|
tractor, electric-fence, van, irrigation.
|
|
|
|
4. **Calendar integration.** Today *something* turns dated journal
|
|
entries into castle-calendar items. Who owns that pipeline?
|
|
Should the bot own it? Should we publish an `.ics` feed off the
|
|
maubot host?
|
|
|
|
5. **Photo / media capture.** Does it matter that journal entries
|
|
capture the photos attached to them, or is text enough for v1?
|
|
(Materially affects storage and the eink panel.)
|
|
|
|
6. **The "Alfred" persona.** Yes / no / opt-in per room?
|
|
|
|
7. **The private-journal room mode.** Would members value a 1-1 DM
|
|
with the bot where every message is auto-journaled, or does the
|
|
explicit `!journal` everywhere feel cleaner?
|
|
|
|
8. **LLM fallback.** Comfortable running a local model on the same
|
|
host that classifies `!add` entries? Or stay rules-only?
|
|
|
|
9. **Cross-room fan-out.** Do members value `+#room1 +#room2`
|
|
syntax, or is "I'll just repost in the other room" fine?
|
|
|
|
---
|
|
|
|
# Appendix A — Glossary
|
|
|
|
- **Verb** — A `!`-prefixed word at the start of a message that the
|
|
bot recognizes as a command (e.g. `!journal`, `!task`).
|
|
- **Tag** — A `#`-prefixed word inside a message that gets attached
|
|
to the entry as metadata (e.g. `#buy`, `#priority:1`).
|
|
- **Subject** — A `@`-prefixed word that names an entity (animal,
|
|
place, asset) the entry is about.
|
|
- **Shortcut** — A per-room alias that expands to a universal verb
|
|
+ tags (e.g. `!buy` expands to `!task #buy`).
|
|
- **Replaceable event** — A NIP-52 event keyed by a `d`-tag, where
|
|
newer events overwrite older ones with the same key. Used for
|
|
living lists like `!goals`.
|
|
- **Inbox** — Where `!add` entries land when the classifier can't
|
|
determine a kind. Cleared via `!sort` or `!reclassify`.
|
|
- **Bot** — The maubot plugin instance attached to a Matrix client
|
|
account (e.g. `@journalbot:ariege.io`).
|
|
- **Renderer** — Any output surface (eink panel, webapp dashboard,
|
|
mobile notification) that consumes captured events.
|
|
|
|
---
|
|
|
|
# Appendix B — File map
|
|
|
|
Concrete files this report's proposals would change:
|
|
|
|
| File | Change |
|
|
|---|---|
|
|
| `docs/community-organizer-spec.md` | §3.1 plural aliases, §3.2 new verbs, §3.3 replaceable, §3.5 frequency, §3.6 subjects, §3.7 inline markers, §3.8 sub-headers |
|
|
| `tracker/tracker.py:52` | Regex updates (case-insensitive, trailing colon) |
|
|
| `tracker/tracker.py:56` | `UNIVERSAL_VERBS` additions |
|
|
| `tracker/tracker.py:184` | Dispatch — multi-verb + inline tag extraction |
|
|
| `tracker/tracker.py` | New `_handle_goals`, `_handle_need`, `_handle_edit` |
|
|
| `tracker/tracker.py` (upgrade table) | `upgrade_v2` — `mx_event_id`, `link_id`, `pinned` columns |
|
|
| `tracker/classify.py` | Optional — LLM fallback wiring |
|
|
| `tracker/README.md:133` | Strike the edit caveat, document new behaviors |
|
|
| `journal/journal.py:34` | Regex update consistent with tracker |
|
|
| `wiki/wiki.py` | Optional `!ask`-from-tracker integration |
|
|
|
|
---
|
|
|
|
*End of report.*
|