feat(base,learn): suggest changes within a shared studyset

ADR 0044's step 6b (D44, D46 to D48): a Viewer, and an agent, suggest
changes within a shared studyset, which its Owner and Editors accept or
decline.

A suggestion or report is written as Explore's are, in its writer's own
synced space, with kinds of its own (space-suggestion, space-report)
and the space's id in feedback_thread's publicationId, so no synced
table changes and older apps, skipping kinds they don't know, keep
syncing. Where the studyset is private it is sealed with its key, bound
to the space; a reply to it is sealed for its thread.

Learn's server gathers a space's threads for its members alone
(feedback.threadsInSpace, NotFound for anyone else): only threads and
replies by members now, decisions only from rows in the space itself,
where the engine lets its Owner and Editors alone write; sealed
payloads pass in base64 with their key and nonce. The inbox adds the
threads its caller decides on or wrote. The module tells a host a
person's spaces and each space's members (sharedSpacesOf,
membersOfSpaces). No migration: no table changes.

In the app, a Viewer's card and note offer Suggest a change: the fields
write into the suggestion alone, sent with a message. A shared
studyset's menu lists its Suggestions, where its Owner and Editors
accept a change as a revision, or a new card or note into the
studyset, and decide in the space. A suggestion naming a file that
isn't the studyset's, or bringing files of its own, isn't taken.

Whats-New: In a studyset shared with you as a viewer, suggest a change to a card or note; its owner and editors find your suggestions under Suggestions in its menu and accept or decline them.
Whats-New-De: In einem Lernset, das du nur ansehen darfst, schlägst du Änderungen an Karteikarten und Notizen vor; Besitzer:in und Bearbeiter:innen finden sie im Menü unter „Vorschläge“ und nehmen sie an oder lehnen sie ab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-11 20:34:06 +01:00
commit 82c777b1a5
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -6,7 +6,7 @@
agent's recommendations, which they chose on 11 Nov 2026, D14 too, and D15 to D26;
D27 their choice; D28 the agent's, to be confirmed; D29 to D32 the agent's
recommendations, which they chose.
Steps 1 to 5 and step 6's first part built; the rest below.
Steps 1 to 5 and step 6's first two parts built; the rest below.
- **Builds on:** ADR 0005 (publishing, reports and suggestions), ADR 0014 (the module),
ADR 0016 (one account across an instance), ADR 0017 (key pairs), ADR 0019 (private
studysets), ADR 0021 (operators and assistants).
@ -250,6 +250,24 @@ member reads everything in the space.
and signs in no other way. It sets its public keys itself, once. Deleting the owner
deletes their agents first, as accounts are deleted; its public profile says whose
agent it is.
- **D46.** **A suggestion in a shared space is kept as Explore's are** (decided 11 Nov
2026, the agent's recommendation): in its writer's own synced space, so it is written
offline, sealed with the shared studyset's key where that is private; the instance
gathers each space's for its members, checking membership and role as it reads.
`feedback_thread` takes it as kinds of its own (`space-suggestion`, `space-report`),
its `publicationId` holding the space's id, so no synced table changes and older apps,
skipping kinds they don't know, keep syncing. Editors' and the Owner's decisions are
written into the shared space itself, where the engine already allows them alone.
Over rows of the shared space written by Viewers, which would need the engine to let
a read-only member write some tables.
- **D47.** **Every member sees them** (decided 11 Nov 2026, the agent's recommendation):
a suggestion or report in a shared space, and its replies, show to everyone in it,
Viewers too, as Explore's show to everyone learning a studyset.
- **D48.** **Changes and new items** (decided 11 Nov 2026, the agent's
recommendation): a Viewer or an agent suggests a changed card, note or step, as on
Explore, and new cards and notes for the studyset or one of its topics; deleting is
asked for with a report. A suggestion may name the files the studyset holds; new
files it would bring come later.
## Steps
@ -313,7 +331,22 @@ member reads everything in the space.
once to copy, new token, taken back, deleted) and members marked as agents
(`SpaceMember.agent`; Learn's Share sheet: a bot, "Agent", no role above
Viewer offered, none to hand the studyset on to).
b. Suggestions within a shared space (D10, D44).
b. **Suggestions within a shared space** (D10, D44, D46 to D48), built 11 Nov
2026: Learn's `feedback.threadsInSpace` gathers a space's threads
(`space-suggestion`, `space-report`) for its members alone, its writers
and repliers members now, its decisions read from the space's own rows;
the inbox adds those the caller decides on or wrote; a sealed payload
passes in base64 with its key and nonce (`FeedbackView.space`, `keyId`,
`nonce`). The module tells a host a person's spaces and each space's
members (`sharedSpacesOf`, `membersOfSpaces`). In the app,
`FeedbackRepository` suggests changed cards, notes and steps and new
cards and notes, reports, replies (sealed for their thread) and decides
in the space (`SpaceRouter.placeRow`), and takes a suggestion in only
where it names the studyset's own files and brings none; a Viewer's
card and note offer Suggest a change, and a shared studyset's menu its
Suggestions, where its Owner and Editors accept or decline. New cards
and notes are suggested through the repository (the agent, step 6c);
the app offers a Viewer no button for them yet.
c. The agent itself, its CLI and MCP server, on a pure-Dart core (D7, D41).
## Open questions, before building