papilot 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -2
  3. package/README.zh-CN.md +127 -0
  4. package/bin/papilot.mjs +113 -0
  5. package/dist/apple-touch-icon.png +0 -0
  6. package/dist/assets/Inconsolatazi4-Regular-Dbtq7t_r.otf +0 -0
  7. package/dist/assets/TeXGyrePagellaX-Bold-CEtYdOXj.otf +0 -0
  8. package/dist/assets/TeXGyrePagellaX-Italic-CSuYIstn.otf +0 -0
  9. package/dist/assets/TeXGyrePagellaX-Regular-DQJjZE_L.otf +0 -0
  10. package/dist/assets/cursor-editorTextHighlight-kG3uUOwL.svg +8 -0
  11. package/dist/assets/index-BhQFCMTx.js +131 -0
  12. package/dist/assets/index-CAV3-87U.css +1 -0
  13. package/dist/assets/pdf-view-DJo0X38w.js +598 -0
  14. package/dist/assets/pdf.worker.min-CjEcRF4W.mjs +28 -0
  15. package/dist/favicon.png +0 -0
  16. package/dist/index.html +4 -0
  17. package/examples/papilot-paper/.latex-review.json +4 -0
  18. package/examples/papilot-paper/appendix/proofs.tex +60 -0
  19. package/examples/papilot-paper/appendix/reference.tex +54 -0
  20. package/examples/papilot-paper/main.tex +57 -0
  21. package/examples/papilot-paper/preamble.tex +53 -0
  22. package/examples/papilot-paper/references.bib +158 -0
  23. package/examples/papilot-paper/sections/01-introduction.tex +66 -0
  24. package/examples/papilot-paper/sections/02-using.tex +134 -0
  25. package/examples/papilot-paper/sections/03-background.tex +97 -0
  26. package/examples/papilot-paper/sections/04-model.tex +185 -0
  27. package/examples/papilot-paper/sections/05-conflicts.tex +99 -0
  28. package/examples/papilot-paper/sections/06-building.tex +70 -0
  29. package/examples/papilot-paper/sections/07-geometry.tex +193 -0
  30. package/examples/papilot-paper/sections/08-notes.tex +104 -0
  31. package/examples/papilot-paper/sections/09-agents.tex +106 -0
  32. package/examples/papilot-paper/sections/10-usage.tex +56 -0
  33. package/examples/papilot-paper/sections/11-git.tex +62 -0
  34. package/examples/papilot-paper/sections/12-security.tex +41 -0
  35. package/examples/papilot-paper/sections/13-evaluation.tex +106 -0
  36. package/examples/papilot-paper/sections/14-related.tex +38 -0
  37. package/examples/papilot-paper/sections/15-conclusion.tex +27 -0
  38. package/package.json +85 -4
  39. package/scripts/demo.ts +21 -0
  40. package/scripts/service.ts +35 -0
  41. package/src/notes.ts +40 -0
  42. package/src/server/agents.ts +343 -0
  43. package/src/server/codex.ts +63 -0
  44. package/src/server/frontend.ts +15 -0
  45. package/src/server/main.ts +202 -0
  46. package/src/server/manuscript.ts +337 -0
  47. package/src/server/paths.ts +11 -0
  48. package/src/server/pdf.ts +27 -0
  49. package/src/server/review.ts +53 -0
  50. package/src/server/security.ts +15 -0
  51. package/src/server/store.ts +60 -0
  52. package/src/server/workspace.ts +530 -0
  53. package/src/shared.ts +28 -0
  54. package/vendor/latex-review/LICENSE +21 -0
  55. package/vendor/latex-review/dist/web/assets/TeXGyrePagellaX-Bold-CEtYdOXj.otf +0 -0
  56. package/vendor/latex-review/dist/web/assets/TeXGyrePagellaX-Regular-DQJjZE_L.otf +0 -0
  57. package/vendor/latex-review/dist/web/assets/index-DyzYnIGk.css +1 -0
  58. package/vendor/latex-review/dist/web/assets/index-HxBK-dls.js +19 -0
  59. package/vendor/latex-review/dist/web/index.html +18 -0
  60. package/vendor/latex-review/package-lock.json +3114 -0
  61. package/vendor/latex-review/package.json +49 -0
  62. package/vendor/latex-review/src/cli.ts +494 -0
  63. package/vendor/latex-review/src/client.ts +198 -0
  64. package/vendor/latex-review/src/core/build.ts +296 -0
  65. package/vendor/latex-review/src/core/changes.ts +126 -0
  66. package/vendor/latex-review/src/core/config.ts +270 -0
  67. package/vendor/latex-review/src/core/diff.ts +54 -0
  68. package/vendor/latex-review/src/core/files.ts +96 -0
  69. package/vendor/latex-review/src/core/git.ts +317 -0
  70. package/vendor/latex-review/src/core/outline.ts +314 -0
  71. package/vendor/latex-review/src/core/process.ts +111 -0
  72. package/vendor/latex-review/src/core/publish.ts +339 -0
  73. package/vendor/latex-review/src/core/review.ts +734 -0
  74. package/vendor/latex-review/src/core/store.ts +66 -0
  75. package/vendor/latex-review/src/core/tasks.ts +237 -0
  76. package/vendor/latex-review/src/render/inline.ts +805 -0
  77. package/vendor/latex-review/src/render/locate.ts +481 -0
  78. package/vendor/latex-review/src/render/pdf.ts +281 -0
  79. package/vendor/latex-review/src/render/pdfdiff.ts +272 -0
  80. package/vendor/latex-review/src/render/round.ts +236 -0
  81. package/vendor/latex-review/src/render/worker.ts +10 -0
  82. package/vendor/latex-review/src/runtime.ts +23 -0
  83. package/vendor/latex-review/src/server.ts +401 -0
  84. package/vendor/latex-review/src/types.ts +283 -0
  85. package/vendor/latex-review/src/web/ChangeMap.tsx +212 -0
  86. package/vendor/latex-review/src/web/PdfStrip.tsx +77 -0
  87. package/vendor/latex-review/src/web/fonts/GUST-FONT-LICENSE.txt +29 -0
  88. package/vendor/latex-review/src/web/fonts/LPPL.txt +415 -0
  89. package/vendor/latex-review/src/web/fonts/MANIFEST-newpx.txt +20 -0
  90. package/vendor/latex-review/src/web/fonts/README-newpx.txt +473 -0
  91. package/vendor/latex-review/src/web/fonts/README.md +12 -0
  92. package/vendor/latex-review/src/web/fonts/TeXGyrePagellaX-Bold.otf +0 -0
  93. package/vendor/latex-review/src/web/fonts/TeXGyrePagellaX-Regular.otf +0 -0
  94. package/vendor/latex-review/src/web/index.html +17 -0
  95. package/vendor/latex-review/src/web/main.tsx +10 -0
  96. package/vendor/latex-review/src/web/model.ts +153 -0
  97. package/vendor/latex-review/src/web/overview.tsx +146 -0
  98. package/vendor/latex-review/src/web/review.tsx +991 -0
  99. package/vendor/latex-review/src/web/style.css +1249 -0
Binary file
@@ -0,0 +1,4 @@
1
+ <!doctype html>
2
+ <html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content"/><meta name="theme-color" content="#ffffff"/><meta name="description" content="Revise LaTeX papers with an agent and review the PDF changes."/><link rel="icon" type="image/png" href="/favicon.png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><title>Papilot</title> <script type="module" crossorigin src="/assets/index-BhQFCMTx.js"></script>
3
+ <link rel="stylesheet" crossorigin href="/assets/index-CAV3-87U.css">
4
+ </head><body><div id="root"></div></body></html>
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "main.tex",
3
+ "engine": "pdflatex"
4
+ }
@@ -0,0 +1,60 @@
1
+ \section{Proofs}
2
+ \label{app:proofs}
3
+
4
+ \subsection{Expected rounds}
5
+
6
+ We prove \cref{prop:rounds}. Write $q = 1 - p$. The rounds of different changes are independent, so
7
+ $\Prob(R_{\max} \le r) = \Prob(R \le r)^{m} = (1 - q^{r})^{m}$, and since
8
+ $R_{\max}$ takes values in $\N$,
9
+ \begin{equation}
10
+ \E[R_{\max}] = \sum_{r \ge 0} \Prob(R_{\max} > r)
11
+ = \sum_{r \ge 0} \Bigl( 1 - \bigl(1 - q^{r}\bigr)^{m} \Bigr).
12
+ \end{equation}
13
+ By the binomial theorem,
14
+ $1 - (1 - q^{r})^{m} = \sum_{k=1}^{m} (-1)^{k+1} \binom{m}{k} q^{rk}$. The inner
15
+ sum is finite, so the two sums may be exchanged, and
16
+ $\sum_{r \ge 0} q^{rk} = 1 / (1 - q^{k})$ gives \cref{eq:rounds}.
17
+
18
+ For the asymptotics, $1 - q^{k} = 1 - (1-p)^{k} = kp + O(p^2)$ as $p \to 0$, so
19
+ \begin{equation}
20
+ \E[R_{\max}] = \frac{1}{p} \sum_{k=1}^{m} \frac{(-1)^{k+1}}{k} \binom{m}{k}
21
+ + O(1)
22
+ = \frac{H_m}{p} + O(1),
23
+ \end{equation}
24
+ using the identity $\sum_{k=1}^{m} \frac{(-1)^{k+1}}{k}\binom{m}{k} = H_m$,
25
+ which follows by integrating $\bigl(1 - (1-x)^{m}\bigr)/x
26
+ = \sum_{j=0}^{m-1} (1-x)^{j}$ from $0$ to $1$. \qed
27
+
28
+ \subsection{Mid-line drift}
29
+
30
+ We prove \cref{thm:drift}. Let $\gamma = \Cov(\delta_i, \delta_j)$ for $i \ne j$, which does not depend on the
31
+ pair by exchangeability. Since $\sum_{i=1}^{N} \delta_i = 0$,
32
+ \begin{equation}
33
+ 0 = \Var\Bigl(\sum_{i=1}^{N} \delta_i\Bigr) = N v + N(N-1)\, \gamma,
34
+ \qquad\text{so}\qquad \gamma = -\frac{v}{N-1} .
35
+ \end{equation}
36
+ With $j = k - 1$ terms in $\varepsilon_k$,
37
+ \begin{equation}
38
+ \Var(\varepsilon_k) = j v + j(j-1)\, \gamma
39
+ = j v \Bigl(1 - \frac{j - 1}{N - 1}\Bigr)
40
+ = v\, \frac{j\,(N - j)}{N - 1}
41
+ = v\, \frac{(k-1)(N-k+1)}{N-1} .
42
+ \end{equation}
43
+ The product $j(N-j)$ is largest at $j = N/2$, where it equals $N^2/4$, and
44
+ $N^2/(4(N-1)) \approx N/4$ for large $N$. \qed
45
+
46
+ \subsection{Partial commits}
47
+
48
+ We prove \cref{prop:partial}. Papilot commits $P$ in two steps. First, adding $P$ to the index sets
49
+ $I(\pi) = W(\pi)$ for every $\pi \in P$ that exists on disk and removes from the
50
+ index every $\pi \in P$ that does not, leaving the entries for $\overline{P}$
51
+ unchanged:
52
+ \begin{equation}
53
+ I_1 = I|_{\overline{P}} \cup W|_{P} .
54
+ \end{equation}
55
+ Second, a commit restricted to $P$ builds its tree from $H$ with the entries
56
+ for $P$ taken from the working tree and ignores the entries of the index for
57
+ $\overline{P}$, which gives $T_c = H|_{\overline{P}} \cup W|_{P}$. It then
58
+ updates the index entries for $P$ and keeps the others, so $I' = I_1$. For a
59
+ rename from $\pi$ to $\pi'$, the entry for $\pi$ is absent from $W$; including
60
+ $\pi$ in $P$ removes it from $T_c$, and including $\pi'$ adds the new path. \qed
@@ -0,0 +1,54 @@
1
+ \section{Notation and keyboard}
2
+ \label{app:reference}
3
+
4
+ \subsection{Notation}
5
+
6
+ \begin{center}
7
+ \small
8
+ \begin{tabular}{@{}lll@{}}
9
+ \toprule
10
+ Symbol & Meaning & Where \\
11
+ \midrule
12
+ $x_k$, $F$ & auxiliary state of the build, one run & \cref{eq:fixed-point} \\
13
+ $T_{rm}$, $T_m$ & text rendering and text matrices & \cref{eq:trm} \\
14
+ $\doc$, $n$ & manuscript source and its length & \cref{sec:model} \\
15
+ $e = (a, b, w)$, $\delta(e)$ & edit replacing $[a, b)$ by $w$, its shift & \cref{eq:apply} \\
16
+ $e \perp e'$ & compatible edits & \cref{eq:compatible} \\
17
+ $\tau(e', e)$ & $e'$ rebased past $e$ & \cref{eq:transform} \\
18
+ $\theta$, $\alpha$ & decision state, action & \cref{eq:round,eq:idempotent} \\
19
+ $p$, $R_{\max}$, $r_{\eta}$ & acceptance probability, rounds, rounds with confidence & \cref{eq:rounds,eq:rounds-confidence} \\
20
+ $\ell$, $k_i$, $\nu$ & edit length, edits per task, clustered fraction & \cref{eq:conflict,eq:clustered} \\
21
+ $T$, $\key(W)$ & snapshot tree, build key & \cref{eq:snapshot,eq:key} \\
22
+ $s$, $V_s$, $R_{\phi}$ & viewer scale, viewport, rotation & \cref{eq:viewport} \\
23
+ $r$, $b(r)$, $d$ & adjustment ratio, badness, demerits & \cref{eq:ratio,eq:badness,eq:demerits} \\
24
+ $\varepsilon_k$, $\sigma$, $\beta_k$ & text layer drift, stretch factor, bias & \cref{eq:drift,eq:bias} \\
25
+ $\mathcal{S}$, $\letters$, $\dist$ & SyncTeX query, letter normalisation, line distance & \cref{sec:notes} \\
26
+ $\epsilon$, $\kappa$, $q$ & effort, tokens per turn, acceptance per turn & \cref{eq:effort-cost} \\
27
+ $c$, $A$, $C(c, A)$ & slots, offered load, waiting probability & \cref{eq:erlang} \\
28
+ $u_w$, $B_w$, $S(t)$ & window utilisation, budget, usage process & \cref{eq:utilisation,eq:compound} \\
29
+ $H$, $I$, $W$, $P$ & Git trees, index, working tree, chosen paths & \cref{eq:partial} \\
30
+ $\anc(X)$ & commits reachable from $X$ & \cref{eq:ahead-behind} \\
31
+ $\chi$, $\mathcal{O}$, $o$ & request token, allowed origins, owner & \cref{eq:allow} \\
32
+ \bottomrule
33
+ \end{tabular}
34
+ \end{center}
35
+
36
+ \subsection{Keyboard}
37
+
38
+ \begin{center}
39
+ \small
40
+ \begin{tabular}{@{}ll@{}}
41
+ \toprule
42
+ Key & Action \\
43
+ \midrule
44
+ \texttt{A}, \texttt{R}, \texttt{C} & accept, reject or comment on the current change \\
45
+ \texttt{J}, \texttt{K} & next and previous change \\
46
+ \texttt{N} & next undecided change \\
47
+ \texttt{S} & show the \LaTeX{} source of the current change \\
48
+ $\text{\texttt{Cmd}} + \text{\texttt{F}}$ & find in the PDF \\
49
+ $\text{\texttt{Cmd}} + \text{\texttt{+}}$, $\text{\texttt{Cmd}} + \text{\texttt{-}}$, $\text{\texttt{Cmd}} + \text{\texttt{0}}$ & zoom in, zoom out, fit width \\
50
+ \texttt{Enter}, \texttt{Shift+Enter} & send, new line \\
51
+ \texttt{Esc} & close a menu, cancel a note, stop marking a region \\
52
+ \bottomrule
53
+ \end{tabular}
54
+ \end{center}
@@ -0,0 +1,57 @@
1
+ \documentclass[11pt]{article}
2
+ \input{preamble}
3
+
4
+ \title{Papilot: Reviewable Agent Edits for \LaTeX{} Manuscripts}
5
+ \author{The Papilot Authors}
6
+ \date{}
7
+
8
+ \begin{document}
9
+ \maketitle
10
+
11
+ \begin{abstract}
12
+ Papilot is a personal workspace for revising \LaTeX{} papers with an AI agent
13
+ and reviewing every resulting change as a PDF difference before it reaches the
14
+ manuscript. Each editing task runs in an isolated Git worktree, may be driven
15
+ by Codex, Claude or Antigravity, and proceeds in review rounds in which the
16
+ author accepts, rejects or comments on individual changes. This paper describes
17
+ the system through a sequence of small formal models. We define edits and
18
+ review rounds as operators on a document, prove that compatible edits commute
19
+ and can be rebased, and bound the number of rounds a task needs. We estimate
20
+ how often concurrent tasks conflict, both for uniformly placed and for
21
+ clustered edits. We then treat the geometry of the PDF view: the chain of
22
+ matrices from a glyph to a pixel, why a line-wide text layer drifts from the
23
+ printed words, and how per-word runs bound that drift. We show how a mark on
24
+ the page becomes a source location, model agent scheduling as a queue and
25
+ usage limits as a compound Poisson process, and give the index algebra behind
26
+ partial commits. A model-based evaluation tabulates the resulting quantities.
27
+ The paper doubles as Papilot's example manuscript: every equation in it is a
28
+ place to try a review.
29
+ \end{abstract}
30
+
31
+ \tableofcontents
32
+ \clearpage
33
+
34
+ \input{sections/01-introduction}
35
+ \input{sections/02-using}
36
+ \input{sections/03-background}
37
+ \input{sections/04-model}
38
+ \input{sections/05-conflicts}
39
+ \input{sections/06-building}
40
+ \input{sections/07-geometry}
41
+ \input{sections/08-notes}
42
+ \input{sections/09-agents}
43
+ \input{sections/10-usage}
44
+ \input{sections/11-git}
45
+ \input{sections/12-security}
46
+ \input{sections/13-evaluation}
47
+ \input{sections/14-related}
48
+ \input{sections/15-conclusion}
49
+
50
+ \appendix
51
+ \input{appendix/proofs}
52
+ \input{appendix/reference}
53
+
54
+ \bibliographystyle{plainnat}
55
+ \bibliography{references}
56
+
57
+ \end{document}
@@ -0,0 +1,53 @@
1
+ % Packages and notation shared by every chapter.
2
+ \usepackage[margin=1in]{geometry}
3
+ \usepackage[T1]{fontenc}
4
+ \usepackage{lmodern}
5
+ \usepackage{microtype}
6
+ \usepackage{amsmath,amssymb,amsthm,mathtools}
7
+ \usepackage{bm}
8
+ \usepackage{booktabs}
9
+ \usepackage{enumitem}
10
+ \usepackage{caption}
11
+ \usepackage{algorithm}
12
+ \usepackage[noend]{algpseudocode}
13
+ \usepackage{tikz}
14
+ \usetikzlibrary{automata,positioning,arrows.meta,calc,decorations.pathreplacing}
15
+ \usepackage{pgfplots}
16
+ \pgfplotsset{compat=1.18}
17
+ \usepackage[numbers,sort&compress]{natbib}
18
+ \usepackage[colorlinks=true,linkcolor=blue!50!black,citecolor=blue!50!black,urlcolor=blue!50!black]{hyperref}
19
+ \usepackage[nameinlink]{cleveref}
20
+
21
+ % thmtools lets cleveref name each kind of statement correctly although they
22
+ % share one counter.
23
+ \usepackage{thmtools}
24
+ \declaretheorem[style=plain, numberwithin=section]{theorem}
25
+ \declaretheorem[style=plain, sibling=theorem]{proposition}
26
+ \declaretheorem[style=plain, sibling=theorem]{lemma}
27
+ \declaretheorem[style=plain, sibling=theorem]{corollary}
28
+ \declaretheorem[style=definition, sibling=theorem]{definition}
29
+ \declaretheorem[style=definition, sibling=theorem]{example}
30
+ \declaretheorem[style=definition, sibling=theorem]{assumption}
31
+ \declaretheorem[style=remark, sibling=theorem]{remark}
32
+ \numberwithin{equation}{section}
33
+
34
+ \newcommand{\R}{\mathbb{R}}
35
+ \newcommand{\N}{\mathbb{N}}
36
+ \newcommand{\Z}{\mathbb{Z}}
37
+ \newcommand{\E}{\mathbb{E}}
38
+ \newcommand{\Prob}{\mathbb{P}}
39
+ \newcommand{\Var}{\operatorname{Var}}
40
+ \newcommand{\Cov}{\operatorname{Cov}}
41
+ \newcommand{\doc}{D}
42
+ \newcommand{\edit}{\Delta}
43
+ \newcommand{\apply}{\oplus}
44
+ \newcommand{\letters}{\lambda}
45
+ \newcommand{\anc}{\operatorname{anc}}
46
+ \newcommand{\ind}{\mathbf{1}}
47
+ \DeclareMathOperator{\key}{key}
48
+ \DeclareMathOperator{\dist}{dist}
49
+ \DeclareMathOperator*{\argmin}{arg\,min}
50
+ \DeclarePairedDelimiter{\abs}{\lvert}{\rvert}
51
+ \DeclarePairedDelimiter{\norm}{\lVert}{\rVert}
52
+ \DeclarePairedDelimiter{\floor}{\lfloor}{\rfloor}
53
+ \DeclarePairedDelimiter{\ceil}{\lceil}{\rceil}
@@ -0,0 +1,158 @@
1
+ @article{laurens2008,
2
+ author = {J{\'e}r{\^o}me Laurens},
3
+ title = {Direct and reverse synchronization with {SyncTeX}},
4
+ journal = {TUGboat},
5
+ volume = {29},
6
+ number = {3},
7
+ pages = {365--371},
8
+ year = {2008}
9
+ }
10
+
11
+ @article{erlang1917,
12
+ author = {A. K. Erlang},
13
+ title = {Solution of some problems in the theory of probabilities of significance in automatic telephone exchanges},
14
+ journal = {Elektroteknikeren},
15
+ volume = {13},
16
+ pages = {5--13},
17
+ year = {1917}
18
+ }
19
+
20
+ @book{chacon2014,
21
+ author = {Scott Chacon and Ben Straub},
22
+ title = {Pro Git},
23
+ edition = {Second},
24
+ publisher = {Apress},
25
+ year = {2014}
26
+ }
27
+
28
+ @book{knuth1984,
29
+ author = {Donald E. Knuth},
30
+ title = {The {\TeX}book},
31
+ publisher = {Addison-Wesley},
32
+ year = {1984}
33
+ }
34
+
35
+ @article{knuth1981,
36
+ author = {Donald E. Knuth and Michael F. Plass},
37
+ title = {Breaking paragraphs into lines},
38
+ journal = {Software: Practice and Experience},
39
+ volume = {11},
40
+ number = {11},
41
+ pages = {1119--1184},
42
+ year = {1981}
43
+ }
44
+
45
+ @book{lamport1994,
46
+ author = {Leslie Lamport},
47
+ title = {{\LaTeX}: A Document Preparation System},
48
+ edition = {Second},
49
+ publisher = {Addison-Wesley},
50
+ year = {1994}
51
+ }
52
+
53
+ @inproceedings{ellis1989,
54
+ author = {C. A. Ellis and S. J. Gibbs},
55
+ title = {Concurrency control in groupware systems},
56
+ booktitle = {Proceedings of the 1989 ACM SIGMOD International Conference on Management of Data},
57
+ pages = {399--407},
58
+ year = {1989}
59
+ }
60
+
61
+ @inproceedings{shapiro2011,
62
+ author = {Marc Shapiro and Nuno Pregui{\c{c}}a and Carlos Baquero and Marek Zawirski},
63
+ title = {Conflict-free replicated data types},
64
+ booktitle = {Stabilization, Safety, and Security of Distributed Systems (SSS 2011)},
65
+ series = {Lecture Notes in Computer Science},
66
+ volume = {6976},
67
+ pages = {386--400},
68
+ publisher = {Springer},
69
+ year = {2011}
70
+ }
71
+
72
+ @article{myers1986,
73
+ author = {Eugene W. Myers},
74
+ title = {An {$O(ND)$} difference algorithm and its variations},
75
+ journal = {Algorithmica},
76
+ volume = {1},
77
+ number = {1--4},
78
+ pages = {251--266},
79
+ year = {1986}
80
+ }
81
+
82
+ @techreport{hunt1976,
83
+ author = {James W. Hunt and M. Douglas McIlroy},
84
+ title = {An algorithm for differential file comparison},
85
+ institution = {Bell Laboratories},
86
+ type = {Computing Science Technical Report},
87
+ number = {41},
88
+ year = {1976}
89
+ }
90
+
91
+ @article{little1961,
92
+ author = {John D. C. Little},
93
+ title = {A proof for the queuing formula: {$L = \lambda W$}},
94
+ journal = {Operations Research},
95
+ volume = {9},
96
+ number = {3},
97
+ pages = {383--387},
98
+ year = {1961}
99
+ }
100
+
101
+ @book{kleinrock1975,
102
+ author = {Leonard Kleinrock},
103
+ title = {Queueing Systems, Volume 1: Theory},
104
+ publisher = {Wiley},
105
+ year = {1975}
106
+ }
107
+
108
+ @book{feller1968,
109
+ author = {William Feller},
110
+ title = {An Introduction to Probability Theory and Its Applications, Volume 1},
111
+ edition = {Third},
112
+ publisher = {Wiley},
113
+ year = {1968}
114
+ }
115
+
116
+ @book{billingsley1999,
117
+ author = {Patrick Billingsley},
118
+ title = {Convergence of Probability Measures},
119
+ edition = {Second},
120
+ publisher = {Wiley},
121
+ year = {1999}
122
+ }
123
+
124
+ @manual{iso32000,
125
+ organization = {International Organization for Standardization},
126
+ title = {{ISO} 32000-1:2008, Document management --- Portable document format --- Part 1: {PDF} 1.7},
127
+ year = {2008}
128
+ }
129
+
130
+ @inproceedings{barth2008,
131
+ author = {Adam Barth and Collin Jackson and John C. Mitchell},
132
+ title = {Robust defenses for cross-site request forgery},
133
+ booktitle = {Proceedings of the 15th ACM Conference on Computer and Communications Security (CCS '08)},
134
+ pages = {75--88},
135
+ year = {2008}
136
+ }
137
+
138
+ @misc{latexdiff,
139
+ author = {Frederik Tilmann},
140
+ title = {latexdiff: Determine and mark up significant differences between {\LaTeX} files},
141
+ howpublished = {\url{https://ctan.org/pkg/latexdiff}}
142
+ }
143
+
144
+ @misc{pdfjs,
145
+ author = {{Mozilla}},
146
+ title = {{PDF.js}: A general-purpose, web standards-based platform for parsing and rendering {PDFs}},
147
+ howpublished = {\url{https://mozilla.github.io/pdf.js/}}
148
+ }
149
+
150
+ @article{shannon1951,
151
+ author = {Claude E. Shannon},
152
+ title = {Prediction and entropy of printed {English}},
153
+ journal = {Bell System Technical Journal},
154
+ volume = {30},
155
+ number = {1},
156
+ pages = {50--64},
157
+ year = {1951}
158
+ }
@@ -0,0 +1,66 @@
1
+ \section{Introduction}
2
+ \label{sec:introduction}
3
+
4
+ Writing a research paper is a long sequence of small decisions. A sentence is
5
+ shortened, a definition is moved before its first use, a symbol is renamed so
6
+ that it no longer collides with another, a proof gains the step a referee
7
+ asked for. An agent that edits \LaTeX{} can propose many of these decisions
8
+ quickly, but a proposal is only useful when the author can see what it changes
9
+ in the typeset paper, decide, and say why. Papilot is built around that loop.
10
+
11
+ \subsection{Three commitments}
12
+
13
+ Papilot organises the loop around three commitments.
14
+
15
+ \begin{enumerate}[label=(C\arabic*)]
16
+ \item \emph{Isolation.} Every task edits its own Git worktree, never the
17
+ manuscript checkout, so that unreviewed text cannot leak into the paper.
18
+ \item \emph{Typeset review.} Changes are reviewed as differences between two
19
+ compiled PDFs, with the \LaTeX{} source one click away.
20
+ \item \emph{Explicit acceptance.} Only accepted changes are merged into the
21
+ working tree, and every decision can be undone.
22
+ \end{enumerate}
23
+
24
+ The first commitment is about safety, the second about legibility and the
25
+ third about authority. Together they turn an agent from a co-author that writes
26
+ into the manuscript into an assistant that proposes to it.
27
+
28
+ \subsection{What this paper does}
29
+
30
+ The rest of this paper makes the commitments precise and studies their
31
+ consequences with small, explicit models. Our contributions are:
32
+
33
+ \begin{itemize}
34
+ \item an algebra of edits and review rounds, with a proof that compatible
35
+ edits commute and can be rebased onto each other (\cref{sec:model}), and
36
+ tight bounds on the number of rounds a task needs;
37
+ \item an estimate of the conflict rate between concurrent tasks under uniform
38
+ and clustered edits (\cref{sec:conflicts});
39
+ \item a content-addressed build scheme in which undoing a decision never
40
+ recompiles (\cref{sec:build});
41
+ \item a geometric account of the PDF view, explaining why a line-wide text
42
+ layer drifts from the printed words and proving that per-word runs bound
43
+ the drift (\cref{sec:geometry});
44
+ \item an algorithm that turns a mark on the page into source lines, and an
45
+ analysis of when its matches are unique (\cref{sec:notes});
46
+ \item queueing and usage models for agents (\cref{sec:agents,sec:usage}),
47
+ the index algebra behind partial commits (\cref{sec:git}) and a security
48
+ model (\cref{sec:security});
49
+ \item a model-based evaluation that tabulates the quantities above
50
+ (\cref{sec:evaluation}).
51
+ \end{itemize}
52
+
53
+ \Cref{sec:using} describes Papilot as an author uses it, \cref{sec:background}
54
+ collects the background on \TeX{}, PDF, Git and SyncTeX that the later sections
55
+ rely on, \cref{sec:related} discusses related
56
+ work, and \cref{sec:conclusion} concludes. Longer proofs are in
57
+ \cref{app:proofs}; \cref{app:reference} lists the notation and the keyboard
58
+ shortcuts.
59
+
60
+ \subsection{A note on this document}
61
+
62
+ This paper is also Papilot's example manuscript. It is deliberately dense with
63
+ displayed mathematics, theorems and cross-references, because those are the
64
+ places where an agent's edit is easiest to get subtly wrong and a typeset
65
+ review most useful. The reader is invited to start a task against any equation
66
+ and to review the result.
@@ -0,0 +1,134 @@
1
+ \section{Using Papilot}
2
+ \label{sec:using}
3
+
4
+ This section describes Papilot as an author meets it. The later sections
5
+ explain why it behaves as it does.
6
+
7
+ \subsection{Running it}
8
+
9
+ Papilot needs Node.js~22.22 or later, Git, a \TeX{} installation with
10
+ \texttt{latexmk} and \texttt{synctex}, and a signed-in agent on the host. It is
11
+ installed and started with
12
+ \begin{verbatim}
13
+ npm install -g papilot
14
+ papilot
15
+ \end{verbatim}
16
+ and then opened at \texttt{http://127.0.0.1:7274}. \emph{Add paper} registers a
17
+ \LaTeX{} Git repository on the host; later papers are added and switched from
18
+ the paper menu at the top of the sidebar. A repository must have at least one
19
+ commit and compile with \texttt{latexmk}; a custom root document is named in a
20
+ \texttt{.latex-review.json} file. To try a sample first, \texttt{papilot demo}
21
+ copies this paper into a separate repository and registers it as
22
+ \emph{Papilot paper}, without touching any existing manuscript.
23
+
24
+ \subsection{A task from start to finish}
25
+
26
+ \begin{enumerate}
27
+ \item Select \emph{New task}, describe the revision and press Enter. The first
28
+ line of the prompt becomes the task's title, and the task runs on the paper
29
+ selected in the sidebar. Below the prompt, choose the agent, its model and
30
+ its reasoning effort; Papilot remembers all three for the next task.
31
+ \item Follow the conversation and answer the agent's questions or permission
32
+ requests. When both execution slots are busy, further tasks queue
33
+ (\cref{sec:agents}).
34
+ \item When the agent finishes, Papilot builds the PDF review automatically.
35
+ Accept, reject or comment on each change in the typeset review.
36
+ \item Send the saved comments, or write further instructions in the
37
+ conversation. Either starts the next round, which carries the review
38
+ feedback with it (\cref{sec:model}).
39
+ \end{enumerate}
40
+
41
+ While the agent works, the composer shows a stop button that pauses the task.
42
+ The desktop workspace offers three views, \emph{Review}, \emph{Split} and
43
+ \emph{Chat}, and remembers the choice; on a phone the header switches between
44
+ the review and the chat. The review toolbar shows the round's progress, accepts
45
+ or rejects every undecided change at once, opens the full PDF of the round,
46
+ builds the review again, and opens it in a separate tab. \emph{Accept all} and
47
+ \emph{Reject all} act only on changes not yet decided, and one undo reverses the
48
+ whole batch.
49
+
50
+ Conversation drafts are saved per task in the browser; Enter sends, Shift+Enter
51
+ adds a line, and an input method's composition is never sent by Enter. Closing
52
+ the browser does not stop a run. After a restart of the host process, turns that
53
+ were in flight are marked interrupted and can be continued, and queued messages
54
+ are kept. If the outcome of a request is uncertain, the task offers
55
+ \emph{Check status}, and further decisions wait until it is resolved.
56
+
57
+ \subsection{Reading the paper}
58
+
59
+ \emph{PDF}, under the paper in the sidebar, shows the manuscript as it is on
60
+ disk, including accepted but uncommitted changes (\cref{sec:build}). It behaves
61
+ like a local PDF reader: continuous pages with crisp text at any zoom,
62
+ selectable text, working links and cross-references, and search across the
63
+ whole document.
64
+ \begin{itemize}
65
+ \item \emph{Contents} lists the PDF's bookmarks, which \texttt{hyperref}
66
+ writes for every section, highlights the section being read, and jumps to
67
+ any entry. The same list opens from the toolbar.
68
+ \item A page number or the arrows change page; the zoom buttons, the zoom
69
+ menu, the keyboard and a pinch change the zoom, which is remembered.
70
+ \item Find (Cmd+F) searches every page, with Enter and Shift+Enter stepping
71
+ through the matches.
72
+ \end{itemize}
73
+
74
+ \subsection{Notes on the PDF}
75
+
76
+ To ask for a change directly on the PDF, select text and choose \emph{Add note},
77
+ or mark a region around a figure or an equation, then describe the change. The
78
+ selection follows the printed words exactly (\cref{sec:geometry}), each note is
79
+ settled on the source lines that produced it (\cref{sec:notes}), and every
80
+ pending note is sent to the agent as one task.
81
+
82
+ \subsection{The Git panel}
83
+
84
+ Beside the PDF, a small source-control panel shows the branch and how it
85
+ compares with its upstream, the last commit, and the uncommitted changes with
86
+ their line counts. Selecting a file shows its difference. Ticking files,
87
+ writing a message and pressing Enter commits exactly those files as they are on
88
+ disk; fetch, a fast-forward pull and push keep the branch in step with its
89
+ remote (\cref{sec:git}).
90
+
91
+ \subsection{Agents}
92
+
93
+ Each task runs on one agent: Codex through its app server, Claude through the
94
+ Claude Agent SDK, or Antigravity through its command line. Every agent uses its
95
+ own login on the host, and an agent that is not installed or signed in is listed
96
+ as unavailable. When an agent reports usage, the new-task page shows each usage
97
+ window with how much is used and when it resets (\cref{sec:usage}).
98
+
99
+ \subsection{Working from another device}
100
+
101
+ Papilot binds only to \texttt{127.0.0.1}. To reach it from a phone or another
102
+ computer, it is published on a private Tailscale network, and the server checks
103
+ the host, the browser's origin and the Tailscale identity of every remote
104
+ request (\cref{sec:security}):
105
+ \begin{verbatim}
106
+ export PAPILOT_PUBLIC_ORIGIN=https://your-mac.your-tailnet.ts.net:8443
107
+ export PAPILOT_TAILSCALE_LOGIN=your-tailscale-login
108
+ papilot service install
109
+ tailscale serve --bg --https=8443 http://127.0.0.1:7274
110
+ \end{verbatim}
111
+ A background service starts Papilot after login, restarts it if it exits and
112
+ keeps the computer from sleeping while it runs. Without Tailscale, an SSH
113
+ tunnel serves the same purpose.
114
+
115
+ \subsection{Configuration}
116
+
117
+ \begin{center}
118
+ \small
119
+ \begin{tabular}{@{}lp{0.62\linewidth}@{}}
120
+ \toprule
121
+ Variable & Purpose \\
122
+ \midrule
123
+ \texttt{PAPILOT\_PORT} & local HTTP port, $7274$ by default \\
124
+ \texttt{PAPILOT\_DATA} & state and generated example, \texttt{\textasciitilde/.papilot} by default \\
125
+ \texttt{PAPILOT\_CODEX\_BIN} & Codex executable \\
126
+ \texttt{ANTHROPIC\_API\_KEY} & API key for Claude tasks \\
127
+ \texttt{PAPILOT\_AGY\_BIN} & Antigravity command line \\
128
+ \texttt{PAPILOT\_AGY\_PROXY} & HTTP proxy used only for Antigravity \\
129
+ \texttt{PAPILOT\_REVIEW\_ENGINE} & review engine directory \\
130
+ \texttt{PAPILOT\_PUBLIC\_ORIGIN} & exact browser origin for remote access \\
131
+ \texttt{PAPILOT\_TAILSCALE\_LOGIN} & Tailscale login allowed to connect \\
132
+ \bottomrule
133
+ \end{tabular}
134
+ \end{center}