fix(cli): emit structured JSON warning when archive/unarchive owner-auth extraction fails - #4824
Open
wpfleger96 wants to merge 2 commits into
Open
fix(cli): emit structured JSON warning when archive/unarchive owner-auth extraction fails#4824wpfleger96 wants to merge 2 commits into
wpfleger96 wants to merge 2 commits into
Conversation
…n fails When `buzz agents archive` or `buzz agents unarchive` runs for a non-self target, `resolve_auth` fetches the target's kind:0 and looks for a NIP-OA `auth` tag. If the tag is absent or invalid the CLI was silently sending a bare request, which caused the relay to respond with the opaque error `400: missing auth tag` — exactly what Will hit when archiving duplicate agent instances. Four distinct causes can prevent attestation: 1. No kind:0 profile found for the target pubkey. 2. Target kind:0 has no `tags` array. 3. kind:0 has zero or multiple `auth`-labelled tags (ambiguous ownership). 4. Sole `auth` tag is structurally malformed, or its owner pubkey does not match the signer (the diagnostic prints the actual owner so the user can identify the mismatch). Each cause now emits a distinct warning to stderr naming what was wrong, then falls through to send the bare request — relay admins can still succeed without owner attestation. The self path (target == signer) is unchanged and silent. Also fixes the `resolve_auth` doc-comment, which incorrectly described the degradation as silent after the non-silent network-error behaviour was added. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Addresses three IMPORTANT findings from Thufir's pass-1 review:
1. JSON warnings, not prose
Replace eprintln! calls with writeln!(warn_sink, ...) emitting exactly
one {"warning":"..."} JSON object per fallback — consistent with the
CLI's documented structured-stderr contract (README.md, VISION.md) and
the precedent in channels.rs:597. relay-supplied values (target pubkey,
actual owner pubkey) pass through serde_json serialization so no
unescaped text reaches the output stream.
2. Injected warn-sink seam
Thread 'warn_sink: &mut dyn std::io::Write' through resolve_auth (same
pattern as finalize_roster_resolution in channels.rs). Production callers
pass &mut std::io::stderr(); tests pass &mut Vec<u8>. New boundary tests
prove each of the four fallback causes emits exactly one parseable JSON
warning, and that the success path emits nothing.
3. Single typed classifier
Replace the parallel describe_auth_failure mirror with AuthFailure enum
+ classify_owner_auth_tag returning Result<[String;4], AuthFailure>.
extract_owner_auth_tag is reduced to a #[cfg(test)] .ok() wrapper for
the existing option-style tests; the unreachable 'not a JSON array'
branch is eliminated.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96
force-pushed
the
wpfleger/cli-archive-auth-diagnostics
branch
from
August 5, 2026 03:31
db80d7c to
c17eead
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
emit structured JSON diagnostics when NIP-OA owner-auth extraction fails during
buzz agents archive/unarchiveProblem
When owner-auth extraction returned
None, the CLI silently sent a bare request. The relay replied with400: missing auth tagand the caller had no way to know why extraction failed.Solution
Extract
resolve_auth_from_profile— a sync function that owns all three warning branches and the success path.resolve_authreduces to: self-check → fetch kind:0 → delegate.classify_owner_auth_tagfailure (typedAuthFailureenum:NoAuthTag,AmbiguousAuthTag,WrongArity,NonStringElement,InvalidOwnerHex,InvalidSigHex,OwnerMismatch){"warning":"..."}line to stderr, matching the CLI's documented structured-stderr contract and the precedent inchannels.rs:597serde_jsonserialization — no unescaped textBoundary tests
Tests call
resolve_auth_from_profiledirectly with&mut Vec<u8>. Each of the three productionwriteln!calls is covered: deleting any one fails at least one test. Success path asserts zero bytes written.Changes
crates/buzz-cli/src/commands/agents.rsonly:AuthFailureenum withmessage()formatterclassify_owner_auth_tagreturningResult<[String;4], AuthFailure>extract_owner_auth_tagreduced to#[cfg(test)].ok()wrapperresolve_auth_from_profilesync helper (testable withoutBuzzClient)resolve_authreduced to self-check + fetch + delegate