Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
0f74baa
feat: scaffold JOSS paper with gates for CI, pre-commit, and Makefile
SkyeAv Oct 19, 2026
ecc4340
fix: sync paper gates with CONTRIBUTING and llms.txt truth tests
SkyeAv Oct 19, 2026
aa53172
docs(paper): first full JOSS draft with verified citations
SkyeAv Oct 20, 2026
241e98b
docs(paper): set author order Goetz/Roach/Glusman and drop KGX author…
SkyeAv Oct 20, 2026
bfa1239
docs(paper): AI disclosure, benchmarks, and state-of-the-field updates
SkyeAv Oct 28, 2026
df645a5
docs(paper): dedicated Benchmarks section, KGX-eval comparison, fullm…
SkyeAv Oct 28, 2026
29103e0
docs(paper): correct fullmap store size to full 17-file total (92.9 GB)
SkyeAv Oct 28, 2026
8cd0b84
docs(paper): fold benchmarks into Software design; cite LinkML, BioCy…
SkyeAv Oct 28, 2026
de50561
docs(paper): cite SPIRES in State of the field
SkyeAv Oct 28, 2026
7563e15
chore: read first draft of paper and made several small corrections
SkyeAv Oct 29, 2026
c03d452
docs(paper): document normalization, parallelism, QC example, and gra…
SkyeAv Oct 29, 2026
f8e4d71
docs(paper): apply revised wording and consistent paragraph wrapping
SkyeAv Oct 29, 2026
2f45740
docs(paper): draft author contributions and simplify AI disclosure
SkyeAv Oct 29, 2026
e3eb9bb
docs(paper): remove confirmed-contributions TODO
SkyeAv Oct 29, 2026
7ae23e9
docs(paper): clarify funder role and consortium authorship consultation
SkyeAv Oct 29, 2026
8734dbb
docs(paper): verify benchmark coverage and scope comparative claims
SkyeAv Oct 29, 2026
fe7c579
docs(paper): replace Koza timing with configuration-size comparison
SkyeAv Oct 30, 2026
f14eb35
docs(paper): compare Koza using identical Tablassert resolution
SkyeAv Oct 30, 2026
6e8b8be
docs(paper): clarify benchmark comparisons and supporting citations
SkyeAv Oct 30, 2026
55ffc8c
docs(paper): clarify declarative validation and comparisons
SkyeAv Oct 30, 2026
6d60849
docs(paper): frame two central design trade-offs
SkyeAv Oct 30, 2026
9aa3bbf
docs(paper): apply approved design and comparison revisions
SkyeAv Oct 30, 2026
e859192
docs(paper): merge manuscript audit fixes
SkyeAv Oct 30, 2026
692ed40
docs(paper): cite Bioconda publication
SkyeAv Oct 30, 2026
afaa01f
Fix capitalization in acknowledgements section
SkyeAv Oct 30, 2026
851aa7a
Update summary of Tablassert functionality
jaredroach Nov 2, 2026
fdc8f64
Revise AI usage disclosure in manuscript
jaredroach Nov 2, 2026
e13157f
Fix formatting in the summary section of paper.md
jaredroach Nov 2, 2026
3def764
Revise statement of need for Tablassert
jaredroach Nov 2, 2026
bb4ff0d
Enhance 'Statement of need' with Tablassert details
jaredroach Nov 2, 2026
f987967
Refactor section headings in paper.md
jaredroach Nov 2, 2026
9b651b6
Clarify Tablassert output requirements
jaredroach Nov 2, 2026
e1a0948
docs(paper): add build-vs-contribute justification
SkyeAv Nov 2, 2026
47228ef
docs(paper): accept title-case headings and replace non-ASCII dashes
SkyeAv Nov 2, 2026
6664b70
chore(lint): ban double-hyphen em dash substitutes in markdown prose
SkyeAv Nov 2, 2026
f390f13
Merge remote-tracking branch 'origin/chore/markdownlint-ban-double-hy…
SkyeAv Nov 2, 2026
0f8a2ca
Refine State of the Field section
jaredroach Nov 3, 2026
f2a933b
Research Impact Statement
jaredroach Nov 3, 2026
0224509
Revise AI usage disclosure in paper.md
SkyeAv Nov 3, 2026
77f31ff
docs(paper): refine JOSS manuscript
SkyeAv Nov 3, 2026
5adc43e
Revise paper content for clarity and consistency
SkyeAv Nov 4, 2026
d6e639b
Fix Markdown header for State of the Field section
SkyeAv Nov 4, 2026
1af0656
Enhance quality control and provenance in builds
SkyeAv Nov 4, 2026
039e098
Revise optional quality control section in paper.md
SkyeAv Nov 4, 2026
bf6fd43
Update terminology from 'Python 3.11' to 'CPython'
SkyeAv Nov 4, 2026
9236aa7
docs(paper): clarify resolution and recipe execution
SkyeAv Nov 4, 2026
b0a17a1
Refine normalization and quality control descriptions
SkyeAv Nov 4, 2026
d4361b8
Update Tablassert comparison and rationale in paper
SkyeAv Nov 4, 2026
469e8b2
Clarify Multiomics knowledge provider references
SkyeAv Nov 4, 2026
7b08e50
Revise title and enhance summary clarity
SkyeAv Nov 4, 2026
ece8cbf
docs(paper): rename agent instructions and update manuscript
SkyeAv Nov 5, 2026
e1b3090
chore: updated the AI usage disclosure
SkyeAv Nov 5, 2026
88ea1db
feat: added the tablassert drawio figure
SkyeAv Nov 5, 2026
c893dbc
chore: added height scaling
SkyeAv Nov 5, 2026
f8a4ad9
feat: add preprint make target
SkyeAv Nov 5, 2026
ab5be96
chore: reformatted the AI usage disclosure
SkyeAv Nov 5, 2026
986b99f
chore: expanded gitignore for new paper based files
SkyeAv Nov 5, 2026
a80e45a
chore: made dates more concise
SkyeAv Nov 5, 2026
b1f6ce5
chore: improved statement of need wording
SkyeAv Nov 5, 2026
45dce5a
chore: updated the authors in the bibliography
SkyeAv Nov 5, 2026
013b9d4
chore: added comment and improved software design intro
SkyeAv Nov 5, 2026
9fcb621
docs(paper): revise manuscript and remove metadata tags
SkyeAv Nov 5, 2026
811d1d6
Remove performance metrics from paper.md
SkyeAv Nov 5, 2026
5887b6f
Change image caption to 'Tablassert Architecture'
jaredroach Nov 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/paper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Paper

# JOSS paper preview: compiles paper/paper.md to PDF whenever paper content changes, so a
# broken front matter, malformed bibtex, or unresolvable citation fails here instead of at
# submission. The paper's structural gates (citation resolution, word budgets, front
# matter) live in tests/test_paper.py and run in ci.yml's python-test job on every PR;
# this workflow deliberately adds only the compiled artifact, path-filtered so untouched
# PRs pay nothing.
#
# Compilation uses the official JOSS paperdraft resources from the archived (frozen
# 2024-04-16) openjournals/whedon repository. The prebuilt openjournals/whedon Docker Hub
# image is gone, so the image is built per run; the Dockerfile needs three patches,
# identical to the Makefile's paper-image target (keep the two in sync):
# 1. fully-qualify the pandoc/latex base image registry,
# 2. pin tlmgr to the frozen TeXLive 2021 historic repo (the live tlnet now serves a
# newer TeXLive, so the stock install commands silently install nothing),
# 3. strip the vestigial biblatex block from the JOSS latex template (frozen polyglossia
# forbids the template's load order; pandoc citeproc renders references anyway).
on:
pull_request:
paths:
- "paper/**"
- ".github/workflows/paper.yml"
push:
branches:
- main
paths:
- "paper/**"
- ".github/workflows/paper.yml"

permissions:
contents: read

concurrency:
group: paper-${{ github.ref }}
cancel-in-progress: true

jobs:
paper:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Clone and patch JOSS paperdraft sources
run: |
git clone --depth 1 https://github.com/openjournals/whedon.git /tmp/whedon
sed -i 's|^FROM pandoc/latex|FROM docker.io/pandoc/latex|' /tmp/whedon/paperdraft.Dockerfile
sed -i '/^RUN tlmgr update --self/i RUN tlmgr option repository https://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2021/tlnet-final' /tmp/whedon/paperdraft.Dockerfile
perl -0pi -e 's/\\usepackage\[\n backend=biber,\n%[^\n]*\n%[^\n]*\n\]\{biblatex\}\n\\bibliography\{[^}]*\}\n//; s/\\renewcommand\{\\bibfont\}\{[^{}]*\}\n//' /tmp/whedon/resources/joss/latex.template
- name: Build paperdraft image
run: docker build -f /tmp/whedon/paperdraft.Dockerfile -t paperdraft /tmp/whedon
# paperdraft writes paper.pdf next to paper.md (fail-if-warnings: on), so an
# unresolvable citation or latex warning fails the job.
- name: Compile the JOSS paper PDF (test build, fails on warnings)
run: docker run --rm -v "$PWD/paper:/paper" -w /paper paperdraft paper.md
- name: Upload PDF preview
uses: actions/upload-artifact@v4
with:
name: paper
path: paper/paper.pdf
retention-days: 14
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@
*.opencode/
# mkdocs build output
site/
# JOSS paper build output: paper.md/paper.bib/INSTRUCTIONS.md are tracked, the PDF is generated
paper/*.pdf
paper/*.tex
paper/*.aux
paper/*.fls
paper/*.fdb_latexmk

.ralph/
.paperdraft/
18 changes: 16 additions & 2 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
// Scope deliberately includes top-level *.md, docs/, and .github/ templates, and excludes
// machine-generated/internal trees: .git, node_modules, .venv, site (mkdocs output),
// target (Rust build), __pycache__, .ralph (agent state), plans/ + PLAN.md (agent-generated
// planning artifacts), tests/ (fixture data), .tablassert (runtime artifacts).
// planning artifacts), .paperdraft (local clone of the JOSS paperdraft compiler sources),
// tests/ (fixture data), .tablassert (runtime artifacts).
{
"config": {
"default": true,
Expand All @@ -33,8 +34,20 @@
"style": "compact"
}
},
"customRules": ["./.markdownlint/no-unicode-chars.cjs"],
"customRules": ["./.markdownlint/no-unicode-chars.cjs", "./.markdownlint/no-double-hyphen.cjs"],
"globs": ["**/*.md"],
// The JOSS paper template puts every required section (Summary, Statement of need,
// ...) at heading level 1 below the YAML front-matter title; multiple H1s are the
// expected format there, not a structure error.
"overrides": [
{
"filter": ["paper/paper.md"],
"config": {
"MD025": false
},
"combine": "merge"
}
],
"ignores": [
"**/.git/**",
"**/node_modules/**",
Expand All @@ -45,6 +58,7 @@
".ralph/**",
"plans/**",
"PLAN.md",
".paperdraft/**",
"tests/**",
".tablassert/**"
]
Expand Down
64 changes: 64 additions & 0 deletions .markdownlint/no-double-hyphen.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Custom markdownlint rule: bans "--" in markdown prose. "--" is the ASCII stand-in for
// an em dash, the same AI-typical punctuation no-unicode-chars.cjs bans in unicode form.
// Rephrase with a comma, colon, semicolon, or parentheses instead.
//
// Only prose text is checked. Code spans, fenced or indented code, HTML (including
// <!-- comments -->), link destinations, and autolinks are skipped, so CLI flags such as
// `--fix` stay legal when written as code. Runs of three or more hyphens (thematic
// breaks, table delimiter rows, front matter fences) are not matched.
//
// No fixInfo: the right replacement depends on the sentence, so a mechanical rewrite
// would make prose worse. Fix violations by hand.
//
// Loaded via "customRules" in .markdownlint-cli2.jsonc, which both the pre-commit hook and
// the CI markdown-lint job use. tests/test_docs_style.py's em-dash-substitute check covers
// only space-flanked "--" in user-facing docs; this rule covers every form, repo-wide.
"use strict";

// Micromark token types whose text is code, markup, or a URL rather than prose.
const SKIP = new Set([
"autolink",
"codeFenced",
"codeIndented",
"codeText",
"definition",
"htmlFlow",
"htmlText",
"literalAutolink",
"resourceDestination"
]);

const DOUBLE_HYPHEN = /(?<!-)--(?!-)/g;

function walk(tokens, onData) {
for (const token of tokens) {
if (SKIP.has(token.type)) {
continue;
}
if (token.type === "data") {
onData(token);
}
walk(token.children, onData);
}
}

module.exports = {
names: ["no-double-hyphen"],
description: "Double hyphen '--' in prose (em dash substitute); rephrase or use a code span",
tags: ["style"],
parser: "micromark",
function: (params, onError) => {
walk(params.parsers.micromark.tokens, (token) => {
DOUBLE_HYPHEN.lastIndex = 0;
let match = null;
while ((match = DOUBLE_HYPHEN.exec(token.text)) !== null) {
// Data tokens never span lines, so the offset maps directly to a column.
onError({
lineNumber: token.startLine,
detail: "Rephrase with a comma, colon, or parentheses, or wrap a flag in a code span",
range: [ token.startColumn + match.index, 2 ]
});
}
});
}
};
11 changes: 11 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ repos:
- html-validate@11.16.4
- html-validate-markdown@6.0.0
pass_filenames: false
# JOSS paper integrity gate (front matter, citation resolution, word budgets).
# Scoped to one stdlib-only test file so it stays fast enough for the pre-commit
# stage, unlike the full suite (see the two-stage design comment above); the
# regular CI suite also runs it in python-test. markdownlint-cli2 above already
# lints paper/*.md via its **/*.md globs, so no paper scope is added there.
- id: paper-checks
name: paper-checks
entry: uv run pytest tests/test_paper.py -q -p no:cacheprovider
language: system
files: ^(paper/|tests/test_paper\.py$)
pass_filenames: false
- id: pyright
name: pyright
entry: uv run pyright
Expand Down
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# AGENTS.md -- Tablassert
# AGENTS.md: Tablassert

Tablassert turns biomedical spreadsheets into KGX knowledge graphs for NCATS Translator. Python package in `src/tablassert/` plus a PyO3 Rust extension in `rust/` built with maturin; uv-managed. Guidance below is evidence-keyed; fix anything stale when touched.

## Build / Test / Lint

- One-time setup: `make setup` (uv sync --group dev --extra cli --extra qc --extra log, then debug `maturin develop`). [verified]
- One-time setup: `make setup` (`uv sync --group dev --extra cli --extra qc --extra log`, then debug `maturin develop`). [verified]
- After any Rust change, or when the extension may be stale: `make dev` (debug build; `make build` for release-mode performance checks only). [verified]
- Full local gate before a PR: `make check` (ruff lint + format check + pyright + pytest + cargo test + clippy -D warnings). [verified]
- Python tests: `uv run pytest` [verified] -- parallel via pytest-xdist (`-n auto` in pyproject addopts, coverage inline); use `-n 0` for one serial test while debugging.
- Python tests: `uv run pytest` [verified]; parallel via pytest-xdist (`-n auto` in pyproject addopts, coverage inline); use `-n 0` for one serial test while debugging.
- Rust tests: `cargo test --manifest-path rust/Cargo.toml` (evidence: ci)
- CI jobs are exactly: `ruff check`, `ruff format --check`, `uv run pyright`, `uv run pytest` (after `uv run maturin develop`), `cargo fmt --check`, `cargo clippy --all-targets -- -D warnings`, `cargo test`. (evidence: ci)
- After editing `pyproject.toml`, relock; `uv lock --check` runs in pre-commit and catches a stale lockfile. [verified]
Expand Down
10 changes: 5 additions & 5 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ authors:
email: sgoetz@isbscience.org
affiliation: Institute for Systems Biology
orcid: "https://orcid.org/0009-0007-8373-2352"
- given-names: "Gwênlyn"
family-names: Glusman
email: gglusman@isbscience.org
affiliation: Institute for Systems Biology
orcid: "https://orcid.org/0000-0001-8060-5955"
- given-names: Jared C.
family-names: Roach
email: jroach@isbscience.org
affiliation: Institute for Systems Biology
orcid: "https://orcid.org/0000-0003-4524-0107"
- given-names: "Gwênlyn"
family-names: Glusman
email: gglusman@isbscience.org
affiliation: Institute for Systems Biology
orcid: "https://orcid.org/0000-0001-8060-5955"
references:
- type: article
title: "MicrobiomeKG: bridging microbiome research and host health through knowledge graphs"
Expand Down
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ The `Makefile` is intentionally small and mirrors the underlying commands:
| `make fmt-check` | Ruff format check and `cargo fmt --check` |
| `make typecheck` | Pyright |
| `make check` | Lint, format check, typecheck, Python tests, Rust tests, and clippy with `-D warnings` |
| `make paper-check` | JOSS paper gate: front matter, citation resolution, word budgets |
| `make paper-image` | Build the JOSS paperdraft compiler image (local Docker layer cache) |
| `make paper-pdf` | Compile `paper/paper.pdf` from `paper/paper.md` with Docker |
| `make paper` | JOSS paper gate plus PDF compile |
| `make clean` | Local build/test/doc artifacts |

## Project layout
Expand Down
48 changes: 46 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: setup build dev test test-rust lint fmt fmt-check typecheck check clean
.PHONY: setup build dev test test-rust lint fmt fmt-check typecheck check clean paper paper-check paper-pdf paper-image preprint preprint-pdf

# Install Python dev dependencies, CLI/QC/log extras, and the editable Rust extension.
setup:
Expand Down Expand Up @@ -45,4 +45,48 @@ check: lint fmt-check typecheck test test-rust

# Remove local build, test, documentation, and compiled-extension artifacts.
clean:
rm -rf build dist site htmlcov .coverage .pytest_cache .ruff_cache rust/target src/tablassert/*.so
rm -rf build dist site htmlcov .coverage .pytest_cache .ruff_cache rust/target src/tablassert/*.so .paperdraft paper/paper.pdf paper/preprint.pdf paper/preprint.tex paper/preprint.aux paper/preprint.log paper/preprint.out

# Validate the JOSS paper draft: front matter, citation resolution, word budgets.
paper-check:
uv run pytest tests/test_paper.py -q

# Clone + patch the JOSS paperdraft sources once; the stamp file keeps the patches
# single-application across repeated make runs.
.paperdraft/.patched:
git clone --depth 1 https://github.com/openjournals/whedon.git .paperdraft/whedon
# Qualify the base image registry so podman-based runtimes (no unqualified-search
# registries) resolve it exactly like Docker does, and pin tlmgr to the frozen
# TeXLive 2021 historic repo: the base image (pandoc/latex:2.11.2 ships TeXLive 2021)
# points tlmgr at the live tlnet, which now serves a newer TeXLive, so the stock
# tlmgr install calls silently install nothing.
sed -i 's|^FROM pandoc/latex|FROM docker.io/pandoc/latex|' .paperdraft/whedon/paperdraft.Dockerfile
sed -i '/^RUN tlmgr update --self/i RUN tlmgr option repository https://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2021/tlnet-final' .paperdraft/whedon/paperdraft.Dockerfile
# The JOSS template loads biblatex before pandoc's polyglossia and the frozen
# TeXLive 2021 polyglossia forbids that order; pandoc citeproc renders the
# bibliography anyway, so the biblatex block is vestigial and gets stripped.
perl -0pi -e 's/\\usepackage\[\n backend=biber,\n%[^\n]*\n%[^\n]*\n\]\{biblatex\}\n\\bibliography\{[^}]*\}\n//; s/\\renewcommand\{\\bibfont\}\{[^{}]*\}\n//' .paperdraft/whedon/resources/joss/latex.template
touch .paperdraft/.patched

# Build the JOSS paperdraft compiler image from the openjournals/whedon resources.
# whedon is archived (frozen 2024-04-16) but its paperdraft.Dockerfile and LaTeX templates
# are still the official JOSS compilation path; the old openjournals/whedon Docker Hub
# image is gone, so the image is built locally. Docker layer cache makes this a no-op
# after the first build.
paper-image: .paperdraft/.patched
docker build -f .paperdraft/whedon/paperdraft.Dockerfile -t paperdraft .paperdraft/whedon

# Compile paper/paper.md to paper/paper.pdf with the JOSS paperdraft image.
paper-pdf: paper-image
docker run --rm -v $(PWD)/paper:/paper -w /paper paperdraft paper.md

# Full JOSS paper gate: validate the draft, then compile the PDF.
paper: paper-check paper-pdf

# Generate standalone preprint LaTeX with Pandoc.
preprint: paper-check
cd paper && pandoc paper.md --citeproc --standalone --output=preprint.tex

# Compile the generated preprint LaTeX to PDF; two XeLaTeX passes resolve references.
preprint-pdf: preprint
cd paper && xelatex -interaction=nonstopmode -halt-on-error preprint.tex && xelatex -interaction=nonstopmode -halt-on-error preprint.tex
2 changes: 1 addition & 1 deletion llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Current CLI behavior queries an embedded redb database whose primary file is `fu
- [Project Metadata](pyproject.toml): dependencies, tooling config, and CLI entrypoint. Optional extras: `cli`, `rt`, `aria2`, `qc`, and `log`.
- [Tests](tests/): pytest coverage and fixtures.
- [MkDocs Configuration](mkdocs.yml): docs navigation and published pages.
- [GitHub Workflows](.github/workflows/): `ci.yml` runs lint, format, type, test, and rust checks; `docs.yml` builds and deploys MkDocs; `pipy.yml` checks the project version, builds sdist and wheel artifacts, and publishes to PyPI; `tag-version.yml` tags changed project versions.
- [GitHub Workflows](.github/workflows/): `ci.yml` runs lint, format, type, test, and rust checks; `docs.yml` builds and deploys MkDocs; `pipy.yml` checks the project version, builds sdist and wheel artifacts, and publishes to PyPI; `tag-version.yml` tags changed project versions; `paper.yml` tests the JOSS paper compile and uploads the PDF artifact.
- [Changelog](CHANGELOG.md): release history and version notes.

## Implementation Map
Expand Down
Loading