Release history
Changelog
Software version 0.1.0-alpha.4; profile content version 0.4. The machine-readable copy is at /CHANGELOG.md.
# Changelog — joakim.jardenberg.net
Software releases for the public profile site and PPCP/MCP server. Software version and profile content version are distinct: this file tracks the software. The profile content edition is 0.4 (2026-09-13), still under owner review.
The machine-readable copy of this file is served at /CHANGELOG.md.
0.1.0-alpha.4 — 2026-09-13
Error-binding correction found in independent production testing against joakim.jardenberg.net (42/44 grouped checks passed; the two failures were the exact v0.2.1 error payloads for a missing MCP-Protocol-Version header and an unsupported protocol version). No content, key, protocol or design change.
signedErrorFramenow signs exactly the v0.2.1 SPEC.md §8 payload{ id, error: { code, message } }. Previously anyextraData(for examplesupported/requestedfor version negotiation) was spread into the signedpayload.error, so the signed payload no longer matched the published error test vector.extraDatais unchanged on the wire: it still sits inerror.dataalongside the signed envelope, so MCP version negotiation still seessupportedandrequested.- Setup-page regression: the
/mcp"Try it"curlexample omittedMCP-Protocol-Version, so the corrected server rejected its own documented example. The example now sends the requiredMCP-Protocol-Version,Mcp-MethodandMcp-Nameheaders plus modern_meta, and documents the legacyinitialize+2025-11-25alternative. A conformance test extracts the exact rendered example from the served HTML and runs it. - The example includes a descriptive
User-Agent, because the hosting edge in front of this site has been observed to block some default library user-agents (e.g.Python-urllib/3.11) with an edge error before the request reaches the server; named clients are served. Documented as a factual observation; no server-side workaround. ppcp_get_profiledescription now states "Public draft; owner review pending; AI-assisted editorial wording". Profile 0.4 source unchanged.- Regression tests cryptographically verify both failing cases (missing header and unsupported version): the envelope signature is checked against the published JWKS,
payload_digestis recomputed from the canonical payload, and the payload's exact key sets are asserted (id,error;code,message), including that negotiation fields are absent from the signed payload.
0.1.0-alpha.3 — 2026-09-13
Transport edge cases found in the alpha.2 review. No content, key or design change.
- The GET SSE refusal and the
DELETErefusal now use the same signed error-frame constructor as every other error; both also carry CORS headers. - Origin validation now applies to
GETandDELETEas well asPOSTandOPTIONS, matching the transport's rule for all incoming connections. Origin-less non-browser clients are still accepted. - JSON-RPC envelope validation:
"jsonrpc": "2.0"is required, and a requestidmust be a string or a safe integer. Missing/wrongjsonrpc,id: null, and boolean, fractional, array or object ids get a signed-32600+ HTTP 400. - Notifications (any method sent without an
id) now always return HTTP 202 with no body; atools/callnotification can no longer receive a result. MCP-Protocol-Versionis now required as an HTTP header on every non-initializerequest that carries anid, including requests with neither the header nor_meta: the oldest advertised revision is2025-06-18, so an absent header must not silently take an unsupported pre-2025 path. Missing header → signed-32020 HeaderMismatch+ HTTP 400.initialize(legacy negotiation) and notifications remain exempt.clientCapabilitiesmust be a JSON object, so arrays are rejected;clientInfostays optional, as in the spec.- Request bodies are decoded as UTF-8 fatally (malformed bytes → signed
-32700+ 400) and structural nesting is bounded at depth 32 before any recursive traversal, so deep nesting yields a signed-32600+ 400 rather than an unhandled error.
0.1.0-alpha.2 — 2026-09-13
MCP transport and signing-binding corrections.
- Implements the 2026-07-28 Streamable HTTP binding:
MCP-Protocol-Versionmust agree with_meta["io.modelcontextprotocol/protocolVersion"],Mcp-Methodand (fortools/call/resources/read)Mcp-Nameare required and validated against the body, with-32020 HeaderMismatch+ HTTP 400 on any mismatch or missing header, including Base64-sentinel decoding. - Adds
server/discover,resultType: "complete"on every result andio.modelcontextprotocol/serverInfoin result_meta. Unknown methods now return HTTP 404 with-32601; notifications return 202. The legacyinitializepath for 2025-11-25 and 2025-06-18 is unchanged. -32022 UnsupportedProtocolVersionlists supported versions for unknown ones.resources/readnow signs exactly the result'scontentsbinding, with the exact resource text as the signed text arm.- Origin checking uses an exact documented allowlist (no host pattern matching); origin-less clients are still accepted.
DELETEreturns 405 (stateless). - Every JSON-RPC error frame — parse errors, oversized bodies, batch rejection, header mismatches, RPC errors — is now produced by one signed constructor.
- Request bodies are read with a hard byte bound instead of being buffered first; JSON-RPC batches are rejected; lone UTF-16 surrogates are rejected before anything is canonicalized or signed.
0.1.0-alpha.1 — 2026-09-13
First release of the public profile site.
- Public, anonymous, account-free reading of the full profile at
/, with a sticky contents sidebar, mobile contents drawer, section anchors and in-page search. - Exact public Markdown at
/profile.md(text/markdown) as the single source for every other representation. - PPCP 0.1.0 JSON at
/profile.json, validated against the published profile schema, and a signed packaging at/profile.signed.json. - Read-only MCP server on
POST /mcp(stateless streamable HTTP), withppcp_get_profile,ppcp_list_sections,ppcp_get_section,ppcp_search,ppcp_get_sourcesandppcp_get_version, plusresources/listandresources/readover an exact URI allowlist. - Browser setup page on
GET /mcpwith an endpoint copy button; SSEGETstreams are not supported and return 405. - org.jardenberg/verifiable-mcp 0.2.1 signing: Ed25519 (EdDSA), RFC 8785 canonicalization, RFC 7638
kid, signed wrapper withiat,payload,payload_digest,content_digestandprovenance, signed error frames and signedisErrorresults. Missing key degrades visibly to unsigned. - Discovery:
/.well-known/mcp.json(with the signing JWKS),/.well-known/ppcp.json,/llms.txt,/robots.txt,/sitemap.xml,/contact.vcf. /about-this-profile,/changelogand/api/health.- Schema.org
ProfilePage+PersonwithsameAsto Wikidata and Swedish Wikipedia.