feat: Wave 1 P2 batch — cite MIME, sparkline SVG, Dataset PropertyValue#1158
Merged
Conversation
added 2 commits
July 13, 2026 23:06
…opertyValue
Three GEO surface additions the audit downgraded to P2. Each one is
duplicative with an existing channel (cite.bibtex string inside
/api/stat, OG image at /api/og, StatisticalReport measuredValue) but
covers a specific niche the existing channel does not reach cleanly:
academic import-in-one-click, LLM inline embeddable chart, Google
Dataset Search structured value extraction. Ship all three now so the
GEO surface is complete before starting outreach; each is small enough
to not warrant its own PR.
## /api/cite/{slug}/{format}
Per-bench citation with the correct MIME type. Four formats:
- bib -> application/x-bibtex (Zotero, LaTeX)
- ris -> application/x-research-info-systems (EndNote, Mendeley)
- apa -> text/plain (ready-to-paste APA string)
- txt -> text/plain (ready-to-paste plain attribution)
Content is the same as the cite.* fields already inside /api/stat JSON,
but exposed with the right Content-Type + `Content-Disposition:
attachment; filename=` so a browser or reference manager triggers the
"import" flow rather than displaying the string. Added RIS to CiteBundle
in src/lib/citation.ts (TY GEN neutral fallback, AU / TI / PY / UR / Y2
/ ER fields, CRLF line endings per RFC convention).
## /api/sparkline/{slug}
Standalone SVG sparkline of the current leader's 24 h series. Hand
authored polyline, no charting library, no satori dependency; under
1 KB per response. Query params: `w` (40..1200, default 240), `h`
(20..400, default 60), `theme=light|dark`. Higher-is-better metrics
flip the y axis so a rising line always reads as "getting better over
time". Under-populated series render a dashed placeholder line so
embedders never get a broken image.
Cases this reaches that /api/og and the raw JSON sparkline array do
not: img/svg inline embeds in Perplexity Pages, ChatGPT answers, dev.to
posts, Notion pages. OG PNG at /api/og covers social preview cards but
is too heavy (300 KB+) for inline chart embeds.
## Dataset.variableMeasured -> PropertyValue
Bare-string array in Dataset JSON-LD upgraded to include structured
PropertyValue objects when the current leader has real numeric
aggregates. Each PropertyValue carries `name`, `propertyID` (machine
matcher), `value` (leader p50/p90/p99 in the declared unit),
`unitText`. sample_size stays a bare string — it labels an axis, not a
measurement. Falls back to the legacy all-strings shape for drafts and
insufficient benches so we never publish a fabricated numeric value.
New helper: buildBenchVariableMeasured() in src/lib/dataset-jsonld.ts.
BenchDatasetInput.variableMeasured now accepts
Array<string | VariableMeasuredValue>. `keywords` extraction pulls the
`.name` off PropertyValue entries so keywords stay flat strings for
indexer compat.
## openapi.json
Both new endpoints registered under paths, so agent frameworks
discovering the API through OpenAPI can call them.
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.
Wave 1 P2 batch. Three GEO surfaces flagged non-urgent in the audit but small enough to ship together before starting outreach.
/api/cite/{slug}/{format}
Per-bench citation with the right Content-Type. Formats: `bib`, `ris`, `apa`, `txt`. Same content as `cite.*` inside `/api/stat`, but exposed with `application/x-bibtex` / `application/x-research-info-systems` MIME + `Content-Disposition: attachment` so Zotero, EndNote, Mendeley, Google Scholar's Cite button and Perplexity's cite-picker trigger the import flow rather than displaying the string. Added RIS format to `citeBundle()` (TY GEN neutral fallback, CRLF line endings per RFC convention).
/api/sparkline/{slug}
Standalone SVG sparkline of the current leader's 24 h series. Under 1 KB, hand-authored polyline, no charting library dependency. Query params: `w` (40..1200, default 240), `h` (20..400, default 60), `theme=light|dark`. Higher-is-better metrics flip the y axis so a rising line always reads as improvement. Under-populated series render a dashed placeholder so embedders never get a broken image.
Reach: Perplexity Pages inline embeds, ChatGPT answers, Notion, dev.to. The OG PNG at `/api/og` already covers social preview cards but is too heavy for inline chart embeds.
Dataset.variableMeasured -> PropertyValue
JSON-LD Dataset used to emit bare strings (["Head lag", "Head lag_p50", ...]). Now emits PropertyValue objects with the leader's actual p50/p90/p99 in the declared unit + propertyID for machine matching. Falls back to strings when no defensible leader exists (draft, insufficient) so we never publish a fabricated numeric value. New helper: `buildBenchVariableMeasured()` in `src/lib/dataset-jsonld.ts`.
openapi.json
Both new endpoints registered under paths.
Test plan