docs(connections): retitle the Database parity row — MF is ODBC, not JDBC - #9
Merged
Merged
Conversation
…JDBC The competitive-parity row read "Database reader/writer (JDBC/ODBC)" with a bare check in the MF column, which reads as a claim that MessageFoundry speaks JDBC. It does not: MF is pure Python with no JVM, and DB-OUT / DB-IN / db_lookup all connect over ODBC (aioodbc/pyodbc, DSN built in transports/database.py::_build_dsn). Retitle the row transport-neutral and move the mechanism into each engine's own cell (Mirth and Rhapsody are JVM engines, so theirs is JDBC), plus name the generic-ODBC dialect and state the no-JDBC fact explicitly in the MF status cell. `jdbc` now appears in the repo only where it is disclaimed. Docs-only; the CONNECTIONS.md drift guard (tests/test_communications_inventory.py, 77 passed) pins the resource-management section, not this table.
wshallwshall
enabled auto-merge (squash)
July 27, 2026 14:42
wshallwshall
added a commit
that referenced
this pull request
Aug 5, 2026
…sambiguate PR citations that already mis-resolve (#209) * fix(quality): the two advisory gates wrote a status glyph into their own summaries liveness.py and c901_delta.py each emitted a check mark on their clean-result line, and c901_delta rendered its complexity table with a non-ASCII arrow. Both write via sys.stderr.write when no summary file is given, and stderr defaults to backslashreplace, so a stock Windows cp1252 console silently mangled the text at exit 0 rather than raising. Verified by running the pre-edit scripts from HEAD under PYTHONIOENCODING=cp1252: neither crashed, both corrupted. That is the worse failure -- a crash is loud and self- reporting; silent corruption at exit 0 is not. CI was never affected, because the step summary is opened utf-8, so this was a local-run defect only. Say the word instead (CLAUDE.md section 11). PASS trails each sentence because that is where the glyph sat -- the minimal edit -- and it leaves the substring tests/test_c901_delta.py:291 asserts ("No function was introduced over the threshold") byte-identical. That assertion is a containment check rather than a prefix check, so it does not by itself forbid a leading token; nothing in the repo pins the placement either way. The three arrows become ASCII ->, matching lines 227 and 313 of the same file, which already wrote the identical relation that way. Both files now carry zero characters cp1252 cannot encode. * docs(quality): document /simplify, and take the status glyphs out of the rubric Code_Quality_Standards.md carried 40 check marks and one red circle as status markers, which CLAUDE.md section 11 forbids outside the two machine-parsed backlog files. All 41 are gone. Most sat beside the word they decorated and were simply deleted, that word carrying the meaning on its own; only two were genuine rewrites -- the red circle in Appendix A.2 became Failing, and the Appendix A.3 legend, where the glyph was the subject, became prose. Adds section 5.1 as the single home for /simplify: a local, human-invoked review that APPLIES its fixes rather than reporting them, which is why it runs before the local quartet rather than after -- running it after would mutate a tree the quartet just certified. It is not one of the five measurement gates, sits outside the AI companion section 6.5 local gate, and carries no Built status, because it ships with Claude Code rather than with this project and so leaves no artifact here to score. CLAUDE.md gains a "Before you verify" heading so the instruction is not governed by a pass-gate it cannot satisfy: /simplify applies edits and returns no verdict. Also corrects a PRE-EXISTING Appendix A.3 error that removing the glyphs surfaced rather than introduced: the legend glossed its status marker as advisory under two PR numbers, across a five-item list whose fifth item is blocking and shipped under a third. That legend is byte-identical in every commit this file has existed in. HANDOFF-mutation-coverage.md prescribed typing a check mark back into the rubric, which would have undone the pass -- so the removal was not durable. Its instruction is corrected, along with its stale signal numbering and column name, and it now says to write the word. * docs(quality): the handoff cited the PR that built the gates, not the one that restatused them The parenthetical said signals 7 and 8 were "restatused in v0.8 (#1040)". Two different pull requests, verified by subject: 7540f260 ci(quality): mutation (#7) + diff-coverage (#8) advisory gates (#1040) 46714159 docs(rubric): v0.8 -- restatus signals 7 + 8 to Built (#1044) PR #1040 built the gates; PR #1044 did the v0.8 restatus the sentence is about. Caught by the session sweeping citation ambiguity in these docs. Written in the settled "PR #NNN" form rather than a bare number, which is what that sweep is standardising. Bare and bolded #N stays for backlog items, and the distinction is load-bearing in code: backlog_status_check.py defines _CL_EXPLICIT as BACKLOG\s+#(\d+) to pick out item citations, so writing "BACKLOG #1040" for a pull request would make that regex misread it as an item. * docs(quality): the rubric cited pull requests as bare "#N", which already resolves to the wrong item #1020, #1028, #1040 and #1047 are PULL REQUEST numbers (97b79fef, 42756bdb, 7540f260, 3d6c8adf -- subject-anchored search). A bare "#N" in this corpus reads as a backlog item, so these send a reader to the wrong document. #1020 is not a future risk. Backlog item 1020 exists on main, filed 2026-08-04, about a first-run bootstrap Administrator with no email address -- while the rubric uses #1020 four times to mean the PyPI sdist private-doc leak fix. Those four citations already land on the wrong item. 1028 is next; 1040 and 1047 are still unallocated. "PR #N" is the settled repo form rather than a new one, and the repo encodes the distinction in code: backlog_status_check.py defines _CL_EXPLICIT to match the word BACKLOG followed by whitespace and a number, under the comment "Unambiguous CHANGELOG citations of a *backlog item* (not a PR number)". That regex is also why the inverse rewrite is unavailable -- prefixing a pull request number with that word would make the parser read it as an item. 39 markers inserted: 38 in the rubric, 1 in the handoff. The rubric's 40 four-digit citations carry 38 markers because one slash-joined run takes a single "PRs " across its three tokens. Deliberately left alone: the 11 rubric-signal citations (#3, #6, #7, #8, #9, #10, #11). Six of those numbers are also real backlog items, so the ambiguity is genuine, but resolving it is prose surgery ("signal 7", not "PR #7") and sits with the owner as a separate decision. Analysis and the marking script are the work of the session on claude/sleepy-villani-df328d. Verified here as markers-only: stripping every marker from both the committed and the working text yields identical files. * backlog: file 1029 -- the /simplify placement decision had no number to cite Filed closed: the documentation is the whole deliverable, and it shipped in the three commits below this one. REWRITTEN BEFORE FILING. The draft item, written when the change was first made, described a structure that the remediation then reverted -- it claimed a sixth row in the section 5 gate table, a Built status, and a CLAUDE.md bullet. None of those is what shipped: section 5's table is unchanged at five rows, Built is a claim the document explicitly declines to make, and CLAUDE.md carries a "Before you verify" heading placed ahead of the verification list rather than a bullet inside it. Every claim in the filed item was read from the working tree at 17c5212 rather than recalled. APPENDED, NOT INSERTED, and the instruction to insert was checked rather than followed. It was handed over on the grounds that 1028, 1030 and 1031 are being filed concurrently. No such rule exists and the file does not follow one: 108 items carry 10 descending adjacent pairs in file order, the tail running 1019, 1018, 1024, 1026, 1025, 1027; backlog_status_check.py enforces no ordering -- its only sort is a citation report at line 190; this file's own header states only that the numbered items are intentionally deferred, and docs/README.md calls them "ranked", which is not numeric order. So nothing states an ordering rule for the numbered items, and imposing numeric order would discard whatever the existing arrangement encodes. Appending is where every recent item sits. The only real interaction with the concurrent items is a textual end-of-file conflict that resolves by keeping both. Validated with the canonical parser rather than a hand-rolled scan (CLAUDE.md section 11): parse_items reports item 1029 with closed=['<check>'], open=[], is_open=False -- exactly one banner, no OPEN/CLOSED contradiction. The hygiene gate at its ci.yml invocation reports OK, 304 items, each declaring exactly one status. Number allocated via scripts/coord/alloc.ps1, never by grepping for the next free one. * docs: correct the CRLF rationale in this branch's earlier merge commit The merge commit 95cd856 states that docs/BACKLOG.md "is 100 percent CRLF" and that "a resolver that normalises to LF produces a clean-looking merge that churns every line". That is FALSE about the stored file, and this commit exists so the correction travels with the claim -- this repository composes its squash body from the concatenated commit messages, so both land on main together. Every committed revision of that file is pure LF. Measured on the blobs rather than the working tree: origin/main CRLF=0 bareLF=5045 453c95f CRLF=0 bareLF=4994 95cd856 CRLF=0 bareLF=5065 working tree CRLF=5065 bareLF=0 core.autocrlf = true CRLF exists only as the checkout materialisation. The original measurement read bytes on disk and reported them as the stored form -- the working tree answered a question about the object store. THE RESOLUTION ITSELF WAS CORRECT; only the stated reason was wrong. The resolver read and wrote with newline="", so it preserved the on-disk form byte-for-byte and let autocrlf normalise on the way in -- the same outcome a resolver that ignored line endings entirely would have produced. THE INSTRUMENT THAT SETTLES THIS IS CHURN, NOT A LINE-ENDING COUNT: git diff --numstat 453c95f 95cd856 -- docs/BACKLOG.md 71 0 docs/BACKLOG.md 71 added, zero removed -- items 1030, 1031 and 1032 plus one seam blank line. A resolver that had normalised would show thousands of lines on BOTH sides. That reconciles to the line against the independent resolution of the same collision on another branch, which came back 70/0 and needed no seam line. Anyone resolving the next end-of-file collision in this file should run the numstat check and should not chase line endings that are not there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The competitive-parity table in
docs/CONNECTIONS.mdtitled a row "Database reader/writer(JDBC/ODBC)" and put a bare ✅ in the MF column. That reads as a claim that MessageFoundry speaks
JDBC. It does not — MF is pure Python with no JVM, and
DB-OUT/DB-IN/db_lookupall connectover ODBC (
aioodbc/pyodbc; DSN built intransports/database.py::_build_dsn).The row is now transport-neutral, with the mechanism moved into each engine's own cell (Mirth and
Rhapsody are JVM engines, so theirs is genuinely JDBC), plus the generic-ODBC dialect named and the
no-JDBC fact stated explicitly in the MF status cell.
jdbcnow appears in the repo only where it is explicitly disclaimed.Why it matters
This is a customer/prospect-facing parity table. A ✅ on a row titled "(JDBC/ODBC)" is the kind of
claim that gets read back to us in an RFP. The honest answer is that ODBC reaches the same
databases — Oracle, DB2, MySQL, PostgreSQL, SQL Server — via
dialect='generic'.Testing
tests/test_communications_inventory.py— 77 passed. That guard pins the resource-managementsection, not this table, so the edit is unconstrained by it; run for confirmation.
Notes
origin/main(9e4e614) before pushing rather than relying on a stale green,since branch protection is
strict:false.forbidden-contentgate was run locally with the real token list loaded(
names=7, estate=13, site_prefixes=1— matching the CI floor), exit 0.