Skip to content

feat(works): add Dante's Divina Commedia - #39

Merged
maehr merged 2 commits into
mainfrom
feat/dante
Aug 26, 2026
Merged

maehr merged 2 commits into
mainfrom
feat/dante

Conversation

@maehr

@maehr maehr commented Aug 26, 2026

Copy link
Copy Markdown
Member

Closes #37. Verified row from #25, part of #28.

One work, one system, 14,233 references — the whole poem.

The open question in #25 is answered

Dante Lab's reader takes reader[cantica]=2&reader[canto]=5 as query parameters and stops at the canto — it does not address the verse. Check whether any of the three addresses a single verse.

Yes — the Princeton Dante Project does, through INP_START on its CGI. Verified with cross-controls, which is the check #22 taught us to run:

Locator Returns
Inf.1.1 "Nel mezzo del cammin di nostra vita"
Inf.5.121 "Nessun maggior dolore"
Par.33.145 "l'amor che move il sole e l'altre stelle."

The Inf.1.1 page contains no occurrence of Inf.5.121's text, and the reverse. It addresses the verse, not the canto opening.

The cantica vocabulary is Inf/Purg/Par — the locator's own vocabulary — so no provider mapping is needed and textrefs/textrefs.org#71 is not a dependency.

The counts, and a mistake worth recording

Harvested from the provider on 2026-08-26 by requesting each canto with INP_LEN=250 and reading the highest verse number returned. Independently confirmed:

Inferno 4,720 + Purgatorio 4,755 + Paradiso 4,758 = 14,233 — the canonical line count of the Commedia.

That check earned its place. An earlier harvest was silently degraded by rate limiting and summed to 13,939. It returned 78 lines for Inferno XII and 20 for Inferno XVII, and because those are digits rather than errors, a resume pass trusted them. They were caught only by a plausibility bound (no canto is under 100 lines), and the affected cantos were re-harvested at one request per 2 seconds.

Recording it here because the failure mode is invisible to any harvest that only checks for exceptions: a rate-limited server can return a truncated 200 that parses fine.

Two rejections, recorded in the file

Dante Lab — rejected on two independent grounds. Its TLS certificate is CN=*.herokuapp.com with SAN DNS:*.herokuapp.com, which does not match dantelab.dartmouth.edu, so HTTPS fails and only plaintext HTTP works. That is the same disqualifier recorded for wittgensteinsource.org in #24. Its reader also stops at the canto, confirming what #25 suspected.

Dartmouth Dante Project — rejected. search_view.php accepts cantica, canto and line, but every request answers Your session has timed out. Click here to continue. (67 bytes), with and without an established cookie jar. Not deep-linkable, and it serves commentaries rather than the poem.

Both are written into the YAML so the next person does not re-derive them.

One caution carried in the resolver comment

An invalid canto or verse returns HTTP 200 with an 854-byte error page that leaks a raw SQL string, not a 4xx. A status-code-only link check will pass a bad URL against this provider — the body has to be checked. It does not serve the wrong passage, which is the failure that actually matters.

Also: this is a small academic server, and roughly twenty rapid requests were enough to make it start refusing connections. Whatever link-checks the registry should be paced.

Identity

Wikidata Q40185 verified as the Work — "The Divine Comedy", an Italian narrative poem, P50 = Q1067 (Dante Alighieri), with Commedia and Comedìa among its aliases. Not an edition item.

Checks

  • npm run compile:data — 13 works, 11 systems, 82,192 references
  • npm run validate:data — 82,242/82,242 records valid
  • Boundary spot-checks confirmed absent: Inf.35.1, Par.34.1, Inf.1.137, Purg.33.146, Par.33.146
  • Par.34.1 is shape-valid under the regex but not minted — Paradiso has 33 cantos, and references_range bounds the registered set. That split between shape check and registry membership is deliberate and matches how bekker behaves.

…ation

Verified row from registry #25, tracked in #37.

The Princeton Dante Project addresses a single verse through its CGI, which
answers the open question #25 raised: of the three Dante candidates, one does
reach the verse. Verified with cross-controls — the Inf.1.1 page contains no
occurrence of Inf.5.121's text and vice versa.

Verse counts per canto were harvested from that provider on 2026-08-26, not
typed from memory, and confirmed independently: Inferno 4,720 + Purgatorio
4,755 + Paradiso 4,758 = 14,233, the canonical line count of the Commedia.

An earlier harvest was silently degraded by rate limiting and summed to 13,939
— it had returned 78 lines for Inferno XII and 20 for XVII. Those values were
digits, so a resume pass trusted them. They were caught by a plausibility bound
and the affected cantos were re-harvested. Recording this because the same
failure would be invisible in any future harvest that only checks for errors.

Two candidates are rejected in comments, so nobody re-derives them: Dante Lab
presents a TLS certificate for CN=*.herokuapp.com that does not match its
hostname and its reader stops at the canto; the Dartmouth Dante Project always
answers "Your session has timed out" and is not deep-linkable.

Refs #37

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CD9MxbT2jSZmJyR9ywJGEs
Copilot AI lite review requested due to automatic review settings August 26, 2026 06:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Dante Alighieri’s Divina Commedia to the TextRefs registry, including a new three-part citation system (cantica/canto/verse) and a resolver that deep-links to individual verses via the Princeton Dante Project.

Changes:

  • Introduces a new work record dante.commedia with Wikidata/Wikipedia mappings and a Princeton Dante Project verse-level resolver.
  • Registers the new citation system dante-cantica-canto-verse with a fixed cantica vocabulary (Inf|Purg|Par) and named capture groups for templating.
  • Adds the complete reference space for the poem via references_range (Inferno/Purgatorio/Paradiso canto verse-counts; 14,233 references total).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
works/dante.commedia.yaml New work entry with mappings, verse-level resolver, and full canto verse-count ranges for Inf/Purg/Par.
systems/dante-cantica-canto-verse.yaml New citation-system definition with locator regex and documentation of the cantica vocabulary and format.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

…lver

Added at the maintainer's request, with both of its limitations recorded in the
file rather than glossed.

PLAINTEXT HTTP, DELIBERATELY. dantelab.dartmouth.edu presents a TLS certificate
for CN=*.herokuapp.com, which does not match the hostname, so https:// fails
certificate validation in curl and in browsers. Only http:// works. This is the
same condition that disqualified wittgensteinsource.org in #24; it is accepted
here as a conscious exception, not an oversight. Revisit if the certificate is
fixed.

CANTO-LEVEL ONLY. The reader takes no verse parameter, so every verse of a canto
resolves to the same page. It sits beside the verse-level Princeton resolver as
a reading companion, never as a replacement.

The next-generation reader posts to /queries with query[cantica], query[canto]
and query[line] over AJAX. Those are POST-only: /queries returns HTTP 500 on GET,
and the reader ignores them as query parameters, always rendering Inferno 1. The
older reader[...] parameters do work as a GET deep link, so the resolver uses
those. Checked 2026-08-26 across all three cantiche.

The cantica is translated to the provider's numeric vocabulary with a `vars:`
map, so the locator keeps Inf/Purg/Par.

Refs #37

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CD9MxbT2jSZmJyR9ywJGEs
@maehr
maehr merged commit 520b668 into main Aug 26, 2026
4 checks passed
@maehr
maehr deleted the feat/dante branch August 26, 2026 07:22
maehr added a commit to textrefs/textrefs.org that referenced this pull request Aug 26, 2026
* chore(data): bump the registry pointer to 7d109195

Picks up the second-wave works verified against registry #25:

- textrefs/registry#39 — Dante, Divina Commedia (14,233 references), with the
  verse-level Princeton resolver and a canto-level Dante Lab companion
- textrefs/registry#38 — Hume, Treatise and first Enquiry (1,468 references)
- textrefs/registry#40 — eight Nietzsche works (2,737 references)

Closes registry #34, #36 and #37. The registry goes from 12 works to 23, and
from 67,959 references to 86,397.

npm run verify passes on the new pin: 86,477 records valid, 259,811 pages built,
all internal links valid.

* chore(deps): safe update of all dependencies within their semver ranges

`npm update` only. package.json is untouched; the lockfile moves seven packages
to the newest version their declared range already allows:

- @astrojs/starlight     0.41.7 -> 0.41.9
- @commitlint/cli        21.2.1 -> 21.2.2
- @commitlint/config-conventional 21.2.0 -> 21.2.2
- astro                   7.2.1 -> 7.2.7
- mermaid                11.16.1 -> 11.17.2
- starlight-openapi      0.26.0 -> 0.26.1
- uuid                   14.0.1 -> 14.0.2

Deliberately not taken, because neither is a safe update:

- starlight-blog 0.28.0 -> 0.29.0 is outside the declared range.
- typescript 6.0.3 -> 7.0.2 is a major.

Three high-severity advisories remain and are NOT fixed here. All three are the
same chain — form-data (CRLF injection) via httpsnippet via starlight-openapi —
and npm's only offered remedy is a DOWNGRADE of starlight-openapi to 0.24.0,
which it flags isSemVerMajor. `npm audit fix --force` would move the tree
backwards, so it was not run. starlight-openapi is a devDependency used to
render the API docs at build time; nothing in that chain reaches a published
page.

npm run verify passes: 86,477 records valid, 259,811 pages built, all internal
links valid.

---------

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

data: add Dante's Divina Commedia, resolved by the Princeton Dante Project

2 participants