Repository navigation
JDBC 4.3 Appendix B compliance plan #238
Description
JDBC 4.3 Appendix B compliance plan
This plan makes libsql-jdbc follow JDBC 4.3 Appendix B for the six tables in vendor/JDBC4-TYPE-MAPPING.md. It orders seven PRs from the oracle suite to the conformance profile. The evidence is the Appendix B suite added in this session and landed first as PR-0. Appendix B is the oracle, and sqlite-jdbc parity is kept only where the spec is silent. Execution starts on the operator's go, under the execution playbook named below.
Decisions taken before execution
The operator settled these on 2026-10-25.
- The operator lands the stack. Every PR stops at STACK-READY. No owner merges, retargets, or arms auto-merge.
- Verification keeps ten live lanes per PR and a perf gate on every production PR. PR-0 adds no production code, so its ten lanes record per-table baselines and its perf box records the suite wall time.
- PR-5 marks
ARRAY,STRUCT,REF,JAVA_OBJECT, andDISTINCTas N/A and throwsSQLFeatureNotSupportedException. Emulation is rejected. - The Appendix B suite lands as PR-0 on its own, because it is the oracle and PR-1 cannot compile without it. PR-0 also carries the vendor type-mapping document already committed on
task/type-mapping. - The program runs all seven PRs without a checkpoint after PR-1.
- The stack is linear. PR-3 depends only on PR-1, but it branches from PR-2 so the operator lands one chain bottom-up.
How to read this
Delivered. Landed on
mainat6bc7da7through #247. The seven-link stack was merged as one commit because themainruleset requires green required checks at every head. The closing comment records the verification and the residual risks.
One box is one unit of work. Every box names the evidence that checks it. A nested box is a sub-step of the box above it. Check a box only when its evidence exists, a file, a log line, a transcript, a test run, or a SHA. The body is a how-to. The appendices explain and record.
The program runs skills/poteto-mode/playbooks/autopilot-stack.md from the installed plugin. The stack root is PR-0, which branches from 3e8f582 on task/type-mapping and carries the vendor document. Each later PR targets its parent branch. The operator lands the stack, and every PR stops at STACK-READY. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
Program checklist
Arm the program
- State the protocol and this plan to the operator, then stop. Start execution only on the operator's explicit go.
- On the go, write this exact text into the standing orders and restate it in your todolist. "The plan is the GitHub issue titled
JDBC 4.3 Appendix B compliance plan, the PRs are PR-0 through PR-6 in order, Appendix B is the oracle, tests alone are not verification, the operator lands the stack, and the program is done when every Appendix B row is green or recorded N/A." - Read these from the installed plugin at program start. Re-read them at every tick.
-
skills/poteto-mode/playbooks/autopilot-stack.md -
skills/swarm/SKILL.md -
skills/poteto-mode/playbooks/opening-a-pr.md -
skills/principle-sequence-verifiable-units/SKILL.md -
skills/principle-prove-it-works/SKILL.md
-
- Arm the hourly audit tick as a real
/loopin dynamic mode. It schedules its own wake-up and never sleeps in the turn. - Use this tick prompt, verbatim. "Re-read the execution playbook from the installed plugin and the standing objective. Audit the operation against both and fix drift in this tick. Probe every active lane and judge progress by side effects only. Stand down a stuck lane and dispatch its replacement now. Then post a short status message to the operator in chat only when the audit found a tracked change that no earlier status message reported, such as a PR opened, a code-ready head, a round launched or closed, a verdict, a merge, a stuck agent and the action taken, a blocker added or cleared, or a decision only the operator can make. Name every such change and nothing else. Do not repeat a table, the merged list, or an unchanged blocker. If the audit found none, end the turn with no reply text. Either way, log this tick's row in your decision trail. The row names the items reported, or none."
- On the operator's hold or stand-down, send every owner a zero-writes order at once.
Spawn owners
- Spawn one owner per PR with the full lifecycle the execution playbook names.
- Follow this dependency graph. Start dependent work only after its parent merges, or base it on the parent branch when the execution playbook stacks.
- PR-0 is first and branches from
3e8f582ontask/type-mapping. It targetsmain. - PR-1 branches from PR-0.
- PR-2 branches from PR-1.
- PR-3 branches from PR-2.
- PR-4 branches from PR-3.
- PR-5 branches from PR-4.
- PR-6 branches from PR-5.
- The chain is linear even though PR-3 needs only PR-1. The operator lands one chain, so a parallel branch would force a retarget mid-landing.
- PR-0 is first and branches from
- Hold the file boundaries. PR-0 adds the three Appendix B test files and carries the vendor document already on
task/type-mapping. PR-1 and PR-2 touch onlylibsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/. PR-3 touches the same package plus its new wrapper files. PR-4 and PR-5 touch the same package. PR-6 toucheslibsql-conformance/,docs/,README.md, andAGENTS.md. - Hold the review gate. No PR changes an interaction. No PR is review-gated.
PR mechanics, for every PR
- Resolve the forge once. Default to
gh. Ifcommand -v originsucceeds and Origin can resolve the repository, useorigin prfor every PR operation. Record any fallback togh. Never requiregt. - Open the PR ready, never draft, per Opening a PR. Use the run's built-in PR tool when it has one, else
origin pr create --status open --base <base-branch>orgh pr create --base <base-branch>according to the resolved forge. A stack child targets its parent branch. - Run the repo's lint and typecheck once before the PR-facing push. Push with hooks on.
- Run
/deslopbefore each commit and/no-commentsbefore review. - Triage every review-bot and security-reviewer comment per
../references/bugbot-triage.md. - Before the code-ready report and babysit, and again after merge prep, record the base and head SHAs prepared by the topology owner under the execution playbook.
Verdict and merge, for every PR
- A full swarm runs once, at the code-ready head. Another full swarm runs only for new behavior, a redesign, or a large new diff. A rebase, a merge-conflict resolution, or a minor fix gets a single verifier at the new head. Run each full swarm per
skills/swarm/SKILL.md. One gates lane. The ten live lanes from the PR's Verify, live block. The perf lane from its Verify, perf block. Two or more audit lanes, each with its own focus, that read the diff and the receipts and distrust the PR body. The root audits the receipts in the merge-ready report before the verdict. - Clean only when every lane is
PASS. Findings go back to the owner, including a defect that a lane filed as a note. A new head gets a fresh verdict, except for results that stay valid under the patch-id rule inplaybooks/shipping.md. - The root appends the clean PR to the base-branch stack in dependency order. The operator lands the stack bottom-up. No owner merges, closes, retargets, or arms auto-merge.
Boot recipe, for every live lane
Each live lane runs in its own worktree at the PR head. Drive the JDBC surface through the commands recorded here. The driver is headless, so each lane saves a JDBC transcript instead of an image.
-
git fetch origin <head-branch> && git checkout <head SHA>. - Start the pinned sqld container. Run
DOCKER_CONFIG="$PWD/libsql-conformance/src/test/docker-config" ./mvnw -pl libsql-itests -Dit.test=Jdbc4AppendixBTypeMappingIT -Dtest=NoSuchTest -Dsurefire.failIfNoSpecifiedTests=false verify, or start the same image directly. - Run the lane's Java client through
jdbc:libsql:http://<host>:<port>. The read-only diagnostics areSELECT typeof(v), v,ResultSetMetaData.getColumnType,getColumnClassName, and the driver log. - Save every transcript to
/tmp/swarm-<pr-id>/worker-<n>/<slug>.txtand return the paths with the report.
Land the Appendix B oracle suite (PR-0)
The suite that encodes JDBC 4.3 Appendix B lands before any production change. It is red on arrival and stays red until PR-6. The PR also carries vendor/JDBC4-TYPE-MAPPING.md, so the oracle and its source travel together.
Depends on. None. Branch from 3e8f582 on task/type-mapping. Target main.
Files.
- Add
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBReadTest.java. - Add
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBSetObjectTest.java. - Add
libsql-itests/src/test/java/com/github/magnusp/libsql/itest/Jdbc4AppendixBTypeMappingIT.java. - Carry
vendor/JDBC4-TYPE-MAPPING.mdfrom3e8f582.
Build.
- Add the suite unchanged from the baseline run recorded in Appendix A.
- Make no production change.
- Record the baseline numbers in Appendix A.
You see.
- The unit suite compiles and runs 1,077 tests with 518 failures and no errors.
- The integration suite compiles and runs 146 tests with 63 failures and no errors.
Verify, unit. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Run
./mvnw -pl libsql-jdbc -am -Dtest='Jdbc4AppendixB*' -Dsurefire.failIfNoSpecifiedTests=false test. Expect 1,077 tests, 518 failures, 0 errors. - Read ten failure messages and confirm each names an Appendix B row, not a compile error or a harness fault.
Verify, live. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked. Ten lanes on the configured swarm workers model at the PR head, per the boot recipe. PR-0 adds no production code, so each lane records one table's baseline instead of a behavior change.
- Lane 1. Regression lane against trunk. Run the unit suite at
c4357d2and at the PR-0 head. Savepr-0/lane-1-regression.txt. Pass when trunk reports no matching Appendix B tests and the head reports 1,077 tests with 518 failures. - Lane 2. B-1 unit baseline. Run
Jdbc4AppendixBReadTest#b1NaturalGetterReturnsDeclaredJavaType. Savepr-0/lane-2-b1.txt. Pass when the failure count is 7. - Lane 3. B-3 unit baseline. Run
Jdbc4AppendixBReadTest#b3GetObjectReturnsDeclaredObjectType. Savepr-0/lane-3-b3.txt. Pass when the failure count is 18. - Lane 4. B-5 unit baseline. Run
Jdbc4AppendixBSetObjectTest#b5SetObjectRejectsUnlistedTargetTypes. Savepr-0/lane-4-b5.txt. Pass when the failure count is 31. - Lane 5. B-6 unit baseline. Run
Jdbc4AppendixBReadTest#b6GetterHonoursSupportedJdbcTypes. Savepr-0/lane-5-b6.txt. Pass when the failure count is 462. - Lane 6. B-1 integration baseline. Run
Jdbc4AppendixBTypeMappingIT#b1AndB3ReadPathAgainstRealDdland filter to the B-1 rows. Savepr-0/lane-6-b1-it.txt. Pass when the failure count is 7. - Lane 7. B-2 integration baseline. Run
Jdbc4AppendixBTypeMappingIT#b2StandardSettersMapJavaTypeToJdbcType. Savepr-0/lane-7-b2-it.txt. Pass when the failure count is 8. - Lane 8. B-3 integration baseline. Run
Jdbc4AppendixBTypeMappingIT#b1AndB3ReadPathAgainstRealDdland filter to the B-3 rows. Savepr-0/lane-8-b3-it.txt. Pass when the failure count is 18. - Lane 9. B-4 integration baseline. Run
Jdbc4AppendixBTypeMappingIT#b4SetObjectMapsJavaObjectTypeToJdbcType. Savepr-0/lane-9-b4-it.txt. Pass when the failure count is 14. - Lane 10. B-5 and B-6 integration baseline. Run
Jdbc4AppendixBTypeMappingIT#b5SetObjectConvertsToExplicitTargetTypeand#b6GetterReadsRecommendedTypeFromRealDdl. Savepr-0/lane-10-b5-b6-it.txt. Pass when the failure counts are 26 and 8.
Verify, perf. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Metric. Wall time of the Appendix B unit suite and of the Appendix B integration suite.
- Probe. Run both suites at
c4357d2and at the PR-0 head, interleaved, with one warmup and three measured runs each against the same container cache. - Baseline. Record the trunk wall times first.
- Rule. The head unit suite finishes under 60 seconds and the integration suite under 5 minutes. PR-0 adds test sources only, so a slower head means a harness fault, not a product regression.
Review gate. None. PR-0 changes no interaction. It is not review-gated.
Merge.
- Root's clean verdict at the exact head SHA.
- Bugbot triage done.
- Base and verdict are current under the execution playbook and the patch-id rule.
- The root appends PR-0 to the stack as its root. The operator lands it before PR-1.
Resolve JDBC types from the declared type (PR-1)
The driver resolves one JdbcType per column from Col.decltype. Value magnitude stops deciding Integer versus Long. Metadata, getObject, and the natural getters read the same resolved type. Expression columns with no decltype fall back to the storage class, and the fallback is recorded.
Depends on. PR-0.
Files.
- Create
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/JdbcTypeMapping.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/DeclaredType.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetMetaData.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java. - Delete
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/XerialColumnType.javaafter every caller moves. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetMetaDataTest.java. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetTest.java.
Build.
- Add a
JdbcTyperecord withsqlType,javaClass,objectClass,storage, andsupport. - Add a registry that maps a declared type name to
JdbcType, coveringTINYINT,SMALLINT,INTEGER,BIGINT,REAL,FLOAT,DOUBLE,NUMERIC,DECIMAL,BIT,BOOLEAN,CHAR,VARCHAR,LONGVARCHAR,NCHAR,NVARCHAR,LONGNVARCHAR,BINARY,VARBINARY,LONGVARBINARY,DATE,TIME,TIMESTAMP,CLOB,NCLOB,BLOB, andDATALINK. - Resolve an unknown or missing declared type to a storage-class fallback. Record the fallback in the type.
- Make
getColumnTypeandgetColumnClassNameuse the resolved type, not the runtime value. - Make
getObject(int)use the resolved object type.BIGINTreturnsLongeven for 42.INTEGERreturnsIntegerand throwsSQLExceptionwhen the value does not fit.NUMERICandDECIMALreturnBigDecimal.BITandBOOLEANreturnBoolean.REALreturnsFloat.DATE,TIME, andTIMESTAMPreturnjava.sql.Date,Time, andTimestamp.CLOBandBLOBreturnClobandBlob. - Teach
getBooleanto parsetrueandfalsetext and to treat numeric zero as false. - Keep the existing SQLite date, real, and numeric text helpers. They are the value codecs under the resolved type.
You see.
- A
BIGINTcolumn with 42 returns aLongfromgetObject. - A
NUMERICcolumn with 42 returns aBigDecimal. - A
BITcolumn with 1 returns aBoolean. - A
DATEcolumn with2024-01-02returns ajava.sql.Date. -
getColumnTypeandgetColumnClassNameagree with the declared type. -
SELECT 1 + 1still returns anIntegerthrough the storage fallback.
Verify, unit. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBReadTest#b3GetObjectReturnsDeclaredObjectType' -Dsurefire.failIfNoSpecifiedTests=false test. Expect the B-3 failure count to fall from 18 to the 7 unrepresentable types left for PR-3 and PR-5. - Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBReadTest#b1NaturalGetterReturnsDeclaredJavaType' -Dsurefire.failIfNoSpecifiedTests=false test. Expect the 7 wrapper failures to remain. - Run
./mvnw -q -pl libsql-jdbc -Dtest='LibsqlResultSetMetaDataTest,LibsqlResultSetTest' test. Expect green after the two tests that encode value-basedgetObjectare updated in this PR. - Add and run a test for
getBooleanon the text valuestrueandfalse. Expect true and false.
Verify, live. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked. Ten lanes on the configured swarm workers model at the PR head, per the boot recipe.
- Lane 1. Regression lane against trunk. Run the same
getObjectscenario on aBIGINTcolumn with 42 at trunk and head. If trunk lacks the declared-type behavior, record that and gate the end state. Savepr-1/lane-1-regression.txt. Pass when the head returnsLongand the trunk transcript showsInteger. - Lane 2. B-3
BIGINT. Savepr-1/lane-2-bigint.txt. Pass whengetObjectis aLong. - Lane 3. B-3
NUMERICandDECIMAL. Savepr-1/lane-3-decimal.txt. Pass when both areBigDecimal. - Lane 4. B-3
BITandBOOLEAN. Savepr-1/lane-4-boolean.txt. Pass when both areBoolean. - Lane 5. B-3
DATE,TIME, andTIMESTAMP. Savepr-1/lane-5-temporal.txt. Pass when the threejava.sqltypes appear. - Lane 6. B-3
REAL. Savepr-1/lane-6-real.txt. Pass whengetObjectis aFloat. - Lane 7. B-3
CLOBandBLOB. Savepr-1/lane-7-lob.txt. Pass when the values areClobandBlob. - Lane 8. Expression fallback. Run
SELECT 1 + 1andgetObject. Savepr-1/lane-8-expression.txt. Pass when the result is anIntegerand the transcript records the fallback. - Lane 9. Out-of-range
INTEGER. Insert 5000000000 into anINTEGERcolumn and callgetObject. Savepr-1/lane-9-overflow.txt. Pass whengetObjectthrowsSQLExceptionand the message names the declared type. - Lane 10. Metadata. Read
getColumnTypeandgetColumnClassNameon a declaredBIGINTcolumn. Savepr-1/lane-10-metadata.txt. Pass when the type isTypes.BIGINTand the class isjava.lang.Long.
Verify, perf. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Metric.
getObjectthroughput on a 1,000,000-row result set withINTEGER,REAL, andVARCHARcolumns. - Probe. Run the same fixed loop at trunk and at the head, interleaved, with five warmups and five measured runs.
- Baseline. Record the trunk operations per second first.
- Rule. Head is within 5 percent of trunk. The resolved type is computed once per column, not once per call.
Review gate. None. PR-1 changes no interaction. It is not review-gated.
Merge.
- Root's clean verdict at the exact head SHA.
- Bugbot triage done.
- Base and verdict are current under the execution playbook and the patch-id rule.
- The root appends PR-1 to the stack. The operator lands it.
Convert Java values to the target JDBC type (PR-2)
setObject(x, targetSqlType) stops ignoring the target type. A single converter maps a Java value to the target JDBC type first, then to a Hrana value. setObject(x) without a target follows Table B-4. setNull still accepts every target type.
Depends on. PR-1.
Files.
- Create
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/JdbcValueConverter.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlPreparedStatement.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/JdbcTypeMapping.java. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlPreparedStatementTest.java. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBSetObjectTest.java.
Build.
- Add
JdbcValueConverter.toValue(Object value, int targetSqlType)andtoValue(Object value)for the no-target path. - Convert numeric targets with Java narrowing.
TINYINTtobyte,SMALLINTtoshort,INTEGERtoint,BIGINTtolong,REALtofloat,FLOATandDOUBLEtodouble, andDECIMALandNUMERICtoBigDecimal. - Convert
BITandBOOLEANto0or1integers. - Convert text targets from the Java
toStringform, exceptBoolean, where the text format is recorded in the compliance profile. - Convert binary targets from
byte[]or from aBlobstream. - Convert
DATE,TIME, andTIMESTAMPfromDate,Time,Timestamp,LocalDate,LocalTime,LocalDateTime,Calendar, andjava.util.Dateto the SQLite text format. - Read
Clobcontent throughgetCharacterStreamandBlobcontent throughgetBinaryStream. Do not usetoString. - Convert
BigIntegerto an integer value, and boxedByteandShortto integer values. - Reject an unlisted pair with
SQLFeatureNotSupportedException. Any SQL exception is the contract for the negative suite. - Leave
ARRAY,STRUCT,REF,JAVA_OBJECT, andDISTINCTto PR-5. Until then they still bindtoString, and the positive rows for them stay red.
You see.
-
setObject("42", Types.INTEGER)stores SQLite integer 42. -
setObject(BigInteger.valueOf(7))stores integer 7. -
setObject(true, Types.CHAR)stores a text value and reads back aString. -
setObject(clob, Types.CLOB)stores the clob content, not its object identity. -
setObject(blob, Types.BLOB)stores the blob bytes. -
setObject(calendar)stores a timestamp text thatgetTimestampparses. -
setObject("42", Types.ARRAY)throwsSQLFeatureNotSupportedException.
Verify, unit. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBSetObjectTest' test. Expect the 31 failing rows to clear. - Run
./mvnw -q -pl libsql-jdbc -Dtest='LibsqlPreparedStatementTest' test. Expect green after the xerialsetObjectexpectations are updated in this PR. - Add and run a test for each target family. Expect one Hrana value kind per family.
Verify, live. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked. Ten lanes on the configured swarm workers model at the PR head, per the boot recipe.
- Lane 1. Regression lane against trunk. Run
setObject("42", Types.INTEGER)at trunk and head. Savepr-2/lane-1-regression.txt. Pass when the head stores an integer and the trunk transcript stores text. - Lane 2. String to
TINYINT. Savepr-2/lane-2-tinyint.txt. Pass when the stored type is integer andgetByteis 42. - Lane 3.
BigIntegertoBIGINT. Savepr-2/lane-3-biginteger.txt. Pass when the stored type is integer. - Lane 4.
BooleantoCHAR. Savepr-2/lane-4-boolean-char.txt. Pass when the read-back is aStringand the format matches the profile. - Lane 5.
ClobtoCLOB. Savepr-2/lane-5-clob.txt. Pass when the read-back text equals the source. - Lane 6.
BlobtoBLOB. Savepr-2/lane-6-blob.txt. Pass when the stored type is blob and the bytes equal the source. - Lane 7.
CalendartoTIMESTAMP. Savepr-2/lane-7-calendar.txt. Pass whengetTimestampequals the calendar instant. - Lane 8.
java.util.DatetoTIMESTAMP. Savepr-2/lane-8-util-date.txt. Pass whengetTimestampequals the date instant. - Lane 9. Unlisted target. Run
setObject("42", Types.ARRAY). Savepr-2/lane-9-reject.txt. Pass when it throwsSQLFeatureNotSupportedException. - Lane 10.
setNullwith a target. Savepr-2/lane-10-setnull.txt. Pass when the stored type is null and the read-back is null.
Verify, perf. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Metric.
setObjectplus insert throughput for 100,000 rows across the numeric, text, and temporal families. - Probe. Run the same insert loop at trunk and at the head, interleaved, with five warmups and five measured runs.
- Baseline. Record the trunk rows per second first.
- Rule. Head is within 5 percent of trunk. The converter allocates no more than one Hrana value per bind.
Review gate. None. PR-2 changes no interaction. It is not review-gated.
Merge.
- Root's clean verdict at the exact head SHA.
- Bugbot triage done.
- Base and verdict are current under the execution playbook and the patch-id rule.
- The root appends PR-2 to the stack. The operator lands it.
Add the missing getters and LOB wrappers (PR-3)
The read side gains getURL, getNClob, getSQLXML, getRowId, getAsciiStream, and getNCharacterStream. The driver stores these values as text or blob and wraps them in the JDBC types. ARRAY and REF remain for PR-5.
Depends on. PR-1.
Files.
- Create
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlNClob.java. - Create
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlSQLXML.java. - Create
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlRowId.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlPreparedStatement.java. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBReadTest.java.
Build.
- Implement
getURLby parsing the text withjava.net.URL. ThrowSQLExceptionwhen the text is not a URL. - Implement
getNClobwithLibsqlNClob, includinglength,getSubString,getCharacterStream, andfree. - Implement
getSQLXMLwithLibsqlSQLXML, includinggetString,getBinaryStream,getCharacterStream, andfree. - Implement
getRowIdwithLibsqlRowIdover the text or blob value. - Implement
getAsciiStreamover the text bytes in US-ASCII. - Implement
getNCharacterStreamovergetNString. - Route
getObjectforNCLOB,SQLXML, andROWIDto the new wrappers. - Implement
setSQLXMLby reading the SQLXML content and binding text. ImplementsetRowIdby binding the RowId bytes as text or blob.setNClobalready reads the character stream. - Keep
setArrayandsetRefthrowing. PR-5 decides their status.
You see.
-
getURLon aDATALINKcolumn returns ajava.net.URL. -
getNClobreturns anNClobwhose content matches the stored text. -
getSQLXMLreturns anSQLXMLwhose string matches the stored text. -
getRowIdreturns aRowIdwhose bytes match the stored value. -
getAsciiStreamreturns the stored text as an ASCII stream. -
getNCharacterStreamreturns the stored text as a reader. - A freed wrapper throws
SQLExceptionon the next read.
Verify, unit. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBReadTest#b1NaturalGetterReturnsDeclaredJavaType' -Dsurefire.failIfNoSpecifiedTests=false test. Expect the B-1 failures to fall from 7 to the 3 wrapper types left for PR-5. - Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBReadTest#b6GetterHonoursSupportedJdbcTypes' -Dsurefire.failIfNoSpecifiedTests=false test. Expect the listed-cell failures to fall from 27 to the 2 types left for PR-5. - Add and run wrapper tests for
free,length, and stream reads.
Verify, live. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked. Ten lanes on the configured swarm workers model at the PR head, per the boot recipe.
- Lane 1. Regression lane against trunk. Run
getURLon aDATALINKcolumn at trunk and head. Savepr-3/lane-1-regression.txt. Pass when the head returns aURLand the trunk transcript shows the old exception. - Lane 2. Malformed
DATALINK. Savepr-3/lane-2-bad-url.txt. Pass whengetURLthrowsSQLException. - Lane 3.
getNClob. Savepr-3/lane-3-nclob.txt. Pass when the content matches. - Lane 4.
getSQLXML. Savepr-3/lane-4-sqlxml.txt. Pass when the content matches. - Lane 5.
getRowId. Savepr-3/lane-5-rowid.txt. Pass when the bytes match. - Lane 6.
getAsciiStream. Savepr-3/lane-6-ascii.txt. Pass when the stream content matches. - Lane 7.
getNCharacterStream. Savepr-3/lane-7-nchar.txt. Pass when the reader content matches. - Lane 8.
setSQLXMLround trip. Savepr-3/lane-8-set-sqlxml.txt. Pass when the text round trips. - Lane 9.
setRowIdround trip. Savepr-3/lane-9-set-rowid.txt. Pass when the value round trips. - Lane 10. Wrapper
free. Savepr-3/lane-10-free.txt. Pass when a read afterfreethrowsSQLException.
Verify, perf. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Metric. Per-call latency for
getURL,getNClob,getSQLXML, andgetRowIdover 100,000 calls. - Probe. Run the same loop at trunk and at the head. Trunk throws, so interleave the existing temporal getter as the unchanged control.
- Baseline. Record the trunk control latency first.
- Rule. Each new call is under 50 microseconds at p99 and allocates no more than one wrapper. The control stays within 5 percent.
Review gate. None. PR-3 changes no interaction. It is not review-gated.
Merge.
- Root's clean verdict at the exact head SHA.
- Bugbot triage done.
- Base and verdict are current under the execution playbook and the patch-id rule.
- The root appends PR-3 to the stack. The operator lands it.
Add timezone-aware temporal types (PR-4)
TIME_WITH_TIMEZONE and TIMESTAMP_WITH_TIMEZONE become first-class declared types. The driver stores and reads them as ISO-8601 text with an offset. getObject returns OffsetTime and OffsetDateTime.
Depends on. PR-2.
Files.
- Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/JdbcTypeMapping.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/JdbcValueConverter.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBReadTest.java. - Edit
libsql-itests/src/test/java/com/github/magnusp/libsql/itest/Jdbc4AppendixBTypeMappingIT.java.
Build.
- Map
TIME_WITH_TIMEZONEtoOffsetTimeandTIMESTAMP_WITH_TIMEZONEtoOffsetDateTime. - Parse ISO-8601 offset text in
getObject(int, Class)and in the declared-typegetObject(int). - Serialize
OffsetTimeandOffsetDateTimeto ISO-8601 text in the no-target and target paths. - Reject malformed offset text with
SQLException. - Keep the local date and time paths unchanged.
You see.
-
setObject(OffsetTime.of(3, 4, 5, 0, ZoneOffset.UTC))round trips throughgetObject(OffsetTime.class). -
setObject(OffsetDateTime.of(2024, 1, 2, 3, 4, 5, 0, ZoneOffset.UTC))round trips throughgetObject(OffsetDateTime.class). - A declared
TIME_WITH_TIMEZONEcolumn returnsOffsetTimefromgetObject. - A declared
TIMESTAMP_WITH_TIMEZONEcolumn returnsOffsetDateTimefromgetObject. -
+01:00andZboth parse and keep their offsets.
Verify, unit. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBReadTest#b6GetterHonoursSupportedJdbcTypes' -Dsurefire.failIfNoSpecifiedTests=false test. Expect the offset type cells to pass. - Add and run offset parser tests for
Z,+01:00, and malformed text. Expect two values and oneSQLException.
Verify, live. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked. Ten lanes on the configured swarm workers model at the PR head, per the boot recipe.
- Lane 1. Regression lane against trunk. Run
getObject(col, OffsetTime.class)at trunk and head. Savepr-4/lane-1-regression.txt. Pass when the head returnsOffsetTimeand the trunk transcript shows the old exception. - Lane 2.
OffsetTimewithout a target. Savepr-4/lane-2-offset-time.txt. Pass when the value round trips. - Lane 3.
OffsetDateTimewithout a target. Savepr-4/lane-3-offset-datetime.txt. Pass when the value round trips. - Lane 4.
OffsetTimewith targetTIME_WITH_TIMEZONE. Savepr-4/lane-4-target-time.txt. Pass when the value round trips. - Lane 5.
OffsetDateTimewith targetTIMESTAMP_WITH_TIMEZONE. Savepr-4/lane-5-target-timestamp.txt. Pass when the value round trips. - Lane 6.
OffsetDateTimewith targetTIME_WITH_TIMEZONE. Savepr-4/lane-6-target-time-from-datetime.txt. Pass when the time part and offset round trip. - Lane 7. Declared
TIME_WITH_TIMEZONEread. Savepr-4/lane-7-declared-time.txt. Pass whengetObjectreturnsOffsetTime. - Lane 8. Declared
TIMESTAMP_WITH_TIMEZONEread. Savepr-4/lane-8-declared-timestamp.txt. Pass whengetObjectreturnsOffsetDateTime. - Lane 9. Malformed offset text. Save
pr-4/lane-9-bad-offset.txt. Pass whenSQLExceptionis thrown. - Lane 10. Zone forms. Save
pr-4/lane-10-zone.txt. Pass when+01:00andZboth parse and the offsets match.
Verify, perf. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Metric. Offset parse and serialize throughput over 100,000 values.
- Probe. Run the loop at trunk and at the head, with the existing timestamp getter as the control.
- Baseline. Record the trunk control throughput first.
- Rule. The new path is under 20 microseconds at p99. The control stays within 5 percent.
Review gate. None. PR-4 changes no interaction. It is not review-gated.
Merge.
- Root's clean verdict at the exact head SHA.
- Bugbot triage done.
- Base and verdict are current under the execution playbook and the patch-id rule.
- The root appends PR-4 to the stack. The operator lands it.
Record unrepresentable types and strict conversions (PR-5)
Every remaining Appendix B row gets one answer. A supported row passes. An unrepresentable type is N/A and the driver throws SQLFeatureNotSupportedException instead of returning a wrong Java type. A declared column rejects an unlisted Table B-6 conversion. An expression column keeps the storage fallback and the profile records the exception.
The default policy is Appendix B wins. ARRAY, STRUCT, REF, JAVA_OBJECT, and DISTINCT are N/A. ROWID, SQLXML, NCLOB, and DATALINK are supported through PR-3. If the operator wants emulation instead, replace the N/A boxes with the serialization design in Appendix B.
Depends on. PR-4.
Files.
- Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/JdbcTypeMapping.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java. - Edit
libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlPreparedStatement.java. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBReadTest.java. - Edit
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBSetObjectTest.java. - Create
libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBProfileTest.java. - Edit
libsql-itests/src/test/java/com/github/magnusp/libsql/itest/Jdbc4AppendixBTypeMappingIT.java.
Build.
- Add a
Supportvalue ofSUPPORTED,FALLBACK, orUNSUPPORTEDtoJdbcType. - Mark
ARRAY,STRUCT,REF,JAVA_OBJECT, andDISTINCTasUNSUPPORTED. MakegetObject,getArray,getRef, andsetObjectfor those types throwSQLFeatureNotSupportedException. - Keep
ARRAYandREFsetter rejection. Extend it tosetObjectwith aStructor with a class whose declared type isJAVA_OBJECT. - Add the Table B-6 supported set for each getter. Reject an unlisted conversion on a declared column with
SQLFeatureNotSupportedException. - Keep the storage fallback for an expression column with no
decltype. Record the fallback in the profile. - Add a profile test that asserts the N/A list and the supported list. The list is the compliance claim.
- Update the Appendix B tests so an N/A row asserts
SQLFeatureNotSupportedExceptionand not a wrong Java type. - Confirm the policy box in this PR. The operator can switch to emulation before coding starts.
You see.
-
getInton aBLOBcolumn throwsSQLFeatureNotSupportedException. -
getStringon aBLOBcolumn throws. -
getByteson aVARCHARcolumn throws. -
getDateon anINTEGERcolumn throws. -
getObjecton anARRAYcolumn throws and the profile listsARRAYas N/A. - A listed conversion such as
getIntonINTEGERstill returns 42. - The profile test lists exactly the supported and N/A types.
Verify, unit. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBReadTest' -Dsurefire.failIfNoSpecifiedTests=false test. Expect every unlisted-cell failure recorded in Appendix A to clear and the remaining failures to be only the N/A assertions. - Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBProfileTest' test. Expect green. - Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixBSetObjectTest' test. Expect green for the negative matrix.
Verify, live. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked. Ten lanes on the configured swarm workers model at the PR head, per the boot recipe.
- Lane 1. Regression lane against trunk. Run
getInton aBLOBcolumn at trunk and head. Savepr-5/lane-1-regression.txt. Pass when the head throws and the trunk transcript returns 0. - Lane 2.
getStringonBLOB. Savepr-5/lane-2-getstring-blob.txt. Pass whenSQLFeatureNotSupportedExceptionis thrown. - Lane 3.
getBytesonVARCHAR. Savepr-5/lane-3-getbytes-text.txt. Pass whenSQLFeatureNotSupportedExceptionis thrown. - Lane 4.
getDateonINTEGER. Savepr-5/lane-4-getdate-integer.txt. Pass whenSQLFeatureNotSupportedExceptionis thrown. - Lane 5. Declared
ARRAY. Savepr-5/lane-5-array.txt. Pass whengetObjectthrows and the profile listsARRAYas N/A. - Lane 6. Declared
STRUCT. Savepr-5/lane-6-struct.txt. Pass whengetObjectthrows and the profile listsSTRUCTas N/A. - Lane 7. Declared
JAVA_OBJECT. Savepr-5/lane-7-java-object.txt. Pass whengetObjectthrows and the profile listsJAVA_OBJECTas N/A. - Lane 8. Expression fallback. Run
SELECT 1 + 1andgetInt. Savepr-5/lane-8-expression.txt. Pass when the permissive fallback still works and the profile records it. - Lane 9. Listed conversion. Run
getIntonINTEGER. Savepr-5/lane-9-listed.txt. Pass when the value is 42. - Lane 10. Profile list. Save
pr-5/lane-10-profile.txt. Pass when the N/A list containsARRAY,STRUCT,REF,JAVA_OBJECT, andDISTINCTand no supported type.
Verify, perf. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Metric. The rejection path for an unlisted conversion, and
getIntonINTEGERas the control. - Probe. Run 100,000 calls at trunk and at the head. Trunk returns 0 for the rejection path, so record that and use the absolute budget.
- Baseline. Record the trunk control throughput first.
- Rule. The rejection path is under 10 microseconds at p99. The control stays within 2 percent.
Review gate. None. PR-5 changes no interaction. It is not review-gated.
Merge.
- Root's clean verdict at the exact head SHA.
- Bugbot triage done.
- Base and verdict are current under the execution playbook and the patch-id rule.
- The root appends PR-5 to the stack. The operator lands it.
Reconcile conformance and publish the profile (PR-6)
The default build goes green. The conformance suite keeps only the xerial tests that do not conflict with Appendix B. The compliance profile names every row as supported, emulated, or N/A, with the test that proves it.
Depends on. PR-5.
Files.
- Edit
libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialConformanceDriver.java. - Edit
libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialHarnessTest.java. - Create
docs/jdbc-appendix-b-compliance.md. - Edit
README.md. - Edit
AGENTS.md.
Build.
- Run the conformance suite and list every failing test. For each one, decide whether the test encodes xerial behavior that Appendix B replaces.
- Remove or quarantine the conflicting selections in
libsql-conformance. Do not editupstream-xerial_sqlite-jdbc. - Write
docs/jdbc-appendix-b-compliance.mdas a reference. Include one row per Appendix B row, the status, the reason, and the test that proves it. - Record the expression-column fallback as a documented exception, not as a supported row.
- Add the exact unit and integration commands to
README.md. - Record the policy in
AGENTS.md. Appendix B wins, parity is kept only where the spec is silent, and unrepresentable types are N/A. - PR-0 makes the default build red by design. After this PR,
./mvnw clean verifyis green.
You see.
- The Appendix B unit suite has no unexpected failures.
- The Appendix B integration suite has no unexpected failures.
- The conformance suite is green with the documented deviations.
- The profile has a status for every Appendix B row.
- A clean checkout runs the documented commands green.
Verify, unit. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Run
./mvnw -q -pl libsql-jdbc -Dtest='Jdbc4AppendixB*' -Dsurefire.failIfNoSpecifiedTests=false test. Expect green except the profile's N/A cases. - Run
./mvnw -q -pl libsql-jdbc test. Expect green. - Run
./mvnw -q spotless:check. Expect green.
Verify, live. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked. Ten lanes on the configured swarm workers model at the PR head, per the boot recipe.
- Lane 1. Regression lane against trunk. Run the full build at trunk and head. Save
pr-6/lane-1-regression.txt. Pass when the head build is green and the trunk baseline is recorded. - Lane 2. Appendix B unit suite. Save
pr-6/lane-2-unit.txt. Pass when zero unexpected failures. - Lane 3. Appendix B integration suite. Save
pr-6/lane-3-it.txt. Pass when zero unexpected failures. - Lane 4. Existing
libsql-jdbcsuite. Savepr-6/lane-4-jdbc.txt. Pass when green. - Lane 5. Existing
libsql-itestssuite. Savepr-6/lane-5-itests.txt. Pass when green. - Lane 6. Conformance suite. Save
pr-6/lane-6-conformance.txt. Pass when green with the documented deviations. - Lane 7. Profile document. Save
pr-6/lane-7-profile.txt. Pass when every Appendix B row has a status and a test reference. - Lane 8. README and AGENTS commands. Save
pr-6/lane-8-docs.txt. Pass when the commands run as written. - Lane 9. N/A list. Save
pr-6/lane-9-na.txt. Pass when the list matches the profile. - Lane 10. Clean clone. Save
pr-6/lane-10-clean.txt. Pass when a clean checkout runs the documented commands green.
Verify, perf. Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.
- Metric. Clean
./mvnw clean verifywall time and the Appendix B suite wall time. - Probe. Run both at trunk and at the head, interleaved, with the same container cache.
- Baseline. Record the trunk wall times first.
- Rule. Head build time is within 10 percent of trunk. The Appendix B suite finishes in under 5 minutes.
Review gate. None. PR-6 changes no interaction. It is not review-gated.
Merge.
- Root's clean verdict at the exact head SHA.
- Bugbot triage done.
- Base and verdict are current under the execution playbook and the patch-id rule.
- The root appends PR-6 to the stack. The operator lands the stack bottom-up.
Close the program
- Every box above is checked with its evidence. Reply to the operator with the report the execution playbook names.
Appendix A. Prototype evidence
The baseline is the Appendix B suite added in this session, run on 3e8f582 on 2026-10-25. The run was repeated on the same commit before execution started and returned the same counts.
PR-0 lands this baseline on main by design. main is red from PR-0 until PR-6, and the stack records which failures each PR clears.
The unit command was ./mvnw -pl libsql-jdbc -am -Dtest='Jdbc4AppendixB*' -Dsurefire.failIfNoSpecifiedTests=false test. It ran 1,077 tests with 518 failures and 0 errors.
The integration command was ./mvnw -q -DskipTests install -pl libsql-hrana-codec,libsql-client,libsql-jdbc followed by DOCKER_CONFIG="$PWD/libsql-conformance/src/test/docker-config" ./mvnw -pl libsql-itests -Dit.test=Jdbc4AppendixBTypeMappingIT -Dtest=NoSuchTest -Dsurefire.failIfNoSpecifiedTests=false verify. It ran 146 tests with 63 failures and 0 errors.
The unit failures were B-1 7, B-3 18, B-5 31, and B-6 462. The integration failures were B-1 7, B-2 8, B-3 18, B-4 14, B-5 26, and B-6 8. The total is 581 failing test methods.
What remains unproven is the post-PR count for each table, the perf numbers, and the operator's policy choice between N/A and emulation for the unrepresentable types.
Appendix B. Alternatives rejected
Full emulation of ARRAY, STRUCT, REF, JAVA_OBJECT, and DISTINCT lost because SQLite has no interoperable representation for them. A driver-specific JSON or serialization format would create a compatibility hazard.
Keeping sqlite-jdbc parity for the divergent cells lost because the parity behavior is the non-compliance. The two goals cannot both win.
Type maps through getObject(col, Map) lost because Hrana has no type map and the JDBC type map is optional.
A shadow type table lost because it changes the schema and makes the driver depend on data the user did not create.
Strict rejection for expression columns lost because Hrana reports decltype as null. The storage fallback is the only honest answer, and the profile records it as an exception.
Client-side emulation of the whole SQL type system lost because it duplicates SQLite and surprises users who expect a text value to stay text.
Appendix C. Risks
SQLite affinity can undo a client-side conversion. A declared TINYINT column turns text 42 into integer 42 on its own, and a declared BINARY column keeps text. Every lane asserts typeof and every test uses a declared type.
Expression columns have no decltype. The fallback is documented as a profile exception, and PR-5 keeps it permissive.
The conformance suite will conflict with the new behavior. PR-6 lists each test it removes or quarantines, and the profile names the reason.
Wrapper lifetimes can leak. PR-3 tests free and stream reads.
The getObject hot path can regress. PR-1 and PR-2 gate it at 5 percent.
The N/A policy may be wrong for a user who needs ARRAY. The operator can switch PR-5 to emulation before coding starts.
The driver is headless, so the live lanes save transcripts, not screenshots. The review gate is None because no PR changes an interaction.
Appendix D. Links and reading list
vendor/JDBC4-TYPE-MAPPING.mdis the oracle.vendor/HRANA_3_SPEC.mdrecords the value and column model.libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/holds the driver.libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBReadTest.javaholds the read suite.libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/Jdbc4AppendixBSetObjectTest.javaholds the write suite.libsql-itests/src/test/java/com/github/magnusp/libsql/itest/Jdbc4AppendixBTypeMappingIT.javaholds the server suite.libsql-conformance/README.mdrecords the conformance harness.AGENTS.mdrecords the build and Docker commands.skills/poteto-mode/playbooks/autopilot-stack.mdis the execution playbook.
Activity
magnusp commentedon Oct 25, 2026
Delivered. The stack is STACK-READY from PR-0 to PR-6. The operator lands it bottom-up.
6a9e74ad900f630ea436c4067d423d11c0c068e91d234186dclean verifygreen, CI greenAt the tip,
./mvnw clean verifyis green in about 65 seconds. The unit suite is 1,510 tests, the Appendix B integration suite is 148, and the conformance suite is 270 with 7 skipped. A fresh clone at234186dreproduces the unit and integration results. CI is green on all six checks at the tip.The five N/A types are recorded in
docs/jdbc-appendix-b-compliance.mdwith one status and test reference per Appendix B row. The expression-column fallback is documented as an exception.Known costs, disclosed in the PR verdicts. PR-2's bind-only lane is 29 percent below trunk even though the plan's end-to-end metric passes. PR-6's conformance quarantine is method-level and drops two groups of non-conflicting assertions from the libSQL run. The four quarantined methods still pass under the xerial control profile.
magnusp commentedon Oct 25, 2026
Head correction. PR-6 moved to
0861960after an independent review found a weakened NCLOB content assertion and an incomplete quarantine record. The fix round restored the content check, named the assertions lost to the method-level quarantine, and corrected the setter test references in the profile.The corrected tip is green:
clean verifyisBUILD SUCCESSwith 2,006 tests in about 63 seconds, CI is green on all six checks, and a fresh clone at0861960runs 1,510 unit tests and 148 integration tests with zero failures. The landing order is unchanged.magnusp commentedon Oct 25, 2026
Landed. The verified stack tip
0861960is onmainas commite41cac1, through #247.Bottom-up landing was blocked by the active
mainruleset, which requiresBuild & Test (Java 25)andBuild & Test (Java 26)on every head. The Appendix B oracle is red at PR-0 through PR-4 by design, so the first link readBLOCKED.gh stack mergebatched the seven links into one atomic operation and stopped at the same gate, with no merge. Bypass is not supported for stack merges, and I did not use the ruleset bypass.The integration PR carried the same 28-file diff and the same verified head. All required checks passed before the merge. The seven stack PRs are closed as superseded, and their verdict comments remain as the review record.
mainis nowe41cac1.clean verifyat the merged head runs 2,006 tests with 0 failures and 7 skipped. The compliance profile isdocs/jdbc-appendix-b-compliance.md. The five N/A types areARRAY,STRUCT,REF,JAVA_OBJECT, andDISTINCT.magnusp commentedon Oct 25, 2026
Delivered and closed.
mainis at6bc7da7. The seven-link stack landed through #247 because themainruleset requires the full build green at every head, and the Appendix B oracle is red until the last link. The warnings cleanup landed as #248. All seven stack PRs are closed as superseded, and their verdict comments remain as the review record.The merged head passes
clean verifywith 2,006 tests, 0 failures, and 7 skipped.mainCI is green, and a fresh clone at the landed tree reproduces 1,510 unit tests and 148 integration tests with zero failures. The compliance profile isdocs/jdbc-appendix-b-compliance.md, with a status and a test reference for every Appendix B row.ARRAY,STRUCT,REF,JAVA_OBJECT, andDISTINCTare N/A, and the expression-column fallback is documented as an exception.Residual risks are recorded in the PR verdicts. The PR-2 bind-only path is about 29 percent below trunk while the plan's end-to-end metric passes. The PR-6 conformance quarantine is method-level, with the lost checks named in
libsql-conformance/README.mdand the four methods passing under the xerial control profile. The offset types supportgetObjectonly, per the Table B-6 strict reading.