| name | repo-maintenance |
| description | Use for maintaining and releasing this repository. |
Repository Maintenance
When to Use
Use for source changes, tests, documentation, generated examples, CI, releases,
and compatibility reviews in this repository.
For every task, load the sibling idsd-workflow
first. Keep general LaTeX knowledge outside this repository; this skill contains
only project-specific rules and pointers.
Source of Truth
Read only the focused sources needed for the task:
AGENTS.md — canonical project rules and boundaries.
justfile — canonical maintainer command surface.
docs/features/v2/modernization.md
— shipped v2 intent, expectations, evidence, and progress.
docs/features/v2/public-api-compatibility.md
— 1.x helper compatibility policy and machine-checked baseline.
docs/source-optimization-review.md
— prioritized modernization, performance, and CI evidence.
docs/release-versioning.md — release
version, packaging, promotion, and public-verification contract.
docs/sample-repository-migration.md
— generated-example provenance and migration record.
docs/overleaf-distribution.md —
unofficial-template policy, import package limits, and publication blockers.
Inspect current source and Git state before trusting historical notes. When a
rule changes, update its canonical repository source in the same slice.
Canonical Commands
Use just; do not introduce a Makefile or duplicate orchestration in CI:
just
just thesis
just watch
just example
just test
just check
just ci
just overleaf <version>
just release <version>
just clean
latexmk is the XeLaTeX/BibTeX/rerun orchestrator underneath just. Keep the
student project directly buildable without repository tooling:
latexmk -xelatex -synctex=1 -interaction=nonstopmode thesis.tex
Compatibility Boundary
- XeLaTeX remains the supported v2 engine; do not silently migrate engines.
- Preserve
thesis.tex, conf/conf.tex, every entry in
tests/v1-public-api.json, and the visible NCKU layout unless a focused
fixture and authoritative evidence justify a documented correction.
- Keep
tests/v1-project-migration.json passing. It pins the v1.8.2
student-owned inputs byte-for-byte; just test separately proves the unchanged
entry/configuration path and active StudentMode content/BibTeX dependencies.
- Keep generic command/renderer layers free of NCKU assets, Taiwan-year policy,
and institution-specific degree-submission wording. The selected profile owns
these values, while Master/Doctoral branching follows numeric degree state
rather than localized display strings. Cover date formats are profile tokens:
generic/custom output must not borrow an oral day that
\SetCoverDate does
not own; an institution profile may inject that policy explicitly.
- Keep committee renderer capacity separate from institution rules.
\SetCommitteeSize delegates to the selected profile's policy hook; NCKU
clamps Master to 3--5 and Doctoral to 5--9, while neutral/custom retains 2--9.
- Keep student data in
conf/ and institution-level style ports under
template/style/; never introduce conf/style.tex.
- Preserve direct XeLaTeX and Overleaf compatibility;
just is maintainer
orchestration, not a student requirement.
- Keep the full teaching document as integration coverage and add focused
fixtures before changing output-sensitive macros.
- Keep
tests/theorem-contract.tex in the test gate before consolidating theorem
internals. Its label option must create an auxiliary label without visible key
leakage, and titled labels must freeze nameref metadata before temporary pgf
key state is reused. Introduce registry behavior in bounded slices: first let
one private ordered type list drive aggregate initialization and setter
dispatch while preserving every per-type public wrapper, initializer, key
family, style, and counter implementation. Preserve unknown-type no-op
behavior explicitly and cover every registered route plus an unknown sentinel.
The completed registry owns type order, style/numbering policy, default
metadata, key families, membership, aggregate initialization, and default
application. Keep every v1 insertion/initializer declaration literal as a
compatibility adapter. Resolve forward and multi-hop counter chains to a
frozen terminal value, including an existing non-registry LaTeX counter,
before choosing \newtheorem; optional types with a
configured parent become numbered, and cycles must fail with the package
diagnostic rather than recursive overflow. Keep both theorem fixtures and the
negative cycle fixture in the gate. Generic initializer scratch values must be
frozen into each environment declaration so headings cannot leak from the
final registry row. Keep the 13 numbered-counter getter declarations literal:
the v1 source manifest historically discovered them through repeated
\renewcommand branches even though registry-owned keys now populate values.
- Float compatibility: caption text stored in pgf temporaries must be frozen
into
\@currentlabelname after \caption/\caption* and before \label.
Test \nameref after a later key parse and after subfigure scope exit, and
require literal caption text rather than temporary macros in the auxiliary
file. Extract only the exact minipage/mdframed/opacity wrapper shared by
figure, multi-figure, and table paths; keep [H] and no-op compatibility
placement/alignment keys unchanged.
- Numbering compatibility: freeze parsed title prefixes, separators, and counter
names into each format getter, but keep the counter formatter/value dynamic.
Exercise all general/appendix title and F/T/E paths after later setup calls and
counter mutations, and require repeated setup to be idempotent.
- Source-manifest cleanup: remove
comment-environment blocks only after the
scanner strips them, the runtime baseline is corrected, and every comment-only
or overlapping declaration is retained in the separate audit artifact; compare
names and signatures.
- Do not claim tagged PDF or PDF/UA compliance from metadata alone.
- Current university and department requirements override template guidance.
Documentation and Package Boundaries
Keep audiences separate:
- maintainer commands, CI, release scripts, benchmarks, and architectural
decisions belong in root/internal documentation;
- direct compiler, editor, configuration, and writing guidance belongs in the
packaged
thesis/ project and teaching content;
- root
README.md routes both audiences without exposing unnecessary internals;
- the student ZIP must not contain
justfile, AGENTS.md, CI, tests, scripts,
internal docs, or a redundant thesis/ wrapper.
Generated defense-certificate PDFs are unofficial demonstrations and regression
outputs. Current students must use files produced by the university
degree-examination system and follow current university/department guidance.
Release Contract
A release promotes exactly two custom, versioned packages from one verified
source revision:
ncku-thesis-template-latex-<version>.zip
ncku-thesis-template-latex-examples-<version>.zip
The student archive extracts to stable ncku-thesis-template-latex/; its regular
files must exactly equal the tracked HEAD:thesis tree, including the
student-facing README with concise offline migration guidance, v1 adapter, and
base/NCKU/custom profiles. Keep a focused negative test that deletes the required
student README and proves the archive checker fails. The full migration reference
lives at docs/MIGRATION-1.x-TO-2.x.md in the complete repository.
When this gate runs inside xu-cheng/texlive-action, configure
$GITHUB_WORKSPACE as a Git safe directory before git archive/git ls-tree
and install full Info-ZIP unzip/zip; BusyBox unzip does not support
unzip -Z1, and the negative mutation requires zip -d. A local macOS pass
is not sufficient evidence for this container-specific path.
The examples archive extracts to stable ncku-thesis-template-latex-examples/
and contains exactly:
README.md
cover.pdf
thesis-chi.pdf
thesis-eng.pdf
thesis-full.pdf
defense-certificate-master.pdf
defense-certificate-phd.pdf
The outer archives carry the version. Inner names remain stable and omit a
redundant example- prefix. Loose generated PDFs are build intermediates, not
public Release assets.
Do not move an immutable tag or rebuild old tagged PDFs during an asset-only
migration. Follow docs/release-versioning.md for download, digest, public
read-back, byte-comparison, and exact-allowlist gates.
Verification
For source or build changes, run at minimum:
python3 scripts/test/check-v1-project-migration.py
just test
just ci
git diff --check
git status --short
For release changes, run a clean-worktree release build with an explicit version
and inspect both archives. For PDF-affecting changes, inspect metadata and text,
render affected pages, and check new warnings separately from inherited ones:
pdfinfo build/thesis.pdf
pdftotext build/thesis.pdf -
After pushing, verify the exact GitHub Actions run. After publishing or changing
Release assets, download them from their public URLs and verify the public state;
a local or workflow artifact alone is insufficient.
Development Branch and Hosted Test Gate
The Test workflow push filter covers main and feat/**. Use the feat/**
namespace for development branches (for example, feat/v2.x) so every pushed
update automatically enters the required hosted test gate. A bare
version-shaped branch such as v2.x does not match that filter.
After every feature-branch push:
- find the Test run whose
headSha exactly matches the pushed commit;
- wait for that run to complete successfully;
- inspect annotations and the expected test artifact when relevant;
- call the update hosted-tested only after those checks pass.
If no run appears, inspect the workflow branch trigger before treating the push
as tested. A successful run for an older SHA is not evidence for the latest
update.
For GitHub Actions dependency maintenance, enumerate every repository-owned
uses: reference across all workflow files and check each action's official
latest stable release plus action.yml runtime. After pushing, run the normal
Test workflow and a manual build-only Release workflow, then inspect job
annotations; a green status alone does not prove runtime deprecation warnings
are gone. Manual Release dispatch must not promote a GitHub Release.
Pitfalls
- Mixing student instructions with maintainer-only
just or CI commands.
- Treating the 271-page teaching document as the normal student rebuild cost.
- Caching LaTeX auxiliary state in required clean test/release lanes.
- Switching to an Arm runner while the selected TeX container is amd64-only.
- Treating Overleaf's accepted community-maintained Gallery listing as NCKU
endorsement. Keep the unofficial label, and update only through the original
Overleaf project followed by resubmission and reapproval.
- Publishing loose example PDFs in addition to the examples ZIP.
- Using
legacy in a public filename when generated plus a clear package
notice communicates the institutional-document boundary more accurately.
- Letting imported Python test modules leave unignored
__pycache__/*.pyc
files. The release recipe intentionally checks for a clean worktree after its
test dependency; ignore interpreter bytecode instead of weakening that guard.
- Using
pdftotext ... | grep -q under pipefail; write text to a file first to
avoid producer SIGPIPE failures in Alpine CI.