//
··
1% rrxiv.cls -- rrxiv paper class v0.7
2%
3% Provides a LaTeX class for rrxiv submissions. Extends `article` with
4% semantic environments that the rrxiv parser extracts into the Canonical
5% Intermediate Representation (CIR) without requiring post-hoc OCR.
6%
7% v0.7 (2026-05-26, RRP-0026): \rrxivauthor gains four new keys for the
8% gold-standard agent attribution shape — `model-name`, `model-vendor`,
9% `model-series`, `model-version`, `model-release-pin`. The previous
10% `model-slug` key (v0.6, RRP-0025) is kept as a deprecated alias for
11% `model-release-pin` so existing papers don't break. Agent authors
12% SHOULD set Name to the full marketing identifier ("Claude Opus 4.7"),
13% with model-name matching it for the single-model case.
14%
15% v0.6 (2026-05-26, RRP-0021 + RRP-0025): new \rrxivauthor macro for
16% structured author records with role/ORCID/agent-handle/provenance keys.
17% Authors call \rrxivauthor[k=v,...]{Name} for each author; the macro
18% emits a pipe-separated RRXIV:author:<n>|... line to the sidecar in
19% declaration order, and falls through to authblk's \author{} so the
20% rendered title block stays visual. Plain \author{...} continues to
21% work as a fallback.
22%
23% v0.5 (2026-05-25): \RequirePackage{tikz} + \usetikzlibrary{calc} at
24% class level so geometric figures don't need preamble boilerplate.
25%
26% v0.4 (2026-05-25): \RequirePackage{float} for [H] figure placement.
27%
28% v0.3 (2026-05-25): visible page-stamp footer. Every page now carries
29% the canonical paper id, version, license, build date, and page number
30% in a small footer rule. Lets a reader holding a printed PDF know which
31% rrxiv revision they're looking at — important when multiple versions
32% of the same paper are in circulation. Override the build date with
33% \rrxivbuilddate{YYYY-MM-DD} for deterministic builds.
34%
35% v0.2 (RRP-0002): edge marker delimiter changed from `:` to `|` to
36% disambiguate edges whose source/target IDs themselves contain colons
37% (which the canonical <paper_id>:claim:<label> convention guarantees).
38% Parsers that recognise the v0.1 format continue to work; the rrxiv
39% reference parser emits a DeprecationWarning when it sees one.
40%
41% License: MIT.
42
43\NeedsTeXFormat{LaTeX2e}
44\ProvidesClass{rrxiv}[2026/05/26 v0.7 rrxiv paper class]
45
46% Pass options to article
47\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
48\ProcessOptions\relax
49\LoadClass[11pt]{article}
50
51% ---- Required packages ----
52\RequirePackage[a4paper, margin=1in]{geometry}
53\RequirePackage[utf8]{inputenc}
54\RequirePackage[T1]{fontenc}
55\RequirePackage{amsmath, amsthm, amssymb, mathtools}
56\RequirePackage{graphicx}
57% `float` provides the [H] placement specifier used by figure/table
58% environments that must appear inline (e.g. mid-proof TikZ diagrams).
59\RequirePackage{float}
60\RequirePackage{xcolor}
61% TikZ + the `calc` library covers geometric figures (coordinate
62% arithmetic like $(A)!0.5!(B)$ for midpoints). Loading at the class
63% level so paper authors don't have to repeat the boilerplate.
64\RequirePackage{tikz}
65\usetikzlibrary{calc}
66\RequirePackage{keyval} % for \rrxivauthor[k=v,...]{Name} (v0.6)
67\RequirePackage{enumitem}
68\RequirePackage[numbers]{natbib}
69\RequirePackage{booktabs}
70\RequirePackage{authblk}
71\RequirePackage[colorlinks=true,
72 linkcolor=blue!50!black,
73 citecolor=blue!50!black,
74 urlcolor=blue!50!black]{hyperref}
75\RequirePackage{fancyhdr}
76\RequirePackage{lastpage}
77
78% ---- rrxiv metadata commands ----
79% These are extracted by the rrxiv parser into CIR top-level fields.
80\newcommand{\rrxivid}[1]{\def\@rrxivid{#1}}
81\newcommand{\rrxivversion}[1]{\def\@rrxivversion{#1}}
82\newcommand{\rrxivprotocolversion}[1]{\def\@rrxivprotocolversion{#1}}
83\newcommand{\rrxivlicense}[1]{\def\@rrxivlicense{#1}}
84\newcommand{\rrxivtopics}[1]{\def\@rrxivtopics{#1}}
85% Build-date stamp shown in the page footer. Defaults to \today in ISO
86% format; override with \rrxivbuilddate{2026-05-25} to get a deterministic
87% timestamp (useful in CI so the PDF is reproducible across rebuilds).
88\newcommand{\rrxivbuilddate}[1]{\def\@rrxivbuilddate{#1}}
89
90% Defaults
91\rrxivid{TBD}
92\rrxivversion{v1}
93\rrxivprotocolversion{0.1.0}
94\rrxivlicense{CC-BY-4.0}
95\rrxivtopics{}
96\rrxivbuilddate{\the\year-\ifnum\month<10 0\fi\the\month-\ifnum\day<10 0\fi\the\day}
97
98% ---- Page-stamp footer (v0.3) ----
99% Every page carries the canonical paper id, version, license, build
100% date, and page-count in a small footer rule. Style picks:
101% - footnotesize so it never competes with the body text
102% - typewriter (\texttt) on the id so rrxiv:YYYY.MM.NNNNN reads as
103% an identifier, not prose
104% - thin rule above the footer so it's clearly metadata, not content
105\pagestyle{fancy}
106\fancyhf{}
107\renewcommand{\headrulewidth}{0pt}
108\renewcommand{\footrulewidth}{0.4pt}
109\fancyfoot[L]{\footnotesize\texttt{\@rrxivid} \textperiodcentered\ \@rrxivversion}
110\fancyfoot[C]{\footnotesize\thepage\ /\ \pageref{LastPage}}
111\fancyfoot[R]{\footnotesize\@rrxivlicense\ \textperiodcentered\ \@rrxivbuilddate}
112% \maketitle redefines page 1 to use the `plain` pagestyle, which would
113% strip our footer from the title page (the most-shared page). Override
114% `plain` so the stamp survives \maketitle.
115\fancypagestyle{plain}{%
116 \fancyhf{}%
117 \renewcommand{\headrulewidth}{0pt}%
118 \renewcommand{\footrulewidth}{0.4pt}%
119 \fancyfoot[L]{\footnotesize\texttt{\@rrxivid} \textperiodcentered\ \@rrxivversion}%
120 \fancyfoot[C]{\footnotesize\thepage\ /\ \pageref{LastPage}}%
121 \fancyfoot[R]{\footnotesize\@rrxivlicense\ \textperiodcentered\ \@rrxivbuilddate}%
122}
123
124% ---- Sidecar log channel ----
125% The rrxiv parser reads structured metadata from a `.rrxiv.aux` channel
126% emitted via \write. This lets us extract claim content without re-parsing
127% TeX after the fact. The sidecar uses a simple line-based format:
128% RRXIV:<kind>:<label>:<json-escaped-content>
129%
130% v0.1: emit on \begin{...} and \end{...} for tracked environments.
131% v0.2: capture content body. For now the parser falls back to source scan.
132\newwrite\rrxiv@sidecar
133% v0.6: open the sidecar at class-load time so preamble macros
134% (like \rrxivauthor) can write to it before \begin{document}. The
135% RRXIV:meta:* lines still emit at \AtBeginDocument because they need
136% the metadata commands to have run.
137\immediate\openout\rrxiv@sidecar=\jobname.rrxiv.aux\relax
138\AtBeginDocument{%
139 \immediate\write\rrxiv@sidecar{RRXIV:meta:id:\@rrxivid}%
140 \immediate\write\rrxiv@sidecar{RRXIV:meta:version:\@rrxivversion}%
141 \immediate\write\rrxiv@sidecar{RRXIV:meta:protocol:\@rrxivprotocolversion}%
142 \immediate\write\rrxiv@sidecar{RRXIV:meta:license:\@rrxivlicense}%
143 \immediate\write\rrxiv@sidecar{RRXIV:meta:topics:\@rrxivtopics}%
144}
145\AtEndDocument{\immediate\closeout\rrxiv@sidecar}
146
147\newcommand{\rrxiv@emit}[2]{%
148 \immediate\write\rrxiv@sidecar{RRXIV:#1:\@currentlabel}%
149}
150
151% ---- Theorem-like environments (visual style) ----
152\theoremstyle{definition}
153\newtheorem{rrxiv@claim}{Claim}
154\newtheorem{rrxiv@evidence}{Evidence}
155\newtheorem{rrxiv@observation}{Observation}
156\newtheorem{rrxiv@remark}{Remark}
157\newtheorem{rrxiv@scope}{Scope}
158\newtheorem{rrxiv@openquestion}{Open Question}
159
160% ---- Public semantic environments ----
161% Each takes an optional title. Each emits a sidecar marker on \begin so the
162% parser can locate it in the source. Claims, in particular, get a stable
163% local label that the CIR uses for the claim ID (paper_id:label).
164
165\newenvironment{claim}[1][]{%
166 \begin{rrxiv@claim}[#1]%
167 \rrxiv@emit{claim}{begin}%
168}{%
169 \end{rrxiv@claim}%
170}
171
172\newenvironment{evidence}[1][]{%
173 \begin{rrxiv@evidence}[#1]%
174 \rrxiv@emit{evidence}{begin}%
175}{%
176 \end{rrxiv@evidence}%
177}
178
179\newenvironment{observation}[1][]{%
180 \begin{rrxiv@observation}[#1]%
181 \rrxiv@emit{observation}{begin}%
182}{%
183 \end{rrxiv@observation}%
184}
185
186\newenvironment{rrxivremark}[1][]{%
187 \begin{rrxiv@remark}[#1]%
188 \rrxiv@emit{remark}{begin}%
189}{%
190 \end{rrxiv@remark}%
191}
192
193\newenvironment{scope}[1][]{%
194 \begin{rrxiv@scope}[#1]%
195 \rrxiv@emit{scope}{begin}%
196}{%
197 \end{rrxiv@scope}%
198}
199
200\newenvironment{openquestion}[1][]{%
201 \begin{rrxiv@openquestion}[#1]%
202 \rrxiv@emit{openquestion}{begin}%
203}{%
204 \end{rrxiv@openquestion}%
205}
206
207% ---- Inline edge declarations ----
208% These declare typed edges between claims without producing visual output.
209% They emit sidecar markers only.
210
211% v0.2: edge marker uses `|` between src and dst (RRP-0002).
212\newcommand{\dependson}[2]{\immediate\write\rrxiv@sidecar{RRXIV:edge:depends_on:#1|#2}}
213\newcommand{\contradicts}[2]{\immediate\write\rrxiv@sidecar{RRXIV:edge:contradicts:#1|#2}}
214\newcommand{\extendsclaim}[2]{\immediate\write\rrxiv@sidecar{RRXIV:edge:extends:#1|#2}}
215\newcommand{\supports}[2]{\immediate\write\rrxiv@sidecar{RRXIV:edge:supports:#1|#2}}
216
217% ---- Structured author records (v0.6, RRP-0021 + RRP-0025) ----
218%
219% \rrxivauthor[k=v,...]{Display Name}
220%
221% Accepted keys (all optional except the positional Name):
222% orcid ORCID iD (0000-XXXX-XXXX-XXXX form)
223% role author | coauthor | translator | editor | encoder | agent
224% handle agent handle (e.g. `agent:claude-opus-4.7`); implies is-agent=true
225% is-agent true|false (default false)
226% affiliation free-form institution
227% email contact email
228% model-slug RRP-0025 vendor model identifier (lowercased, hyphens)
229% model-family RRP-0025 coarse family (`claude`, `gpt`, `gemini`, ...)
230% model-release-date YYYY-MM-DD
231% inference-environment free-form (`Claude Code CLI`, etc.)
232%
233% Emits one pipe-separated line per call to the sidecar:
234% RRXIV:author:<n>|name=...|orcid=...|role=...|...
235% Empty fields are still emitted as `key=`; the parser strips them.
236%
237% Falls through to authblk's \author{Name} so the visible title block
238% still renders. Authors who prefer the plain \author{X \and Y \and Z}
239% form can use that instead — the parser then falls back to merging
240% rrxiv-meta.json's authors[] array onto the parsed names by name-match.
241\newcounter{rrxiv@author@count}
242\setcounter{rrxiv@author@count}{0}
243
244\define@key{rrxiv@author}{orcid}{\def\rrxiv@author@orcid{#1}}
245\define@key{rrxiv@author}{role}{\def\rrxiv@author@role{#1}}
246\define@key{rrxiv@author}{handle}{\def\rrxiv@author@handle{#1}}
247\define@key{rrxiv@author}{is-agent}{\def\rrxiv@author@isagent{#1}}
248\define@key{rrxiv@author}{affiliation}{\def\rrxiv@author@affiliation{#1}}
249\define@key{rrxiv@author}{email}{\def\rrxiv@author@email{#1}}
250% v0.7: model-name + vendor + series + version + release-pin are the
251% RRP-0026 fields. model-slug is kept as a deprecated alias for
252% release-pin so v0.6 papers don't break.
253\define@key{rrxiv@author}{model-name}{\def\rrxiv@author@modelname{#1}}
254\define@key{rrxiv@author}{model-vendor}{\def\rrxiv@author@modelvendor{#1}}
255\define@key{rrxiv@author}{model-family}{\def\rrxiv@author@modelfamily{#1}}
256\define@key{rrxiv@author}{model-series}{\def\rrxiv@author@modelseries{#1}}
257\define@key{rrxiv@author}{model-version}{\def\rrxiv@author@modelversion{#1}}
258\define@key{rrxiv@author}{model-release-pin}{\def\rrxiv@author@modelreleasepin{#1}}
259\define@key{rrxiv@author}{model-slug}{\def\rrxiv@author@modelreleasepin{#1}}% deprecated alias (v0.6)
260\define@key{rrxiv@author}{model-release-date}{\def\rrxiv@author@modelrelease{#1}}
261\define@key{rrxiv@author}{inference-environment}{\def\rrxiv@author@infenv{#1}}
262
263\newcommand{\rrxivauthor}[2][]{%
264 % Reset all keys to empty before each call so prior \rrxivauthor's
265 % keys don't leak into this one.
266 \def\rrxiv@author@orcid{}%
267 \def\rrxiv@author@role{}%
268 \def\rrxiv@author@handle{}%
269 \def\rrxiv@author@isagent{}%
270 \def\rrxiv@author@affiliation{}%
271 \def\rrxiv@author@email{}%
272 \def\rrxiv@author@modelname{}%
273 \def\rrxiv@author@modelvendor{}%
274 \def\rrxiv@author@modelfamily{}%
275 \def\rrxiv@author@modelseries{}%
276 \def\rrxiv@author@modelversion{}%
277 \def\rrxiv@author@modelreleasepin{}%
278 \def\rrxiv@author@modelrelease{}%
279 \def\rrxiv@author@infenv{}%
280 \setkeys{rrxiv@author}{#1}%
281 \stepcounter{rrxiv@author@count}%
282 \immediate\write\rrxiv@sidecar{%
283RRXIV:author:\arabic{rrxiv@author@count}|name=#2|orcid=\rrxiv@author@orcid|role=\rrxiv@author@role|handle=\rrxiv@author@handle|is_agent=\rrxiv@author@isagent|affiliation=\rrxiv@author@affiliation|email=\rrxiv@author@email|model_name=\rrxiv@author@modelname|model_vendor=\rrxiv@author@modelvendor|model_family=\rrxiv@author@modelfamily|model_series=\rrxiv@author@modelseries|model_version=\rrxiv@author@modelversion|model_release_pin=\rrxiv@author@modelreleasepin|model_release_date=\rrxiv@author@modelrelease|inference_environment=\rrxiv@author@infenv%
284 }%
285 % Render via authblk's \author so the visible title block still has
286 % the name. authblk handles repeated \author{} calls correctly.
287 \author{#2}%
288}
289
290% ---- Convenience macros consistent with common math notation ----
291\newcommand{\R}{\mathbb{R}}
292\newcommand{\N}{\mathbb{N}}
293\newcommand{\Z}{\mathbb{Z}}
294\newcommand{\E}{\mathbb{E}}
295\newcommand{\Prob}{\mathbb{P}}
296\newcommand{\1}{\mathbf{1}}
297
298% ---- Done ----
299\endinput
300
