% Owner: Agent 10 (Stage E writing). Every generated exhibit is \input exactly once in the prose at the anchor % where it is discussed; please do not add a second \input of the same float (duplicate labels). — 2026-11-05 % ============================================================================ \begin{appendices} \crefalias{section}{appendix} % cleveref: refer to appendix sections as ``Appendix E'', not ``Section E'' % ============================================================================ \section{Taxonomy}\label{app:taxonomy} \input{tables/tab_taxonomy} \section{Extraction contract}\label{app:prompt} The system prompt below is reproduced from \texttt{spid/extract/llm.py} with the \SPIDtaxonomyN\ taxonomy codes and labels substituted exactly as the code does (generated by \texttt{code/make\_tables.py}; never retyped). The user message is the string ``\texttt{SECTION: }'' followed by the focused section text (\Cref{sec:focus}), cut at \SPIDuserMessageCap\ characters. Decoding parameters: temperature 0, JSON-object response format (valid JSON is guaranteed; the field list is not enforced by a schema), \SPIDcompletionTokens\ completion tokens, \SPIDretries\ attempts before an empty list is returned, \SPIDtimeoutSeconds-second timeout, no \texttt{seed}. The model identifier is not recorded in the ledger or the logs (\Cref{sec:versioning}). Straight quotes are rendered as sent. \input{tables/prompt_verbatim} \noindent The candidate gate is the case-insensitive regular expression below, reproduced from \texttt{spid/extract/rules.py} (\SPIDgateRegexAlternatives\ alternatives, \SPIDgateRegexLength\ characters, compiled with \texttt{\SPIDgateRegexFlags}); line breaks are inserted for display only. Sections without a match, or with fewer than \SPIDminWords\ words, are not submitted; sections with fewer than \SPIDminWords\ words are not ledgered either, except the \SPIDbackfilledUnderThirtyWords\ June rows backfilled without the filter. \input{tables/gate_regex} \section{Data dictionary and data-model audit}\label{app:dictionary} \Cref{tab:datamodel} lists the tables required by the research-design specification against the current implementation (generated from \texttt{data/datamodel\_audit.csv}). The full field-level dictionary of the current tables is maintained in \texttt{docs/data\_dictionary.md} of the working-paper folder and in the repository documentation; \texttt{amount\_raw} is documented there as a formatted copy of \texttt{amount\_usd}, not as a source string. % longtable generated by code/make_tables.py \input{tables/tab_datamodel} \section{Evidence register}\label{app:evidence} {\footnotesize \begin{longtable}{@{}>{\raggedright\arraybackslash}p{9.5cm}>{\raggedright\arraybackslash}p{6.5cm}@{}} \caption{Evidence register: status of the main claims of this paper at revision \texttt{2324b58} after the Stage D audits}\label{tab:evidence}\\ \toprule Claim & Status \\ \midrule \endfirsthead \multicolumn{2}{@{}l}{\footnotesize\itshape Evidence register (continued)}\\ \toprule Claim & Status \\ \midrule \endhead \midrule \multicolumn{2}{@{}r@{}}{\footnotesize\itshape continued on the next page}\\ \endfoot \bottomrule \endlastfoot Universe of \SPIDuniverseN\ issuers built from the IWV holdings file (\SPIDiwvHoldingsDate) and the S\&P~500 cache (\SPIDspWikipediaDate); covers \SPIDrussellProxyCoveragePct\% of the index constituent count & Implemented; derived artefacts verified and hashed; source holdings and ticker files not archived; index count read from the factsheet \\ \SPIDfilingsTotal\ primary documents of Forms 10-K/10-Q/8-K since 2010 downloaded; \SPIDfilingsNotParsed\ not parsed (\SPIDfilingsMissingOnDisk\ missing on disk) & Implemented, verified (database counts; accession list published) \\ Acquisition respected the SEC rate limit (aggregate token bucket; no 403 recorded) & Implemented; documented from run notes; orchestrator logs not archived \\ \SPIDsectionsTotal\ sections, \SPIDchunks\ chunks and embeddings; factor panels for \SPIDannualPanelFirms\ issuers & Implemented, verified (database counts) \\ \SPIDledgerTotal\ sections ledgered; \SPIDgatePassTotal\ calls; outage rows removed reconcile with the log & Implemented, verified (gate recomputed; log reconciled) \\ Ledger free of failed-call artefacts & Not verified: \SPIDllmFailedJsonDecodeError\ silent failures outside the outage; first post-outage batch (\SPIDresumeBatchSections\ sections) suspect; re-submission not authorised \\ Two runs under one prompt text & File-system evidence only (modification times, two-line diff between October revisions); no June revision, no model identifier or prompt hash in the ledger \\ \SPIDmentions\ stored mentions (\SPIDledgerMentionsReturned\ returned; \SPIDcollisionMentions\ lost to identifier collisions), \SPIDprojectCountCurrentKey\ projects under the current key, graph of \SPIDkgNodes\ nodes & Implemented, verified; project count depends on the key (\SPIDprojectsKeyTypeDropped--\SPIDprojectsKeyStrict); representative fields depend on tie order \\ Structured fields of each mention grounded in its source section & Measured for all mentions: \SPIDgroundAllPct\% fully grounded (years \SPIDgroundYearsPct\%, partners \SPIDgroundPartnersPct\%, amounts \SPIDgroundAmountNumberPct\%, locations \SPIDgroundLocationsPct\%, technologies \SPIDgroundTechPct\%); transcription, not correctness \\ Description grounded in the passage & Documented (prompt rule); not mechanically checkable (no span stored) \\ What the model was shown & Measured for every ledgered section (median \SPIDmdnaShownMedianPct\% of a 10-K MD\&A; \SPIDmentionsFromLtTwentyFivePct\% of mentions from sections shown $<$ 25\%); recall bound \SPIDrulesFocusRecoveredPct\% \\ Category consistent with an external classification & Measured for 8-Ks as a consistency proxy (Item~2.01 $\to$ \texttt{ma\_integration} \SPIDbenchMaGivenTwoOhOne; Item~2.05 $\to$ \texttt{cost\_reduction} \SPIDbenchCostGivenTwoOhFive); not precision or recall \\ Agreement with a rule-based baseline & Measured on a weighted sample of \SPIDrulesSampleProductive\ + \SPIDrulesSampleZero\ sections (rules flag \SPIDrulesGivenLlmPct\% of model-productive sections); neither is a ground truth \\ Financing instruments and Item~2 swaps as false-positive classes & Measured by pattern (\SPIDfinMentionsPct\% of mentions; \SPIDswapCandidates\ swap candidates); not annotated \\ Extraction precision/recall, category accuracy, field accuracy, calibration & Not measured; frame drawn and weighted ($n = \SPIDannNProductive + \SPIDannNZero$), protocol published, labels pending (author task) \\ Linkage precision/recall of the resolution key & Not measured; over-merge indicators measured (\Cref{sec:resolution_rule}); audit protocol specified \\ Stability under re-submission, prompt paraphrase and model substitution & Not measured; protocol specified; requires model calls not authorised \\ Amounts typed and separated from realized expenditure & Not implemented (proposed); \texttt{amount\_raw} is a formatted float; tail audited (\SPIDamountGeFiftyBMentions\ mentions $\geq$ 50 B USD) \\ Dated project events and point-in-time revision flags & Not implemented (mention-level timeline only) \\ Release of the derived tables; licence & Author decisions pending \\ Author order, affiliations and CRediT contributions & Pending confirmation by the three coauthors \\ \end{longtable} \noindent\footnotesize Notes: ``Measured'' entries refer to the read-only audits of \texttt{code/audit/} whose outputs are in \texttt{results/} with a manifest (script hash, database sizes and modification times, row counts); none involved a model call. ``Verified'' means recomputed from the exported data or the databases; ``documented'' means stated by the code or the run notes without an independent check.\par} \section{The two extraction runs}\label{app:runs} \paragraph{Git and file-system evidence.} The repository holds \SPIDrepoCommits\ commits, all dated October~27--28, 2026 (\texttt{results/runs/git\_evidence.md}); \texttt{project-db/} enters at the first commit. The extractor modules carry modification times of \SPIDextractorMtimeDate\ and SHA-256 hashes recorded in \texttt{code/audit/spid\_snapshot/SHA256SUMS}; the driver files were edited on October~27, 2026 before the first commit. The diff between the revision the earlier version called ``the June revision'' (\texttt{df7905d}, dated October~27) and the build revision \texttt{2324b58} on the extractor, parser and driver files is the following change to \texttt{store.py}: \lstinputlisting{../results/runs/git_diff_df7905d_2324b58.patch} \noindent The diff from the first commit (\texttt{0304133}) to \texttt{2324b58} on the same files adds the following change to the corpus-layer \texttt{filing\_parser.py} (the patch repeats the \texttt{store.py} lines above): \lstinputlisting{../results/runs/git_diff_0304133_2324b58.patch} \paragraph{Mentions and projects by cohort, run and form.} \Cref{tab:june_october} reconciles the mentions of the S\&P~500 cohort (\texttt{in\_sp500} true) and of the Russell-only cohort by run and form; the June block is identified by the backfill timestamp. The S\&P~500 cohort's 10-Q mentions come from both runs for the same issuers, which permits a within-issuer comparison. Pooled over the cohort's 10-Q ledger rows, the productive share is \SPIDwithinProductiveJune\% in June and \SPIDwithinProductiveOctober\% in October; on the \SPIDpairedIssuers\ issuers with 10-Qs in both runs, the per-issuer means are \SPIDpairedProductiveJune\% and \SPIDpairedProductiveOctober\% (paired difference \SPIDpairedDeltaPp\ percentage points, standard error \SPIDpairedSePp). The cohort is the same in both files (\texttt{in\_sp500} of the issuer), but \Cref{tab:june_october} counts stored mentions whereas the within-cohort files sum the ledger's mention counts, which exceed the stored ones by the identifier collisions of \Cref{sec:ledger}. Mentions per row are \SPIDwithinMentionsPerRowJune\ and \SPIDwithinMentionsPerRowOctober, mean confidence \SPIDwithinConfJune\ and \SPIDwithinConfOctober, and the M\&A share \SPIDwithinMaShareJune\% and \SPIDwithinMaShareOctober\% (\texttt{results/runs/within\_sp500\_*.csv}). For 10-Qs, whose text went through the same parser in both runs, the two runs therefore behave alike; the cohort difference of \Cref{sec:time} comes from the volume of sections and from the 10-K segmenter, not from the extractor. \input{tables/tab_june_october} \paragraph{Fiscal year.} \texttt{fiscal\_year} is empty for \SPIDfiscalYearNullMentions\ mentions because the corresponding \SPIDfiscalYearNullFilings\ filings carry no fiscal year in the corpus layer; a derived fill from the report or filing date is exported for \SPIDfiscalYearFillAccessions\ accessions (\texttt{results/runs/fiscal\_year\_fill\_by\_accession.csv}) and is not stored in the database. \section{Additional tables}\label{app:tables} \input{tables/tab_universe_artefacts} \input{tables/tab_coverage_year} \input{tables/tab_timeseries_cohort} \input{tables/tab_top_issuers} \input{tables/tab_confidence} \input{tables/tab_graph} \input{tables/tab_top_name_tokens} \input{tables/tab_overmerge} \section{Stage D audit exhibits}\label{app:audit} The exhibits generated from the read-only audits of this revision (\texttt{code/audit/}, outputs in \texttt{results/}) are placed in the sections that discuss them: the ledger and outage reconciliation in \Cref{sec:ledger} (\Cref{tab:ledger_calls,tab:outage}), the focus-window coverage in \Cref{sec:focus} (\Cref{tab:focus,fig:focus}), the financing class in \Cref{sec:construct_def} (\Cref{tab:fp_classes}), the specification curve in \Cref{sec:speccurve} (\Cref{tab:spec_curve,fig:spec_curve}), the cohort regression in \Cref{sec:time} (\Cref{tab:cohort}), the grounding, 8-K consistency and rules-baseline results in \Cref{sec:val_mechanical} (\Cref{tab:grounding,fig:grounding,tab:benchmark_8k,tab:rules_agreement}), and the universe artefacts, cohort reconciliation, time series, name tokens and over-merge indicators in \Cref{app:runs,app:tables}. \section{Replication}\label{app:replication} \begin{enumerate} \item Clone the repository at revision \texttt{2324b58} and create the Python environment from the lock files shipped with the paper (\texttt{.python-version} = \SPIDpythonVersion; \texttt{requirements.lock}, \SPIDrequirementsLockPackages\ packages from the master node, including DuckDB \SPIDduckdbVersion, pyarrow, lxml and sentence-transformers; \texttt{environment.md} records the hardware). The exhibit environment of the paper is pinned separately in \texttt{reproducibility/environment/}. \item \texttt{python scripts/build\_universe.py} rebuilds \texttt{data/metadata/universe.json} from a \emph{current} download of the holdings and ticker files, which will not reproduce the October 2026 snapshot; the frozen artefacts used here are kept with the paper (\texttt{data/metadata/}, SHA-256 in \texttt{SHA256SUMS}) and must be used instead. \item \texttt{python scripts/download\_filings.py -{}-universe -{}-rate 9} downloads the corpus (idempotent; about \SPIDrawGb~GB; \SPIDacqHours\ hours at two IP addresses in October 2026). The cluster orchestration used for the October 2026 build is in \texttt{scripts/cluster/}. \item \texttt{python scripts/build\_database.py}, \texttt{parse\_filings.py}, \texttt{build\_embeddings.py}, \texttt{build\_factors.py} build the corpus layer; \texttt{export\_shard.py}/\texttt{merge\_shards.py} are needed only for a distributed build. The S\&P~500 10-K items of the June 2026 block cannot be rebuilt by this path (\Cref{sec:segmenters}). \item In \texttt{project-db/}: \texttt{python -m spid pending} reports the sections to be extracted and the estimated cost; \texttt{python run\_full\_extract.py -{}-workers \SPIDworkers} runs the extraction against the ledger (a re-run is not expected to return identical mentions; \Cref{sec:contract}); \texttt{python -m spid resolve graph embed analytics} builds the project layer (representative fields depend on tie order; \Cref{sec:resolution_rule}). \item In the working-paper folder: \texttt{./run\_all.sh} regenerates every table, figure and inline number from \texttt{data/} and \texttt{results/} and runs the \SPIDtestsN\ checks of \texttt{tests/}; \texttt{./run\_all.sh -{}-with-node} first re-runs \texttt{code/export\_stats.py} read-only on the master node, and \texttt{-{}-with-audit} re-runs the Stage D audits of \texttt{code/audit/} (read-only connections, temporary tables only, seed \SPIDannSeed). \texttt{latexmk} in \texttt{paper/} compiles the manuscript. \end{enumerate} \end{appendices}