Files
buzz/beehive/PUBLIC_METADATA.md
Logan Johnson caedde0d83 fix(beehive): report post-submission metadata interruption as unknown not failed
An authority-check exception after the accepted POST /events - while reading
the response or during the final latest-kind0 query - previously became the
host's generic failed receipt even though the relay may already hold the
signed event. publishPublicMetadata now maps authority-guard interruptions to
the dedicated metadataPublicationInterrupted result once a submission may be
live: after the /events response and across the final readback query entry
and post-body checks. Pre-send query checks and the /events entry remain
definitive refusals and the guard itself is unchanged. intents.ts maps the
metadata-only result to unknown, matching interrupted-reconcile-locally.

Signed-off-by: Logan Johnson <loganj@squareup.com>
2026-09-10 23:26:22 -04:00

7.1 KiB

Public agent metadata (separate from private instructions)

Public kind0 contains only display_name, picture, about. Do not put behavior instructions, private inventory, provider details or credentials in these fields. Empty fields clear the previous public value; about is at most 280 Unicode characters. Picture is an HTTPS URL, not an upload operation.

Edit without a host, network or key

Run beehive drafts <owner-state-directory> (the directory containing the owner TUI identity reference). Use metadata-new, metadata-edit <draft-id>, metadata-discard <draft-id>, metadata-drafts, quit. Discard only removes a local draft, never a submitted operation or public event. Enter the exact retained relay URL and agent hex public key, then the three public fields. The final valid about line + Enter atomically saves the whole form. Partial forms are not saved; closing mid-form retains the previous saved version. Blank input clears a field, not “keep previous.” Resume prints the saved values before prompting.

Drafts live in metadata-drafts/drafts.json (owner-only 0700/0600) under owner control state, not on the current host. The separate profile-drafts store and immutable private instruction library are untouched. Concurrent stale edits fail instead of overwriting another save. There are at most 100 drafts. The short directory edit lock is the same mechanism as instruction drafts: after a crash, confirm no live editor before locally removing a leftover edit.lock.

Deliberate publication while the model is stopped

In the private owner TUI, the same draft commands work. Select the exact agent on its currently assigned eligible host, then metadata-publish <draft-id>. Review the complete PUBLIC payload and confirm yes. No Start, Restart, ACP executable, model or provider readiness is required. Stale/unreachable host inventory prevents submission and retains the draft. Host disappearance after submission leaves an owner journal operation pending/unknown.

The private management command is owner-signed and encrypted. The host consumer checks the signer (transport), host/agent/relay binding, retained assignment, operation identity, host CAS revision and exact metadata hash before reading the selected agent credential. The host key is infrastructure, never the public profile signer. Only the existing agent key signs both real kind0 and the NIP98 request authentication for the relay's supported POST /events and /query. The retained conversation relay must equal the management relay, and a valid existing agent-owner NIP-OA association must be present in that local conversation binding. Its signature, owner, agent and conditions are checked; no attestation is created, copied from another agent, or repaired. Conditions restricted to a single kind cannot authorize both kind0 and kind27235 and are refused. Missing association/key, removed key or denied credential access is an explicit recoverable error; no key regeneration or owner-key access occurs.

Draft, pending, published, failed/unknown

metadata-drafts lists saved desired values and matching submitted-operation statuses; operations shows all attempts. A saved draft is never evidence of publication. The existing owner management-intents journal durably retains the exact operation before sending. The host retains the exact agent-signed candidate in its per-agent journal's publicMetadata field before submitting it. This is an attempt record, not a new editable agent definition.

Only a positive matching event ACK and a signature-verified latest kind0 readback with that exact event ID produce published; signed latest kind0 <id>. A receipt records a historical observation; later external edits may supersede it. The published representation lives on the community relay as the latest kind0 by the agent pubkey. Public readback never replaces the owner's draft.

reconcile reopens management transport and retrieves retained receipts. Duplicate operations never repeat the public side effect, including after a host crash. If interruption loses the terminal observation, status remains unknown; this bounded slice does not automatically republish or turn queue persistence into success. An authority interruption (host close, revision/assignment change or persistence failure) after the signed event POST — while reading the /events response or during the final latest-kind0 query — reports the dedicated metadata publication interrupted after submission; outcome unknown; reconcile locally result with status unknown, never a definitive failure, because the relay may already hold the accepted event; the durable candidate and operation ID are retained. The same interruption before submission or at the /events entry is a definitive refusal. Check the desired draft, wait for fresh host state, then deliberately submit a new publish attempt if needed. A same-second retained signed attempt or same-second/future-dated latest kind0 is refused rather than inventing a timestamp or gambling on Nostr event-ID tie ordering; wait until its timestamp is past before retrying. Stale host revisions and old operation IDs cannot overwrite a newer accepted edit. ACK refusal, readback mismatch and network failures remain visible, not silently retried.

Publication changes no selected instructions/configuration, actual model run or sibling agent profile. It consumes the host operation revision on success, like other serialized owner actions; use refreshed inventory for the next action. No generic Move, key recovery, membership, invite or provider subsystem is added.

Source and validation scope

Native contract reference is immutable Buzz 051c3a270be9c73da9ab06700bcab7d5552fceaa: Desktop relay.rs build_profile_event, sync_managed_agent_profile, query_relay_at_with_keys, query_agent_profile; commands/agents_profile.rs; SDK nip_oa.rs; relay api/bridge.rs. At this pin Desktop's managed-agent builder/query/reconcile include the separately authored public about, alongside name/picture. These contracts were verified with git show at the immutable pin; the reference checkout's live HEAD differs and must not be used as that pin. Beehive likewise never derives about from private behavior text.

test/public-metadata.test.ts drives the real offline CLI, private management consumer and signature-enforcing loopback HTTP consumer with synthetic keys and an explicitly isolated credential adapter. It checks stopped publication with nonexistent ACP/provider executables, negative ACK/readback, wrong owner/relay, malformed public payload, stale revision, missing key and timestamp ordering, plus pre-send and post-submission host authority interruption: a preliminary-query or /events-entry close is a definitive refusal with no event POST, while a close after the accepted event POST leaves status unknown with the retained candidate, exactly one POST, and no duplicate POST or credential read across host reopen and owner reconcile. A phase-indexed direct publisher case covers the /events post-body, final-query entry and final-query post-body boundaries. This is source-shaped relay evidence, not a production relay, OS credential, installed-native or live-person profile publication claim.