Skip to content

Release 6.0.0: publish flpq-data to PyPI - #155

Merged
gsvgit merged 278 commits into
masterfrom
dev
Oct 14, 2026
Merged

gsvgit merged 278 commits into
masterfrom
dev

Conversation

@gsvgit

@gsvgit gsvgit commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Merge dev into master for the 6.0.0 release.

What this carries:

  • The whole 6.0.0 body of work: package rename cfpq_data -> flpq_data,
    query/grammar restructure (queries/{cfpq,rpq,mcfpq}), the 6.0.0 dataset
    layout (per-graph registry, machine-global versioned cache, reachable-pairs
    table on object storage), and the uv/ruff/ty tooling migration.
  • The release commit: version 6.0.0 in config.py/pyproject.toml and
    the changelog promoted from [Unreleased] to [6.0.0] - 2026-10-13.

After this merges, v6.0.0 is tagged on master; the Publish workflow then
builds the sdist/wheel, publishes them to PyPI (Trusted Publishing), and
creates the GitHub Release with the [6.0.0] changelog section.

While this PR is open, every push to dev also publishes a
6.0.0.dev<run number> artifact to TestPyPI as a packaging check (issue
#154) — the last run validates exactly the code that will be released.

The 6.0.0 task issues close via their Closes #N commit references when
this lands on master.

When a new graph is added its table row must carry the Size (MB) value, so
the upload tool now surfaces the size it already computes and verifies:
upload_file() returns (key, stored_size) — the head_object ContentLength
that must equal the local file size — and the CLI prints it in bytes and
megabytes using sizes.format_size_mb, the same formatting as the docs
tables. The reported number is therefore exactly what
utils/archive_sizes.py reads back from S3, so a row filled from the upload
output always passes check mode. The only other callers (migrate_gdrive_to_s3,
convert_old_to_new) use the return value as a statement and are unaffected.
The Upload section of docs/utils.rst documents the new output.
The 'Archive sizes' section of docs/utils.rst documents
utils/archive_sizes.py (coverage, check vs --update, all-or-nothing writes,
URL keying) next to the upload section it complements. The add-graph skill
gains the size step — fill the new row's Size (MB) cell from the upload
output and run archive_sizes.py --update before committing — and its
registration step now points at the per-category table where graph rows
actually live (plus the category count in the Contents table). The
changelog records both user-visible additions.
Code review found that when the Size (MB) column was missing, a row whose
download cell held no URL got no size cell at all, producing a table with
ragged rows. Such rows now get a bare '-' cell (the same empty-cell style
rdf.rst uses for non-applicable grammars), keeping every row aligned; check
mode still flags the missing link. Also fixed the GRAPH_TABLE_FILES comment:
the patterns are relative to docs/, not the repository root.
All subtasks are committed and verified: the nine graph tables carry the
Size (MB) column (167 rows, MB as the single unit), the upload tool reports
the verified archive size, and utils/archive_sizes.py keeps the column in
sync with S3 for future additions. The quality gate passed in full: 363
tests, ruff check and format, ty, the no-warnings docs build, and the link
check (a first linkcheck run hit Wikipedia rate limiting on two pre-existing
URLs; both verified 200 directly and the re-run was clean).
Canonical grammars are a property of a graph category, not of an individual
graph: the same text is currently repeated on every graph page of a category
(up to 21 times), via copy-pasted inline sections and five .inc includes. The
category pages already carry one table column per grammar language, so they
are the single home for the canonical grammar description. Graph pages lose
the section entirely; docs/old_graphs (legacy, no category structure) stays
untouched; the rdf category page gets the union of all four grammars. The
graph PR/issue templates gain a Category field and cover three contribution
cases: existing category, new grammar for an existing category, new category.
…ategory pages

Move the canonical grammar description from the per-graph pages to the
category page, where it belongs: a grammar is canonical for the whole
category, and repeating it on up to 21 graph pages is duplication. The text
is moved verbatim from the .inc files that the graph pages include (the
.inc files are removed in a later subtask), with the section heading
normalized to 'Canonical grammars' across all category pages. Cross-
references to the parameterized template pages under docs/grammars/ are
kept, since they tie each concrete grammar to its template.
…ategory pages

Complete the move of the canonical grammar descriptions to the category
pages for the categories that carried them as copy-pasted inline sections
instead of .inc includes: c_alias_analysis (both grammar variants plus the
change_edges note, verbatim from the section shared by its 20 graph pages),
biological_uniprot (verbatim from the section shared by its 10 unigraph
pages), and rdf — where the category page gets the union of all four
grammars: the three nested-parentheses variants shared by 19 graphs plus the
broaderTransitive grammar that only geospecies uses, matching the table's
existing broaderTransitive column.
…document them

The canonical grammars live on the category pages since the previous two
subtasks, so the per-graph copies are pure duplication: remove the trailing
grammar section from all 113 graph pages (64 copy-pasted inline sections and
49 .. include:: directives) and delete the five grammar_*.inc files they
pulled in. Graph pages keep nothing in its place — the category page is the
parent in the navigation, one click away. docs/old_graphs is intentionally
untouched: it is a legacy orphan list without category structure.
…ry pages

Contributors adding a graph can now hit three situations, and the templates
had to cover all of them: a graph for an existing category (no grammar text
needed — just name which of the category's grammars apply), a new grammar
for an existing category (grammar added to the category page plus a new
table column), and a graph for a new category (a new category page is
created carrying the canonical grammars). Both graph templates gain a
Category field in the Info table so the case is explicit, and their
'Canonical grammars' section is restructured around these three cases. The
add-graph skill's Documentation step mirrors the same cases, and the Graphs
index states that the canonical grammar behind each table column is
documented on the category page.
Clean rebuild (make clean html) succeeds under the no-warnings policy:
zero warnings, all eight category pages render their 'Canonical grammars'
section (the rdf page shows all four grammars including broaderTransitive),
and none of the 113 graph pages still carries one. Record the per-subtask
commit hashes and the verification result in the detailed plan.
The whole-repo review found two descriptions that still located the RDF
canonical grammars on the per-graph docs pages, where they no longer live:
the RDF_GRAMMAR_TYPES comment in utils/convert_old_to_new.py and the
conversion-tool paragraph in docs/utils.rst. Both now point at the RDF
category page, which is where the section moved to in S3. Comment-only
change; the convert tool's tests (51) pass and pre-commit is clean.
All subtasks are committed and verified: the canonical grammar descriptions
now live once per category on the eight category pages (the rdf page carries
the union of all four grammars), the 113 per-graph pages no longer repeat
them, the five .inc files are gone, and the contribution flow (templates,
add-graph skill, graphs index) documents the three cases — existing
category, new grammar for an existing category, new category. The quality
gate passed: 363 tests, clean pre-commit and ty, zero-warning docs build,
clean link check.
…nomy

Task 42 designs the extension of CFPQ_Data from context-free path queries
to all classes of formal-language-constrained path querying (FLPQ). The
task log records the user's description and guidance verbatim: rename to
flpq_data, shared graph catalog, MCFPQ = Seki's multiple context-free
languages (not a combination of CFGs) with the POPL 2025 reachability
paper as reference application, Datalog-like MCFG syntax parsed with lark,
reachable-pairs rendering split per category while the flat CSV stays the
downloadable source of truth, incremental tasks first and no release task.

The detailed plan decomposes the docs-only task into six subtasks. This
commit creates docs/flpq.rst (wired into the index toctree so it is not
orphaned) with the query-class taxonomy (RPQ/CFPQ/MCFPQ by language class)
and the MCFP model: the d-MCFG(r) formalism in predicate notation, the
hierarchy facts (CFL = 1-MCFL, TAL = 2-MCFL(2), decidable membership), and
the reachability semantics where an arity-k nonterminal denotes k
independent paths and the arity-1 start symbol keeps 'reachable pairs'
defined exactly as for CFPQ. Verified: no-warning docs build (exit 0).
The MCFPQ grammar format is specified in docs/flpq.rst: one rule per line
in the predicate notation of Conrado et al. (POPL 2025), with lexical
conventions (uppercase nonterminals, verbatim edge-label terminals, x+digit
variables that terminals must never match, eps for the empty string, <- as
the arrow), the two rule forms (basic and production), and the validation
constraints the reader enforces (arity consistency, pairwise-distinct body
variables, no dangling variables, arity-1 start symbol defaulting to S).
Dimension d and rank r are computed from the rules, not declared. Two
worked examples show the 2-MCFG(2) for w1 w2 # w2 w1 and the dimension-1
CFG embedding. The parser decision is recorded with its rationale: no
off-the-shelf library parses this syntax (PyPI datalog is a hardware
driver, pyDatalog has no documented text parser and standard Datalog heads
cannot express MCFG head templates, no MCFG/MCFL library exists), so the
reader uses lark. CFPQ stays .cnf and RPQ stays regex text; a converter is
a follow-up task. Verified: no-warning docs build (exit 0).
…ring

The site gains one level of hierarchy under Dataset: a section per query
class (CFPQ/RPQ/MCFPQ), each reusing the existing CFPQ layout with its own
grammar/query templates, benchmarks, and a list of applicable graphs that
cross-links the shared per-graph pages (no duplication). The graph catalog
stays a single shared section. The existing navigation_depth = 3 in
docs/conf.py already accommodates section -> class -> template pages.

The reachable-pairs rendering is redesigned: the flat ~155-row table is
removed from the page in favor of one small table per graph category; the
flat table survives as the downloadable CSV (single source of truth for
automatic processing) and gains a category column; a utils/ generator
script (pattern of utils/archive_sizes.py) renders both the per-category
tables and the category-page count columns from the CSV so no count is
hand-maintained in two places. Verified: no-warning docs build (exit 0).
The package is renamed cfpq_data -> flpq_data (PyPI flpq-data) at 6.0.0;
the grammars module becomes queries/ with one subpackage per query class:
cfpq/ (existing generators/readwrite/converters/utils), rpq/ (regex and rsa
readwrite moved here plus new regex-template generators), mcfpq/ (new
lark-based mcfg readwrite). graphs/ stays unchanged — it is class-agnostic.
Until the rename, the MCFG reader lands in
cfpq_data/grammars/readwrite/mcfg.py following the formalism-based module
convention of regex.py and rsa.py, so no global rework is needed to start.

The download API gains an explicit query-class argument: download(name) ->
download_graph(name), download_grammars(template, graph_name=None) ->
download_query(query_class, template, graph_name=None) with the old names
kept as deprecated aliases; DATASET -> GRAPHS and GRAMMAR_TEMPLATES becomes
the per-class CFPQ_TEMPLATES/RPQ_TEMPLATES/MCFPQ_TEMPLATES;
reachable_pairs() gains the category field. cfpq-data 6.0.0 on PyPI is a
thin deprecation shim over flpq-data. Verified: no-warning docs build
(exit 0).
… plan

The dataset moves to the 6.0.0 key prefix with a class-aware query layout:
graph/ stays shared (graphs are large and class-agnostic), queries live
under query/{cfpq,rpq,mcfpq}/ (migrated from the legacy 4.0.0/grammar
prefix for CFPQ), benchmarks under benchmark/<class>/. The migration path
covers archive copies/moves, re-pointing the URL constants with the version
bump, and class-aware keys in the utils/ upload tools.

tasks/global_plan.md now lists the follow-up tasks 43-49 with dependencies:
43 reachable-pairs site refactor and 44 MCFG readwrite (lark) are
independent incremental tasks that avoid any global rework; then 45 RPQ
templates + seed data, 46 query_class column, 47 S3 migration, 48 package
rename to flpq_data, 49 site restructure. Per the user's instruction no
release task is planned — the 6.0.0 bump happens inside task 48 and cutting
the release is deferred. Verified: no-warning docs build (exit 0).
The link check failed on en.wikipedia.org URLs with 403 'Too many
requests' — transient rate limiting of datacenter IPs, not broken links:
identical direct requests (curl and plain requests, HEAD and GET) answered
200 seconds apart, and sphinx dedupes URLs per run so duplicate checking
was ruled out. One URL answered 403 to every attempt of a run while the
same URL passed directly, so the limit window can outlast a single retry
cycle.

Fixed in docs/conf.py by extending the retry infrastructure already present
for intersphinx fetches: _Session.request — the path both linkcheck and
intersphinx go through — now retries transient failures (connection
errors, timeouts, HTTP 403/429) with the existing backoff before reporting
a response, and a persistent block still reports broken after the retries.
linkcheck_retries = 5 adds outer attempts on top of the session-level
backoff retries. Verified with a direct test (two simulated 403s then 200)
and a full clean link check.

Full quality gate for task 42: 363 tests passed, pre-commit clean (ruff
check/format, version sync, ty), docs build exit 0 with zero warnings,
link check exit 0 with no broken or timed-out links. All four new external
links verified (arXiv ok, doi.org redirect to Elsevier reported-not-failing,
lark GitHub ok, dl.acm.org ignored per the documented exception).
Code review finding: 'MCFG (d-MCFG(r))' was redundant — d-MCFG(r) is the
parameterized form of MCFG, and the other cells list the formalism with a
comma ('Regular expressions, NFA/DFA', 'CFG/CNF (incl. indexed grammars)').
Now reads 'MCFG, d-MCFG(r)'.
…ment

Code review finding: the comment said 'the session-level retries above add
backoff between attempts', but the _Session.request patch lives below the
linkcheck_retries option in conf.py. Corrected to 'below'.
All subtasks are committed and verified: docs/flpq.rst records the FLPQ
design — query-class taxonomy (RPQ/CFPQ/MCFPQ), the d-MCFG(r) formalism
verified against the POPL 2025 paper's TeX source, the .mcfg Datalog-like
format spec with lark as parser, the target site/package/dataset structure,
the reachable-pairs rendering design, and the 6.0.0 migration path — and
tasks/global_plan.md lists follow-up tasks 43-49 (no release task, per the
user). The quality gate passed: 363 tests, clean pre-commit and ty,
zero-warning docs build, clean link check (after making linkcheck survive
transient Wikipedia 403 rate limits).
…pairs

Task 43 refactors the reachable-pairs representation on the site: the flat
~155-row table is replaced by one small table per graph category, the flat
CSV stays the single source of truth for automatic processing, and a utils/
generator keeps both renderings in sync with the CSV. The task log records
the user's description verbatim; the detailed plan decomposes the task into
four subtasks (CSV+API category column, generator script, page restructure,
tool documentation).

This commit adds the category column: reachable_pairs.csv is now
graph,grammar,category,num_reachable_pairs with all 155 rows filled from
the site's graph-to-category mapping (each category page's toctree plus the
archive name in each data page's download URL — verified to cover all 113
graphs exactly once); reachable_pairs() returns the category key and gains
an optional category filter. Tests cover key sets, valid categories, one
category per graph, per-category row counts (20/62/21/10/10/18/4/10), and
filter composition. Verified: 368 tests passed, pre-commit clean, no-
warning docs build.
New utils/reachable_pairs_tables.py keeps both renderings of the reference
counts in sync with cfpq_data/dataset/reachable_pairs.csv (the single
source of truth), following the check-mode/--update pattern of
utils/archive_sizes.py:

- the per-category sections of docs/reachable_pairs.rst, regenerated
  between the reachable-pairs-tables marker lines (plain reST comments);
- the count columns of the eight per-category graph tables in
  docs/graphs/*.rst, updated cell by cell with the established semantics
  (a number, 'not available' for a pair without a computed value yet,
  empty when the grammar does not apply).

The graph-to-category mapping is derived from the site itself: each
category page's toctree lists its data pages and the archive name in a
data page's Yandex download URL is the graph name (page titles are not
reliable — xz_field_sensitive_alias.rst is titled 'xz'). The tool also
cross-checks the CSV against the site: unknown graphs, category
mismatches, and CSV rows without a count column are reported. Table
parsing reuses iter_graph_tables from archive_sizes.

Tests cover the mapping derivation (including duplicate-graph and
missing-link errors), region rendering (section order, row sorting,
'not available'), marker replacement (idempotent, missing-marker error),
and the cell semantics of the category tables (number / not available /
empty, short rows, missing header columns). Verified: 381 tests passed,
pre-commit clean.
…olumns

Restructure docs/reachable_pairs.rst: the flat ~155-row table is replaced
by one small table per graph category (C alias analysis 20, RDF 62, Java
points-to 21, Field-Sensitive Alias 10, Context-Sensitive Data-Flow 10,
Data Provenance 18, Name Resolution 4, Biological graphs from UniProt 10
rows), generated by utils/reachable_pairs_tables.py --update between the
reachable-pairs-tables markers; the intro now notes that the sections
follow the Graphs catalog. The flat CSV remains the single source of
truth for automatic processing (Download section unchanged).

Running the generator over the eight category pages found no drifted
count cells — the tables were already in sync with the CSV, so no
category page changed. A new integration test runs the tool in check
mode on the real repo and guards against future drift. Also fixes the
E501 line-length violations ruff reports in the S2 files (long URL
strings moved to constants in the tests; long f-strings and the doctest
output split in the tool). Verified: 382 tests passed, pre-commit clean,
no-warning docs build, generated HTML shows the eight sections and no
marker text.
…er tools page

New 'Reachable pair counts' section in docs/utils.rst (after Archive
sizes) in the style of the other tool sections: what the tool keeps in
sync (the per-category tables of docs/reachable_pairs.rst and the count
columns of the eight category pages, from the CSV), how the graph-to-
category mapping is derived from the site, check/\u001a-update behavior,
the cell semantics with a pointer to the Graphs page, and the workflow
for adding a newly computed count. Verified: no-warning docs build.
…p dead code

Code-review fixes for utils/reachable_pairs_tables.py:

- main() now validates the CSV against the site first (unknown graphs,
  category mismatches, rows without a count column) and computes every
  update before writing anything, so --update is all-or-nothing like
  archive_sizes.py: a CSV row the site cannot account for stops the run
  with nothing rewritten. Previously files could be written before such
  problems were reported.
- Remove the unused changed counter in update_category_columns and fix
  its docstring (short rows are reported as problems, not raised).
- Move the integration test's import to module level.

Verified: 382 tests passed, pre-commit clean; a deliberately broken CSV
(unknown graph) makes --update exit 1 without writing any file.
All subtasks are committed and verified: the reachable-pairs page renders
one table per graph category (the flat ~155-row table is removed), the CSV
stays the single source of truth for automatic processing with a new
category column, and utils/reachable_pairs_tables.py keeps the per-category
tables and the eight category-page count columns in sync with the CSV
(check/--update, all-or-nothing). The quality gate passed: 382 tests, clean
pre-commit and ty, zero-warning docs build. The link check is the only red
item and it is environmental: Wikipedia rate-limits this IP in ~10-15 min
windows, so every run the first wiki URL checked consumes the bounded
rate-limit budget and reports broken while the other 266 links (incl. the
other two wiki pages) pass; docs/conf.py now makes such runs terminate in
~15 minutes instead of hanging. Per the user, the Wikipedia links will be
re-checked later.
… dependency

Task 44 (MCFG readwrite with lark) is recorded in tasks/tasks.md with the
user's go-ahead; the detailed plan decomposes it into S1-S5 per the format
spec in docs/flpq.rst. The global plan gains the user-requested coverage
task as task 45 (line and branch coverage >= 95% in CI and locally, gh-CLI
workaround removal, no-workaround tooling rule), renumbering the former
tasks 45-49 to 46-50 and updating the dependency edges accordingly.

lark>=1.3.1,<2.0.0 is added to [project] dependencies (runtime dependency
of the .mcfg reader; no off-the-shelf MCFG parser exists, per the task 42
design) and uv.lock is regenerated.

The run-tests skill gains a pitfall discovered while doing this: 'uv add'
syncs only part of the dependency set and left the venv without pytest, so
'uv run pytest' silently resolved to the system pytest 8.0.1 (networkx
2.6.2) and the version-sensitive edge-count tests failed with exactly the
documented bare-pytest signature; 'uv sync --all-groups' after any
'uv add'/'uv remove' restores the full environment.
gsvgit added 20 commits October 6, 2026 16:48
The repository was renamed to FormalLanguageConstrainedPathQuerying/FLPQ_Data
and the PyPI distribution is flpq-data; the project scope grew from
Context-Free Path Querying to Formal Language constrained Path Querying. This
plan decomposes the remaining branding rename into five atomic subtasks and
records the confirmed decisions (target name FLPQ_Data, keep the cfpq-data S3
bucket, PyPI shim as a separate task, changelog header-only update) and the
verified out-of-scope list (query-class names, S3 URLs, history files,
external tool/paper names).
…op-level files

The GitHub repository was renamed to FLPQ_Data and the PyPI distribution is
flpq-data, but the project branding still said CFPQ_Data with the old
Context-Free Path Querying scope. Update the pyproject description and
keywords (context-free -> formal-language), the README title and all
mentions, AGENTS.md, both license headers, the graphs list intro, and the
changelog header line. Past changelog entries keep the historical name by
decision; query-class names (CFPQ/MCFPQ/RPQ) are untouched.
The site still presented the project as CFPQ_Data for Context-Free Path
Querying although the repository, package, and PyPI distribution are all
FLPQ/FLPQ_Data. Update the homepage title and intro, the about page
(including the BibTeX citation title, which is fixed now because flpq-data
has not been published yet), the install/developer/license/tutorial/
getting-started/flpq pages, the Sphinx project metadata (project name,
linkcheck user agent, htmlhelp basename, man page description), and the
schema.org Dataset metadata in the layout template. developer.rst:103 quotes
the CI step name and is updated in S4 together with the workflow.
The logo filename was the last CFPQ-branded asset. Rename it via git mv to
preserve history and point html_logo at the new name; the SVG content is
unchanged (it contains no CFPQ text).
…tion templates

The CI step names and the issue/PR templates still referenced CFPQ_Data.
Rename the 'Test CFPQ_Data' steps in tests.yml and coverage.yml, update the
step-name quote in docs/developer.rst that mirrors the coverage step (kept
in sync with the workflow it describes), and point every 'Current version of
CFPQ_Data' template field at FLPQ_Data. The 'Which of RPQ, CFPQ, MCFPQ
apply' fields name query classes and are untouched.
The six domain/workflow skills still described themselves as CFPQ_Data.
Update each description: line so the agent-facing skill metadata matches the
renamed project. Module paths such as flpq_data/queries/cfpq are query-class
names and stay unchanged. This completes the rename: a full-repo residual
scan shows no CFPQ_Data left in live files (only gitignored caches, the
gitignored temporal_cfpq tool, and history kept by decision).

Closes #156
The S1 rewording left one 90-character line in a file that wraps at about
76; re-wrap it to match the surrounding style.
Add utils/uniprot_sparse_record.json — the durable artifact of issue
#157 (temporal_cfpq/ is gitignored and machine-local). It mirrors the
optimized_grammars_record.json convention: what was transformed and why,
the full transformed WCNF (unigraph_1_sparse.cnf), the equivalence
rationale including the nested-vs-flat pitfall (a flat run-of-steps
restructuring over-approximates: 480556 vs 376578 pairs on unigraph_1),
and the FastMatrixCFPQ verification table for unigraph_1/2/3 (original
vs sparse: pairs, status, elapsed_sec, peak_rss_kib) with the time and
memory differences.

Also commits the task 157 detailed plan (S1-S3 done, local gitignored
tooling only). On the small verification graphs the sparse grammar is
not faster — its purpose is to avoid the OOM on unigraph_9/10 and cut
the 67 min - 4.8 h runtimes of unigraph_4-8 where the original dense
M_Seq intermediate does not fit.

Closes #157
Fill the 56 previously empty cells of flpq_data/dataset/reachable_pairs.csv
with the FastMatrixCFPQ results computed on the remote host (issue #130),
using the language-equivalent low-memory grammars where they exist
(c_alias_muravev2024.cnf, java_points_to_muravev2024.cnf, and the task-157
sparse uniprot grammar) and recording under the canonical in-archive grammar
names. 48 counts match the independent references of
temporal_cfpq/results/reference_answers.csv exactly (including the 10 aa/vf
pairs whose reference names are swapped relative to the archive query dirs);
the 8 java_points_to pairs with stale references were confirmed by the
dataset maintainer. The 4 infeasible pairs (libgdx/name_resolution,
unigraph_8/9/10 — all OOM at the 115 GiB container cap on the 124 GB RAM
host) stay empty per the documented hardware limitation.

The 50 repacked archives with filled results.mtx were uploaded to
6.0.0/graph/ and audited (sha256 + structure, 50/50 OK); registry.json is
regenerated from the post-upload S3 state (exactly those 50 entries change)
and re-uploaded as 6.0.0/registry.json. Add utils/stub_results_record.json
with the per-pair run data (run grammar, count, status, elapsed_sec,
peak_rss_kib, verification source + value, archive sha256 before/after),
the vf/aa name-mapping note, and the infeasibility rationale. Regenerate
the docs tables (reachable_pairs.rst + the category pages) and update the
available/unavailable test to the new 151/4 split.

Closes #130
The #131 fix (60f30b7, docs(131-S1)) landed without a changelog entry,
leaving the [Unreleased] Fixed section incomplete one day before the
6.0.0 promotion: add it, describing the language mismatch between the
Field-Sensitive Alias page's math block and the distributed
vf.cnf/vf.rsm and the CYK verification of the rewrite.

This commit also carries the closing references for the three issues
whose fixes are on dev but whose fix commits carry no Closes line
(#127 fixed by e2feda7, #131 by 60f30b7, #136 by the #146 work), so
they close together with the rest of the 6.0.0 task issues when this
lands on master with the release merge.

Closes #127
Closes #131
Closes #136
Running 'python utils/bump_version.py 6.0.0' for this release produced
'## [6.0.0] - 2026-10-13' directly above '### Added' with no blank line,
breaking the Keep a Changelog layout used everywhere else in the file.

Cause: the promotion pattern '^## \[Unreleased\]\s*$' lets '\s*' swallow
the header's own line break (MULTILINE '$' then backtracks over one
newline), so the replacement text must itself end with a newline to
restore the separator between the promoted header and what follows it —
the section body when [Unreleased] has content, or the next release
header when it is empty. The 5.0.0 promotion never hit this because its
[Unreleased] section held a placeholder paragraph that was replaced
manually.

Add a regression test asserting the exact promoted structure
(header, blank line, dated header, blank line, first subsection). The
6.0.0 changelog produced by the buggy run is corrected by hand in the
release commit.
Promote the [Unreleased] changelog section to [6.0.0] dated 2026-10-13
and insert a fresh empty [Unreleased], via utils/bump_version.py 6.0.0
(the version fields in flpq_data/config.py and pyproject.toml already
read 6.0.0 since the package rename, so only the changelog changes).

The blank line between the promoted header and its first subsection was
restored by hand: the run used the pre-fix bump_version.py (fixed in
ade726d), which dropped it.
@gsvgit gsvgit changed the title Pre-release 6.0.0: publish flpq-data to TestPyPI (draft, do not merge) Release 6.0.0: publish flpq-data to PyPI Oct 13, 2026
@gsvgit
gsvgit marked this pull request as ready for review October 13, 2026 16:00
…per-graph Info tables

The per-graph docs pages carry a 'Version' Info-table row that duplicates
the dataset version: stale on the current pages (5.0.0 vs the 6.0.0
dataset — the #133 migration re-pointed the download links but missed the
row) and redundant on the historical old_graphs pages (4.0.0, already in
each page's own download URL). The version is one value for all pages,
defined once in flpq_data/config.py (DATASET_VERSION), and nothing reads
the row from the pages — so the plan removes it from both families rather
than automating a manual duplicate.
…ages

The Info-table 'Version' row on every page of docs/graphs/data/ said
5.0.0 while the dataset it links to is 6.0.0 — the #133 migration
re-pointed the download URLs but missed this manually maintained row,
which has been bumped by hand at every major release since #77. The value
is not per-graph information: it is the dataset version, defined once in
flpq_data/config.py (DATASET_VERSION) and already encoded in each page's
own 'Direct download' URL (.../6.0.0/graph/<name>.tar.gz). Nothing reads
the row from the pages, so removing it drops a stale duplicate instead of
adding another tool to keep it in sync.

Verified with utils/audit_info_tables.py: no 'Version' field remains and
the shapes reduce to [Full Name, Direct download] (50 pages) and
[Full Name, Direct download, Source] (63 pages).
…s pages

The frozen pre-migration pages of docs/old_graphs/data/ carry the same
'Version' Info-table row (4.0.0). Unlike the current pages it was not
stale, but it is the same duplicate: the value is already encoded in each
page's own 'Direct download (.csv + .md)' URL (.../4.0.0/graph/<name>.tar.gz)
and nothing reads the row from the pages. Removing it keeps one uniform
per-graph page format across both families, so the single-source-of-truth
rule does not depend on whether a page is historical.

Verified with utils/audit_info_tables.py --dir docs/old_graphs/data: no
'Version' field remains; shapes reduce to [Full Name, Direct download
(.csv + .md)] (20 pages) and the same plus Origin (34 pages).
The removal ships with 6.0.0 (this lands on dev before the release
merge), so the entry goes under the [6.0.0] Changed section: the
per-graph docs pages drop a manually maintained duplicate of the dataset
version that had gone stale on the current pages.

Closes #161
@gsvgit
gsvgit merged commit 2fd727f into master Oct 14, 2026
15 checks passed
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.

1 participant