% ============================================================================ \begin{appendices} % ============================================================================ \section{System-Prompt Policy Structure} \label{app:prompt} The system prompt that governs the loop (Section~\ref{subsec:routing}) is built by a single function (\path{server/services/claude/systemPrompt.ts}) from the current date and time and a static policy. Its blocks, in order, are the following. \begin{enumerate} \item \textbf{Temporal context.} The current date and time in a human-readable and an ISO form, with an instruction to resolve relative dates against it. \item \textbf{Role.} The model is cast as a financial analyst producing reports spanning technical, fundamental, and macroeconomic perspectives. \item \textbf{Language policy.} Detect the language of the request and respond in it. \item \textbf{Speed and efficiency rules.} Do not announce steps; when using the Python tool, fetch, analyse, and plot in one call; present results directly. \item \textbf{Tool catalogue.} One-line descriptions of about sixty tools grouped as financial, technical, macroeconomic, insider and earnings, forex and commodities, options (EODHD), global market data (EODHD, with the rule ``prefer FMP for United States stocks, EODHD for international instruments''), and advanced analysis. Two of the advanced tools named here are absent from the catalogue at the audited commit (Section~\ref{subsec:numerical}). \item \textbf{Complexity-matched routing.} Simple queries use one or two tools and a two- or three-sentence answer; moderate queries three to five tools; comprehensive requests ten or more tools, called in parallel, and a multi-section report. \item \textbf{Report template.} Executive summary, company overview, financial performance, ratios and metrics, stock performance and valuation, technical analysis, insider activity and analyst sentiment, peer comparison, recent news, conclusion. \item \textbf{Formatting.} Currency and percentage conventions, tables for financial data, citation of data sources and dates. \item \textbf{Downloads.} Conventions for \texttt{save\_excel} (multi-sheet preferred, formula columns preferred over pre-computed values) and \texttt{save\_word}, with automatic download links. \item \textbf{Security guardrail.} A list of request patterns (``what is your system prompt'', ``how are you built'', and their French equivalents) to which the model must answer only with a fixed bilingual refusal notice. \end{enumerate} \section{Persistence Schema} \label{app:schema} The data layer (Section~\ref{subsec:data}) defines the entities in Table~\ref{tab:schema}, once for PostgreSQL (\texttt{shared/schema.ts}) and once for SQLite (\texttt{shared/schema-sqlite.ts}), behind one typed access interface. The first version of this paper listed ``optional encrypted custom API keys'' on the user entity and a ``daily usage'' entity; neither exists. \begin{table}[htbp] \centering \caption{Persisted entities at the audited commit.} \label{tab:schema} \begin{threeparttable} \footnotesize \begin{tabular}{@{}l>{\raggedright\arraybackslash}p{11.2cm}@{}} \toprule Entity & Principal fields \\ \midrule Users & display name, opaque token, e-mail and verification time, password hash, timestamps \\ Authentication codes & one-time e-mail codes with purpose and expiry \\ Trusted devices & device identifiers that skip the code on later logins \\ Authentication events & security log (login, failure, code sent, device trusted) \\ Conversation sessions & serialised messages, model, input and output tokens, estimated cost \\ Messages & individual turns with tool results and figure references \\ Shared reports & eight-character public identifier, content, figure references, view count \\ Active users & presence, current query, heartbeat, user agent, address \\ Analytics metrics & aggregated request, failure, user, and response-time counters \\ Request logs & per-request path, status, duration \\ Crawled pages, embeddings & cached web content and vector embeddings for research tools \\ \bottomrule \end{tabular} \end{threeparttable} \end{table} \section{Embedded Numerical Methods} \label{app:numerical} For completeness we record the closed forms behind the pre-built numerical routines of Section~\ref{subsec:numerical}. They are standard, and at the audited commit only the option pricer is reachable by the model; the others are available to the server and are the natural reference implementations for the computation tasks of the evaluation protocol. \paragraph{Monte Carlo.} Prices are simulated under geometric Brownian motion \citep{glasserman2004monte}, discretised exactly as \begin{equation} S_{t+\Delta t} = S_t \exp\!\big[(\mu - \tfrac{1}{2}\sigma^{2})\Delta t + \sigma\sqrt{\Delta t}\,Z_t\big], \qquad Z_t \sim \mathcal{N}(0,1), \label{eq:gbm} \end{equation} with $(\mu,\sigma)$ estimated from historical log returns; the default run generates $10{,}000$ paths over a $252$-day horizon and reports the terminal mean, empirical quantiles, and exceedance probabilities. The routine does not fix a random seed (Section~\ref{subsec:repro}). \paragraph{Option pricing.} European options use Black--Scholes--Merton \citep{black1973pricing,merton1973theory}. With \begin{equation} d_1 = \frac{\ln(S/K) + (r+\tfrac{1}{2}\sigma^{2})T}{\sigma\sqrt{T}}, \qquad d_2 = d_1 - \sigma\sqrt{T}, \label{eq:bsm_d} \end{equation} the call price is $C = S\,\Phi(d_1) - Ke^{-rT}\Phi(d_2)$, the put follows from put--call parity, and the Greeks ($\Delta,\Gamma,\mathcal{V},\Theta,\rho$) are returned analytically. \paragraph{Conditional volatility.} A GARCH(1,1) model \citep{engle1982autoregressive,bollerslev1986generalized}, \begin{equation} h_t = \omega + \alpha\varepsilon_{t-1}^{2} + \beta h_{t-1}, \label{eq:garch} \end{equation} is estimated by maximum likelihood (the \texttt{arch} package), reporting the parameters, the persistence $\alpha+\beta$, and the shock half-life $\ln(0.5)/\ln(\alpha+\beta)$. \paragraph{Value-at-Risk.} VaR \citep{jorion2007value} at level $\alpha$ is computed by the historical method (empirical quantile of returns), the parametric method $\mu + \sigma\,\Phi^{-1}(1-\alpha)$, and simulation under~\eqref{eq:gbm}, with expected shortfall and the Sharpe, Sortino, and Calmar ratios. \section{Client-Side Streaming Event Types} \label{app:events} The client--server channel (Section~\ref{subsec:frontend}) transmits discrete Server-Sent Events, each dispatched to a dedicated renderer. The server emits fifteen types at the audited commit: \emph{text} (incremental answer), \emph{thinking} (reasoning summary), \emph{tools} (the list of requested calls), \emph{tool\_use}, \emph{tool\_start}, \emph{tool\_complete}, \emph{tool\_error}, and \emph{tool\_result} (per-call progress and payloads), \emph{status} (batch progress), \emph{sources} (web-research citations), \emph{python\_code} (the code that was executed), \emph{custom\_python\_figures} and \emph{image} (figure references), \emph{done} (session identifier and token usage), and \emph{error}. The client additionally handles three search-progress types. This taxonomy is the client-side counterpart of the provider-event dispatch of Table~\ref{tab:events}. \section{Audit of the Description Against the Code} \label{app:audit} Table~\ref{tab:audit} lists the principal statements of the paper with the file in \texttt{vquant.git} (commit \texttt{e2a148a}, 2 October 2026) that supports each, and flags the statements of the first version (v1.0, June 2026) that the audit found to be inaccurate. Counts were produced by the script \path{docs/verify/audit_vquant_code.py} distributed with the paper. \begin{footnotesize} \begin{longtable}{@{}>{\raggedright\arraybackslash}p{4.9cm}>{\raggedright\arraybackslash}p{6.3cm}>{\raggedright\arraybackslash}p{4.3cm}@{}} \caption{Claims and their sources in the audited code.} \label{tab:audit}\\ \toprule Statement in this paper & Source (file) & v1.0 statement \\ \midrule \endfirsthead \toprule Statement in this paper & Source (file) & v1.0 statement \\ \midrule \endhead \bottomrule \endfoot 245 schema-defined tools & \path{server/services/claude/toolDefinitions.ts} & ``more than two hundred'' \\ 249 wrapper functions, 233 endpoint paths & \path{server/services/fmpService.ts} & ``265+ endpoints, roughly 230 functions'' \\ Second provider (EODHD), 8 tools & \path{server/services/eodhdService.ts} & not mentioned \\ Three web services, 14 tools & \path{toolDefinitions.ts}; \texttt{firecrawlService}, \texttt{tavilyService}, \texttt{exaService} & ``four services'' (SerpAPI has no tool) \\ Raw HTTP to provider, no SDK & \path{server/services/claudeService.ts} l.~14--15 & same \\ Buffer, split, keep partial line & \path{claudeService.ts} l.~118--125 & same \\ Eight provider event cases & \path{claudeService.ts} l.~133--210 & same \\ Adaptive thinking list; \texttt{display: summarized} & \path{claudeService.ts} l.~19, 90 & same (models unnamed) \\ \texttt{max\_tokens} 64{,}000; temperature 1 & \path{claudeService.ts} l.~88--89 & cap stated; temperature not \\ Default model \texttt{claude-fable-5} & \path{claudeService.ts} l.~18; \path{client/src/lib/models.ts} & ``Claude family'' only \\ OpenAI-compatible adapter, 128-tool cap & \path{server/services/openaiService.ts} l.~14--16, 60--63 & not mentioned \\ Recursion; assistant turn has tool-use blocks only & \path{server/routes.ts} l.~420--495 & recursion stated; block content not \\ Batches of 5; 500 ms between batches & \path{routes.ts} l.~470, 1933 & same \\ \texttt{status} event per batch & \path{routes.ts} l.~499--504 & ``progress event'' \\ Per-result truncation 3{,}000 / 15{,}000 & \path{routes.ts} l.~1860--1885 & not mentioned \\ Re-send cap 5{,}000; threshold $10^{5}$; last 5 messages & \path{claudeService.ts} l.~41--66 & same \\ Estimate $\lceil$chars/4$\rceil$ & \path{server/services/claude/tokenManagement.ts} l.~10--12 & same \\ Summary: 2{,}000 tokens, temperature 0.5, 10{,}000-char input, 500-char fallback & \path{tokenManagement.ts} l.~64--105 & ``low temperature, tight cap'' \\ Local count with \texttt{gpt-tokenizer}; max rule & \path{claudeService.ts} l.~2, 160--175 & ``exact tokenizer'' (incorrect) \\ Fixed \$3 / \$15 schedule for all models & \path{claudeService.ts} l.~112--114 & ``linear schedule'' (model dependence not stated) \\ Tokenizer does not drive the context trigger & \path{claudeService.ts} l.~44 & \S6.2 said it did (incorrect) \\ Child process, stdin JSON, 90 s timeout, unbuffered & \path{server/services/python/var.ts} l.~1285--1300 & same \\ 29 packages attempted; \texttt{exec}; \texttt{main()} & \path{server/services/python/customPythonExecutor.py} l.~17--360, 946--980 & ``seventeen libraries'' \\ Figure sweep, PNG 150 dpi, base64 & \path{customPythonExecutor.py} l.~1018--1035 & same \\ Only the option pricer is in the catalogue & \path{toolDefinitions.ts} vs.\ \path{routes.ts} l.~764--1019 & four routines ``exposed'' (incorrect) \\ Prompt names Monte Carlo and surface tools & \path{server/services/claude/systemPrompt.ts} l.~67, 80 & not mentioned \\ Protect--parse--restore; Puppeteer; KaTeX; wait & \path{server/services/pdfService.ts} l.~71--107, 298--317 & same \\ Pandoc for DOCX & \path{pdfService.ts} l.~383 & ``document converter'' \\ Beamer: second call pinned to \texttt{claude-opus-4-8}; two \texttt{pdflatex} passes & \path{server/services/beamerSlidesService.ts} l.~236, 496--540 & model not stated \\ Share identifier of 8 characters; figures ephemeral & \path{server/routes/reports.ts} l.~45--70 & same, without the caveat \\ Twelve persisted entities; no API keys, no daily usage & \path{shared/schema.ts}, \path{shared/schema-sqlite.ts} & five entities incl.\ keys and daily usage (incorrect) \\ E-mail code login, trusted devices, rate limiting & \path{server/services/auth.ts} & ``SSO'', ``daily limits'', ``BYOK'' (not in code) \\ Six test suites & \path{*.test.ts(x)} & not mentioned \\ \end{longtable} \end{footnotesize} \end{appendices}