mirror of
https://github.com/block/buzz.git
synced 2026-10-28 21:11:48 +00:00
docs(protocol): make artifact specification standalone
Signed-off-by: Fizz <400e8babadcee6a7f420103f10a2849d84c4a9c71d5bd04f3948c814216648a3@buzz.block.builderlab.xyz>
This commit is contained in:
12
VISION.md
12
VISION.md
@@ -152,13 +152,11 @@ Beyond chat: channels are workspaces.
|
||||
|
||||
The relay hosts git repos. Smart HTTP — standard `git clone`, `git push`, nothing special. Your npub signs pushes. Same domain, same auth, same identity as everything else on the relay.
|
||||
|
||||
The proposed [channel artifact model](docs/nips/NIP-AR.md) replaces the earlier
|
||||
“branches are channels” direction: channels contain work records and may host
|
||||
several projects, tasks, or branches. A dedicated branch channel remains a useful
|
||||
workspace choice, not a required identity or one-to-one relationship. Completing
|
||||
one record does not automatically archive the shared channel. Existing Git
|
||||
objects and review authority retain their separate protocol contracts during
|
||||
migration. This is proposed direction, not shipped artifact support.
|
||||
[Channel artifacts](docs/nips/NIP-AR.md) bring durable work records into channels
|
||||
and threads. A channel can host several projects, tasks, or branches. Teams can
|
||||
choose a dedicated branch channel when the work benefits from its own space.
|
||||
Completing one record leaves the shared channel available for other work.
|
||||
Git objects and review authority retain their own protocol contracts.
|
||||
|
||||
See [VISION_PROJECTS.md](VISION_PROJECTS.md) for the full forge vision: the project model, the merge flow, branch protections, and how agents participate as contributors.
|
||||
|
||||
|
||||
@@ -8,23 +8,21 @@ This document is the software-forge slice of the broader Buzz platform. [VISION.
|
||||
|
||||
---
|
||||
|
||||
## Proposed evolution: channels contain work
|
||||
## Channels contain work
|
||||
|
||||
The [channel artifact proposal](docs/nips/NIP-AR.md) and its
|
||||
[client contracts](docs/nips/NIP-AR-CLIENTS.md) supersede this document's earlier
|
||||
one-branch/one-channel assumption as proposed direction, not shipped behavior.
|
||||
Projects and tasks are editable records inside channels or threads; a channel
|
||||
may contain many of either. Projects organize related work without being a
|
||||
prerequisite for a task or granting access to it. Dedicated workspaces remain
|
||||
an option. Completing a task, retiring a branch record, or archiving a project
|
||||
does not automatically archive its channel.
|
||||
[Channel artifacts](docs/nips/NIP-AR.md) and their
|
||||
[client contracts](docs/nips/NIP-AR-CLIENTS.md) give projects, tasks, and branch
|
||||
collaboration records a home inside channels or threads. A channel may contain
|
||||
many records of each type. Projects organize related work without being a
|
||||
prerequisite for a task or granting access to it. Teams choose dedicated
|
||||
workspaces when useful. Completing a task, retiring a branch record, or archiving
|
||||
a project leaves the channel available for other work.
|
||||
|
||||
The forge workflows below remain useful examples of dedicated workspaces,
|
||||
not mandatory identity/cardinality rules. NIP-34 remains authoritative for Git
|
||||
identity and operations. Existing NIP-MP projects remain the current shipped
|
||||
representation pending an explicit migration; the proposal must not create a
|
||||
second competing project record. Private artifact access does not automatically
|
||||
make existing repository metadata, code, or reviews private.
|
||||
This model supersedes the one-branch/one-channel assumption; the forge workflows
|
||||
below illustrate optional dedicated workspaces. NIP-34 remains authoritative
|
||||
for Git identity and operations. Converting NIP-MP projects to artifacts
|
||||
preserves one canonical record and its references. Private artifact access does
|
||||
not automatically make repository metadata, code, or reviews private.
|
||||
|
||||
For the intended experience without protocol details, see
|
||||
[Work lives alongside the conversation](docs/channel-artifacts-design-note.md).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Artifact client contracts
|
||||
|
||||
`draft` `clients` `not implemented`
|
||||
`draft` `clients`
|
||||
|
||||
Depends on [NIP-AR](NIP-AR.md). These are shared desktop, mobile, CLI, SDK, and
|
||||
agent contracts, **not relay business validation rules**. All types use the same
|
||||
@@ -20,11 +20,10 @@ Clients use a bounded fallback rather than deeply parsing oversized content.
|
||||
A malformed known type uses the fallback card with a clear unavailable-details
|
||||
state. Unknown types/versions show type, title, last editor, and a route to the
|
||||
home conversation when available. They must not disappear from the workspace.
|
||||
The default experience works without selecting or installing plugins.
|
||||
|
||||
## `buzz.project`
|
||||
|
||||
A grouping of related work, not a channel identity or access-control container.
|
||||
A grouping of related work.
|
||||
|
||||
| Payload field | Type | Meaning |
|
||||
|---------------|------|---------|
|
||||
@@ -54,8 +53,8 @@ A living definition of work, independent of any prerequisite project or repo.
|
||||
| `state` | string | `open`, `done`, or `cancelled` |
|
||||
| `status_label` | string, optional | Display refinement, e.g. “In review” |
|
||||
|
||||
The broad state supports common views; teams may use labels without a relay
|
||||
deploy. Clients must not infer done/cancelled solely from an arbitrary label.
|
||||
`state` supplies the common completion state; `status_label` refines its display.
|
||||
Clients must not infer done/cancelled solely from an arbitrary label.
|
||||
Assignees use repeatable `assignee` tags containing public keys. Assignment here
|
||||
is task metadata, not permission to read or edit, and does not automatically
|
||||
notify or subscribe the assignee. `assignee` deliberately differs from `p`,
|
||||
@@ -80,8 +79,7 @@ it or widen its audience. The same task may appear in several project views.
|
||||
|
||||
## `buzz.branch`
|
||||
|
||||
A collaboration record concerning a Git branch; not the ref itself or a second
|
||||
review/merge authority.
|
||||
A collaboration record concerning a Git branch.
|
||||
|
||||
| Payload field | Type | Meaning |
|
||||
|---------------|------|---------|
|
||||
@@ -92,12 +90,11 @@ review/merge authority.
|
||||
Required tags are `repository` (a NIP-34 `30617:<owner-hex>:<identifier>`
|
||||
coordinate) and `ref` (a valid full `refs/heads/...` Git ref). Split the coordinate
|
||||
on its first two colons only. Clients validate Git ref syntax with established
|
||||
Git-compatible validation, not an invented permissive approximation.
|
||||
Git-compatible validation.
|
||||
|
||||
A record may precede first push. Its repository/ref pair is immutable in this
|
||||
client contract: another ref or a recreated branch lifecycle gets a new record.
|
||||
Retirement is terminal for this client version. These are client semantics;
|
||||
the relay does not certify them. Multiple records may reference the same ref;
|
||||
Retirement is terminal. Multiple records may reference the same ref;
|
||||
clients may offer duplicate cleanup without merging their identities silently.
|
||||
|
||||
Git tips, push rights, checks, approval, and merge state come from authoritative
|
||||
@@ -108,7 +105,6 @@ Automatic summaries/notifications must respect the destination audience too.
|
||||
## Example: task started in a conversation
|
||||
|
||||
Standard signed-event fields are omitted. Placeholder IDs below are explanatory.
|
||||
The numeric kind is proposed; see the allocation note in NIP-AR.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -130,11 +126,9 @@ Later adding `["project", "<project-uuid>"]` uses `op=update` and `prev` naming
|
||||
the current accepted revision. It preserves `d`, `h`, and `root`. The project may
|
||||
live elsewhere; viewing that project does not grant access to this task.
|
||||
|
||||
## Compatibility release gate
|
||||
## Conformance
|
||||
|
||||
Publish shared valid/invalid fixtures before shipping editors. Exercise them
|
||||
in desktop, mobile, CLI/SDK, and agent tooling: unsupported versions, unknown
|
||||
fields/tags, bad JSON, cycles, inaccessible links, and concurrent updates.
|
||||
The relay suite should demonstrate both envelope rejection and acceptance of
|
||||
opaque content that a business client declines to interpret. Acceptance by one
|
||||
layer is not a correctness certificate from the other.
|
||||
Clients MUST handle unsupported versions, unknown fields and tags, malformed
|
||||
JSON, cyclic references, inaccessible links, and concurrent updates according
|
||||
to the rules above. A relay-accepted revision whose content fails the client
|
||||
contract MUST use the fallback display rather than a typed editor.
|
||||
|
||||
@@ -4,45 +4,34 @@ NIP-AR
|
||||
Channel Artifacts
|
||||
-----------------
|
||||
|
||||
`draft` `optional` `relay` `not implemented`
|
||||
`draft` `optional` `relay`
|
||||
|
||||
**Depends on:** NIP-01 (signed events), NIP-29 (channel access).
|
||||
|
||||
## Decision
|
||||
## Abstract
|
||||
|
||||
An **artifact** is a durable, editable record inside a channel, optionally
|
||||
attached to a conversation within it. Channels contain artifacts; they are not
|
||||
artifacts themselves. Projects, tasks, and branch collaboration records use the
|
||||
same envelope, with client-defined content types.
|
||||
attached to a conversation within it. This NIP defines a common envelope,
|
||||
identity, revision chain, access rules, and lifecycle for artifacts with
|
||||
client-defined content types.
|
||||
|
||||
- One current home channel determines an artifact's current audience.
|
||||
- Any number of artifacts, including of the same type, may share a location.
|
||||
- Relationships organize work; they never grant access or operational authority.
|
||||
- The relay validates the common envelope and lifecycle, not business schemas.
|
||||
- Clients share published contracts for first-party types; unknown types remain
|
||||
readable as a basic card.
|
||||
|
||||
This replaces the conversation-subject proposal in
|
||||
[PR #7656](https://github.com/block/buzz/pull/7656): no exclusive/primary claims,
|
||||
no type-specific event kinds or relay relationship validation, no required
|
||||
project for a task, and no permanently fixed home. This is a specification PR,
|
||||
not a claim that these behaviors are available in existing clients or relays.
|
||||
The current home channel determines the artifact's audience. Any number of
|
||||
artifacts, including of the same type, may share a channel or conversation.
|
||||
Relationships between artifacts organize work without granting access or
|
||||
operational authority. The relay validates the envelope and lifecycle; clients
|
||||
interpret and validate content according to its type.
|
||||
|
||||
MUST, MUST NOT, SHOULD, and MAY have their RFC 2119 meanings.
|
||||
|
||||
## Identity and envelope
|
||||
|
||||
The proposal uses one regular stored event kind, **45010**, for all artifact
|
||||
revisions. This number is proposed, not allocated by this docs-only change;
|
||||
implementation must reserve it in `crates/buzz-core/src/kind.rs`. It replaces,
|
||||
not interoperates with, the unshipped project-kind proposal using that number.
|
||||
Artifact revisions use regular stored event kind **45010**.
|
||||
|
||||
Each revision is a complete snapshot, not a field patch. Common tags have
|
||||
exactly two string elements. Required tags occur exactly once; optional tags at
|
||||
most once. Duplicate common tags are invalid even if their values agree. The
|
||||
relay MUST reject more than 256 total tags per revision, including common and
|
||||
unknown tags. This is a new artifact-specific bound; the advertised event-size
|
||||
limit also applies.
|
||||
unknown tags. The relay's advertised event-size limit also applies.
|
||||
|
||||
| Tag | Count | Meaning |
|
||||
|-----|-------|---------|
|
||||
@@ -58,11 +47,11 @@ limit also applies.
|
||||
`content` is opaque UTF-8 to the relay, subject to the relay's advertised event
|
||||
size and rate limits. Type names are lowercase ASCII dot-separated components,
|
||||
each starting with a letter and otherwise containing letters, digits, `_`, or
|
||||
`-`; total length is at most 128 bytes. `buzz.*` names are reserved by convention
|
||||
for published Buzz contracts, not proof of trusted authorship.
|
||||
`-`; total length is at most 128 bytes. `buzz.*` names are reserved by
|
||||
convention for published Buzz contracts, not proof of trusted authorship.
|
||||
|
||||
Identity is `(community, d)`, independent of signer, type, and home. It is not a
|
||||
NIP-01 addressable coordinate. The relay retains accepted revisions and an
|
||||
Identity is `(community, d)`, independent of signer, type, and home. It is not
|
||||
a NIP-01 addressable coordinate. The relay retains accepted revisions and an
|
||||
explicit current-head index; neither timestamps nor signer changes select a
|
||||
winner. `type` and `d` are immutable. A new business-schema version belongs in
|
||||
the content contract, not in a replacement artifact identity.
|
||||
@@ -72,13 +61,7 @@ confer authority. Business relationship tags are specified by clients, not
|
||||
resolved or validated by this NIP. Unsupported envelope versions are rejected.
|
||||
Missing `h` is a rejection, never a fallback to global visibility.
|
||||
|
||||
The existing canvas kind (40100) provides a channel-scoped, non-chat precedent;
|
||||
see `required_scope_for_kind` and `requires_h_channel_scope` in
|
||||
`crates/buzz-relay/src/handlers/ingest.rs`. Artifact implementation must explicitly
|
||||
join that scoped class, not `is_global_only_kind`. Kind allocation alone does
|
||||
not establish unread, quota, or fan-out behavior: implementation must audit and
|
||||
test those paths. Artifacts remain subject to bounded storage/write quotas even
|
||||
though they do not count as chat messages.
|
||||
Artifacts remain subject to the relay's storage and write quotas.
|
||||
|
||||
## Conversations and multiple artifacts
|
||||
|
||||
@@ -94,31 +77,26 @@ Replies use the conversation's existing protocol, not the latest artifact
|
||||
revision ID. An artifact revision is not a chat reply and MUST NOT increment
|
||||
reply counters, chat-message counts, or unread-chat state.
|
||||
|
||||
There is no exclusive slot, primary slot, or per-type singleton. Two tasks in
|
||||
one thread are two records, not competing declarations of what the thread is. A
|
||||
preferred card, pin, or dedicated workspace is a presentation choice, not
|
||||
uniqueness or authority. Archiving one project MUST NOT archive its channel or
|
||||
other artifacts in it.
|
||||
Artifacts at the same location retain separate identities and revision chains.
|
||||
Archiving an artifact MUST NOT archive its channel or other artifacts in it.
|
||||
|
||||
## Authorization and concurrency
|
||||
|
||||
Channel read access controls artifact read access. Threads introduce no
|
||||
additional audience. This applies to direct-ID lookups, history, current state,
|
||||
search, counts, previews, exports, and live delivery, within the host-derived
|
||||
community boundary. No title or relationship metadata may leak through errors or
|
||||
unreadable search/count results.
|
||||
community boundary. No title or relationship metadata may leak through errors
|
||||
or unreadable search/count results.
|
||||
|
||||
The proposed generic write policy is **channel collaboration**. “Write
|
||||
permission” means the same authorization that admits a kind-9 message in that
|
||||
channel: channel membership of any role (including agents/Bot), or open
|
||||
visibility, plus existing authentication, token-channel restrictions,
|
||||
moderation, and archive gates. It is not a `MemberRole` threshold. Thus an
|
||||
otherwise authorized community participant may create/edit in an open channel
|
||||
without first joining it. “Administration” means Admin/Owner channel authority
|
||||
under existing channel checks. Artifact writes require `Scope::ChannelsWrite`,
|
||||
matching canvas, plus the operation-specific channel checks below. Clients and
|
||||
agent tokens must request that scope; a numeric member-role threshold must not
|
||||
exclude agents.
|
||||
“Write permission” means the same authorization that admits a kind-9 message in
|
||||
that channel: channel membership of any role (including agents/Bot), or open
|
||||
visibility, plus authentication, token-channel restrictions, moderation, and
|
||||
archive gates. An otherwise authorized community participant may create/edit in
|
||||
an open channel without first joining it. “Administration” means Admin/Owner
|
||||
channel authority under channel authorization rules. Artifact writes require
|
||||
`Scope::ChannelsWrite` plus the operation-specific channel checks below.
|
||||
Clients and agent tokens must request that scope; a numeric member-role
|
||||
threshold must not exclude agents.
|
||||
|
||||
| Operation | Required authority at commit time |
|
||||
|-----------|------------------------------------|
|
||||
@@ -127,36 +105,34 @@ exclude agents.
|
||||
| Delete | Administration in current home; in a DM, participant write permission |
|
||||
| Move to another channel | Write permission in source AND destination |
|
||||
|
||||
Being an artifact's creator is attribution, not a permanent exclusive editing
|
||||
right. A reader without write permission cannot edit. Removed members lose
|
||||
write permission in private channels even if they created the record; an open
|
||||
channel still follows the open-channel admission rule above. These rules do not vary by
|
||||
`type` and do not introduce per-artifact access lists or plugin-defined rules.
|
||||
Existing authenticated-agent/channel authorization applies; provenance alone
|
||||
must not create a new grant. Signed authorship remains the actual event signer.
|
||||
Authorization is independent of the artifact's creator. A reader without write
|
||||
permission cannot edit. Removed members lose write permission in private
|
||||
channels even if they created the record; an open channel still follows the
|
||||
open-channel admission rule above. These rules do not vary by `type`.
|
||||
Authenticated-agent/channel authorization applies; provenance alone must not
|
||||
create a new grant. Signed authorship remains the actual event signer.
|
||||
|
||||
Creation uses `op=create`, no `prev`, and an unused `d`. All subsequent operations
|
||||
must name the current accepted head in `prev`. Ordinary updates and deletion
|
||||
must keep `h`; only `move` may change it. A move must actually change channels.
|
||||
`op` MUST agree with these structural constraints; it cannot disguise a move as
|
||||
an update or an update as a new creation.
|
||||
The relay checks permission, previous head, envelope, and anchor, then stores
|
||||
the event and advances the head in one transaction. Two writes against the
|
||||
same head cannot both succeed. Knowing `prev` is not edit authorization.
|
||||
On conflict, clients must refetch the current accessible head and reconcile
|
||||
their intended change, not blindly retry or silently overwrite newer state. Retrying an accepted event ID is idempotent;
|
||||
permission to retrieve its contents is still checked.
|
||||
Creation uses `op=create`, no `prev`, and an unused `d`. All subsequent
|
||||
operations must name the current accepted head in `prev`. Ordinary updates and
|
||||
deletion must keep `h`; only `move` may change it. A move must actually change
|
||||
channels. `op` MUST agree with these structural constraints; it cannot disguise
|
||||
a move as an update or an update as a new creation. The relay checks
|
||||
permission, previous head, envelope, and anchor, then stores the event and
|
||||
advances the head in one transaction. Two writes against the same head cannot
|
||||
both succeed. Knowing `prev` is not edit authorization. On conflict, clients
|
||||
must refetch the current accessible head and reconcile their intended change,
|
||||
not blindly retry or silently overwrite newer state. Retrying an accepted event
|
||||
ID is idempotent; permission to retrieve its contents is still checked.
|
||||
|
||||
Rejected writes never enter history, search, or live delivery. Error responses
|
||||
must not reveal an inaccessible current head or destination. The relay MUST reject NIP-09
|
||||
kind-5 requests targeting artifact revisions, with an explicit reason such as
|
||||
`invalid: use artifact delete operation`; it must not report successful deletion
|
||||
or release an artifact identity through that path.
|
||||
must not reveal an inaccessible current head or destination. The relay MUST
|
||||
reject NIP-09 kind-5 requests targeting artifact revisions, with an explicit
|
||||
reason such as `invalid: use artifact delete operation`; it must not report
|
||||
successful deletion or release an artifact identity through that path.
|
||||
|
||||
Deletion is a terminal tombstone on the same identity, with empty content.
|
||||
Delete events permit only the common envelope tags and the existing validated
|
||||
Delete events permit only the common envelope tags and validated
|
||||
authentication/provenance tags (such as NIP-OA `auth`), not annotation tags.
|
||||
This generic allowlist removes relationships without recognizing business types.
|
||||
Its type, `h`, `root`, and title must equal the head it deletes; deletion must
|
||||
not rename or relocate it. Its type and last title remain under its home
|
||||
permissions for an unavailable/deleted display. It is absent from active lists;
|
||||
@@ -164,6 +140,14 @@ subscribers receive a removal. Retained history follows retention/moderation
|
||||
policy; deletion is not a promise to erase downloaded copies. A deleted `d` is
|
||||
never reused. Business completion/archive is not deletion.
|
||||
|
||||
### Direct messages
|
||||
|
||||
A DM channel is a valid home. Artifacts inherit its participant access rules.
|
||||
DM participants are peers: deleting an artifact in a DM requires participant
|
||||
write permission rather than an Admin/Owner role. The relay MUST determine
|
||||
channel type from the stored channel, not an artifact tag. This rule applies to
|
||||
every artifact type.
|
||||
|
||||
## Moving and audience changes
|
||||
|
||||
Moving preserves identity and publishes a complete current snapshot into the
|
||||
@@ -173,43 +157,39 @@ relationship labels, attachments, and any private material copied into content.
|
||||
A reference does not automatically authorize copying its resolved contents.
|
||||
|
||||
The move revision is scoped to the destination. Its anchor must be absent or
|
||||
belong to that destination; the old conversation does not move with it. **Moving
|
||||
an artifact moves zero conversation messages.** Prior revisions stay under the
|
||||
visibility of the channel in which each was published. A destination-only reader
|
||||
can load the current snapshot without reading the old chain. A source-only
|
||||
reader retains access to permitted source history, not later destination
|
||||
revisions. Moves cannot revoke previously learned data.
|
||||
belong to that destination; the old conversation does not move with it.
|
||||
**Moving an artifact moves zero conversation messages.** Prior revisions stay
|
||||
under the visibility of the channel in which each was published. A
|
||||
destination-only reader can load the current snapshot without reading the old
|
||||
chain. A source-only reader retains access to permitted source history, not
|
||||
later destination revisions. Moves cannot revoke previously learned data.
|
||||
|
||||
One commit must advance the single head and durably record changes for both
|
||||
scopes: removal/invalidation in the source and arrival in the destination. These
|
||||
are two scoped change records, not one signed event pretending to have two `h`
|
||||
values. The destination carries the client-signed revision; the source uses a
|
||||
relay-authenticated invalidation in the platform sync change envelope. That
|
||||
envelope must bind community, source scope, artifact identity, and replay
|
||||
position, with no destination payload. If transported as a Nostr event instead,
|
||||
it requires a separately allocated relay-only sidecar kind and rejection of
|
||||
client-authored substitutes. Its wire schema is a sync-integration release gate,
|
||||
not an already allocated part of kind 45010. Publication must be retryable after
|
||||
a crash. The source removal must not contain the destination channel, title, or
|
||||
payload; a forward link may resolve only with the requesting reader's
|
||||
destination permissions. Concurrent edits/moves cannot create two active copies.
|
||||
Moving back to a former home still uses the one current head.
|
||||
One transaction MUST advance the current head and durably record removal from
|
||||
the source scope and arrival in the destination scope. The destination carries
|
||||
the client-signed revision. The source receives a separate relay-authenticated
|
||||
invalidation that binds community, source scope, artifact identity, and replay
|
||||
position. The invalidation MUST NOT contain the destination channel, title, or
|
||||
payload. Clients MUST reject invalidations that lack relay authentication.
|
||||
|
||||
Publication of both changes MUST be retryable after a crash. A forward link may
|
||||
resolve only with the requesting reader's destination permissions. Concurrent
|
||||
edits and moves MUST preserve a single current head. Moving back to a former
|
||||
home uses that same head and identity.
|
||||
|
||||
Channel membership and open/private visibility changes are also audience
|
||||
changes: artifact access follows channel policy, rather than being frozen to the
|
||||
membership at creation. Every subsequent read and delivery must honor the new
|
||||
access policy; clients must invalidate cached views when access is revoked.
|
||||
changes: artifact access follows channel policy, rather than being frozen to
|
||||
the membership at creation. Every subsequent read and delivery must honor the
|
||||
new access policy; clients must invalidate cached views when access is revoked.
|
||||
Offline copies cannot be recalled; UI must not promise otherwise.
|
||||
|
||||
## Current state, history, and sync
|
||||
|
||||
Use the generic signed-event ingestion path, not artifact-specific CRUD APIs.
|
||||
Artifact changes belong in channel/thread sync alongside other scoped changes,
|
||||
but **applied updates and human read positions are different state**. Receiving
|
||||
an update neither marks conversation read nor necessarily notifies someone.
|
||||
Explicit notification policy may call attention to meaningful changes. Clients
|
||||
MUST NOT add the artifact kind to conversational-unread kind sets; rendering a
|
||||
card alongside `root` is a separate presentation decision.
|
||||
Revisions are submitted through signed Nostr event ingestion. Artifact changes
|
||||
belong in channel/thread sync alongside other scoped changes, but **applied
|
||||
updates and human read positions are different state**. Receiving an update
|
||||
neither marks conversation read nor necessarily notifies someone. Explicit
|
||||
notification policy may call attention to meaningful changes. Clients MUST NOT
|
||||
count artifact revisions as unread conversation messages.
|
||||
|
||||
A compliant implementation must offer:
|
||||
|
||||
@@ -227,17 +207,18 @@ A compliant implementation must offer:
|
||||
must not require opening every thread. Channel visibility still gates results.
|
||||
|
||||
Multi-character tag filters are a Buzz extension, not portable NIP-01 behavior.
|
||||
Unsupported predicates must be rejected, never silently ignored. `EOSE` is not a
|
||||
durable applied checkpoint. A cursor must identify its covered stream/filter; a
|
||||
filtered result cannot stand in for a complete channel checkpoint.
|
||||
Unsupported predicates must be rejected, never silently ignored. `EOSE` is not
|
||||
a durable applied checkpoint. A cursor must identify its covered stream/filter;
|
||||
a filtered result cannot stand in for a complete channel checkpoint.
|
||||
|
||||
**Implementation boundary:** this draft specifies those observable guarantees,
|
||||
not a second sync protocol. The current-state query mode, snapshot/checkpoint
|
||||
wire shape, move-removal delivery, and expired-cursor/reset response must be
|
||||
bound to the platform sync specification before implementing or advertising NIP-
|
||||
AR support. Ordinary timestamp-sorted `REQ` history alone does not satisfy this
|
||||
contract. Until move delivery is supported, relays must reject `move`, not
|
||||
approximate it as independent delete/create writes.
|
||||
### Sync transport requirements
|
||||
|
||||
A relay advertising support MUST provide a sync transport that satisfies the
|
||||
current-state, replay, reset, and invalidation requirements above. This NIP
|
||||
defines their required semantics; the transport's wire format is specified
|
||||
separately. A relay MUST reject `move` until it supports atomic head
|
||||
advancement and durable delivery to both scopes. Independent delete/create
|
||||
writes do not satisfy move semantics.
|
||||
|
||||
## Client types and privileged operations
|
||||
|
||||
@@ -247,39 +228,34 @@ validate before interpreting business fields; unsupported or malformed content
|
||||
falls back to a safe card. Render title/type as untrusted text, not executable
|
||||
markup. A type namespace is not a publisher identity or installed capability.
|
||||
|
||||
Unknown versions must not be edited destructively. Editors must preserve unknown
|
||||
content fields and annotation tags when safe, or decline editing that version.
|
||||
Relations may be missing, inaccessible, deleted, self-referential, or cyclic.
|
||||
Traversals must be bounded and fail visibly without crashing.
|
||||
Unknown versions must not be edited destructively. Editors must preserve
|
||||
unknown content fields and annotation tags when safe, or decline editing that
|
||||
version. Relations may be missing, inaccessible, deleted, self-referential, or
|
||||
cyclic. Traversals must be bounded and fail visibly without crashing.
|
||||
|
||||
Links and payloads cannot authorize push, merge, membership changes, payments,
|
||||
or another privileged action. Those actions require their own trusted service
|
||||
checks. A client-observed status is not a relay-certified operational fact.
|
||||
|
||||
## Existing Git and project objects
|
||||
## Interoperability
|
||||
|
||||
This proposal does not create a second Git repository or replace NIP-34
|
||||
identity. Repository announcements (30617), ref state (30618), reviews, patches,
|
||||
and their statuses remain their existing protocol objects. Branch artifacts
|
||||
describe collaboration around a ref, not authoritative Git state.
|
||||
NIP-34 repository announcements (30617), ref state (30618), reviews, patches,
|
||||
and statuses retain their identities and access rules. An artifact referencing
|
||||
one of these objects MUST NOT alter its access policy or confer Git authority.
|
||||
Branch artifacts describe collaboration around a ref; Git state is obtained
|
||||
from the referenced repository under its own access checks.
|
||||
|
||||
**Legacy exception, not completed consolidation:** existing global
|
||||
project/issue/ repository objects do not acquire private channel reads or
|
||||
channel sync simply because they contain `buzz-channel`. A push binding alone is
|
||||
insufficient. NIP-34 read, search, clone/fetch, preview, and live-delivery
|
||||
scoping require a separate coordinated migration before promising private
|
||||
repository workspaces. This draft does not tighten or widen existing Git access
|
||||
as a side effect.
|
||||
A project event (30621) or issue event (1621) is not an artifact revision. A
|
||||
`buzz-channel` tag on another event kind does not apply this NIP's access or
|
||||
revision rules to it. Conversion between representations requires an explicit
|
||||
identity mapping and an authoritative current record; it MUST NOT create two
|
||||
independently writable representations of the same record. Conversion MUST
|
||||
preserve references and ownership information, and MUST NOT change access
|
||||
without authorization.
|
||||
|
||||
Existing 30621 projects and 1621 issues must not be dual-written as competing
|
||||
new artifacts. Migration requires an explicit canonical mapping and cutover,
|
||||
retaining old links, ownership information, and existing access until changed
|
||||
through an authorized migration. Previously published data cannot be made secret
|
||||
retroactively. No automatic conversion is specified here.
|
||||
## Conformance scenarios
|
||||
|
||||
## Acceptance scenarios
|
||||
|
||||
These are implementation requirements, not tests claimed to pass in this PR.
|
||||
Implementations MUST satisfy the following scenarios.
|
||||
|
||||
| Scenario | Required result |
|
||||
|----------|-----------------|
|
||||
@@ -300,21 +276,3 @@ These are implementation requirements, not tests claimed to pass in this PR.
|
||||
| Reconnect after deletion or filter exit | No ghost current records |
|
||||
| Background revision arrives | State updates; chat unread/read position unchanged |
|
||||
| Generic repository tag on a task | No push, clone, review, or membership capability gained |
|
||||
|
||||
## Non-goals and naming
|
||||
|
||||
No per-artifact audience lists, relay-executed plugins, schema-registration
|
||||
service, generic automation engine, or one-record-per-room requirement. Existing Buzz DMs are channels: an artifact with their `h` inherits participant
|
||||
access just like their messages (see `handle_dm_open` in
|
||||
`crates/buzz-relay/src/handlers/command_executor.rs`). This is not a new DM ACL.
|
||||
DM participants are peers (existing DM creation assigns `member` to all), so
|
||||
artifact deletion in a DM requires participant write permission instead of an
|
||||
Admin/Owner role. The relay must determine DM type from the stored channel,
|
||||
never an artifact tag. This channel-type rule does not vary by artifact type.
|
||||
Personal/no-room artifacts need a separately specified scope; missing `h` must not become an accidental
|
||||
global/private mode.
|
||||
|
||||
“Artifact” is the protocol/design term. User interfaces should usually say
|
||||
“task,” “project,” or the specific type name. “Work item” sounds task-specific;
|
||||
“card” describes a presentation. Neither is a better common identity name.
|
||||
Build-output artifacts/files remain distinct from these editable records.
|
||||
Reference in New Issue
Block a user