Commit Graph

2 Commits

Author SHA1 Message Date
Kgothatso Ngako
aceef313ed docs: record what building projects changed about the plan
Five places the build chose differently, and one thing the plan did not
anticipate: a project reaches a chronicle only off the GroupSignedEvent record,
because the deprecated rebuild has no `toProjectEvent` and deliberately never
will. `recordSignedEvents` catches its own failure so a ceremony that succeeded
is not reported as failed, which leaves a narrow window where the row exists and
the signed event does not -- a project this device can show and can never hand
on. There is a test holding that case open.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-02 19:50:41 +02:00
Kgothatso Ngako
de4f15794a docs: a phased plan for projects, and the four keys it has to re-answer
The platform's server schema has had `project` and its two join models since
before this app existed. Bringing them here is not a port: the server answers
"whose project is this" out of a table of accounts, and this app is a group with
no accounts, no server and no authority but a quorum of its own members.

So every foreign key on `project` is re-answered. The creator becomes a `creator`
tag and the owners a set of `p` tags with an owner role -- written into the
template before it is proposed, so they are inside the id the quorum signs rather
than one device's note about who inserted a row. The owner of record is still
structurally the room, and `chatRoomId` carries that; the tags are what let a
project be the group's work and somebody else's property. Campaign is out of
scope entirely.

Two things the plan is mostly about, because neither is recoverable from the
code. The nip30303 kind band is not merely full -- 30310, 30311 and 30312 are
double-booked with the ceremony family, survivable only because none of the three
nip30303 kinds has a producer -- so projects take 30330-30332 and the collision
gets written down. And `ContributorTag.parse` drops a role that is not in
`KNOWN_ROLES`: the tag parses, the role comes back null, the string stays inside
the signed event id, the event still verifies, and the project lands with no
owners. Nothing is logged. `ROLE_OWNER` reaching that set is Phase 1's first
line, and three tests point at it.

Ten phases, 0-7 to build and 8-9 deferred. The one decision to make before Phase
1 is the scope fork: a project's contents are same-room, with real foreign keys,
because the FK is what makes a bad proposal fail loudly. Cross-room is Phase 9
and follows `parentChatRoomId`'s precedent -- a plain column, never a foreign
key, because a dangling value is the normal state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-02 18:55:23 +02:00