- ?format=json on the six dashboard procurement-evidence CSV endpointsCloses the explicitly-named rev-121 next-sprint candidate. Rev 121 added `?format=json` to every v1 export endpoint so MCP hosts could pipe audit history through their own analytics pipelines without parsing CSV; the dashboard counterparts (the routes session-authenticated callers hit when they're already logged in) still spoke CSV-only. Rev 122 closes that gap on every axis (activity / outputs / decisions / stale-tasks / sources / cost-summary). Each dashboard CSV export now also accepts `?format=json` and returns the same typed shape the rev-121 v1 endpoint emits โ so in-app analytics, embedded dashboards, and browser-side audit tooling consume one canonical shape regardless of whether the caller authenticates with a session cookie or a bearer ingest token.
- Paired CSV / JSON chip cluster on the integrations panel data-export sectionCumulative dashboard polish (every rev 22+ has carried at least one). New `ExportButtonPair` client component renders a primary CSV download chip (the rev-22+ design language) paired with a small ambient `JSON` sibling chip on every procurement-evidence export (activity log / outputs / decisions / stale tasks / cost summary / sources). The CSV chip stays the primary affordance โ the JSON chip wears subtler `.ld-export-pair-json` styling so it reads as ambient affordance rather than competing with the primary action. One round-radius cluster, two output formats, zero new mental model. Closes the dashboard-side affordance loop on the rev-122 endpoint primitive in the same cycle the primitive ships.
- /api/v1/blog?q=โฆ keyword search across title + excerpt + tagsThe rev-102 dashboard `BlogSearch` client component has been client-side-only for 20 revs โ MCP hosts and AI tooling roundup newsletters reading the blog via JSON had no protocol-bound way to retrieve posts by keyword and were forced to fetch the full listing and filter client-side. Rev 122 closes that gap: the existing `/api/v1/blog` endpoint accepts an optional `q` keyword query (โค200 chars) that searches across title, excerpt, and tags. Mirrors the rev-102 dashboard matcher exactly so the dashboard and protocol-bound surfaces never drift on which posts match a query. Composes with `tag` and `sinceDate` via intersection. OpenAPI 3.1 spec typed in lockstep with the dashboard primitive (cadence pattern from rev 78 onward holds unbroken into rev 122).
- Cumulative typed-contract polish โ OpenAPI changelog block + self-describing index for rev-122Cumulative micro-polish on the typed-contract surface itself. The OpenAPI 3.1 spec's blog endpoint description picks up the new `q` query parameter inline; the response body's `q` echo is added to the `required` set so code generators see the field consistently regardless of whether it was supplied. The `/api/v1` self-describing endpoint index updates the blog endpoint signature accordingly. The rev-22+ design-language thread continues into rev 122 โ every public surface continues to read as authoritative with-or-without code generation, so the upcoming MCP server's wrapping work has nothing left to design on the procurement-evidence axis or the public marketing axis at either output shape (CSV / JSON).