ci: a gate that can fail, and the 24 papers it catches

`make -k all` returned 0 over any number of broken papers, so CI was green the
whole time it existed. Four things had to be true for that:

  - every recipe line ended in `|| true` and the rule printed "FAIL" instead of
    exiting, so make never saw a failure;
  - nonstopmode emits a PDF for almost any input, so "the PDF exists" is not
    the same question as "the paper compiled" — zen-nano_whitepaper produced
    one through 23 LaTeX errors;
  - pdfs/ was tracked, so a checkout handed the "check every paper came out"
    step 100 of the PDFs it was about to look for;
  - discovery was three wildcards, so 69 of the repo's 219 papers were
    compiled by nothing at all, defense/ by a second copy of the same
    swallowing loop written inline in ci.yml.

The rule is now one latexmk per paper and its exit status is the gate:
-halt-on-error (no PDF from a broken paper), -bibtex (a declared bibliography
must resolve rather than being skipped when the .bib is absent), -Werror (an
undefined citation is a defect, not a log note), -cd (each paper compiles from
its own directory, so zen/ finds references.bib and defense/ finds
hanzo-defense.sty). .DELETE_ON_ERROR so a failed run leaves nothing behind,
and pdfs/ is untracked because it is output.

Run against the tree it was guarding, the honest gate fails 24 papers:

  6  \begin{itemize} with its backslash-b eaten, leaving a bare `egin{itemize}`
     and no \end — artist, designer-instruct, eco, nano, next, omni
  3  the same list with the opener deleted outright, so five \item stood in no
     environment — artist-edit, designer-thinking, scribe
  4  \and in a cover page's raw \@author: it expands to \end{tabular} and closed
     a tabular nothing had opened, and \thanks left hyperref pointing at a
     footnote anchor that was never created; plus five stray \end{table} at the
     end of those documents — director, foley, musician, video
  9  \color{gray} under \usepackage{color}, which defines eight names and not
     that one — xcolor is the superset the working papers already load
  6  \bibliography{references} naming a database that was never written, so
     every citation rendered [?] — zen/references.bib now holds all 27 works
  9  \bibliographystyle+\bibliography in papers with no \cite at all — dropped
  3  characters pdflatex has no glyph for: CO₂ -> CO\textsubscript{2},
     ↔ -> $\leftrightarrow$, Persian letters -> their code points, the
     SentencePiece marker -> \textvisiblespace
  1  \IF{...} \COMMENT{...}: algorithmic's \IF opens a list and the comment
     landed in it before any \item; the comment slot is \IF[...]{...}
  1  \ref{eq:anchor_update} to an equation the paper never writes

All 219 papers now compile from a clean tree: `make -k all` exits 0.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
zooqueen
2026-07-28 17:35:30 -07:00
co-authored by Hanzo Dev
parent 0bf688376a
commit 44ec401a31
292 changed files with 654 additions and 488 deletions
+4 -2
View File
@@ -19,8 +19,10 @@
# LaTeX temporary files
*.dvi
*.ps
# Compiled PDFs (optional - comment out if you want to track PDFs)
# *.pdf
# Build output. Tracking it made the CI gate vacuous: a checkout supplied
# the PDFs the gate was looking for, before anything was compiled.
pdfs/
# MacOS files
.DS_Store
# Editor files
+16 -51
View File
@@ -6,19 +6,27 @@ name: ci
# GitHub is a mirror now, so neither belongs here — the PDFs are the run's
# artifact and the site image bakes its own copies.
#
# The predecessor could not fail. Every rule in the Makefile ends in `|| true`
# and prints "FAIL" rather than exiting, so `make all` returned 0 with any
# number of papers missing. The compile is therefore run with -k (attempt every
# paper, do not stop at the first break) and the result is checked against
# `make manifest`, which is the Makefile's own ALL_PDFS — one definition of the
# paper set, read rather than restated.
# This could not fail, at four depths. Every rule in the Makefile ended in
# `|| true` and printed "FAIL" rather than exiting, so `make all` returned 0
# over any number of broken papers. The defense papers were compiled by a second
# copy of the same swallowing loop, written inline in this file. The step that
# checked the PDFs
# existed was satisfied by the 100 stale PDFs that used to be committed under
# pdfs/, which the checkout supplied before the build ran. And discovery covered
# only the root, zen/ and defense/, so 69 of the repo's 219 papers were compiled
# by nothing at all.
#
# So: pdfs/ is a build output and is no longer tracked, the Makefile discovers
# every .tex with a \documentclass, and `make -k all` is the whole gate — -k to
# attempt every paper rather than stopping at the first break, and a nonzero
# status if any of them did not come out.
on:
push:
branches: [main]
paths: ['**.tex', '**.bib', 'Makefile', '.hanzo/workflows/ci.yml']
paths: ['**.tex', '**.bib', '**.sty', 'Makefile', '.hanzo/workflows/ci.yml']
pull_request:
paths: ['**.tex', '**.bib', 'Makefile', '.hanzo/workflows/ci.yml']
paths: ['**.tex', '**.bib', '**.sty', 'Makefile', '.hanzo/workflows/ci.yml']
workflow_dispatch:
concurrency:
@@ -41,53 +49,10 @@ jobs:
- name: compile
run: make -k all
- name: compile defense papers
run: |
set -euo pipefail
mkdir -p pdfs/defense
cd defense
rc=0
for tex in *.tex; do
case "$tex" in
hanzo-defense.sty|logo-convert.tex) continue ;;
esac
name="${tex%.tex}"
echo "compiling defense/$tex"
pdflatex -interaction=nonstopmode "$tex" >/dev/null 2>&1 || true
bibtex "$name" >/dev/null 2>&1 || true
pdflatex -interaction=nonstopmode "$tex" >/dev/null 2>&1 || true
pdflatex -interaction=nonstopmode "$tex" >/dev/null 2>&1 || true
if [ -f "${name}.pdf" ]; then
mv "${name}.pdf" ../pdfs/defense/
echo " ok defense/${name}.pdf"
else
echo " fail defense/${name}.pdf"
rc=1
fi
rm -f ./*.aux ./*.log ./*.bbl ./*.blg ./*.out ./*.toc
done
exit "$rc"
- name: check every paper came out
run: |
set -euo pipefail
missing=0
while read -r pdf; do
[ -n "$pdf" ] || continue
if [ ! -f "$pdf" ]; then
echo "::error file=${pdf%.pdf}::did not compile: $pdf"
missing=$((missing + 1))
fi
done < <(make --no-print-directory manifest)
echo "missing: ${missing}"
[ "$missing" -eq 0 ]
# v3, NOT v4. This forge is Gitea, which presents as GHES, and the v4
# action refuses outright:
# @actions/artifact v2.0.0+, upload-artifact@v4+ and download-artifact@v4+
# are not currently supported on GHES
# Every paper compiled ("missing: 0") — this step alone failed the run, so
# the red badge was reporting an unusable action, not a broken paper.
- uses: actions/upload-artifact@v3
if: always()
with:
+222 -223
View File
@@ -2,227 +2,226 @@
Auto-generated catalogue of research papers. Regenerate: `scripts/gen-index.sh` (or `make index`).
| Paper | PDF | Path |
|-------|-----|------|
| `astle-reactive-sdk` | ✓ | `astle-reactive-sdk/astle-reactive-sdk.tex` |
| `cloud-unified-binary` | ✓ | `cloud-unified-binary/main.tex` |
| `code-trajectory` | ✓ | `code-trajectory/code-trajectory.tex` |
| `cover-hanzo` | ✓ | `cover-hanzo.tex` |
| `crowdstart-commerce` | ✓ | `crowdstart-commerce/crowdstart-commerce.tex` |
| `hanzo-agentic-ai` | ✓ | `defense/hanzo-agentic-ai.tex` |
| `hanzo-agentic-prowess` | ✓ | `defense/hanzo-agentic-prowess.tex` |
| `hanzo-assured-networking` | ✓ | `defense/hanzo-assured-networking.tex` |
| `hanzo-cloud-economics` | ✓ | `defense/hanzo-cloud-economics.tex` |
| `hanzo-compendium` | ✓ | `defense/hanzo-compendium.tex` |
| `hanzo-compliance` | ✓ | `defense/hanzo-compliance.tex` |
| `hanzo-countermeasures` | ✓ | `defense/hanzo-countermeasures.tex` |
| `hanzo-cross-domain` | ✓ | `defense/hanzo-cross-domain.tex` |
| `hanzo-edge-ai-ml` | ✓ | `defense/hanzo-edge-ai-ml.tex` |
| `hanzo-fhe-native` | ✓ | `defense/hanzo-fhe-native.tex` |
| `hanzo-formal-verification` | ✓ | `defense/hanzo-formal-verification.tex` |
| `hanzo-full-spectrum-cyber` | ✓ | `defense/hanzo-full-spectrum-cyber.tex` |
| `hanzo-overview` | ✓ | `defense/hanzo-overview.tex` |
| `hanzo-quantum-sensing-qkd` | ✓ | `defense/hanzo-quantum-sensing-qkd.tex` |
| `hanzo-security` | ✓ | `defense/hanzo-security.tex` |
| `hanzo-test-evaluation` | ✓ | `defense/hanzo-test-evaluation.tex` |
| `hanzo-vs-claude` | ✓ | `defense/hanzo-vs-claude.tex` |
| `hanzo-zap-protocol` | ✓ | `defense/hanzo-zap-protocol.tex` |
| `logo-convert` | — | `defense/logo-convert.tex` |
| `earle-genetic-marketing` | ✓ | `earle-genetic-marketing/earle-genetic-marketing.tex` |
| `enso` | ✓ | `enso/main.tex` |
| `evolutionary-schedule-search` | ✓ | `evolutionary-schedule-search.tex` |
| `hanzo-4-0-launch` | ✓ | `hanzo-4-0-launch/hanzo-4-0-launch.tex` |
| `hanzo-aci` | ✓ | `hanzo-aci/hanzo-aci.tex` |
| `hanzo-adversarial-mean-field-feedback` | ✓ | `hanzo-adversarial-mean-field-feedback.tex` |
| `hanzo-agent-grpo` | ✓ | `hanzo-agent-grpo/hanzo-agent-grpo.tex` |
| `hanzo-agent-sdk` | ✓ | `hanzo-agent-sdk/hanzo-agent-sdk.tex` |
| `hanzo-agi-platform` | ✓ | `hanzo-agi-platform/hanzo-agi-platform.tex` |
| `hanzo-ai-chain` | ✓ | `hanzo-ai-chain/hanzo-ai-chain.tex` |
| `hanzo-ai-cloud` | ✓ | `hanzo-ai-cloud/hanzo-ai-cloud.tex` |
| `hanzo-ai-commerce` | ✓ | `hanzo-ai-commerce/hanzo-ai-commerce.tex` |
| `hanzo-ai-safety` | ✓ | `hanzo-ai-safety/hanzo-ai-safety.tex` |
| `hanzo-analytics-ml` | ✓ | `hanzo-analytics-ml/hanzo-analytics-ml.tex` |
| `hanzo-api-gateway` | ✓ | `hanzo-api-gateway/hanzo-api-gateway.tex` |
| `hanzo-aso` | ✓ | `hanzo-aso/hanzo-aso.tex` |
| `hanzo-base-runtime` | ✓ | `hanzo-base-runtime/hanzo-base-runtime.tex` |
| `hanzo-bitexact-oracle` | ✓ | `hanzo-bitexact-oracle.tex` |
| `hanzo-blockchain-platform` | ✓ | `hanzo-blockchain-platform/hanzo-blockchain-platform.tex` |
| `hanzo-candle` | ✓ | `hanzo-candle/hanzo-candle.tex` |
| `hanzo-chat` | ✓ | `hanzo-chat/hanzo-chat.tex` |
| `hanzo-checkout` | ✓ | `hanzo-checkout/hanzo-checkout.tex` |
| `hanzo-cloud-infrastructure` | ✓ | `hanzo-cloud-infrastructure/hanzo-cloud-infrastructure.tex` |
| `hanzo-cloud-network-bench` | — | `hanzo-cloud-network-bench.tex` |
| `hanzo-collapse-methodology` | ✓ | `hanzo-collapse-methodology.tex` |
| `hanzo-commerce-payments` | ✓ | `hanzo-commerce-payments.tex` |
| `hanzo-comptime-autotune` | ✓ | `hanzo-comptime-autotune.tex` |
| `hanzo-consensus-ai` | ✓ | `hanzo-consensus-ai/hanzo-consensus-ai.tex` |
| `hanzo-consensus-plugin-platform` | — | `hanzo-consensus-plugin-platform/main.tex` |
| `hanzo-consensus-zap-compute` | ✓ | `hanzo-consensus-zap-compute.tex` |
| `hanzo-console-dashboard` | ✓ | `hanzo-console-dashboard.tex` |
| `hanzo-continuous-learning-privacy` | ✓ | `hanzo-continuous-learning-privacy.tex` |
| `hanzo-cross-backend-inference` | ✓ | `hanzo-cross-backend-inference.tex` |
| `hanzo-crypto-commerce-2018` | ✓ | `hanzo-crypto-commerce-2018/hanzo-crypto-commerce-2018.tex` |
| `hanzo-crypto-payments` | ✓ | `hanzo-crypto-payments/hanzo-crypto-payments.tex` |
| `hanzo-datastore` | — | `hanzo-datastore/hanzo-datastore.tex` |
| `hanzo-deepseek-v4-dspark` | — | `hanzo-deepseek-v4-dspark.tex` |
| `hanzo-digital-securities-integration` | ✓ | `hanzo-digital-securities-integration/hanzo-digital-securities-integration.tex` |
| `hanzo-distributed-decode-latency` | ✓ | `hanzo-distributed-decode-latency.tex` |
| `hanzo-distributed-open-problems` | ✓ | `hanzo-distributed-open-problems.tex` |
| `hanzo-dso` | ✓ | `hanzo-dso/hanzo-dso.tex` |
| `hanzo-edge-inference` | ✓ | `hanzo-edge-inference.tex` |
| `hanzo-encryption-security` | ✓ | `hanzo-encryption-security/hanzo-encryption-security.tex` |
| `hanzo-engine-ml` | ✓ | `hanzo-engine-ml.tex` |
| `hanzo-engine` | ✓ | `hanzo-engine/main.tex` |
| `hanzo-evolutionary-orchestration` | ✓ | `hanzo-evolutionary-orchestration.tex` |
| `hanzo-exchange-architecture` | ✓ | `hanzo-exchange-architecture/hanzo-exchange-architecture.tex` |
| `hanzo-federated-agents` | ✓ | `hanzo-federated-agents/hanzo-federated-agents.tex` |
| `hanzo-fhe-inference` | ✓ | `hanzo-fhe-inference/hanzo-fhe-inference.tex` |
| `hanzo-flow` | ✓ | `hanzo-flow/hanzo-flow.tex` |
| `hanzo-formal-verification` | ✓ | `hanzo-formal-verification/hanzo-formal-verification.tex` |
| `hanzo-fusion-is-composition` | ✓ | `hanzo-fusion-is-composition.tex` |
| `hanzo-gateway-krakend` | ✓ | `hanzo-gateway-krakend.tex` |
| `hanzo-generative-games` | ✓ | `hanzo-generative-games.tex` |
| `hanzo-gpu-inference` | ✓ | `hanzo-gpu-inference/hanzo-gpu-inference.tex` |
| `hanzo-harness-hacking` | ✓ | `hanzo-harness-hacking/hanzo-harness-hacking.tex` |
| `hanzo-heterogeneous-distributed-inference` | ✓ | `hanzo-heterogeneous-distributed-inference.tex` |
| `hanzo-hmm` | ✓ | `hanzo-hmm/hanzo-hmm.tex` |
| `hanzo-iam-platform` | ✓ | `hanzo-iam-platform.tex` |
| `hanzo-ico-infrastructure` | ✓ | `hanzo-ico-infrastructure/hanzo-ico-infrastructure.tex` |
| `hanzo-identity-nft` | ✓ | `hanzo-identity-nft/hanzo-identity-nft.tex` |
| `hanzo-inference-stack` | ✓ | `hanzo-inference-stack.tex` |
| `hanzo-ingress-proxy` | ✓ | `hanzo-ingress-proxy.tex` |
| `hanzo-insights-analytics` | ✓ | `hanzo-insights-analytics.tex` |
| `hanzo-int8-mmq-negative-result` | ✓ | `hanzo-int8-mmq-negative-result.tex` |
| `hanzo-intrinsic-islands` | ✓ | `hanzo-intrinsic-islands.tex` |
| `hanzo-jin-architecture` | ✓ | `hanzo-jin-architecture/hanzo-jin-architecture.tex` |
| `hanzo-jin` | ✓ | `hanzo-jin/hanzo-jin.tex` |
| `hanzo-kernel-dsl` | ✓ | `hanzo-kernel-dsl.tex` |
| `hanzo-kernel-optimization` | ✓ | `hanzo-kernel-optimization.tex` |
| `hanzo-kms-secrets` | ✓ | `hanzo-kms-secrets.tex` |
| `hanzo-ledger-finance` | ✓ | `hanzo-ledger-finance.tex` |
| `hanzo-llm-gateway` | ✓ | `hanzo-llm-gateway/hanzo-llm-gateway.tex` |
| `hanzo-longform-media` | ✓ | `hanzo-longform-media.tex` |
| `hanzo-mcp-server` | ✓ | `hanzo-mcp-server/hanzo-mcp-server.tex` |
| `hanzo-mean-field-alignment` | ✓ | `hanzo-mean-field-alignment.tex` |
| `hanzo-ml-framework` | ✓ | `hanzo-ml-framework/hanzo-ml-framework.tex` |
| `hanzo-native-stack-thesis` | ✓ | `hanzo-native-stack-thesis.tex` |
| `hanzo-native-training` | ✓ | `hanzo-native-training.tex` |
| `hanzo-network-architecture` | ✓ | `hanzo-network-architecture/hanzo-network-architecture.tex` |
| `hanzo-network-whitepaper` | ✓ | `hanzo-network-whitepaper.tex` |
| `hanzo-observability` | ✓ | `hanzo-observability/hanzo-observability.tex` |
| `hanzo-on-chain-commerce` | ✓ | `hanzo-on-chain-commerce/hanzo-on-chain-commerce.tex` |
| `hanzo-operative` | ✓ | `hanzo-operative/hanzo-operative.tex` |
| `hanzo-payments-platform` | ✓ | `hanzo-payments-platform/hanzo-payments-platform.tex` |
| `hanzo-platform-infra-desktop` | ✓ | `hanzo-platform-infra-desktop.tex` |
| `hanzo-platform` | ✓ | `hanzo-platform/hanzo-platform.tex` |
| `hanzo-pq-crypto` | ✓ | `hanzo-pq-crypto/hanzo-pq-crypto.tex` |
| `hanzo-pq-object-store` | — | `hanzo-pq-object-store.tex` |
| `hanzo-proof-of-ai` | ✓ | `hanzo-proof-of-ai/hanzo-proof-of-ai.tex` |
| `hanzo-pubsub-events` | ✓ | `hanzo-pubsub-events.tex` |
| `hanzo-rocm-inference` | ✓ | `hanzo-rocm-inference.tex` |
| `hanzo-router` | ✓ | `hanzo-router/main.tex` |
| `hanzo-sdk-ecosystem` | ✓ | `hanzo-sdk-ecosystem/hanzo-sdk-ecosystem.tex` |
| `hanzo-search` | ✓ | `hanzo-search/hanzo-search.tex` |
| `hanzo-self-improving-agents` | ✓ | `hanzo-self-improving-agents/hanzo-self-improving-agents.tex` |
| `hanzo-stack-comparison` | ✓ | `hanzo-stack-comparison/hanzo-stack-comparison.tex` |
| `hanzo-storage-s3` | ✓ | `hanzo-storage-s3.tex` |
| `hanzo-threshold-signing` | ✓ | `hanzo-threshold-signing/hanzo-threshold-signing.tex` |
| `hanzo-tokenomics` | ✓ | `hanzo-tokenomics/hanzo-tokenomics.tex` |
| `hanzo-unified-harness` | ✓ | `hanzo-unified-harness/hanzo-unified-harness.tex` |
| `hanzo-unified-tenant-cloud` | ✓ | `hanzo-unified-tenant-cloud.tex` |
| `hanzo-vector-search` | ✓ | `hanzo-vector-search.tex` |
| `hanzo-webhooks` | ✓ | `hanzo-webhooks/hanzo-webhooks.tex` |
| `hip-0302-replicate` | ✓ | `hip-0302-replicate/hip-0302-replicate.tex` |
| `lightspeed-dex` | ✓ | `lightspeed-dex/lightspeed-dex.tex` |
| `native-object-store-vfs` | ✓ | `native-object-store-vfs.tex` |
| `ntt-transform` | ✓ | `ntt-transform/ntt-transform.tex` |
| `refutation-driven-perf` | ✓ | `refutation-driven-perf.tex` |
| `verus-analytics` | ✓ | `verus-analytics/verus-analytics.tex` |
| `training-without-retention` | ✓ | `zen/training-without-retention.tex` |
| `zen_family_overview` | ✓ | `zen/zen_family_overview.tex` |
| `ZEN_WHITEPAPER_2025` | ✓ | `zen/ZEN_WHITEPAPER_2025.tex` |
| `zen-3d` | ✓ | `zen/zen-3d.tex` |
| `zen-agent-framework` | ✓ | `zen/zen-agent-framework.tex` |
| `zen-agent` | ✓ | `zen/zen-agent.tex` |
| `zen-alignment` | ✓ | `zen/zen-alignment.tex` |
| `zen-artist_whitepaper` | ✓ | `zen/zen-artist_whitepaper.tex` |
| `zen-artist-edit_whitepaper` | ✓ | `zen/zen-artist-edit_whitepaper.tex` |
| `zen-aso-protocol` | ✓ | `zen/zen-aso-protocol.tex` |
| `zen-audio-architecture` | ✓ | `zen/zen-audio-architecture.tex` |
| `zen-base_whitepaper` | ✓ | `zen/zen-base_whitepaper.tex` |
| `zen-benchmark-suite` | ✓ | `zen/zen-benchmark-suite.tex` |
| `zen-chain-of-thought` | ✓ | `zen/zen-chain-of-thought.tex` |
| `zen-code_whitepaper` | ✓ | `zen/zen-code_whitepaper.tex` |
| `zen-code-benchmarks` | ✓ | `zen/zen-code-benchmarks.tex` |
| `zen-coder_whitepaper` | ✓ | `zen/zen-coder_whitepaper.tex` |
| `zen-coder-flash_whitepaper` | ✓ | `zen/zen-coder-flash_whitepaper.tex` |
| `zen-context-extension` | ✓ | `zen/zen-context-extension.tex` |
| `zen-designer-instruct_whitepaper` | ✓ | `zen/zen-designer-instruct_whitepaper.tex` |
| `zen-designer-thinking_whitepaper` | ✓ | `zen/zen-designer-thinking_whitepaper.tex` |
| `zen-director` | ✓ | `zen/zen-director.tex` |
| `zen-distributed-training` | ✓ | `zen/zen-distributed-training.tex` |
| `zen-dso-protocol` | ✓ | `zen/zen-dso-protocol.tex` |
| `zen-dub_whitepaper` | ✓ | `zen/zen-dub_whitepaper.tex` |
| `zen-dub-live_whitepaper` | ✓ | `zen/zen-dub-live_whitepaper.tex` |
| `zen-eco_whitepaper` | ✓ | `zen/zen-eco_whitepaper.tex` |
| `zen-embeddings-retrieval` | ✓ | `zen/zen-embeddings-retrieval.tex` |
| `zen-enterprise-deployment` | ✓ | `zen/zen-enterprise-deployment.tex` |
| `zen-financial-ai` | ✓ | `zen/zen-financial-ai.tex` |
| `zen-finetuning` | ✓ | `zen/zen-finetuning.tex` |
| `zen-foley` | ✓ | `zen/zen-foley.tex` |
| `zen-guard_whitepaper` | ✓ | `zen/zen-guard_whitepaper.tex` |
| `zen-guard-gen_whitepaper` | ✓ | `zen/zen-guard-gen_whitepaper.tex` |
| `zen-guard-stream_whitepaper` | ✓ | `zen/zen-guard-stream_whitepaper.tex` |
| `zen-hallucination-reduction` | ✓ | `zen/zen-hallucination-reduction.tex` |
| `zen-hardware-optimization` | ✓ | `zen/zen-hardware-optimization.tex` |
| `zen-inference-optimization` | ✓ | `zen/zen-inference-optimization.tex` |
| `zen-knowledge-distillation` | ✓ | `zen/zen-knowledge-distillation.tex` |
| `zen-legal-ai` | ✓ | `zen/zen-legal-ai.tex` |
| `zen-live_whitepaper` | ✓ | `zen/zen-live_whitepaper.tex` |
| `zen-mathematical-reasoning` | ✓ | `zen/zen-mathematical-reasoning.tex` |
| `zen-max_whitepaper` | ✓ | `zen/zen-max_whitepaper.tex` |
| `zen-medical-ai` | ✓ | `zen/zen-medical-ai.tex` |
| `zen-medical` | ✓ | `zen/zen-medical.tex` |
| `zen-mixture-of-experts` | ✓ | `zen/zen-mixture-of-experts.tex` |
| `zen-multilingual` | ✓ | `zen/zen-multilingual.tex` |
| `zen-multimodal-architecture` | ✓ | `zen/zen-multimodal-architecture.tex` |
| `zen-musician` | ✓ | `zen/zen-musician.tex` |
| `zen-nano_whitepaper` | ✓ | `zen/zen-nano_whitepaper.tex` |
| `zen-next_whitepaper` | ✓ | `zen/zen-next_whitepaper.tex` |
| `zen-omni_whitepaper` | ✓ | `zen/zen-omni_whitepaper.tex` |
| `zen-privacy-federated` | ✓ | `zen/zen-privacy-federated.tex` |
| `zen-pro_whitepaper` | ✓ | `zen/zen-pro_whitepaper.tex` |
| `zen-quantization` | ✓ | `zen/zen-quantization.tex` |
| `zen-reasoning` | ✓ | `zen/zen-reasoning.tex` |
| `zen-reranker` | ✓ | `zen/zen-reranker.tex` |
| `zen-reward-modeling` | ✓ | `zen/zen-reward-modeling.tex` |
| `zen-safety-evaluation` | ✓ | `zen/zen-safety-evaluation.tex` |
| `zen-scribe_whitepaper` | ✓ | `zen/zen-scribe_whitepaper.tex` |
| `zen-synthetic-data` | ✓ | `zen/zen-synthetic-data.tex` |
| `zen-technical-paper` | ✓ | `zen/zen-technical-paper.tex` |
| `zen-training-methodology` | ✓ | `zen/zen-training-methodology.tex` |
| `zen-translator_whitepaper` | ✓ | `zen/zen-translator_whitepaper.tex` |
| `zen-translator` | ✓ | `zen/zen-translator.tex` |
| `zen-video-i2v_whitepaper` | ✓ | `zen/zen-video-i2v_whitepaper.tex` |
| `zen-video` | ✓ | `zen/zen-video.tex` |
| `zen-vision-architecture` | ✓ | `zen/zen-vision-architecture.tex` |
| `zen-vl_whitepaper` | ✓ | `zen/zen-vl_whitepaper.tex` |
| `zen-voice-clone` | ✓ | `zen/zen-voice-clone.tex` |
| `zen-voyager` | ✓ | `zen/zen-voyager.tex` |
| `zen-world` | ✓ | `zen/zen-world.tex` |
| `zen3-embedding_whitepaper` | ✓ | `zen/zen3-embedding_whitepaper.tex` |
| `zen3-guard_whitepaper` | ✓ | `zen/zen3-guard_whitepaper.tex` |
| `zen3-nano_whitepaper` | ✓ | `zen/zen3-nano_whitepaper.tex` |
| `zen3-omni_whitepaper` | ✓ | `zen/zen3-omni_whitepaper.tex` |
| `zen3-vl_whitepaper` | ✓ | `zen/zen3-vl_whitepaper.tex` |
| `zen4_whitepaper` | ✓ | `zen/zen4_whitepaper.tex` |
| `zen4-coder_whitepaper` | ✓ | `zen/zen4-coder_whitepaper.tex` |
| `zen4-coder-flash_whitepaper` | ✓ | `zen/zen4-coder-flash_whitepaper.tex` |
| `zen4-coder-pro_whitepaper` | ✓ | `zen/zen4-coder-pro_whitepaper.tex` |
| `zen4-max_whitepaper` | ✓ | `zen/zen4-max_whitepaper.tex` |
| `zen4-mini_whitepaper` | ✓ | `zen/zen4-mini_whitepaper.tex` |
| `zen4-pro_whitepaper` | ✓ | `zen/zen4-pro_whitepaper.tex` |
| `zen4-thinking_whitepaper` | ✓ | `zen/zen4-thinking_whitepaper.tex` |
| `zen4-ultra_whitepaper` | ✓ | `zen/zen4-ultra_whitepaper.tex` |
| Paper | Path |
|-------|------|
| `astle-reactive-sdk` | `astle-reactive-sdk/astle-reactive-sdk.tex` |
| `cloud-unified-binary` | `cloud-unified-binary/main.tex` |
| `code-trajectory` | `code-trajectory/code-trajectory.tex` |
| `cover-hanzo` | `cover-hanzo.tex` |
| `crowdstart-commerce` | `crowdstart-commerce/crowdstart-commerce.tex` |
| `hanzo-agentic-ai` | `defense/hanzo-agentic-ai.tex` |
| `hanzo-agentic-prowess` | `defense/hanzo-agentic-prowess.tex` |
| `hanzo-assured-networking` | `defense/hanzo-assured-networking.tex` |
| `hanzo-cloud-economics` | `defense/hanzo-cloud-economics.tex` |
| `hanzo-compendium` | `defense/hanzo-compendium.tex` |
| `hanzo-compliance` | `defense/hanzo-compliance.tex` |
| `hanzo-countermeasures` | `defense/hanzo-countermeasures.tex` |
| `hanzo-cross-domain` | `defense/hanzo-cross-domain.tex` |
| `hanzo-edge-ai-ml` | `defense/hanzo-edge-ai-ml.tex` |
| `hanzo-fhe-native` | `defense/hanzo-fhe-native.tex` |
| `hanzo-formal-verification` | `defense/hanzo-formal-verification.tex` |
| `hanzo-full-spectrum-cyber` | `defense/hanzo-full-spectrum-cyber.tex` |
| `hanzo-overview` | `defense/hanzo-overview.tex` |
| `hanzo-quantum-sensing-qkd` | `defense/hanzo-quantum-sensing-qkd.tex` |
| `hanzo-security` | `defense/hanzo-security.tex` |
| `hanzo-test-evaluation` | `defense/hanzo-test-evaluation.tex` |
| `hanzo-vs-claude` | `defense/hanzo-vs-claude.tex` |
| `hanzo-zap-protocol` | `defense/hanzo-zap-protocol.tex` |
| `earle-genetic-marketing` | `earle-genetic-marketing/earle-genetic-marketing.tex` |
| `enso` | `enso/main.tex` |
| `evolutionary-schedule-search` | `evolutionary-schedule-search.tex` |
| `hanzo-4-0-launch` | `hanzo-4-0-launch/hanzo-4-0-launch.tex` |
| `hanzo-aci` | `hanzo-aci/hanzo-aci.tex` |
| `hanzo-adversarial-mean-field-feedback` | `hanzo-adversarial-mean-field-feedback.tex` |
| `hanzo-agent-grpo` | `hanzo-agent-grpo/hanzo-agent-grpo.tex` |
| `hanzo-agent-sdk` | `hanzo-agent-sdk/hanzo-agent-sdk.tex` |
| `hanzo-agi-platform` | `hanzo-agi-platform/hanzo-agi-platform.tex` |
| `hanzo-ai-chain` | `hanzo-ai-chain/hanzo-ai-chain.tex` |
| `hanzo-ai-cloud` | `hanzo-ai-cloud/hanzo-ai-cloud.tex` |
| `hanzo-ai-commerce` | `hanzo-ai-commerce/hanzo-ai-commerce.tex` |
| `hanzo-ai-safety` | `hanzo-ai-safety/hanzo-ai-safety.tex` |
| `hanzo-analytics-ml` | `hanzo-analytics-ml/hanzo-analytics-ml.tex` |
| `hanzo-api-gateway` | `hanzo-api-gateway/hanzo-api-gateway.tex` |
| `hanzo-aso` | `hanzo-aso/hanzo-aso.tex` |
| `hanzo-base-runtime` | `hanzo-base-runtime/hanzo-base-runtime.tex` |
| `hanzo-bitexact-oracle` | `hanzo-bitexact-oracle.tex` |
| `hanzo-blockchain-platform` | `hanzo-blockchain-platform/hanzo-blockchain-platform.tex` |
| `hanzo-candle` | `hanzo-candle/hanzo-candle.tex` |
| `hanzo-chat` | `hanzo-chat/hanzo-chat.tex` |
| `hanzo-checkout` | `hanzo-checkout/hanzo-checkout.tex` |
| `hanzo-cloud-infrastructure` | `hanzo-cloud-infrastructure/hanzo-cloud-infrastructure.tex` |
| `hanzo-cloud-network-bench` | `hanzo-cloud-network-bench.tex` |
| `hanzo-collapse-methodology` | `hanzo-collapse-methodology.tex` |
| `hanzo-commerce-payments` | `hanzo-commerce-payments.tex` |
| `hanzo-comptime-autotune` | `hanzo-comptime-autotune.tex` |
| `hanzo-consensus-ai` | `hanzo-consensus-ai/hanzo-consensus-ai.tex` |
| `hanzo-consensus-plugin-platform` | `hanzo-consensus-plugin-platform/main.tex` |
| `hanzo-consensus-zap-compute` | `hanzo-consensus-zap-compute.tex` |
| `hanzo-console-dashboard` | `hanzo-console-dashboard.tex` |
| `hanzo-continuous-learning-privacy` | `hanzo-continuous-learning-privacy.tex` |
| `hanzo-cross-backend-inference` | `hanzo-cross-backend-inference.tex` |
| `hanzo-crypto-commerce-2018` | `hanzo-crypto-commerce-2018/hanzo-crypto-commerce-2018.tex` |
| `hanzo-crypto-payments` | `hanzo-crypto-payments/hanzo-crypto-payments.tex` |
| `hanzo-datastore` | `hanzo-datastore/hanzo-datastore.tex` |
| `hanzo-deepseek-v4-dspark` | `hanzo-deepseek-v4-dspark.tex` |
| `hanzo-digital-securities-integration` | `hanzo-digital-securities-integration/hanzo-digital-securities-integration.tex` |
| `hanzo-distributed-decode-latency` | `hanzo-distributed-decode-latency.tex` |
| `hanzo-distributed-open-problems` | `hanzo-distributed-open-problems.tex` |
| `hanzo-dso` | `hanzo-dso/hanzo-dso.tex` |
| `hanzo-edge-inference` | `hanzo-edge-inference.tex` |
| `hanzo-encryption-security` | `hanzo-encryption-security/hanzo-encryption-security.tex` |
| `hanzo-engine-ml` | `hanzo-engine-ml.tex` |
| `hanzo-engine` | `hanzo-engine/main.tex` |
| `hanzo-evolutionary-orchestration` | `hanzo-evolutionary-orchestration.tex` |
| `hanzo-exchange-architecture` | `hanzo-exchange-architecture/hanzo-exchange-architecture.tex` |
| `hanzo-federated-agents` | `hanzo-federated-agents/hanzo-federated-agents.tex` |
| `hanzo-fhe-inference` | `hanzo-fhe-inference/hanzo-fhe-inference.tex` |
| `hanzo-flow` | `hanzo-flow/hanzo-flow.tex` |
| `hanzo-formal-verification` | `hanzo-formal-verification/hanzo-formal-verification.tex` |
| `hanzo-fusion-is-composition` | `hanzo-fusion-is-composition.tex` |
| `hanzo-gateway-krakend` | `hanzo-gateway-krakend.tex` |
| `hanzo-generative-games` | `hanzo-generative-games.tex` |
| `hanzo-gpu-inference` | `hanzo-gpu-inference/hanzo-gpu-inference.tex` |
| `hanzo-harness-hacking` | `hanzo-harness-hacking/hanzo-harness-hacking.tex` |
| `hanzo-heterogeneous-distributed-inference` | `hanzo-heterogeneous-distributed-inference.tex` |
| `hanzo-hmm` | `hanzo-hmm/hanzo-hmm.tex` |
| `hanzo-iam-platform` | `hanzo-iam-platform.tex` |
| `hanzo-ico-infrastructure` | `hanzo-ico-infrastructure/hanzo-ico-infrastructure.tex` |
| `hanzo-identity-nft` | `hanzo-identity-nft/hanzo-identity-nft.tex` |
| `hanzo-inference-stack` | `hanzo-inference-stack.tex` |
| `hanzo-ingress-proxy` | `hanzo-ingress-proxy.tex` |
| `hanzo-insights-analytics` | `hanzo-insights-analytics.tex` |
| `hanzo-int8-mmq-negative-result` | `hanzo-int8-mmq-negative-result.tex` |
| `hanzo-intrinsic-islands` | `hanzo-intrinsic-islands.tex` |
| `hanzo-jin-architecture` | `hanzo-jin-architecture/hanzo-jin-architecture.tex` |
| `hanzo-jin` | `hanzo-jin/hanzo-jin.tex` |
| `hanzo-kernel-dsl` | `hanzo-kernel-dsl.tex` |
| `hanzo-kernel-optimization` | `hanzo-kernel-optimization.tex` |
| `hanzo-kms-secrets` | `hanzo-kms-secrets.tex` |
| `hanzo-ledger-finance` | `hanzo-ledger-finance.tex` |
| `hanzo-llm-gateway` | `hanzo-llm-gateway/hanzo-llm-gateway.tex` |
| `hanzo-longform-media` | `hanzo-longform-media.tex` |
| `hanzo-mcp-server` | `hanzo-mcp-server/hanzo-mcp-server.tex` |
| `hanzo-mean-field-alignment` | `hanzo-mean-field-alignment.tex` |
| `hanzo-ml-framework` | `hanzo-ml-framework/hanzo-ml-framework.tex` |
| `hanzo-native-stack-thesis` | `hanzo-native-stack-thesis.tex` |
| `hanzo-native-training` | `hanzo-native-training.tex` |
| `hanzo-network-architecture` | `hanzo-network-architecture/hanzo-network-architecture.tex` |
| `hanzo-network-whitepaper` | `hanzo-network-whitepaper.tex` |
| `hanzo-observability` | `hanzo-observability/hanzo-observability.tex` |
| `hanzo-on-chain-commerce` | `hanzo-on-chain-commerce/hanzo-on-chain-commerce.tex` |
| `hanzo-operative` | `hanzo-operative/hanzo-operative.tex` |
| `hanzo-payments-platform` | `hanzo-payments-platform/hanzo-payments-platform.tex` |
| `hanzo-platform-infra-desktop` | `hanzo-platform-infra-desktop.tex` |
| `hanzo-platform` | `hanzo-platform/hanzo-platform.tex` |
| `hanzo-pq-crypto` | `hanzo-pq-crypto/hanzo-pq-crypto.tex` |
| `hanzo-pq-object-store` | `hanzo-pq-object-store.tex` |
| `hanzo-proof-of-ai` | `hanzo-proof-of-ai/hanzo-proof-of-ai.tex` |
| `hanzo-pubsub-events` | `hanzo-pubsub-events.tex` |
| `hanzo-rocm-inference` | `hanzo-rocm-inference.tex` |
| `hanzo-router` | `hanzo-router/main.tex` |
| `hanzo-sdk-ecosystem` | `hanzo-sdk-ecosystem/hanzo-sdk-ecosystem.tex` |
| `hanzo-search` | `hanzo-search/hanzo-search.tex` |
| `hanzo-self-improving-agents` | `hanzo-self-improving-agents/hanzo-self-improving-agents.tex` |
| `hanzo-stack-comparison` | `hanzo-stack-comparison/hanzo-stack-comparison.tex` |
| `hanzo-storage-s3` | `hanzo-storage-s3.tex` |
| `hanzo-threshold-signing` | `hanzo-threshold-signing/hanzo-threshold-signing.tex` |
| `hanzo-tokenomics` | `hanzo-tokenomics/hanzo-tokenomics.tex` |
| `hanzo-unified-harness` | `hanzo-unified-harness/hanzo-unified-harness.tex` |
| `hanzo-unified-tenant-cloud` | `hanzo-unified-tenant-cloud.tex` |
| `hanzo-vector-search` | `hanzo-vector-search.tex` |
| `hanzo-webhooks` | `hanzo-webhooks/hanzo-webhooks.tex` |
| `hip-0302-replicate` | `hip-0302-replicate/hip-0302-replicate.tex` |
| `lightspeed-dex` | `lightspeed-dex/lightspeed-dex.tex` |
| `native-object-store-vfs` | `native-object-store-vfs.tex` |
| `ntt-transform` | `ntt-transform/ntt-transform.tex` |
| `refutation-driven-perf` | `refutation-driven-perf.tex` |
| `verus-analytics` | `verus-analytics/verus-analytics.tex` |
| `training-without-retention` | `zen/training-without-retention.tex` |
| `zen_family_overview` | `zen/zen_family_overview.tex` |
| `ZEN_WHITEPAPER_2025` | `zen/ZEN_WHITEPAPER_2025.tex` |
| `zen-3d` | `zen/zen-3d.tex` |
| `zen-agent-framework` | `zen/zen-agent-framework.tex` |
| `zen-agent` | `zen/zen-agent.tex` |
| `zen-alignment` | `zen/zen-alignment.tex` |
| `zen-artist_whitepaper` | `zen/zen-artist_whitepaper.tex` |
| `zen-artist-edit_whitepaper` | `zen/zen-artist-edit_whitepaper.tex` |
| `zen-aso-protocol` | `zen/zen-aso-protocol.tex` |
| `zen-audio-architecture` | `zen/zen-audio-architecture.tex` |
| `zen-base_whitepaper` | `zen/zen-base_whitepaper.tex` |
| `zen-benchmark-suite` | `zen/zen-benchmark-suite.tex` |
| `zen-chain-of-thought` | `zen/zen-chain-of-thought.tex` |
| `zen-code_whitepaper` | `zen/zen-code_whitepaper.tex` |
| `zen-code-benchmarks` | `zen/zen-code-benchmarks.tex` |
| `zen-coder_whitepaper` | `zen/zen-coder_whitepaper.tex` |
| `zen-coder-flash_whitepaper` | `zen/zen-coder-flash_whitepaper.tex` |
| `zen-context-extension` | `zen/zen-context-extension.tex` |
| `zen-designer-instruct_whitepaper` | `zen/zen-designer-instruct_whitepaper.tex` |
| `zen-designer-thinking_whitepaper` | `zen/zen-designer-thinking_whitepaper.tex` |
| `zen-director` | `zen/zen-director.tex` |
| `zen-distributed-training` | `zen/zen-distributed-training.tex` |
| `zen-dso-protocol` | `zen/zen-dso-protocol.tex` |
| `zen-dub_whitepaper` | `zen/zen-dub_whitepaper.tex` |
| `zen-dub-live_whitepaper` | `zen/zen-dub-live_whitepaper.tex` |
| `zen-eco_whitepaper` | `zen/zen-eco_whitepaper.tex` |
| `zen-embeddings-retrieval` | `zen/zen-embeddings-retrieval.tex` |
| `zen-enterprise-deployment` | `zen/zen-enterprise-deployment.tex` |
| `zen-financial-ai` | `zen/zen-financial-ai.tex` |
| `zen-finetuning` | `zen/zen-finetuning.tex` |
| `zen-foley` | `zen/zen-foley.tex` |
| `zen-guard_whitepaper` | `zen/zen-guard_whitepaper.tex` |
| `zen-guard-gen_whitepaper` | `zen/zen-guard-gen_whitepaper.tex` |
| `zen-guard-stream_whitepaper` | `zen/zen-guard-stream_whitepaper.tex` |
| `zen-hallucination-reduction` | `zen/zen-hallucination-reduction.tex` |
| `zen-hardware-optimization` | `zen/zen-hardware-optimization.tex` |
| `zen-inference-optimization` | `zen/zen-inference-optimization.tex` |
| `zen-knowledge-distillation` | `zen/zen-knowledge-distillation.tex` |
| `zen-legal-ai` | `zen/zen-legal-ai.tex` |
| `zen-live_whitepaper` | `zen/zen-live_whitepaper.tex` |
| `zen-mathematical-reasoning` | `zen/zen-mathematical-reasoning.tex` |
| `zen-max_whitepaper` | `zen/zen-max_whitepaper.tex` |
| `zen-medical-ai` | `zen/zen-medical-ai.tex` |
| `zen-medical` | `zen/zen-medical.tex` |
| `zen-mixture-of-experts` | `zen/zen-mixture-of-experts.tex` |
| `zen-multilingual` | `zen/zen-multilingual.tex` |
| `zen-multimodal-architecture` | `zen/zen-multimodal-architecture.tex` |
| `zen-musician` | `zen/zen-musician.tex` |
| `zen-nano_whitepaper` | `zen/zen-nano_whitepaper.tex` |
| `zen-next_whitepaper` | `zen/zen-next_whitepaper.tex` |
| `zen-omni_whitepaper` | `zen/zen-omni_whitepaper.tex` |
| `zen-privacy-federated` | `zen/zen-privacy-federated.tex` |
| `zen-pro_whitepaper` | `zen/zen-pro_whitepaper.tex` |
| `zen-quantization` | `zen/zen-quantization.tex` |
| `zen-reasoning` | `zen/zen-reasoning.tex` |
| `zen-reranker` | `zen/zen-reranker.tex` |
| `zen-reward-modeling` | `zen/zen-reward-modeling.tex` |
| `zen-safety-evaluation` | `zen/zen-safety-evaluation.tex` |
| `zen-scribe_whitepaper` | `zen/zen-scribe_whitepaper.tex` |
| `zen-synthetic-data` | `zen/zen-synthetic-data.tex` |
| `zen-technical-paper` | `zen/zen-technical-paper.tex` |
| `zen-training-methodology` | `zen/zen-training-methodology.tex` |
| `zen-translator_whitepaper` | `zen/zen-translator_whitepaper.tex` |
| `zen-translator` | `zen/zen-translator.tex` |
| `zen-video-i2v_whitepaper` | `zen/zen-video-i2v_whitepaper.tex` |
| `zen-video` | `zen/zen-video.tex` |
| `zen-vision-architecture` | `zen/zen-vision-architecture.tex` |
| `zen-vl_whitepaper` | `zen/zen-vl_whitepaper.tex` |
| `zen-voice-clone` | `zen/zen-voice-clone.tex` |
| `zen-voyager` | `zen/zen-voyager.tex` |
| `zen-world` | `zen/zen-world.tex` |
| `zen3-embedding_whitepaper` | `zen/zen3-embedding_whitepaper.tex` |
| `zen3-guard_whitepaper` | `zen/zen3-guard_whitepaper.tex` |
| `zen3-nano_whitepaper` | `zen/zen3-nano_whitepaper.tex` |
| `zen3-omni_whitepaper` | `zen/zen3-omni_whitepaper.tex` |
| `zen3-vl_whitepaper` | `zen/zen3-vl_whitepaper.tex` |
| `zen4_whitepaper` | `zen/zen4_whitepaper.tex` |
| `zen4-coder_whitepaper` | `zen/zen4-coder_whitepaper.tex` |
| `zen4-coder-flash_whitepaper` | `zen/zen4-coder-flash_whitepaper.tex` |
| `zen4-coder-pro_whitepaper` | `zen/zen4-coder-pro_whitepaper.tex` |
| `zen4-max_whitepaper` | `zen/zen4-max_whitepaper.tex` |
| `zen4-mini_whitepaper` | `zen/zen4-mini_whitepaper.tex` |
| `zen4-pro_whitepaper` | `zen/zen4-pro_whitepaper.tex` |
| `zen4-thinking_whitepaper` | `zen/zen4-thinking_whitepaper.tex` |
| `zen4-ultra_whitepaper` | `zen/zen4-ultra_whitepaper.tex` |
**Total**: 220 papers, 214 with compiled PDFs
**Total**: 219 papers
+29 -11
View File
@@ -1,8 +1,8 @@
# Papers
Hanzo's research papers: LaTeX sources at the repo root and in `zen/` and
`defense/`, compiled PDFs under `pdfs/`, indexed by `INDEX.md`, and the site at
https://papers.hanzo.ai built from `site/`.
`defense/`, built to `pdfs/` by `make -k all`, indexed by `INDEX.md`, and the
site at https://papers.hanzo.ai built from `site/`.
## How this ships
@@ -45,17 +45,35 @@ directory.
## What ci.yml checks
`make -k all` compiles all 131 discovered papers, `-k` so one broken paper does
not hide the rest, then the gate asserts every expected PDF exists.
`make -k all` compiles all 219 papers in the repo and that is the entire gate.
`-k` so one broken paper does not hide the rest; a nonzero status if any of them
did not come out. A paper is any `.tex` with a `\documentclass`, wherever it
lives — one definition, in the `Makefile`, which `scripts/gen-index.sh` reads
rather than restates.
The predecessor could not fail. Every rule in the `Makefile` ends in `|| true`
and prints `FAIL` instead of exiting, so `make all` returned 0 no matter how many
papers were missing. The gate reads `make manifest` — the Makefile's own
`ALL_PDFS` — so the paper set has one definition and the check cannot drift from
the build.
A paper compiles when `latexmk` says so. The rule runs it once per paper with
`-halt-on-error` (stop at the first error rather than nonstopmode's "carry on and
emit a PDF anyway"), `-bibtex` (a declared bibliography must resolve, rather than
being silently skipped when the `.bib` is absent), `-Werror` (an undefined
citation or cross-reference is a defect in a paper, not a note in a log nobody
reads) and `-cd` (each paper compiles from its own directory, so its relative
paths mean to make what they mean to a human reading the file).
Adding a paper therefore requires it to compile: drop `foo.tex` at the root or in
`zen/`, and `pdfs/foo.pdf` is expected from then on.
**The gate this replaced could not fail, at four depths.** Every rule in the
`Makefile` ended in `|| true` and printed `FAIL` instead of exiting, so
`make all` returned 0 over any number of broken papers. The `defense/` papers
were compiled by a second copy of the same swallowing loop, written inline in
`ci.yml`. The step that checked the PDFs existed was satisfied by the 100 stale
PDFs that used to be committed under `pdfs/` — the checkout handed the gate its
answer before anything was compiled. And discovery was three wildcards over the
root, `zen/` and `defense/`, so 69 of the 219 papers were compiled by nothing at
all. Run against the tree it was guarding, the honest gate fails 24 papers.
`pdfs/` is therefore a build output and is no longer tracked.
Adding a paper requires it to compile: drop a `.tex` with a `\documentclass`
anywhere but `sections/`, `shared/`, `site/` or `pdfs/`, and its PDF is expected
from then on.
`ci.yml` does not write to the repo. The predecessor pushed a `v<run_number>`
GitHub Release and committed the PDFs back to `main`; both wrote to what is now a
+65 -48
View File
@@ -1,60 +1,90 @@
# Makefile for Hanzo Papers
# Compiles all standalone .tex papers (with \documentclass) to PDF.
# Excludes sections/*.tex (included fragments, no \documentclass).
# Compiles every standalone .tex paper in the repo to a PDF under pdfs/.
#
# Usage:
# make all # Build all 42 papers
# make pdfs/hanzo-aso.pdf # Build one root paper
# make pdfs/zen/zen-coder_whitepaper.pdf # Build one zen paper
# make -k all # Build every paper, report all failures
# make pdfs/hanzo-aso.pdf # Build one paper
# make list # Every paper, one path per line
# make clean # Remove aux files
# make clean-all # Remove aux + PDFs
#
# A paper that does not compile fails. Every recipe line here used to end in
# `|| true` and the rule printed "FAIL" instead of exiting, so `make all`
# returned 0 over any number of broken papers — the gate in
# .hanzo/workflows/ci.yml was green for as long as it existed. Use -k to build
# the rest after one breaks; that is what -k is for, and it is the only reason
# the old rule had to swallow the status.
#
# Docker (no local TeX install needed):
# docker run --rm -v "$$PWD:/workdir" -w /workdir texlive/texlive:latest make all
# docker run --rm -v "$$PWD:/workdir" -w /workdir texlive/texlive:latest make -k all
# Discover standalone .tex files (root + zen/, exclude sections/)
ROOT_TEX := $(wildcard *.tex)
ZEN_TEX := $(wildcard zen/*.tex)
ALL_TEX := $(ROOT_TEX) $(ZEN_TEX)
# A paper is any .tex with a \documentclass, wherever it lives. This is the one
# definition of the paper set; scripts/gen-index.sh reads it from here rather
# than restating it. Excluded: sections/ and shared/ hold fragments with no
# \documentclass of their own, site/ is the website, pdfs/ is output, and
# defense/logo-convert.tex is a helper that rasterises the logo through inkscape.
#
# The previous discovery was three wildcards over the root, zen/ and defense/,
# which is 150 of the 219 papers in the repo. The other 69 live in per-paper
# directories and were compiled by nothing.
ALL_TEX := $(shell grep -rl '^\\documentclass' --include='*.tex' . \
| sed 's|^\./||' \
| grep -v -e '^sections/' -e '/sections/' -e '^shared/' -e '^site/' \
-e '^pdfs/' -e 'node_modules/' -e '^defense/logo-convert\.tex$$' \
| sort)
# Map to output PDFs under pdfs/
ALL_PDFS := $(patsubst %.tex,pdfs/%.pdf,$(ALL_TEX))
# A recipe that exits nonzero leaves no PDF behind, so a stale artifact can
# never stand in for a build that did not happen.
.DELETE_ON_ERROR:
# Default: build everything
.PHONY: all
all: $(ALL_PDFS)
@echo ""
@echo "=== Build complete ==="
@echo "Papers compiled: $(words $(ALL_PDFS))"
@echo ""
@find pdfs -name '*.pdf' | sort
# Rule for root-level papers: pdfs/foo.pdf from foo.tex
# Build in-place (not -output-directory) so shared/ sty resolves correctly
# One paper, one rule, wherever it lives. latexmk decides how many passes are
# needed and runs bibtex; its exit status is the answer to "did this paper
# compile?", which is the whole gate.
#
# -halt-on-error stop at the first error rather than nonstopmode's "carry on
# and emit a PDF anyway" — a broken paper leaves no PDF
# -bibtex run bibtex whenever a paper declares a bibliography, so
# naming a .bib that does not exist fails instead of being
# quietly skipped (latexmk's default)
# -Werror an undefined citation or cross-reference is a defect in a
# paper, not a note in a log nobody reads
# -cd compile each paper from its own directory, so a paper's
# relative paths mean the same thing to make as they do to a
# human opening the file: zen/ finds references.bib, defense/
# finds hanzo-defense.sty, the root finds shared/
# -outdir absolute, because -cd moved us: PDF and aux land together
# under pdfs/, never at the repo root
pdfs/%.pdf: %.tex
@mkdir -p $(dir $@)
@echo "Compiling $< ..."
@pdflatex -interaction=nonstopmode $< > /dev/null 2>&1 || true
@bibtex $(*F) > /dev/null 2>&1 || true
@pdflatex -interaction=nonstopmode $< > /dev/null 2>&1 || true
@pdflatex -interaction=nonstopmode $< > /dev/null 2>&1 || true
@[ -f "$(*F).pdf" ] && mv "$(*F).pdf" $@ || true
@rm -f $(*F).aux $(*F).log $(*F).bbl $(*F).blg $(*F).out $(*F).toc 2>/dev/null || true
@if [ -f "$@" ]; then \
echo " OK $@"; \
else \
echo " FAIL $@"; \
fi
@latexmk -pdf -halt-on-error -bibtex -Werror -interaction=nonstopmode -quiet \
-cd -outdir=$(CURDIR)/$(dir $@) $< > $(dir $@)$(*F).latexmk 2>&1 \
|| { echo " FAIL $<"; \
grep -A5 '^!' $(dir $@)$(*F).log; \
sed -n '/^Latexmk: Summary/,/^----/p' $(dir $@)$(*F).latexmk; \
false; }
@echo " OK $@"
# Clean auxiliary files (keep PDFs)
# Clean auxiliary files (keep PDFs). The second sweep clears what the previous
# rule left at the repo root; latexmk writes beside the PDF and never there.
.PHONY: clean
clean:
@echo "Cleaning auxiliary files..."
@find pdfs -type f ! -name '*.pdf' -delete 2>/dev/null || true
@find . -maxdepth 1 -name '*.aux' -o -name '*.log' -o -name '*.out' \
@mkdir -p pdfs
@find pdfs -type f ! -name '*.pdf' -delete
@find . -maxdepth 1 \( -name '*.aux' -o -name '*.log' -o -name '*.out' \
-o -name '*.toc' -o -name '*.bbl' -o -name '*.blg' \
-o -name '*.lof' -o -name '*.lot' | xargs rm -f 2>/dev/null || true
@echo "Done"
-o -name '*.fls' -o -name '*.fdb_latexmk' \) -delete
@echo "Cleaned."
# Clean everything
.PHONY: clean-all
@@ -63,37 +93,24 @@ clean-all:
@rm -rf pdfs
@echo "Done"
# The expected PDFs, one per line, for a reader that is not a human: the gate in
# .hanzo/workflows/ci.yml checks this list rather than restating which papers
# exist, so ALL_PDFS above stays the single definition of the paper set.
.PHONY: manifest
manifest:
@printf '%s\n' $(ALL_PDFS)
# List papers
# Every paper, one per line. scripts/gen-index.sh reads this.
.PHONY: list
list:
@echo "Root papers ($(words $(ROOT_TEX))):"
@for f in $(ROOT_TEX); do echo " $$f"; done
@echo ""
@echo "Zen papers ($(words $(ZEN_TEX))):"
@for f in $(ZEN_TEX); do echo " $$f"; done
@echo ""
@echo "Total: $(words $(ALL_TEX)) papers"
@printf '%s\n' $(ALL_TEX)
.PHONY: help
help:
@echo "Hanzo Papers Makefile"
@echo ""
@echo "Targets:"
@echo " make all - Compile all $(words $(ALL_TEX)) papers"
@echo " make -k all - Compile all $(words $(ALL_TEX)) papers, report every failure"
@echo " make pdfs/<name>.pdf - Compile a specific paper"
@echo " make list - List all discovered papers"
@echo " make clean - Remove auxiliary files"
@echo " make clean-all - Remove all generated files"
@echo ""
@echo "Docker:"
@echo " docker run --rm -v \"\$$PWD:/workdir\" -w /workdir texlive/texlive:latest make all"
@echo " docker run --rm -v \"\$$PWD:/workdir\" -w /workdir texlive/texlive:latest make -k all"
.PHONY: index
index:
+3 -2
View File
@@ -90,9 +90,10 @@ cd <paper-slug>
TEXINPUTS=".:..:" latexmk -pdf <paper-slug>.tex
```
Or build all:
Or build all — every paper, and a nonzero status naming any that did not
compile:
```bash
make all
make -k all
```
## Index
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More