diff --git a/.gitignore b/.gitignore index 1107134..1d4d00b 100644 --- a/.gitignore +++ b/.gitignore @@ -64,8 +64,8 @@ tests/e2e/test-results/ tests/e2e/node_modules/** # rl/sim run outputs -sim/rl/behavior_loader/*.dot -sim/rl/behavior_loader/*.png +# sim/rl/behavior_loader/*.dot +# sim/rl/behavior_loader/*.png sim/rl/behavior_loader/*.svg sim/rl/behavior_loader/*.pdf sim/rl/runs/ diff --git a/paper/defense/defense.nav b/paper/defense/defense.nav index 64ee081..0f2f0fa 100644 --- a/paper/defense/defense.nav +++ b/paper/defense/defense.nav @@ -2,124 +2,128 @@ \headcommand {\beamer@framepages {1}{1}} \headcommand {\slideentry {0}{0}{2}{2/2}{}{0}} \headcommand {\beamer@framepages {2}{2}} -\headcommand {\slideentry {0}{0}{3}{3/9}{}{0}} -\headcommand {\beamer@framepages {3}{9}} -\headcommand {\slideentry {0}{0}{4}{10/12}{}{0}} -\headcommand {\beamer@framepages {10}{12}} -\headcommand {\beamer@sectionpages {1}{12}} -\headcommand {\beamer@subsectionpages {1}{12}} -\headcommand {\sectionentry {1}{Platform Development}{13}{Platform Development}{0}} -\headcommand {\slideentry {1}{0}{1}{13/14}{}{0}} -\headcommand {\beamer@framepages {13}{14}} -\headcommand {\slideentry {1}{0}{2}{15/17}{}{0}} -\headcommand {\beamer@framepages {15}{17}} -\headcommand {\slideentry {1}{0}{3}{18/20}{}{0}} -\headcommand {\beamer@framepages {18}{20}} -\headcommand {\beamer@sectionpages {13}{20}} -\headcommand {\beamer@subsectionpages {13}{20}} -\headcommand {\sectionentry {2}{Distinguishability Construction}{21}{Distinguishability Construction}{0}} -\headcommand {\slideentry {2}{0}{1}{21/22}{}{0}} -\headcommand {\beamer@framepages {21}{22}} -\headcommand {\slideentry {2}{0}{2}{23/23}{}{0}} -\headcommand {\beamer@framepages {23}{23}} -\headcommand {\slideentry {2}{0}{3}{24/30}{}{0}} -\headcommand {\beamer@framepages {24}{30}} -\headcommand {\beamer@sectionpages {21}{30}} -\headcommand {\beamer@subsectionpages {21}{30}} -\headcommand {\sectionentry {3}{Distributionally Robust RL}{31}{Distributionally Robust RL}{0}} -\headcommand {\slideentry {3}{0}{1}{31/31}{}{0}} -\headcommand {\beamer@framepages {31}{31}} -\headcommand {\slideentry {3}{0}{2}{32/34}{}{0}} -\headcommand {\beamer@framepages {32}{34}} -\headcommand {\slideentry {3}{0}{3}{35/36}{}{0}} -\headcommand {\beamer@framepages {35}{36}} -\headcommand {\beamer@sectionpages {31}{36}} -\headcommand {\beamer@subsectionpages {31}{36}} -\headcommand {\sectionentry {4}{Results}{37}{Results}{0}} -\headcommand {\slideentry {4}{0}{1}{37/37}{}{0}} -\headcommand {\beamer@framepages {37}{37}} -\headcommand {\beamer@sectionpages {37}{37}} -\headcommand {\beamer@subsectionpages {37}{37}} -\headcommand {\sectionentry {5}{Conclusions}{38}{Conclusions}{0}} -\headcommand {\slideentry {5}{0}{1}{38/38}{}{0}} -\headcommand {\beamer@framepages {38}{38}} -\headcommand {\slideentry {5}{0}{2}{39/43}{}{0}} -\headcommand {\beamer@framepages {39}{43}} -\headcommand {\slideentry {5}{0}{3}{44/44}{}{0}} -\headcommand {\beamer@framepages {44}{44}} -\headcommand {\gdef \insertmainframenumber {17}} -\headcommand {\partentry {\translate {Appendix}}{1}} -\headcommand {\beamer@partpages {1}{44}} -\headcommand {\beamer@sectionpages {38}{44}} -\headcommand {\beamer@subsectionpages {38}{44}} -\headcommand {\beamer@appendixpages {45}} -\headcommand {\beamer@sectionpages {45}{44}} -\headcommand {\beamer@subsectionpages {45}{44}} -\headcommand {\sectionentry {6}{Appendix}{45}{Appendix}{1}} -\headcommand {\slideentry {6}{0}{1}{45/45}{}{1}} -\headcommand {\beamer@framepages {45}{45}} -\headcommand {\slideentry {6}{0}{2}{46/46}{}{1}} +\headcommand {\slideentry {0}{0}{3}{3/3}{}{0}} +\headcommand {\beamer@framepages {3}{3}} +\headcommand {\slideentry {0}{0}{4}{4/6}{}{0}} +\headcommand {\beamer@framepages {4}{6}} +\headcommand {\slideentry {0}{0}{5}{7/13}{}{0}} +\headcommand {\beamer@framepages {7}{13}} +\headcommand {\slideentry {0}{0}{6}{14/14}{}{0}} +\headcommand {\beamer@framepages {14}{14}} +\headcommand {\beamer@sectionpages {1}{14}} +\headcommand {\beamer@subsectionpages {1}{14}} +\headcommand {\sectionentry {1}{Platform Development}{15}{Platform Development}{0}} +\headcommand {\slideentry {1}{0}{1}{15/16}{}{0}} +\headcommand {\beamer@framepages {15}{16}} +\headcommand {\slideentry {1}{0}{2}{17/19}{}{0}} +\headcommand {\beamer@framepages {17}{19}} +\headcommand {\slideentry {1}{0}{3}{20/22}{}{0}} +\headcommand {\beamer@framepages {20}{22}} +\headcommand {\beamer@sectionpages {15}{22}} +\headcommand {\beamer@subsectionpages {15}{22}} +\headcommand {\sectionentry {2}{Distinguishability Construction}{23}{Distinguishability Construction}{0}} +\headcommand {\slideentry {2}{0}{1}{23/24}{}{0}} +\headcommand {\beamer@framepages {23}{24}} +\headcommand {\slideentry {2}{0}{2}{25/25}{}{0}} +\headcommand {\beamer@framepages {25}{25}} +\headcommand {\slideentry {2}{0}{3}{26/32}{}{0}} +\headcommand {\beamer@framepages {26}{32}} +\headcommand {\beamer@sectionpages {23}{32}} +\headcommand {\beamer@subsectionpages {23}{32}} +\headcommand {\sectionentry {3}{Distributionally Robust RL}{33}{Distributionally Robust RL}{0}} +\headcommand {\slideentry {3}{0}{1}{33/33}{}{0}} +\headcommand {\beamer@framepages {33}{33}} +\headcommand {\slideentry {3}{0}{2}{34/36}{}{0}} +\headcommand {\beamer@framepages {34}{36}} +\headcommand {\slideentry {3}{0}{3}{37/38}{}{0}} +\headcommand {\beamer@framepages {37}{38}} +\headcommand {\beamer@sectionpages {33}{38}} +\headcommand {\beamer@subsectionpages {33}{38}} +\headcommand {\sectionentry {4}{Results}{39}{Results}{0}} +\headcommand {\slideentry {4}{0}{1}{39/39}{}{0}} +\headcommand {\beamer@framepages {39}{39}} +\headcommand {\beamer@sectionpages {39}{39}} +\headcommand {\beamer@subsectionpages {39}{39}} +\headcommand {\sectionentry {5}{Conclusions}{40}{Conclusions}{0}} +\headcommand {\slideentry {5}{0}{1}{40/40}{}{0}} +\headcommand {\beamer@framepages {40}{40}} +\headcommand {\slideentry {5}{0}{2}{41/45}{}{0}} +\headcommand {\beamer@framepages {41}{45}} +\headcommand {\slideentry {5}{0}{3}{46/46}{}{0}} \headcommand {\beamer@framepages {46}{46}} -\headcommand {\slideentry {6}{0}{3}{47/47}{}{1}} +\headcommand {\gdef \insertmainframenumber {19}} +\headcommand {\partentry {\translate {Appendix}}{1}} +\headcommand {\beamer@partpages {1}{46}} +\headcommand {\beamer@sectionpages {40}{46}} +\headcommand {\beamer@subsectionpages {40}{46}} +\headcommand {\beamer@appendixpages {47}} +\headcommand {\beamer@sectionpages {47}{46}} +\headcommand {\beamer@subsectionpages {47}{46}} +\headcommand {\sectionentry {6}{Appendix}{47}{Appendix}{1}} +\headcommand {\slideentry {6}{0}{1}{47/47}{}{1}} \headcommand {\beamer@framepages {47}{47}} -\headcommand {\slideentry {6}{0}{4}{48/48}{}{1}} +\headcommand {\slideentry {6}{0}{2}{48/48}{}{1}} \headcommand {\beamer@framepages {48}{48}} -\headcommand {\slideentry {6}{0}{5}{49/49}{}{1}} +\headcommand {\slideentry {6}{0}{3}{49/49}{}{1}} \headcommand {\beamer@framepages {49}{49}} -\headcommand {\slideentry {6}{0}{6}{50/50}{}{1}} +\headcommand {\slideentry {6}{0}{4}{50/50}{}{1}} \headcommand {\beamer@framepages {50}{50}} -\headcommand {\slideentry {6}{0}{7}{51/51}{}{1}} +\headcommand {\slideentry {6}{0}{5}{51/51}{}{1}} \headcommand {\beamer@framepages {51}{51}} -\headcommand {\slideentry {6}{0}{8}{52/52}{}{1}} +\headcommand {\slideentry {6}{0}{6}{52/52}{}{1}} \headcommand {\beamer@framepages {52}{52}} -\headcommand {\slideentry {6}{0}{9}{53/53}{}{1}} +\headcommand {\slideentry {6}{0}{7}{53/53}{}{1}} \headcommand {\beamer@framepages {53}{53}} -\headcommand {\slideentry {6}{0}{10}{54/54}{}{1}} +\headcommand {\slideentry {6}{0}{8}{54/54}{}{1}} \headcommand {\beamer@framepages {54}{54}} -\headcommand {\slideentry {6}{0}{11}{55/55}{}{1}} +\headcommand {\slideentry {6}{0}{9}{55/55}{}{1}} \headcommand {\beamer@framepages {55}{55}} -\headcommand {\slideentry {6}{0}{12}{56/56}{}{1}} +\headcommand {\slideentry {6}{0}{10}{56/56}{}{1}} \headcommand {\beamer@framepages {56}{56}} -\headcommand {\slideentry {6}{0}{13}{57/57}{}{1}} +\headcommand {\slideentry {6}{0}{11}{57/57}{}{1}} \headcommand {\beamer@framepages {57}{57}} -\headcommand {\slideentry {6}{0}{14}{58/58}{}{1}} +\headcommand {\slideentry {6}{0}{12}{58/58}{}{1}} \headcommand {\beamer@framepages {58}{58}} -\headcommand {\slideentry {6}{0}{15}{59/59}{}{1}} +\headcommand {\slideentry {6}{0}{13}{59/59}{}{1}} \headcommand {\beamer@framepages {59}{59}} -\headcommand {\slideentry {6}{0}{16}{60/60}{}{1}} +\headcommand {\slideentry {6}{0}{14}{60/60}{}{1}} \headcommand {\beamer@framepages {60}{60}} -\headcommand {\slideentry {6}{0}{17}{61/61}{}{1}} +\headcommand {\slideentry {6}{0}{15}{61/61}{}{1}} \headcommand {\beamer@framepages {61}{61}} -\headcommand {\slideentry {6}{0}{18}{62/62}{}{1}} +\headcommand {\slideentry {6}{0}{16}{62/62}{}{1}} \headcommand {\beamer@framepages {62}{62}} -\headcommand {\slideentry {6}{0}{19}{63/63}{}{1}} +\headcommand {\slideentry {6}{0}{17}{63/63}{}{1}} \headcommand {\beamer@framepages {63}{63}} -\headcommand {\slideentry {6}{0}{20}{64/64}{}{1}} +\headcommand {\slideentry {6}{0}{18}{64/64}{}{1}} \headcommand {\beamer@framepages {64}{64}} -\headcommand {\slideentry {6}{0}{21}{65/65}{}{1}} +\headcommand {\slideentry {6}{0}{19}{65/65}{}{1}} \headcommand {\beamer@framepages {65}{65}} -\headcommand {\slideentry {6}{0}{22}{66/66}{}{1}} +\headcommand {\slideentry {6}{0}{20}{66/66}{}{1}} \headcommand {\beamer@framepages {66}{66}} -\headcommand {\slideentry {6}{0}{23}{67/67}{}{1}} +\headcommand {\slideentry {6}{0}{21}{67/67}{}{1}} \headcommand {\beamer@framepages {67}{67}} -\headcommand {\slideentry {6}{0}{24}{68/68}{}{1}} +\headcommand {\slideentry {6}{0}{22}{68/68}{}{1}} \headcommand {\beamer@framepages {68}{68}} -\headcommand {\slideentry {6}{0}{25}{69/69}{}{1}} +\headcommand {\slideentry {6}{0}{23}{69/69}{}{1}} \headcommand {\beamer@framepages {69}{69}} -\headcommand {\slideentry {6}{0}{26}{70/70}{}{1}} +\headcommand {\slideentry {6}{0}{24}{70/70}{}{1}} \headcommand {\beamer@framepages {70}{70}} -\headcommand {\slideentry {6}{0}{27}{71/71}{}{1}} +\headcommand {\slideentry {6}{0}{25}{71/71}{}{1}} \headcommand {\beamer@framepages {71}{71}} -\headcommand {\slideentry {6}{0}{28}{72/72}{}{1}} +\headcommand {\slideentry {6}{0}{26}{72/72}{}{1}} \headcommand {\beamer@framepages {72}{72}} -\headcommand {\slideentry {6}{0}{29}{73/73}{}{1}} +\headcommand {\slideentry {6}{0}{27}{73/73}{}{1}} \headcommand {\beamer@framepages {73}{73}} -\headcommand {\slideentry {6}{0}{30}{74/74}{}{1}} +\headcommand {\slideentry {6}{0}{28}{74/74}{}{1}} \headcommand {\beamer@framepages {74}{74}} -\headcommand {\beamer@partpages {45}{74}} -\headcommand {\beamer@subsectionpages {45}{74}} -\headcommand {\beamer@sectionpages {45}{74}} -\headcommand {\beamer@documentpages {74}} +\headcommand {\slideentry {6}{0}{29}{75/75}{}{1}} +\headcommand {\beamer@framepages {75}{75}} +\headcommand {\slideentry {6}{0}{30}{76/76}{}{1}} +\headcommand {\beamer@framepages {76}{76}} +\headcommand {\beamer@partpages {47}{76}} +\headcommand {\beamer@subsectionpages {47}{76}} +\headcommand {\beamer@sectionpages {47}{76}} +\headcommand {\beamer@documentpages {76}} \headcommand {\gdef \inserttotalframenumber {30}} -\headcommand {\gdef \inserttotalframenumber {17}} +\headcommand {\gdef \inserttotalframenumber {19}} \headcommand {\gdef \appendixtotalframenumber {30}} diff --git a/paper/defense/defense.pdf b/paper/defense/defense.pdf index 888dd1f..50c8c3f 100644 Binary files a/paper/defense/defense.pdf and b/paper/defense/defense.pdf differ diff --git a/paper/defense/defense.tex b/paper/defense/defense.tex index 80069e1..68fa58f 100644 --- a/paper/defense/defense.tex +++ b/paper/defense/defense.tex @@ -2,12 +2,15 @@ % Build: cd paper/defense && pdflatex defense.tex && pdflatex defense.tex \documentclass[aspectratio=169,11pt]{beamer} +% Narrative and visual refinements for final defense delivery. + \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{lmodern} \usepackage{microtype} \usepackage{amsmath,amssymb} \usepackage{graphicx} +\usepackage{xspace} \usepackage{booktabs} \usepackage{appendixnumberbeamer} \usepackage{hyperref} @@ -29,6 +32,7 @@ \definecolor{PhantomSlate}{HTML}{24364C} \definecolor{PhantomCyan}{HTML}{C97A3D} \definecolor{PhantomIndigo}{HTML}{2F8F8A} +\definecolor{PhantomPeach}{HTML}{EEC39C} \setbeamercolor{normal text}{fg=PhantomSlate,bg=PhantomPaper} \setbeamercolor{alerted text}{fg=PhantomCyan!95!black} @@ -78,6 +82,32 @@ \end{tikzpicture}% } +\newcommand{\humaniconraw}{% + \begin{tikzpicture}[x=0.9ex,y=0.9ex] + \fill[PhantomIndigo] (0,1.55) circle (0.42); + \draw[PhantomInk,line width=0.20pt,fill=PhantomSlate!95!black] (0,0.0) ellipse (0.72 and 0.56); + \end{tikzpicture}% +} + +\newcommand{\roboticonraw}{% + \begin{tikzpicture}[x=0.9ex,y=0.9ex] + \draw[PhantomInk,line width=0.20pt,rounded corners=0.35ex,fill=PhantomPeach] (-0.95,-0.78) rectangle (0.95,0.72); + \draw[PhantomInk,line width=0.20pt,fill=white] (-0.42,0.08) circle (0.21); + \draw[PhantomInk,line width=0.20pt,fill=white] (0.42,0.08) circle (0.21); + \fill[PhantomInk] (-0.42,0.08) circle (0.07); + \fill[PhantomInk] (0.42,0.08) circle (0.07); + \draw[PhantomInk,line width=0.20pt] (-0.30,-0.30) -- (0.30,-0.30); + \draw[PhantomInk,line width=0.20pt] (0,0.72) -- (0,1.03); + \fill[PhantomIndigo] (0,1.15) circle (0.10); + \end{tikzpicture}% +} + +\newcommand{\humanicon}{\raisebox{-0.45ex}{\humaniconraw}\xspace} +\newcommand{\roboticon}{\raisebox{-0.45ex}{\roboticonraw}\xspace} +\newcommand{\usersagentslabel}{Users \humanicon + agents \roboticon} +\newcommand{\humanagentpair}{\humanicon, \roboticon} +\newcommand{\humanagentmix}{\humanicon/\roboticon} + \begin{document} { @@ -129,6 +159,71 @@ \stagebar{1} \end{frame} +\begin{frame}{Motivation: one everyday pricing story} + \footnotesize + \begin{columns}[T,onlytextwidth] + \column{0.53\textwidth} + \begin{block}{Imagine you sell weekend hotel rooms online} + A customer asks an assistant to scout many quotes first, then buys in a clean session at the best discovered price. + \end{block} + \begin{alertblock}{Why this matters to everyday people} + If this behavior is untreated, honest shoppers can face noisier prices and a weaker shopping experience because pricing reacts to manipulated intent signals. + \end{alertblock} + + \column{0.44\textwidth} + \centering + \begin{tikzpicture}[ + font=\scriptsize\sffamily, + card/.style={draw=PhantomInk,rounded corners=5pt,minimum width=3.8cm,minimum height=1.0cm,align=center}, + flow/.style={-{Stealth[length=2.2mm]},thick,PhantomSlate} + ] + \node[card,fill=PhantomCyan!15] (seller) at (0,1.55) {Seller posts rooms}; + \node[card,fill=white] (recon) at (0,0.2) {Recon by agent \roboticon}; + \node[card,fill=PhantomIndigo!12] (buy) at (0,-1.15) {Purchase by user \humanicon}; + \draw[flow] (seller) -- (recon); + \draw[flow] (recon) -- (buy); + \node[font=\tiny\itshape,text=PhantomSlate] at (0,-1.95) {query and purchase split across sessions}; + \end{tikzpicture} + \end{columns} + + \vspace{-0.15em} + {\scriptsize\textbf{Takeaway:} protect legitimate shoppers \humanicon while detecting orchestrated recon \roboticon before pricing leakage compounds.} + \stagebar{1} +\end{frame} + +\begin{frame}{Policy first: one rule maps context into price actions} + \begin{columns}[T,onlytextwidth] + \column{0.55\textwidth} + \begin{block}{Policy definition} + \[ + p_t = \pi(x_t) + \] + where context \(x_t\) includes product state, time, and behavior signals from the session. + \end{block} + \begin{itemize}[<+->] + \item Behavior proxy \(\hat q\) is tracked for both user-like and agent-like sessions \((\humanagentpair)\). + \item The score \(f(\tau')\) is a soft estimate that a trajectory is agent-mediated \roboticon. + \item We see reward only for the chosen price action, which motivates a contextual-bandit view first. + \end{itemize} + + \column{0.43\textwidth} + \centering + \begin{tikzpicture}[ + font=\scriptsize\sffamily, + box/.style={draw=PhantomInk,rounded corners=4pt,minimum width=3.35cm,minimum height=0.85cm,align=center}, + flow/.style={-{Stealth[length=2.0mm]},thick,PhantomSlate} + ] + \node[box,fill=white] (ctx) at (0,1.35) {Context \(x_t\)}; + \node[box,fill=PhantomIndigo!12] (pol) at (0,0.15) {Policy \(\pi\)}; + \node[box,fill=PhantomCyan!15] (act) at (0,-1.05) {Price action \(p_t\)}; + \draw[flow] (ctx) -- (pol); + \draw[flow] (pol) -- (act); + \node[font=\tiny\itshape,text=PhantomSlate] at (0,-1.75) {later extended from contextual bandits to DR-RL}; + \end{tikzpicture} + \end{columns} + \stagebar{1} +\end{frame} + \begin{frame}{Agentic recon creates direct financial pressure on pricing power} \centering \begin{tikzpicture}[ @@ -138,44 +233,101 @@ ] \path[use as bounding box] (-6.1,-1.25) rectangle (6.1,2.25); \node<1->[flow,fill=PhantomCyan!18] (recon) at (-3.1,1.1) - {\textbf{Recon session}\\samples multiple quotes}; + {\textbf{Recon session \roboticon}\\samples multiple quotes}; \node<2->[flow,fill=PhantomIndigo!16] (buy) at (3.1,1.1) - {\textbf{Clean execution session}\\buys using the best found quote}; + {\textbf{Clean execution session \humanicon}\\buys using the best found quote}; \draw<2->[-{Stealth[length=3mm]},ultra thick,PhantomSlate] (recon.east) -- (buy.west); \node<2->[font=\scriptsize\bfseries,text=PhantomSlate] at (0,1.98) {query and purchase are decoupled}; \draw<3->[densely dashed,thick,PhantomCyan!90!black] (recon.south east) .. controls +(1.15,-0.95) and +(-1.15,-0.95) .. (buy.south west); \node<3->[note] at (0,-0.65) - {The platform sees behavior proxy $\hat q$, while true demand response $d(p\mid\theta)$ stays latent.}; + {The platform sees behavior proxy $\hat q$ (\humanagentpair), while true demand response $d(p\mid\theta)$ stays latent.}; \end{tikzpicture} - \vspace{0.25em} - \begin{tikzpicture}[font=\scriptsize\sffamily, - card/.style={draw=PhantomInk,rounded corners=4pt,minimum width=3.85cm,text width=3.55cm,minimum height=1.4cm,align=center}] - \path[use as bounding box] (-6.05,-0.95) rectangle (6.05,0.95); - \node<4->[card,fill=PhantomInk,text=white] at (-4.05,0) - {\large$\mathrm{COI}(\pi)=\mathbb{E}[P]-\underline p$\\[-0.05em]\footnotesize pricing power KPI}; - \node<5->[card,fill=PhantomCyan!16,text=PhantomSlate] at (0,0) - {\Large\bfseries$-9{,}014$\\[-0.05em]\footnotesize revenue units\\per +0.1 contamination}; - \node<6->[card,fill=PhantomIndigo!12,text=PhantomSlate] at (4.05,0) - {\large$\lim_{N\to\infty}\mathrm{COI}=0$\\[-0.05em]\footnotesize theorem as intuition guide}; - \end{tikzpicture} + \vspace{0.05em} + \begin{columns}[T,onlytextwidth] + \column{0.31\textwidth} + \uncover<4->{% + \centering + \begin{tikzpicture}[font=\scriptsize\sffamily] + \node[draw=PhantomInk,rounded corners=4pt,fill=PhantomInk,text=white,minimum width=0.97\linewidth,text width=0.84\linewidth,minimum height=1.2cm,align=center] + {\large$\mathrm{COI}(\pi)=\mathbb{E}[P]-\underline p$\\[-0.05em]\footnotesize pricing power KPI}; + \end{tikzpicture}% + } - \vspace{0.15em} - \uncover<6->{\scriptsize\textit{The theorem is used to guide intuition: independent reconnaissance pressure can drive realizable prices toward the floor.}}\\[0.2em] - \uncover<7->{\footnotesize\textbf{Implication:} most production dynamic pricing stacks are not yet ready for AI-agent traffic; when quote discovery and purchase split, session-based pricing overestimates willingness to pay.} + \column{0.31\textwidth} + \uncover<5->{% + \centering + \begin{tikzpicture}[font=\scriptsize\sffamily] + \node[draw=PhantomInk,rounded corners=4pt,fill=PhantomIndigo!12,text=PhantomSlate,minimum width=0.97\linewidth,text width=0.84\linewidth,minimum height=1.2cm,align=center] + {\large$\lim_{N\to\infty}\mathrm{COI}=0$\\[-0.05em]\footnotesize theorem as intuition guide}; + \end{tikzpicture}% + } + + \column{0.34\textwidth} + \uncover<6->{% + \centering + \begin{tikzpicture}[x=0.67cm,y=0.85cm,font=\scriptsize\sffamily] + \draw[->,thick,PhantomSlate] (0,0) -- (4.2,0) node[right] {queries $N$}; + \draw[->,thick,PhantomSlate] (0,0) -- (0,2.05) node[above] {COI}; + \draw[very thick,PhantomCyan!95!black] (0.25,1.8) .. controls (1.2,1.35) and (2.25,0.62) .. (4.0,0.16); + \draw[dashed,PhantomInk!65] (0,0.16) -- (4.0,0.16); + \node[anchor=west,font=\tiny,text=PhantomSlate] at (2.35,0.28) {price-floor proximity}; + \end{tikzpicture}% + } + \end{columns} + + \vspace{-0.1em} + \uncover<6->{\scriptsize\textit{The theorem gives direction, not prophecy: more independent recon pressure pushes realizable prices toward the floor.}}\\[0.1em] + \uncover<7->{\scriptsize\textbf{Implication:} when quote discovery and purchase split, session-based pricing can overestimate willingness to pay.} \stagebar{1} \end{frame} \begin{frame}{The thesis answers one chain: mechanism \(\to\) signal \(\to\) control} - \begin{enumerate}[<+->]\setlength{\itemsep}{0.45em} - \item Can agent and human sessions be reliably distinguished from behavioral interaction signals alone? - \item How do agents affect prices and revenue that can be generated? - \item Can we make new policies that maintain margin in agent contaminated systems? - \end{enumerate} + \begin{columns}[T,onlytextwidth] + \column{0.32\textwidth} + \centering + \begin{tikzpicture}[font=\scriptsize\sffamily] + \draw[rounded corners=4pt,draw=PhantomInk,fill=white] (-1.55,-1.1) rectangle (1.55,1.2); + \fill[PhantomCyan!85!black] (-0.75,0.35) circle (0.14); + \fill[PhantomCyan!85!black] (-0.45,0.70) circle (0.14); + \fill[PhantomCyan!85!black] (-0.15,0.45) circle (0.14); + \fill[PhantomIndigo!85!black] (0.35,-0.20) circle (0.14); + \fill[PhantomIndigo!85!black] (0.65,-0.45) circle (0.14); + \fill[PhantomIndigo!85!black] (0.95,-0.15) circle (0.14); + \draw[dashed,PhantomInk!60] (0.12,-0.92) -- (0.12,1.0); + \node[text=PhantomSlate,font=\tiny] at (0,-0.93) {behavior separability}; + \end{tikzpicture} + {\footnotesize\textbf{SQ1}}\\[-0.15em] + {\scriptsize Can we distinguish \humanicon and \roboticon sessions from interactions alone?} - \vspace{0.35em} + \column{0.32\textwidth} + \centering + \begin{tikzpicture}[font=\scriptsize\sffamily] + \draw[rounded corners=4pt,draw=PhantomInk,fill=white] (-1.55,-1.1) rectangle (1.55,1.2); + \draw[->,thick,PhantomSlate] (-1.2,-0.75) -- (1.2,-0.75); + \draw[->,thick,PhantomSlate] (-1.2,-0.75) -- (-1.2,0.85); + \draw[very thick,PhantomCyan!95!black] (-1.0,0.62) .. controls (-0.4,0.2) and (0.3,-0.18) .. (1.0,-0.58); + \node[text=PhantomSlate,font=\tiny] at (0,-0.95) {COI / revenue pressure}; + \end{tikzpicture} + {\footnotesize\textbf{SQ2}}\\[-0.15em] + {\scriptsize How strong is price and revenue erosion under agentic contamination?} + + \column{0.32\textwidth} + \centering + \begin{tikzpicture}[font=\scriptsize\sffamily] + \draw[rounded corners=4pt,draw=PhantomInk,fill=white] (-1.55,-1.1) rectangle (1.55,1.2); + \draw[thick,fill=PhantomIndigo!20,draw=PhantomInk] (0,0.82) -- (0.98,0.32) -- (0.98,-0.44) -- (0,-0.90) -- (-0.98,-0.44) -- (-0.98,0.32) -- cycle; + \draw[thick,PhantomInk] (0,-0.46) -- (0,0.38); + \draw[thick,PhantomInk] (0,-0.46) -- (0.42,-0.08); + \node[text=PhantomSlate,font=\tiny] at (0,-0.95) {robust policy control}; + \end{tikzpicture} + {\footnotesize\textbf{SQ3}}\\[-0.15em] + {\scriptsize Can policy design recover margin while keeping UX stable?} + \end{columns} + + \vspace{0.2em} \stagebar{1} \end{frame} @@ -188,12 +340,12 @@ box/.style={draw=PhantomInk,rounded corners=3pt,minimum width=2.5cm,minimum height=0.9cm,align=center}, arr/.style={-{Stealth[length=2.2mm]},thick,PhantomSlate} ] - \node[box,fill=PhantomCyan!14] (actors) at (0,1.45) {Humans + Agents}; - \node[box,fill=white] (web) at (2.9,1.45) {Next.js\\storefront}; - \node[box,fill=white] (provider) at (5.8,1.45) {Pricing\\provider}; - \node[box,fill=white] (redis) at (8.7,1.45) {Redis\\serve layer}; - \node[box,fill=PhantomIndigo!10,minimum width=3.1cm] (kafka) at (4.35,-0.15) {Kafka topics\\behavior + price logs}; - \node[box,fill=PhantomCyan!10,minimum width=2.8cm] (airflow) at (8.0,-0.15) {Airflow + worker\\batch updates}; + \node[box,fill=PhantomCyan!14] (actors) at (0,1.45) {\usersagentslabel}; + \node[box,fill=white] (web) at (2.9,1.45) {Web\\storefront}; + \node[box,fill=white] (provider) at (5.8,1.45) {Pricing\\service}; + \node[box,fill=white] (redis) at (8.7,1.45) {Serve\\cache}; + \node[box,fill=PhantomIndigo!10,minimum width=3.1cm] (kafka) at (4.35,-0.15) {Event stream\\behavior + quote logs}; + \node[box,fill=PhantomCyan!10,minimum width=2.8cm] (airflow) at (8.0,-0.15) {Offline trainer\\batch updates}; \draw[arr] (actors) -- (web); \draw[arr] (web) -- (provider); @@ -357,7 +509,7 @@ \vspace{0.25em} \begin{itemize} - \item<3-> The signed gap $g(\tau')$ is positive when a session is closer to agent behavior. + \item<3-> The signed gap $g(\tau')$ is positive when a session is closer to agent behavior \roboticon (vs. human reference \humanicon). \item<4-> Temperature $T$ calibrates how sharply the score moves away from uncertainty. \item<6-> Continuous scoring is used to steer contamination-aware pricing. \item<7-> The design target is guidance, not a hard user-level ban decision. @@ -466,7 +618,7 @@ \vspace{0.25em} \begin{itemize} - \item<2-> Baseline experiments use a query-tax leakage surrogate for tractability. + \item<2-> Baseline experiments use a query-tax leakage surrogate where higher $f(\tau')$ \roboticon increases leakage penalty. \item<3-> Supra-competitive anchor penalties are tracked as an additional safety rail. \end{itemize} \stagebar{4} diff --git a/paper/defense/defense_appendix.tex b/paper/defense/defense_appendix.tex index abc8ded..3fdab31 100644 --- a/paper/defense/defense_appendix.tex +++ b/paper/defense/defense_appendix.tex @@ -30,9 +30,9 @@ \scriptsize \begin{align*} \tau_s &= (e_{s,1},\ldots,e_{s,L_s}) && \text{session} \\ - \hat{q}_{t,i} &= \sum_{s\in S_t}\sum_k \omega(a_{s,k})\,\mathbf{1}[i_{s,k}=i] && \text{proxy} \\ + \hat{q}_{t,i} &= \sum_{s\in S_t}\sum_k \omega(a_{s,k})\,\mathbf{1}[i_{s,k}=i] && \text{proxy }(\humanagentpair) \\ Q(p) &= (1-\alpha)\,\mathbb{E}_{\theta\sim D_H}[d(p;\theta)] \\ - &\quad + \alpha\,\mathbb{E}_{\theta\sim D_A}[d(p;\theta)] + \epsilon_t && \text{mixture} \\ + &\quad + \alpha\,\mathbb{E}_{\theta\sim D_A}[d(p;\theta)] + \epsilon_t && \text{mixture of }\humanagentmix \\ \mathrm{COI}(\pi) &= \mathbb{E}[P]-\underline{p} && \text{COI} \end{align*} \end{frame} @@ -63,7 +63,7 @@ \hat{q}_{t,i}=\sum_{s\in S_t}\sum_{k=1}^{L_s} \omega(a_{s,k})\,\mathbf{1}[i_{s,k}=i] \] \begin{alertblock}{Key distinction} - \(\hat{q}\) is an operational sensor from logs; true demand \(d(p;\theta)\) stays latent. Pricing reacts to \(\hat{q}\), so agent-shaped behavior poisons the signal. + \(\hat{q}\) is an operational sensor from logs (\humanagentpair); true demand \(d(p;\theta)\) stays latent. Pricing reacts to \(\hat{q}\), so agent-shaped behavior can poison the signal. \end{alertblock} \end{frame} @@ -286,21 +286,63 @@ \end{alertblock} \end{frame} -\begin{frame}{Appendix: Stackelberg timing (words)} - \begin{itemize} - \item Leader: platform sets price vector given current state and policy. - \item Follower: demand proxy updates from simulated trajectories drawn from \(\mathcal{G}(\alpha)\) and kernels \((\hat{T}_H,\hat{T}_A)\). - \item \textbf{Limbo} buffer stores alternating moves for a clean game history; relaxing strict alternation is listed future work. - \end{itemize} +\begin{frame}{Appendix: why a Stackelberg game is a useful abstraction} + \footnotesize + \begin{columns}[T,onlytextwidth] + \column{0.52\textwidth} + \begin{itemize} + \item \textbf{Leader move}: the platform commits a quote via policy \(p_t=\pi(x_t)\). + \item \textbf{Follower move}: session behavior then reacts (click, continue, abandon, purchase). + \item This ordering matches real serving APIs: price is emitted before response is observed. + \item Repeating this local sequence gives a tractable leader-follower control model. + \end{itemize} + + \column{0.44\textwidth} + \centering + \begin{tikzpicture}[ + font=\scriptsize\sffamily, + box/.style={draw=PhantomInk,rounded corners=4pt,minimum width=3.45cm,minimum height=0.9cm,align=center}, + arr/.style={-{Stealth[length=2.0mm]},thick,PhantomSlate} + ] + \node[box,fill=PhantomCyan!14] (l) at (0,1.2) {Leader: pricing policy}; + \node[box,fill=white] (f) at (0,-0.05) {Follower: session response}; + \node[box,fill=PhantomIndigo!10] (u) at (0,-1.3) {State update \& next round}; + \draw[arr] (l) -- node[right,font=\tiny] {quote} (f); + \draw[arr] (f) -- node[right,font=\tiny] {events} (u); + \draw[arr] (u.west) to[bend left=35] node[left,font=\tiny] {context} (l.west); + \end{tikzpicture} + \end{columns} + \begin{alertblock}{Boundary} + We do \textbf{not} claim a full market equilibrium. We claim a useful timing model for explainable policy updates under contamination. + \end{alertblock} \end{frame} -\begin{frame}{Appendix: three layers of evidence} +\begin{frame}{Appendix: why Theorem 1 helps (without over-claiming)} \footnotesize - \begin{description} - \item[Theorem 1] Formal COI erosion under independence and fixed-offer assumptions. - \item[Simulator] Dynamic, adaptive pricing and contamination sweeps (different status). - \item[Implementation] Local-$\alpha$ robust training; spirit of DRO without claiming a full numerical Wasserstein solver. - \end{description} + \begin{columns}[T,onlytextwidth] + \column{0.48\textwidth} + \begin{block}{What the theorem gives us} + \begin{itemize} + \item A directional mechanism: independent recon pressure compresses COI. + \item A sanity check for reward design: leakage penalties should grow with recon likelihood. + \item A clean explanatory anchor for stakeholders and governance review. + \end{itemize} + \end{block} + + \column{0.48\textwidth} + \begin{alertblock}{What the theorem does not claim} + \begin{itemize} + \item It is not a finite-sample forecast for every market. + \item It does not cover collusion or all adaptive adversaries. + \item It does not replace simulator evidence or offline policy validation. + \end{itemize} + \end{alertblock} + \end{columns} + + \vspace{0.2em} + \begin{block}{Three evidence layers used in this thesis} + \textbf{Theorem 1} (mechanism direction) \(\rightarrow\) \textbf{simulator} (finite-regime quantification) \(\rightarrow\) \textbf{implementation} (local robust policy training). + \end{block} \end{frame} \begin{frame}{Appendix: composite strip (five plots, small multiples)} diff --git a/scripts/nx_research.sh b/scripts/nx_research.sh index 4cc39ee..6460703 100644 --- a/scripts/nx_research.sh +++ b/scripts/nx_research.sh @@ -120,8 +120,8 @@ case "$cmd" in python3 - <<'PY' from pathlib import Path -skip = {"node_modules", ".venv", "venv"} -exts = {".ts", ".py"} +skip = {"node_modules", ".venv", "venv", ".venv-ray"} +exts = {".ts", ".py", ".ipynb"} total = 0 for path in Path(".").rglob("*"): if not path.is_file() or path.suffix not in exts or any(part in skip for part in path.parts):