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>
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.