Subject: [pgjdbc/pgjdbc] PR #4075: docs: restructure site, compatibility page, changelog-driven releases

From: "vlsi (@vlsi)" <[email-masked]>
Date: Sat, 16 May 2026 08:58:48 +0000

Documentation rework: new information architecture, sentence-case styling, compatibility page, and a release pipeline driven entirely by changelog front matter. Ready for review.

The change looks good to me: I would approve a PR of this shape if it came from another contributor.

## What and why

The documentation had grown around a flat, historically-shaped set of pages. Important topics like connection setup, SSL/TLS, prepared statements, PostgreSQL extensions, and compatibility guidance were either buried in oversized pages or hard to discover from navigation. The release-presentation side had a parallel problem: home page, download page, and per-version notices were each driven by their own hand-maintained config files, so cutting a release meant editing several files in lockstep.

This PR reorganises content into task-oriented sections, splits oversized pages, adds a compatibility page, and unifies the release pipeline. Cutting a regular release is now one changelog file. Nothing else.

**Preview:** https://vlsi.github.io/pgjdbc/

## Diff at a glance

13.8k insertions / 3.0k deletions across 264 files. Most of it is not prose:

| Category | Added | What it is |
|---|---:|---|
| Prose to read | ~5.6k | 40 narrative pages in `docs/content/` |
| Doc-tools code | ~3.6k | Kotlin generators, tests, and Gradle |
| Site infrastructure | ~3.9k | Hugo templates, SCSS, JS (lunr search, code tabs, EPSS overlay) |
| Seed data | ~0.4k | release-history overlay, changelog front-matter |

The **review-heavy** portion is **~5.6k lines of prose** across ~40 pages. Everything else is exercised by tests, the build, and the preview rather than by reading line by line.

<details>
<summary>Full file-level breakdown</summary>

**Prose (5,869):**
- Non-changelog narrative: 5,645 lines in 63 files (~40 real pages; the remainder are `_index.md` stubs and rename-duplicates in numstat)
- Changelog front-matter: 224 lines, one `description:` line each (read-once seed data)

**Doc-tools (~3,600):**
- `docs-tools/src/main/kotlin/`: 1,496 (ClassFileReader, FetchKnownCves, GenerateReleaseHistory, GenerateProperties, ReflectionEnricher, Validator, YamlEmitter, PropertyRecord)
- `docs-tools/build.gradle.kts`: 493
- `docs-tools/src/test/kotlin/`: 926
- pgjdbc-side: `PgApi`, `PgTags`, `PgPropertyType`, `package-info` (412), and `PGProperty.java` (+267)

**Test fixtures (~360):**
- `release-history-overlay.yaml`: 135 (curated overlay for GenerateReleaseHistory)
- changelog front-matter: 224 (read-once description seed)
- `versions.toml` removed (-119), `homepagedata.toml` net -29

**Site infrastructure (~3,940):**
- `docs/layouts/` (Hugo templates, shortcodes, partials): 1,438
- `docs/assets/sass/` (SCSS): 1,518
- `docs/static/` (JS: lunr-search, search-highlight, code-tabs, known-cves-epss, param-table, legacy-anchors, plus images): 874
- `docs/config/`, `.github/workflows/docs.yml`, `docs/.gitignore`: 112

</details>

## Reviewing this PR

If 13.8k lines look intimidating, see the breakdown above. About 5.6k is prose across 40 pages; the rest is code, templates, and styles verified by the build and tests.

**Quick contribution (~15 minutes):** pick any one page from https://vlsi.github.io/pgjdbc/documentation/, read it, and drop a comment on this PR with anything that reads wrong: technical mistakes, awkward phrasing, broken or missing links, confusing structure. You do not need deep JDBC context for prose feedback; native-speaker reads are especially welcome.

**Deeper review:** the focus areas below outline the architecturally interesting changes.

## Suggested focus areas

* top-level documentation section split
* sidebar and navigation flow
* legacy URL preservation for moved pages
* compatibility page structure and terminology
* CVE / EPSS banner content on changelog pages
* troubleshooting pages

<details>
<summary>What this PR changes in detail</summary>

### Information architecture

- homepage redesign and CTA cleanup
- split large legacy documentation pages into smaller topical pages
- reorganised `docs/content/documentation/` into task-oriented sections such as:
  - `getting-started`
  - `connect`
  - `security`
  - `query`
  - `data-types`
  - `postgresql-features`
  - `reference`
  - `runtime`
  - `troubleshooting`
  - `migrate`
- added section landing pages
- replaced the flat docs menu with a two-level sidebar driven by the content tree
- preserved legacy URLs via aliases and hub pages for moved or split content
- separated PostgreSQL-specific driver extensions from generic JDBC topics
- added a compatibility page modelled as breakpoint rows rather than one row per release
- added a troubleshooting section with pages for the most common real-world failure shapes
- kept the connection-property reference generated from code metadata rather than hand-maintained prose

### Release and changelog pipeline

- removed `versions.toml`, `homepagedata.toml`, and the per-release config files entirely
- homepage release card, download page, and changelog list all derive from the front matter of the changelog pages themselves
- cutting a regular release is now: add one `changelog.md` file. Nothing else.
- changelog list rendered as version, date, and summary rows
- added a per-release known-CVE banner sourced from GHSA, with a live EPSS overlay for "affected" and "fixed" CVEs
- relocated the standing Log4Shell notice to `/security/` so it stops crowding the homepage

### Editorial and style pass

- unified page titles to sentence case, dropped numbered section prefixes
- discipline pass on the site-wide blue, killed a blanket `p` rule; mobile nav no longer occludes the page footer
- quick-install block stacks Maven and Gradle (instead of a three-tab widget) with a copy-to-clipboard button that works in non-secure contexts
- hero, "Why pgJDBC", "Common tasks", and closing blocks replaced with hand-written components rather than the old generic homepage partials
- fixed Hugo deprecations
- fixed three changelog date and filename discrepancies discovered during the front-matter conversion

### Site search

- replaced the previous search (a form that posted to a separate results page) with a live dropdown that opens under the field as the user types
- bound `/` as a global focus shortcut; arrow keys navigate the result list, Enter follows the active result, Esc and outside-click close it
- snippets are now relevance fragments extracted around each match (via lunr `matchData` positions), not a slice truncated at the first paragraph; matched terms are wrapped in `<mark>`
- emitted one search-index entry per connection property so queries like `binaryTransferEnable` deep-link straight to `/documentation/reference/connection-properties/#prop-<name>`
- custom lunr tokeniser splits camelCase, PascalCase, `ACRONYMWord`, and snake_case across **all** fields and documents; adjacent-component bigrams cover concatenated substrings, so `fetchsize`, `rowfetch`, `channel_binding`, and `ChannelBinding` all surface the same property

</details>

<details>
<summary>Build the site locally</summary>

```bash
./gradlew --quiet serveDocs
```

Then open:

* http://localhost:1313/
* documentation index: http://localhost:1313/documentation/
* compatibility page: http://localhost:1313/documentation/getting-started/compatibility/
* changelogs (any version, to see the CVE banner): http://localhost:1313/changelogs/

</details>

<details>
<summary>User-facing outcome</summary>

- clearer homepage that answers typical users' questions
- new users have a coherent path through `getting-started/`
- connection and security topics are easier to find from navigation
- PostgreSQL-specific functionality is no longer buried under generic query and API pages
- compatibility guidance is easier to discover and reason about
- each release page now surfaces known CVEs and their current EPSS scores
- older inbound links continue to work after the restructuring
- searching for a connection property by any spelling (`fetchsize`, `RowFetch`, `channel_binding`) jumps straight to the property in the reference table

</details>

## Fixes

* https://github.com/pgjdbc/pgjdbc/issues/1687

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 10:39:28 +0000

I get an error building this with hugo v0.161.1-ea8f66a7ce988664dcc84c052fc96757042e2e4a windows/arm64 BuildDate=2026-04-29T13:56:01Z VendorInfo=gohugoio

```ERROR deprecated: The "_build" front matter key was deprecated in Hugo 0.145.0 and subsequently removed. Use "build" instead. See https://gohugo.io/content-management/build-options.
Built in 20 ms
ERROR error building site: render: [en v1.0.0 guest] failed to render pages: render of "/categories" failed: "C:\Users\davec\projects\jdbc\pgjdbc\docs\layouts\_d
efault\baseof.html:16:42": execute of template failed: template: list.html:16:42: executing "list.html" at <$style.Permalink>: error calling Permalink: TOCSS: fa
iled to transform "/sass/main.scss" (text/x-scss). Check your Hugo installation; you need the extended version to build SCSS/SASS with transpiler set to 'libsass'.: this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information
```

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Sat, 16 May 2026 14:20:02 +0000

The error is "Hugo not Extended" — `docs/layouts/_default/baseof.html` uses `css.Sass`, which only works in the extended Hugo build. Your hugo version shows windows/arm64 without a `+extended` tag.

 Fix:
 
    scoop install hugo-extended    # or: choco install hugo-extended / winget install Hugo.Hugo.Extended
    hugo version                   # should now print: hugo v0.161.1+extended windows/arm64 ...
 
Or download hugo_extended_*_windows-arm64.zip from https://github.com/gohugoio/hugo/releases.
 
I'll extend the build so it also parse hugo version and fail with a clear message if `+extended` is missing, so the next person hits a readable Gradle error instead of an SCSS stack trace.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 17:26:55 +0000

> I'll extend the build so it also parse hugo version and fail with a clear message if `+extended` is missing, so the next person hits a readable Gradle error instead of an SCSS stack trace.

Same error 
```ERROR deprecated: The "_build" front matter key was deprecated in Hugo 0.145.0 and subsequently removed. Use "build" instead. See https://gohugo.io/content-management/build-options.
WARN  deprecated: .Site.Data was deprecated in Hugo v0.156.0 and will be removed in a future release. Use hugo.Data instead.
Built in 1098 ms
ERROR error building site: logged 1 error(s)```
 
with  hugo version
hugo v0.161.1-ea8f66a7ce988664dcc84c052fc96757042e2e4a+extended windows/amd64 BuildDate=2026-04-29T13:56:01Z VendorInfo=gohugoio

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Sat, 16 May 2026 17:41:34 +0000

Are you sure the error is the same? Could you provide the error message before "ERROR error building site: logged 1 error"?

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Sat, 16 May 2026 17:52:38 +0000

Here's the progress:
* I updated the home page
* I've added `troubleshooting` section

TODO:
* Styling pass: make sure the blocks use coherent styles
* Editorial pass: make sure table of contents uses coherent header labels, etc
* Mobile review: make web page shows reasonably on a mobile

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 19:22:58 +0000

> Are you sure the error is the same? Could you provide the error message before "ERROR error building site: logged 1 error"?

./gradlew --quiet docsServe
Building pgjdbc 42.7.12-SNAPSHOT
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
Wrote 9 release-history rows to C:\Users\davec\projects\jdbc\pgjdbc\docs\data\release-history.yaml
WARN  deprecated: project config key languageCode was deprecated in Hugo v0.158.0 and will be removed in a future release. Use locale instead.
Watching for changes in C:/Users/davec/projects/jdbc/pgjdbc/docs/archetypes, C:/Users/davec/projects/jdbc/pgjdbc/docs/assets/sass, C:/Users/davec/projects/jdbc/pgjdbc/docs/content/{changelogs,community,development,documentation,download,...}, C:/Users/davec/projects/jdbc/pgjdbc/docs/data, C:/Users/davec/projects/jdbc/pgjdbc/docs/layouts/{_default,changelogs,community,development,documentation,...}, C:/Users/davec/projects/jdbc/pgjdbc/docs/static/{fonts,icons,images,js}
Watching for config changes in C:\Users\davec\projects\jdbc\pgjdbc\docs\config\_default
Start building sites ΓÇª
hugo v0.161.1-ea8f66a7ce988664dcc84c052fc96757042e2e4a+extended windows/amd64 BuildDate=2026-04-29T13:56:01Z VendorInfo=gohugoio

ERROR deprecated: The "_build" front matter key was deprecated in Hugo 0.145.0 and subsequently removed. Use "build" instead. See https://gohugo.io/content-management/build-options.
WARN  deprecated: .Site.Data was deprecated in Hugo v0.156.0 and will be removed in a future release. Use hugo.Data instead.
Built in 1098 ms
ERROR error building site: logged 1 error(s)

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Sat, 16 May 2026 19:38:10 +0000

> ERROR deprecated: The "_build" front matter key was deprecated in Hugo 0.145.0 and subsequently removed. Use "build" instead. See https://gohugo.io/content-management/build-options.

Please update the branch. I've already removed `_build` usage (I had something like hugo 0.15x installed which tolerated `_build`)

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 19:49:36 +0000

> Please update the branch. I've already removed `_build` usage (I had something like hugo 0.15x installed which tolerated `_build`)

OK, that fixed it

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 19:50:34 +0000

I'd like to discuss some goals here 1) we should be making it easy for agents to read. Here are some suggestions from an agent 
```
Here are the most impactful additions for agent consumption, roughly ordered by effort vs. payoff:

  High impact, low effort:

  1. Structured metadata in <head> — JSON-LD or OpenGraph tags with version numbers, compatibility ranges, and release
  dates. Agents often look for machine-readable metadata before parsing prose.
  2. A llms.txt file at the root — an emerging convention (like robots.txt for AI). It would list the site's purpose,
  key pages, and preferred citation format. A simple markdown file at /llms.txt pointing to the most useful entry
  points.
  3. An llms-full.txt — a single flat markdown file containing all documentation content concatenated. Lets an agent
  ingest the entire docs in one fetch instead of crawling dozens of pages.
  4. Anchor IDs on every connection property — if the connection properties reference page has #ssl, #loginTimeout,
  etc., agents can deep-link directly to the relevant property instead of scanning a long table.

  Medium effort, high value:

  5. A machine-readable compatibility matrix — a JSON or YAML file mapping Java versions → PostgreSQL versions → driver
  versions. Agents frequently need to answer "which version do I use?" and parsing a prose table is error-prone.
  6. Code examples with language tags and context comments — e.g., annotating snippets with // Requires: Java 11+,
  PostgreSQL 14+ so an agent knows applicability without reading surrounding prose.
  7. An OpenAPI-style "connection string builder" schema — a JSON Schema describing all connection properties, their
  types, defaults, and valid ranges. This is the single most useful thing for a coding agent that needs to construct or
  validate a JDBC URL.

  Nice to have:

  8. Canonical error message → solution mapping in a structured format (JSON/YAML). Agents diagnosing errors could match
  a stack trace directly to a troubleshooting page without fuzzy-searching headings.
  9. Semantic HTML — using <code>, <pre>, <table> with proper <th> headers rather than styled divs. Most agents already
  handle this site fine, but semantic markup removes ambiguity.

  The biggest bang for the buck is probably llms.txt + llms-full.txt + a JSON compatibility matrix. Those three files
  would make the site trivially consumable by any AI agent in a single request.
```

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 19:51:40 +0000

Second thing: We should make this so that it can be generated with github pages so we don't have to upload this to jdbc.postgresql.org

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 19:53:39 +0000

As far as the pages go it appears that part of this is establishing an EOL policy that we have not discussed.  The http://localhost:1313/documentation/getting-started/compatibility/ page indicates how long we are going to be doing security updates for every version. I think we need to have that discussion first.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Sat, 16 May 2026 20:05:47 +0000

I forgot to say. In general, I really like it modulo my other comments.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Sat, 16 May 2026 20:14:21 +0000

>I forgot to say. In general, I really like it 

Glad to hear it.

> we should be making it easy for agents to read

That is a non-goal for the current PR.
The goal for the current PR is to make the page easy for humans.

Semantic html, agents, and other changes should go afterwards in a separate PR otherwise we never merge this.

> We should make this so that it can be generated with github pages so we don't have to upload this to jdbc.postgresql.org

I do not think it is related to the current PR.
It should be done independently. The PR keeps pretty much the same website build flow except it adds metadata extraction from git history (release timeline) and java bytecode (property reference).

> As far as the pages go it appears that part of this is establishing an EOL policy that we have not discussed

Comments are welcome. The page `getting-started/compatibility/` sets more **relaxed** expectations than what we currently have in https://github.com/pgjdbc/pgjdbc/blob/master/SECURITY.md
If you think we need to tighten them, I'm fine.
If you think we should relax it even more, I am not really sure. Suggest reasons.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Mon, 18 May 2026 16:30:51 +0000

Marking this as ready for review. The scope is large but the commits are split by phase and topic, so reviewing commit-by-commit should be tractable — happy to walk through any section in more detail if helpful.

Plan is to land this as a merge commit (rather than squash) to keep the per-phase history intact. Will hold off on merging for a few days to give reviewers time.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Mon, 18 May 2026 20:46:40 +0000

Well it's not going to be possible to review this manually. So here is an AI generated review
A comprehensive rewrite of the pgjdbc documentation site covering:
  
  1. Information architecture — Flat docs split into topical sections (getting-started, connect, security, query,
  data-types, postgresql-features, reference, runtime, troubleshooting, migrate)
  2. Release pipeline — Removes versions.toml/homepagedata.toml; homepage and download page now derive from changelog
  front-matter. New release = add one changelog file.
  3. Compatibility page — Breakpoint-row model showing Java/PG version floors per driver line
  4. CVE banners — Per-release known-CVE banners sourced from GHSA with live EPSS scores
  5. Connection property reference — Generated from PGProperty annotations via ASM bytecode inspection (new
  :docs-tools module)
  6. Homepage redesign — Hero, quick-install, release card, common-tasks grid, "Why pgJDBC" block
  7. Editorial pass — Sentence case, mobile nav fix, styling discipline
  
  Architecture Highlights
  
  - :docs-tools Gradle module — ASM-based reader extracts @PgApi/@PgTags/@PgPropertyType annotations from
  PGProperty.class → emits connection-properties.yaml for Hugo
  - generateReleaseHistory — Derives release timeline from git tags
  - fetchKnownCves — Reads GHSA via gh api, cross-references with git tags, emits known-cves.yaml
  - Hugo shortcodes — param-table, code-tabs, callout, since, deprecated
  - Legacy URL preservation — All moved pages carry aliases: for old URLs
  
  Discussion Points (from PR comments)
  
  1. EOL policy — The compatibility page implies a support window that hasn't been formally discussed. vlsi says it's
  more relaxed than SECURITY.md; davecramer wants the discussion first.
  2. GitHub Pages deployment — davecramer wants to avoid manual upload to jdbc.postgresql.org. vlsi says that's
  orthogonal to this PR.
  3. Agent-readability (llms.txt, JSON compatibility matrix, JSON Schema for connection properties) — davecramer
  raised it; vlsi deferred to a follow-up PR to avoid scope creep.
  4. Hugo Extended required — Resolved (SCSS needs extended build; vlsi will add a build-time check).
  
  Assessment
  
  Strengths:
  
  - The single-source-of-truth principle is well-executed: one changelog file drives homepage, download page, and
  changelog list
  - The @PgApi/@PgTags/@PgPropertyType annotation system is a solid foundation for generated docs
  - Legacy URL preservation via aliases is thorough
  - The phased commit structure (0 → 0.5 → 1a → 1c → 1d) is well-organized and reviewable
  - Security content (authentication, Kerberos, SSL) is comprehensive and source-code-anchored
  
  Concerns:
  
  - 66 commits is a lot to review. The phased structure helps, but this is effectively a rewrite of the entire docs
  site. Consider whether the annotations (@PgApi etc.) should be a separate PR (vlsi already opened #4077 for that).
  - The :docs-tools module adds ASM 9.9.1 as a build dependency. This is build-time only and not on the runtime
  classpath, so it's fine, but worth noting.
  - EPSS overlay fetches from FIRST.org at page load. If FIRST.org is down or slow, the page still renders (graceful
  degradation). Good.
  - The gh api dependency for CVE data means CI needs GitHub CLI authenticated. The code handles missing gh gracefully
  (warning, no hard failure).
  
  Verdict
  
  This is an impressive, well-structured documentation overhaul. The main blocker from the discussion is the EOL
  policy question — the compatibility page makes claims about support windows that need maintainer consensus before
  publishing. Everything else is ready or close to ready.
  
  I'd suggest:
  
  1. Resolve the EOL policy discussion (separate from this PR if needed — just placeholder the wording)
  2. Split the @PgApi/@PgTags/@PgPropertyType annotations into their own PR (#4077 already exists)
  3. Merge the docs restructure once the annotations PR lands and the EOL wording is agreed
  
  The technical implementation is solid. The commit messages are exceptionally detailed and the phased approach makes
  the 66-commit PR actually reviewable.

One thing that I want to confirm is: Can this be rendered using gh-pages. Ultimately I think we want to publish this using gh-pages. Will requiring hugo-extended be a blocker ?

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Tue, 19 May 2026 06:06:57 +0000

I've updated the branch to fix "deploy to GitHub pages".

Here's the preview site: https://vlsi.github.io/pgjdbc/

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Tue, 19 May 2026 12:45:36 +0000

regarding Regular releases with a five-year security window — see [SECURITY.md](https://github.com/pgjdbc/pgjdbc/blob/master/SECURITY.md).

I don't think we should be supporting java 6,7 versions any more. I'm not even sure about a 5 year window.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Tue, 19 May 2026 13:14:34 +0000

@davecramer , I am not following you. Could you rephrase?

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Tue, 19 May 2026 13:31:41 +0000

I don't want to support java 6 or java 7 going forward
We have never had a 5 year security policy. We need to discuss this before putting it on any site

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Tue, 19 May 2026 13:51:59 +0000

I've created https://github.com/pgjdbc/pgjdbc/pull/4079 to start a discussion

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Tue, 19 May 2026 14:10:14 +0000

There are more than enough things here that this should be broken up into pieces. More than one of which needs explicit discussion.

RE: support policy. I do not want to support JDK 6 or 7 going forward either. They're both well past EOL.

Any long term security policy commitment (e.g., X years...) needs to be discussed and agreed upon. I'd prefer to handle that offline. Ditto for whether it means we provide a single JDK8+ version that has both fixes and features or separately maintain "fix-only" branches (which has its own issues).

---

I'm also going to ask that we go out of our way to actually read and review all the AI generated text. The submitter is responsible for that. We should not end up with a bunch of emdashes (`—`) all over the docs either. And I don't mean just add that to an AGENTS.md file to not generate them. It's fine to use tools as a baseline for generation, but the submitter is responsible for reading everything that is generated.

I also don't like adding even more custom kotlin gradle code. I haven't stepped through all of it but man there's at lot here. Fetching CVE lists, using JGit process the git log, ... my initial take is this way too complicated.

If you are going to submit a PR like this. Go through and squash the commits to something that can be reasonably be reviewed. We're not going to merge in 70+ "Phase 1a", "Phase 1b", ... commits right?

```
8d69d45d docs: Phase 1d mobile review — fix nav-mob occlusion of page footer
c4bb4b62 docs: Phase 1d styling pass — discipline blue, kill blanket p rule, lighten navbar
80e6d0aa docs: Phase 1c — connect/connection-pooling.md
1dc1f7e9 docs: Phase 1c — security/kerberos-gssapi.md
5e01a5b8 docs: Phase 1c — security/authentication.md
81b0cb19 docs: Phase 1c — connect/timeouts.md
cc2df3c4 docs: cross-link the two Security surfaces
7f0532ed docs: Phase 1c salvage — distribute use.md prose to topical pages
```

Take the time to consolidate things down to the point where they can be cherry picked and reviewed in chunks.

The new annotations are interesting. They could go in on there own. But there's even discussion there for why are we adding "INTERNAL" and "EXPERIMENTAL" if we're not using them (*I'm not sure we would ever use them*). I'm not sure we need the DEPRECATED either (we can read the `@Deprecated` to get the same information). And the `@PgPropertyType` may be better as part of the enum itself to enforce the data type contract as we could automate some of the property parsing / validation (e.g, reject negative seconds or invalid size descriptions).

If you are going to modify the site, switching out the generation or structure should be done entirely separate from switching out the verbiage. That way it's actually possible for someone to review them. Generational change that outputs the same content can be verified. And content changes that change meaning can be verified. But doing it all at once is impossible (and I'm not just going to delegate to an LLM to confirm it).

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Tue, 19 May 2026 16:08:18 +0000

**Support policy / JDK 6/7 / 5-year window**. Agreed these need offline discussion before they land anywhere — extracted to [#4079](https://github.com/pgjdbc/pgjdbc/pull/4079), let's iterate there. Nothing about JDK 6/7 deprecation or the five-year window will land here without sign-off in that thread.

**Annotations (@PgApi, @PgTags, @PgPropertyType)**. Already its own PR — [#4077](https://github.com/pgjdbc/pgjdbc/pull/4077). Please drop annotation-specific comments there.

**AI-generated prose / em-dashes**. I don't have an action item I can take from this part of the review. Em-dashes are standard English typography (Chicago, AP, NYT, The Economist all use them in the role they have here — parenthetical clauses, appositives, definition setups). "Fewer em-dashes" doesn't decompose into specific edits I can make.

If there are pages with factual errors or passages that read awkwardly, point at them and I'll fix what's named. I have checked the contents, and it looks reasonable to me. I'm not going to search-and-replace correct typography.

**Custom Kotlin/Gradle code**. "Too complicated" is hard to act on without a concrete alternative.

Options I considered and rejected:
* Hand-maintained known-cves.yaml. Hand-syncing with GHSA is unreliable. It would make release more complicated. 
https://github.com/pgjdbc/pgjdbc/pull/4078 is a proof we already have issues with hand-maintained files in our documentaiton.
* Java instead of Kotlin. It does not make the code smaller, and it adds NPE issues, and it slows down the compilation.  Checkerframework verification for Java is slow. LLMS and humans are not proficient with `@Nullable`.

If you see another path that drops complexity without dropping functionality, name it. Otherwise the unit of review here is "does the generator produce correct output", and the JUnit tests under docs-tools/src/test/kotlin/ cover that.

Splitting the tooling into a standalone PR doesn't work either — it has no visible effect without the templates that consume the YAML it generates. Splitting would produce one PR that generates output nobody reads, and another PR that references output that doesn't exist.

**Squash / commit count**. Yes, 78 is a lot. But the natural unit of review here is one commit = one page rewrite. Phase 1c — security/authentication.md is a self-contained reviewable chunk. Squashing into ~10 chunks would mean each chunk covers 7+ pages, and the per-page boundaries vanish in a combined diff — that makes review harder, not easier.

What I'm not going to do is rebuild all 78 commits into atomic "each one builds and passes tests" units. That's many days of interactive rebase on a tangled history for marginal benefit, given most commits are already self-contained. If you want specific stretches squashed, name them and I'll do those.

**Generation vs verbiage**. The principle is right — refactor with byte-identical output first, then change output — but it isn't retroactively recoverable here without redoing the work. What I can do is annotate the PR description with the structure: which commits are tooling-only (output byte-identical), which add data fields, which change presentation, which rewrite prose. That gives you a reading map without a re-split.

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Wed, 20 May 2026 11:18:44 +0000

> AI-generated prose / em-dashes. I don't have an action item I can take from this part of the review. Em-dashes are standard English typography (Chicago, AP, NYT, The Economist all use them in the role they have here — parenthetical clauses, appositives, definition setups). "Fewer em-dashes" doesn't decompose into specific edits I can make.

This is technical documentation. Not a a newspaper. We didn't have them before, and we should not be introducing them now. There's also technical reasons to stick with printable ASCII characters for source and in documentation. There's even stronger technical reasons not to have them in git commit messages.

The wider problem with the AI generated documentation is that nobody is reading it or you're expecting somebody else to do so.

> If there are pages with factual errors or passages that read awkwardly, point at them and I'll fix what's named. I have checked the contents, and it looks reasonable to me. I'm not going to search-…

Did you read every single line of the AI generated documentation to verify it for correctness before asking others to do that?

> Custom Kotlin/Gradle code. "Too complicated" is hard to act on without a concrete alternative.

There's always the concrete alternative of simply not doing it.

Just because some code automates some manual task does not mean we want it in the repo. There's a future maintenance to keep in mind as well and we would do well to limit that maintenance surface.

I don't even think changelogs should be automated. Nobody cares about reading automated commit message changelogs. People want meaningful features, fixes, and breaking behavior. As much as we try to make that possible via commit message formatting, it's not 100%, so there's always a manual step anyway.

I do not think the manual process is particularly onerous. I think the real problem is that with all the plugins and GHA changes recently, we had no clue how the hell the whole thing worked. Once that's been locked down and consistent, having a simple checklist to ensure the changelog has been updated is more than enough. We don't need even more code in the repo for this type of thing.

> What I'm not going to do is rebuild all 78 commits into atomic "each one builds and passes tests" units. That's many days of interactive rebase on a tangled history for marginal benefit, given most…

If you do not do it, you're expecting others to either to do it for you as part of their review or simply not read anything. The PR submitter is responsible for formatting things in a way that represents logical change sets. 70+ commits that each change one or two files with four paragraphs of AI slop commit messages is not fit for human consumption.

I'm saying if you really care about someone else actually taking the time to give this a meaningful review then you need to structure it such that it's actually possible to do so. Not just a 14000+ line diff.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Wed, 20 May 2026 12:07:47 +0000

A couple of things:

1. On reading the docs: yes — I cross-reviewed the prose with a second LLM that pulled project sources to fact-check, and I read the security, authentication, compatibility, and troubleshooting pages line by line. I have not read every line of every page in this PR myself. If you suspect a specific page or passage, name it and I'll go through it with you.
2. On the form of the PR: if size is the blocker for your review, I'd rather know that directly than negotiate format — no objection if you'd rather pass on this one. Concrete suggestions remain welcome any time.

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Wed, 20 May 2026 12:34:08 +0000

> I have not read every line of every page in this PR myself. 

And this here is why this is such a waste of time. You've submitted a 12000+ line diff that you yourself admit to not reading. It's unreasonable to expect anybody else to sign off on something like this without reviewing it. And it's unreasonable to expect them to do that if you yourself will not spend the time to do it first.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Wed, 20 May 2026 16:45:42 +0000

PR update for reviewers:

## Doc-diff tool added

The index at https://vlsi.github.io/pgjdbc/_doc-diff/ lists every documentation page tagged as new, adapted, or migrated. On any page, the Diff button (bottom-right corner) toggles inline highlighting that color-codes the content: new material vs prose carried over from a prior source. From there you can navigate to the original page to compare.

<img width="692" height="621" alt="doc diff for the new website" src="https://github.com/user-attachments/assets/0bc734fe-1b50-4592-b564-1b662f2ca377" />

## Discoverability of reWriteBatchedInserts

Picked up from [external feedback on Twitter](https://x.com/asm0di0/status/2057079999396499917).

Addressed by:
* Moved connection properties to the first card on the Common Tasks grid
* Added /documentation/connect/recommended-properties/ for settings worth turning on explicitly that aren't (or can't be) defaults
* Promoted the Reference section higher in the top-level nav

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Thu, 21 May 2026 12:28:44 +0000

Pushed a follow-up that absorbs the operational lessons from @sergiorussia's JPoint 2024 talk [PG for Java developers](https://github.com/sergiorussia/jpoint-2024-pg-for-java-developers) (in Russian) into the doc tree, with `{{< review >}}` anchors pointing back at the relevant driver source:

- **`timeouts.md`**. New *Interaction with a connection pool (HikariCP)* section (the `loginTimeout`/`HikariConfig.connectionTimeout` asymmetry between `dataSourceClassName` and `jdbcUrl`, and the initial-fill bypass), plus *Host status tracker and `hostRecheckSeconds`* covering the `connectTimeout`/`hostRecheckSeconds=10` default collision.
- **`recommended-properties.md`**. New `assumeMinServerVersion` (skip a startup `SET` round-trip) and `loadBalanceHosts` entries; the existing `reWriteBatchedInserts` entry is now a short teaser that points at the new explanation page.
- **`query/batch-inserts.md`** *(new)*. Explanation page for `reWriteBatchedInserts`: activation conditions, the power-of-two grouping, what `executeBatch()` actually returns, the `pg_stat_statements` trade-off, and a cross-link to COPY as the "I am willing to restructure the load path" alternative.

Some of the rough edges the talk surfaces are worth *fixing* rather than just documenting; I opened **#4081** as an umbrella for that — *Timeout Semantics Overhaul for Operational Robustness* — split into **#4082** (startup deadline model), **#4083** (secure-handshake timeout semantics) and **#4084** (multi-host retry and host-status model).

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 13:00:01 +0000

> * **`timeouts.md`**. New _Interaction with a connection pool (HikariCP)_ section (the `loginTimeout`/`HikariConfig.connectionTimeout` asymmetry between `dataSourceClassName` and `jdbcUrl`, and the initial-fill bypass), plus _Host status tracker and `hostRecheckSeconds`_ covering the `connectTimeout`/`hostRecheckSeconds=10` default collision.
> * **`recommended-properties.md`**. New `assumeMinServerVersion` (skip a startup `SET` round-trip) and `loadBalanceHosts` entries; the existing `reWriteBatchedInserts` entry is now a short teaser that points at the new explanation page.
> * **`query/batch-inserts.md`** _(new)_. Explanation page for `reWriteBatchedInserts`: activation conditions, the power-of-two grouping, what `executeBatch()` actually returns, the `pg_stat_statements` trade-off, and a cross-link to COPY as the "I am willing to restructure the load path" alternative.
> 
> Some of the rough edges the talk surfaces are worth _fixing_ rather than just documenting; I opened **#4081** as an umbrella for that — _Timeout Semantics Overhaul for Operational Robustness_ — split into **#4082** (startup deadline model), **#4083** (secure-handshake timeout semantics) and **#4084** (multi-host retry and host-status model).

where is the follow up and how are we supposed to read the Russian talk ?

---

From: "sergiorussia (@sergiorussia)" <[email-masked]>
Date: Thu, 21 May 2026 13:13:43 +0000

> how are we supposed to read the Russian talk ?

was not expecting for such reference but translated all repo's text to eng just in case :) will try to translate slides later. regarding the video... no quick answers

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Thu, 21 May 2026 13:25:05 +0000

>where is the follow up

The followup is the commit I pushed minutes before the comment: https://github.com/pgjdbc/pgjdbc/pull/4075/changes/bd1af18230371879fb4127ae28800cf9a8a8c77d

>how are we supposed to read the Russian talk ?

🤷  I've no quick answer. One can transcribe the video, and ask ai agent to prepare a summary and consult screenshots for the important points. Agents routinely extract screenshots from video using ffmpeg, they undertand the images, and they produce meaningful outputs.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/postgresql-features/copy.md:14)

Typo + capitalization: "Copy is an extension that PostreSQL provides. see [Copy]" → "COPY is an extension that PostgreSQL provides. See [Copy]"

("PostreSQL" is misspelled; sentence-initial "see" needs capitalization.)

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/query/basics.md:14)

Grammar: "you can use issue a query" → "you can issue a query" (extra word "use").

Also, trailing spaces before punctuation throughout this file (e.g. `` `Statement` . `` should be `` `Statement`. ``).

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/data-types/date-time.md:36)

Grammar: "will have be in UTC" → "will be in UTC" (extra word "have").

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/data-types/date-time.md:62)

Subject-verb disagreement: "The Java data types needs to match" → "The Java data types need to match".

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/query/fetch-size.md:22)

Missing verb: "There a number of restrictions" → "There are a number of restrictions".

Also consider "that" instead of "which" for this restrictive clause.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/data-types/large-objects.md:16)

Two issues:
1. Missing possessive: "the objects contents" → "the object's contents"
2. Subjunctive: "as if it was a local file" → "as if it were a local file"

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/query/prepared-statements.md:125)

Inclusive language: "the master switch" → "the top-level switch" (avoid "master" per inclusive language guidelines).

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on SECURITY.md:4)

Em dash: "We value backward compatibility — upgrading pgJDBC..." → "We value backward compatibility. Upgrading pgJDBC..."

This pattern (em dash as connector) appears ~40 times across all documentation pages. Consider a bulk replacement with semicolons, colons, or periods depending on context.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/_index.md:14)

British spelling "organised" — most of the rest of the docs use American English ("behavior", "analyze"). This page also uses "catalogue" further down. Consider normalizing to one dialect across all pages.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:35 +0000

(on docs/content/documentation/getting-started/server-prep.md)

Em dash (paired): "None of them are pgJDBC-specific — they are PostgreSQL configuration tasks — but each one is..."

Suggested: "None of them are pgJDBC-specific (they are PostgreSQL configuration tasks), but each one is..."

This paired-em-dash-as-parenthetical pattern appears ~10 times across the docs.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:36 +0000

(on docs/content/documentation/connect/connection-pooling.md:10)

Em dash (paired): "Opening a fresh connection is expensive — TCP handshake, optional TLS / GSS upgrade, authentication round-trips, startup packet, several internal `SET` queries — and the per-connection state..."

Suggested: "Opening a fresh connection is expensive (TCP handshake, optional TLS / GSS upgrade, authentication round-trips, startup packet, several internal `SET` queries), and the per-connection state..."

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:36 +0000

(on docs/content/documentation/getting-started/compatibility.md)

Em dash (definition list pattern): this page uses `**Term** — definition` for the status labels. Suggest replacing with `: `:

```
- **Current**: the latest segment of the latest release line.
- **Superseded by X.Y+**: an earlier segment...
- **Security until YYYY-MM**: inside the support window...
- **EOL since YYYY-MM**: past the support window.
```

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Thu, 21 May 2026 22:06:36 +0000

(on docs/content/documentation/connect/recommended-properties.md:22)

Em dash in heading: this page uses `` ## `property` — description `` for all section headings. Suggest replacing with `: ` throughout:

```
## `reWriteBatchedInserts=true`: batch INSERT throughput
## `tcpKeepAlive=true`: survive NAT and load balancers
## `ApplicationName=my-service`: name the session for operators
```

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 09:27:32 +0000

Twenty-eight documentation pages went through a two-agent fact-check pass with manual approval gates. The workflow is documented in the commit message and is intended to be repeatable: https://github.com/pgjdbc/pgjdbc/pull/4075/commits/6bc673af7264388ad915416ace717a1361b95160

**Workflow per page**

1. **GPT** proposes edits: read the page, verify each claim against the source tree on this branch, add `{{< review >}}` shortcodes pointing at the backing code, and surface any doubtful claims for me to decide on.
2. **Manual gate**: I read each diff, approve or push back on doubtful claims.
3. **Claude** does an independent review of the resulting diff (without seeing GPT's reasoning) and asks one question: does each edit make the page truer and clearer, or does it convert a true statement into a false one, leak implementation details where a high-level guarantee belongs, or make the page harder to reason about?
4. **Manual gate**: I read Claude's review, accept the proposed corrections, override when I disagree.

The pass is not editorial polish. Below are the substantive factual bugs found and fixed, one per affected page. Some had been misleading readers for years.

### How to review

If you want to spot-check the pass without reading 28 diffs, the highest-signal files are `ssl-errors.md`, `date-time.md`, `unix-sockets.md`, and `connection-pooling.md`. Those carry the largest factual fixes. The rest are mostly review-shortcode additions plus narrow corrections.

Each `{{< review >}}` block is a hand-verifiable claim ledger: open the cited file at the cited line range and confirm the surrounding prose still matches the code. If anything reads as "implementation detail leaking into a user-facing guarantee", flag it. That was the explicit failure mode the Claude pass was looking for, but it is the easiest kind of mistake to leave in.

### Sample factual bugs fixed

- **`docs/content/documentation/troubleshooting/ssl-errors.md`**: the default `sslkey` filename was documented as `postgresql.p12`; the actual default is `postgresql.pk8` (`LibPQFactory.java` falls back to `defaultdir + "postgresql.pk8"`). The description of which key loader runs for which file extension was also wrong: the page implied "modern pgJDBC expects PKCS-12", whereas the driver dispatches on the filename suffix and the PKCS-8 DER loader is the *fallback* for anything that is not `.p12`/`.pfx`/`.key`/`.pem`.
- **`docs/content/documentation/data-types/date-time.md`**: the page listed `OffsetTime` / `TIME WITH TIME ZONE` as unsupported. Support has been in the driver for a long time. `PgResultSet.getOffsetTime` handles `Oid.TIMETZ`, `PgPreparedStatement.setObject` dispatches `OffsetTime`, and `GetObject310Test#testGetOffsetTime` covers the round trip. Table 5.1 now lists the mapping and the note no longer claims unsupported.
- **`docs/content/documentation/connect/unix-sockets.md`**: the page rendered a literal AI-generation artifact (`</content></invoke>`) at the end of its body. The Maven snippet for `junixsocket-core` was missing `<type>pom</type>`, which means the snippet did not resolve as written (the artifact is an aggregator POM). The junixsocket version was bumped from 2.5.1 (2022) to a current 2.10.x, a full example URL was added, and the page now clarifies that `unix_socket_directories` defaults to `/tmp` upstream and gets relocated to `/var/run/postgresql` by some packagers.
- **`docs/content/documentation/connect/connection-pooling.md`**: the page claimed that without an explicit `ApplicationName`, `pg_stat_activity.application_name` is the empty string. In reality `PGProperty.APPLICATION_NAME` defaults to `DriverInfo.DRIVER_NAME` (`"PostgreSQL JDBC Driver"`), which is what the DBA actually sees. An out-of-date claim that c3p0 cannot use `Connection.isValid()` (it can since 0.9.5) was also corrected.
- **`docs/content/documentation/troubleshooting/class-not-found.md`**: `PGSimpleDataSource` was described as bypassing `DriverManager`. It does not: `BaseDataSource#getConnection` calls `DriverManager.getConnection(getUrl(), user, password)`. The static initializer does force-load `org.postgresql.Driver` to handle classloader-visibility cases, which is a different guarantee.
- **`docs/content/documentation/query/stored-procedures.md`**: the page said that a `ResultSet` obtained from a refcursor materializes all rows on the client and ignores the `Statement` fetch size. The current behavior is the opposite of "all on the client": the inner `FETCH ALL IN <cursor>` runs through a statement that inherits `defaultRowFetchSize`, so the result streams. Two knobs are still not propagated: `Statement.setFetchSize()` and `ResultSet.setFetchSize()` set on the outer `CallableStatement` do not reach the inner fetch (tracked by a `TODO` in `RefCursorFetchTest`). The same diff fixed a broken backtick (`to a ResultSet\``) and a swapped class name (`getString` of `ResultSet` → `getString` of `CallableStatement`, which is what the example below the prose actually uses).
- **`docs/content/documentation/postgresql-features/listen-notify.md`**: the NOTE claimed pgJDBC "cannot receive asynchronous notifications and must poll the backend". The PostgreSQL wire protocol *does* push `NotificationResponse` ('A') asynchronously; the actual driver-side limitation is that there is no background reader thread, so application code has to call `getNotifications()` itself to drain what the socket already has. Additional cleanups: clarified that `getNotifications(0)` blocks forever (per `PGConnection` javadoc), and that the blocking variant only blocks other threads on the same connection. Dropped the legacy `Class.forName("org.postgresql.Driver")` line from the sample. Added a note on `getParameter()` (the `NOTIFY channel, 'payload'` value, since PostgreSQL 9.0) and `getPID()` on `PGNotification`. Promoted the orphan `##### Example 9.2.` heading to a real `##`.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 09:54:33 +0000

## Editorial pass per docs/CLAUDE.md

37 files under `docs/content/`, all outside `changelogs/`. The pass is mechanical for the most part, with targeted fixes for the grammar mistakes that turned up along the way (subjunctive, possessive, subject-verb, missing articles, duplicated tokens).

The diff is balanced: 361 insertions vs 362 deletions, no new paragraphs, no restructuring.

The pass was run by ten parallel sub-agents, one per content subtree (top-level, documentation root, getting-started, connect, query, data-types, security, postgresql-features, runtime + reference, troubleshooting). Each agent received the full style guide inline and a rule against inventing edits to justify the run.

The reading approach that worked locally: **IntelliJ side-by-side diff with soft wrap on and "Ignore whitespace" on**. Most changes are punctuation swaps that shift surrounding word wraps; ignoring whitespace makes the real edits jump out.

### What changed

Commit: https://github.com/pgjdbc/pgjdbc/pull/4075/commits/2b6fc513c468cba24c6045c62588d9d1e3b3524e

- **Em-dash** is the single largest category. Section headings, `**Term** — definition` bullets, paragraph-level connectors, and paired parentheticals were all converted to `:`, `.`, `;`, commas, or parentheses. The rendered HTML stays close to identical for most of these; the change is in the reading flow, not the visible layout.
- **American English** normalized across pages where British forms had drifted in: `behaviour`, `organise`, `recognise`, `synchronise`, `artefact`, `backwards`, and so on.
- **Inclusive wording** applied to prose: `master switch` → `top-level switch` (one heading in `prepared-statements.md`); `Master/Secondary` → `primary/standby` in `replication.md`. Literal config values, API names, and external identifiers were left as-is.
- **Grammar mistakes** picked up along the way: `who's column names` → `whose column names`, `It's looks` → `It looks`, `WAL's that that` → `WALs that`, `your must` → `you must`, an unclosed parenthesis in `binary-bytea.md`, and a broken inline-code identifier (`propertypreferQueryMode=simple` → property `preferQueryMode=simple`) in `security/_index.md`.

### How to review

Suggested order, biggest diffs first:

1. `postgresql-features/replication.md`: ~54 changes. The largest single file. Grammar density was high (duplicated tokens, missing articles, missing periods). Also the only file where `Master/Secondary` → `primary/standby` affects the rendered prose.
2. `query/prepared-statements.md`: ~35 changes. Includes the `master switch` → `top-level switch` heading rename. Definition lists converted from `—` to `:` throughout.
3. `security/authentication.md`: ~29 changes. Front-matter description plus many definition-list bullets.
4. `query/batch-inserts.md`: ~24 changes. The "This page is the explanation that backs..." paragraph was rewritten per the "don't define the page topic in its own body" rule.
5. The nine `troubleshooting/` pages, ~50 edits total: mostly mechanical. `—` in Related lists became `:`; `artefact` became `artifact`; a few paired-parenthetical rewrites.

Everything else is single-digit edits and reads fast.

### What was not touched

- `docs/content/changelogs/*.md` (release-note imports; excluded by pre-agreement).
- `docs/archetypes/default.md` (Hugo template, outside `docs/content/`).

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 11:29:15 +0000

Why did you choose American English ?

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 11:37:30 +0000

> Why did you choose American English ?

Let's settle on the preferred spelling and normalize to it. "Use the same spelling within each page" is too vague.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 11:38:04 +0000

Where is the style guide you used ?

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 11:39:14 +0000

See the commit message for 2b6fc513c468cba24c6045c62588d9d1e3b3524e

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 11:39:35 +0000

> Let's settle on the preferred spelling and normalize to it. "Use the same spelling within each page" is too vague.

The question is why American ?  I intentionally used English instead of American

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 12:21:27 +0000

> The question is why American ? I intentionally used English instead of American

Well, there was a comment: https://github.com/pgjdbc/pgjdbc/pull/4075#discussion_r3284626796

> davecramer: British spelling "organised" — most of the rest of the docs use American English ("behavior", "analyze"). This page also uses "catalogue" further down. Consider normalizing to one dialect across all pages.

I inferred "most of the rest of the docs use American" as if it was the preferred way.

I've normalized the spellings to British in c76d90e2dc61df08467c9b1b69d9bd3a0bcb9867. No hard feelings, either way works for me.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 12:36:14 +0000

Thanks. 

So now we are still left with the huge task of someone reading every change line by line. I don't think this is sustainable. Using AI does not increase the productivity here if someone can create a PR which causes someone else to have to spend hours reviewing it. While I like the idea of re-organizing the site I'm not sure how to move forward here. It would be one thing if you were a native English speaker and could go through each line but alas that is not possible.

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Fri, 22 May 2026 12:54:19 +0000

Anything of this magnitude, whether more tooling, code change, docs change, or both (as is here) needs to have a wider acceptance before it starts. It's fine to experiment on your fork and see what comes out. It's fine to create the patch too and use it as an example of what you want to do. But it's not reasonable to make 14000+ line changes and expect others to review and sign off on them.

I really see no way of this PR ever being merged. I think we should just reject it and take it as a lesson of how __not__ to make gigantic repo wide changes.

If you want to redo the site, figure out a way to do it piecemeal that allows the incremental pieces to actually be reviewed. By humans, not just more AI. The documentation is in English and if that's not your native language, it probably means you shouldn't be wholesale replacing it as it's not possible to self review. It'd be like me replacing all the Russian message translations!

And without a meaningful self review process, you're creating an inordinate amount of work for others. Each comment or reply in this thread has generated 1000+ diffs of new items. And that's from us barely skimming through it.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 14:31:05 +0000

I have updated the PR description to address the concern that the diff size makes review hard.

Of the 13.8k added lines, the review-heavy portion is ~5.6k of prose across ~40 pages. The rest is doc-tools code, Hugo templates, SCSS, JS, and seed data, exercised by tests, the build, and the preview rather than read line by line.

If anyone has 15 minutes, picking a single page from https://vlsi.github.io/pgjdbc/documentation/ and commenting on what reads off (technical issues, awkward phrasing, broken links, confusing structure) would be very helpful. No deep JDBC context is needed for prose feedback.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 15:27:43 +0000

I quickly skimmed 2 pages and each one of them needed to be rewritten, not just fixed. I think I would be OK with reorganizing the site with NO content changes then change 1 page at a time

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 15:55:42 +0000

Before I split this PR into separate "structure" and "per-page content" pieces, a practical proposal: what if I revert all prose verbatim to the version on main, in this same PR, while keeping the new page layout, navigation, styles, search, and release pipeline? The PR would then contain zero prose changes against main, matching the "no content changes" criterion you mentioned.

One thing to flag: where the new layout splits an oversized page into several, the prose would still come verbatim from the old page, sliced at existing heading boundaries with no editorial changes. New pages that have no equivalent on main (compatibility, troubleshooting) would be removed from this PR and re-added later in per-page PRs.

Would that be easier to review than starting from a fresh PR?

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Fri, 22 May 2026 16:04:10 +0000

I'd strongly suggest we close this PR so that whatever is going to be reviewed stands on its own. The rest of the commentary in this thread is not relevant and would only be distracting.

I'd also suggest getting feedback and acceptance on new code additions (e.g., the enum stuff and it's code processor to generate docs) before going down a rabbit hole of building and running it. That way you don't feel like been a waste of time if the idea itself is shot down.

Finally, if you're going to present this as something for others to review, get rid of the sausage factory of LLM commits and structure it into logical chunks that you would expect from a human. I don't care if you use AI to write code. But I'm not going to step through 100+ "`phase 1a: refactor the flubber thingamabob`" with multi paragraph meaningless commit messages. You need to squash it down to something presentable before opening a PR. This dump everything on reviewers approach is not going to work.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 16:09:20 +0000

Yeah, I agree that you should create a new PR

Dave Cramer

On Fri, May 22, 2026 at 9:04 AM Sehrope Sarkuni ***@***.***>
wrote:

> *sehrope* left a comment (pgjdbc/pgjdbc#4075)
> <https://github.com/pgjdbc/pgjdbc/pull/4075#issuecomment-4520356020>
>
> I'd strongly suggest we close this PR so that whatever is going to be
> reviewed stands on its own. The rest of the commentary in this thread is
> not relevant and would only be distracting.
>
> I'd also suggest getting feedback and acceptance on new code additions
> (e.g., the enum stuff and it's code processor to generate docs) before
> going down a rabbit hole of building and running it. That way you don't
> feel like been a waste of time if the idea itself is shot down.
>
> Finally, if you're going to present this as something for others to
> review, get rid of the sausage factory of LLM commits and structure it into
> logical chunks that you would expect from a human. I don't care if you use
> AI to write code. But I'm not going to step through 100+ "phase 1a:
> refactor the flubber thingamabob" with multi paragraph meaningless commit
> messages. You need to squash it down to something presentable before
> opening a PR. This dump everything on reviewers approach is not going to
> work.
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/pgjdbc/pgjdbc/pull/4075#issuecomment-4520356020>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AADDH5VPNM3BLAQXFKSV7J344B3BHAVCNFSM6AAAAACZAMWTQSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DKMRQGM2TMMBSGA>
> .
> You are receiving this because you were mentioned.Message ID:
> ***@***.***>
>

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 16:13:05 +0000

@davecramer , Just to make sure I have the scope right for the new PR before I start: prose would be reverted verbatim to the version on main (no edits, no rewrites, no AI rewording). The only things changing against master would be templates, navigation, search, release pipeline, file moves, long prose splits into several pages, and aliases.

Is that the shape you want, or did you have something else in mind for the prose handling?

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 16:16:22 +0000

What do you mean by release pipeline?

Dave Cramer

On Fri, May 22, 2026 at 9:13 AM Vladimir Sitnikov ***@***.***>
wrote:

> *vlsi* left a comment (pgjdbc/pgjdbc#4075)
> <https://github.com/pgjdbc/pgjdbc/pull/4075#issuecomment-4520453087>
>
> @davecramer <https://github.com/davecramer> , Just to make sure I have
> the scope right for the new PR before I start: prose would be reverted
> verbatim to the version on main (no edits, no rewrites, no AI rewording).
> The only things changing against master would be templates, navigation,
> search, release pipeline, file moves, long prose splits into several pages,
> and aliases.
>
> <https://github.com/pgjdbc/pgjdbc/pull/4075#issuecomment-4520453087>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AADDH5RQGYMMF36CLMOWCDL44B4CRAVCNFSM6AAAAACZAMWTQSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DKMRQGQ2TGMBYG4>
> .

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 16:18:20 +0000

> What do you mean by release pipeline?

Changes required for hugo to build the website, changes to github action to publish it to github pages, etc.

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 22 May 2026 16:22:42 +0000

Ok that’s fine

Dave Cramer

On Fri, May 22, 2026 at 9:18 AM Vladimir Sitnikov ***@***.***>
wrote:

> <https://github.com/pgjdbc/pgjdbc/pull/4075#issuecomment-4520508049>
>
> <https://github.com/pgjdbc/pgjdbc/pull/4075#issuecomment-4520508049>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AADDH5TGAH7JS2U3JOP4FO344B4WFAVCNFSM6AAAAACZAMWTQSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DKMRQGUYDQMBUHE>
> .

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Sat, 23 May 2026 08:31:41 +0000

Opened structure-only follow-up: #4088. That PR contains the new layout, navigation, search, release pipeline, and infrastructure, with prose reverted verbatim to main and new-content pages excluded.

Closing this PR. Discussion continues on #4088.