From e9557ca05bfcdba8e5e115ed428b8f3d2882139f Mon Sep 17 00:00:00 2001 From: Kayos Date: Thu, 23 Apr 2026 16:31:27 -0700 Subject: [PATCH] json schema polish: count on list, hash alias on verify_certificate (v1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acceptance test report flagged three cosmetic JSON-schema gaps: 1. 'list -json' had no top-level 'count' — caller had to use .snapshots|length. Added 'count' alongside 'snapshots'. 2. 'verify -json chain' top-level 'kind' was reported null — actually a missing field rather than null. Chain results have per-step kind in .steps[]; chain-level kind would be misleading. Documented intent in README rather than adding the field. 3. MCP 'mithril_verify_certificate' returned 'cert_hash' but agents often look for 'hash'. Added 'hash' alias alongside 'cert_hash' in both genesis and STM result paths so either lookup works. End-to-end loop test on mainnet+preprod: full PASS (89-cert mainnet chain + 90-cert preprod chain both verified, MCP all 8 tools work, exit codes correct, manifest detection clean). v1-tag-able now. --- cmd/mithril-go/main.go | 6 +++++- cmd/mithril-go/mcp.go | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/mithril-go/main.go b/cmd/mithril-go/main.go index 58c578e..b253c61 100644 --- a/cmd/mithril-go/main.go +++ b/cmd/mithril-go/main.go @@ -142,7 +142,11 @@ func cmdList(ctx context.Context, args []string) int { return exitNetwork } if *asJSON { - return emitJSON(map[string]any{"network": n.Name, "snapshots": snaps}) + return emitJSON(map[string]any{ + "network": n.Name, + "count": len(snaps), + "snapshots": snaps, + }) } tw := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintln(tw, "HASH\tEPOCH\tIMMUTABLE\tSIZE\tCREATED") diff --git a/cmd/mithril-go/mcp.go b/cmd/mithril-go/mcp.go index 93862cf..3e8f9a7 100644 --- a/cmd/mithril-go/mcp.go +++ b/cmd/mithril-go/mcp.go @@ -254,6 +254,7 @@ func registerMCPTools(s *mcp.Server) { verr := verify.GenesisFromJSON(vk, cert.SignedMessage, cert.GenesisSignature, cert.ProtocolMessage) return map[string]any{ "kind": "genesis", + "hash": cert.Hash, "cert_hash": cert.Hash, "epoch": cert.Epoch, "verified": verr == nil, @@ -277,6 +278,7 @@ func registerMCPTools(s *mcp.Server) { verr := stm.Verify([]byte(cert.SignedMessage), ms, avk, params) return map[string]any{ "kind": "stm", + "hash": cert.Hash, "cert_hash": cert.Hash, "epoch": cert.Epoch, "signers": len(ms.Signatures),