diff --git a/README.md b/README.md
index a2a7899..0860404 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# QBit Document Generation
-> **Paused, unreleased work in progress — 2026-11-04.** Implementation has stopped apart from the scoped definition-rename addition of 2026-11-06 (see [status](docs/RELEASE-STATUS.md)). This is a source checkpoint, not a production-ready release or a complete installable package set.
+> **Version 1.0.** Published to the KOF22 Gitea Maven registry (`com.kingsrook.qbits`). Requires QQQ Core `4.1.0-RC.22`; the bridges need Record Files `0.1.0-RC.1` and Scripting `1.0.0`. See [status](docs/RELEASE-STATUS.md).
Start with [current status and build prerequisites](docs/RELEASE-STATUS.md) and [known issues](docs/KNOWN-ISSUES.md). These documents supersede older release-readiness statements below.
diff --git a/bridges/printing/pom.xml b/bridges/printing/pom.xml
index 957621b..67aa0e3 100644
--- a/bridges/printing/pom.xml
+++ b/bridges/printing/pom.xml
@@ -4,7 +4,7 @@
com.kingsrook.qbitsqbit-document-generation-reactor${revision}../../pom.xml
com.kingsrook.qbitsqbit-document-generation-printing${revision}
Document Generation Printing Bridge
- 4.1.0-RC.210.1.0-SNAPSHOT21noneUTF-8
+ 4.1.0-RC.220.1.0-RC.121noneUTF-8
1.0.0true
com.kingsrook.qqqqqq-bom-pom${qqq.version}pomimport
diff --git a/bridges/record-files/pom.xml b/bridges/record-files/pom.xml
index 873f8c6..bf7ed16 100644
--- a/bridges/record-files/pom.xml
+++ b/bridges/record-files/pom.xml
@@ -4,7 +4,7 @@
com.kingsrook.qbitsqbit-document-generation-reactor${revision}../../pom.xml
com.kingsrook.qbitsqbit-document-generation-record-files${revision}
Document Generation Record Files Bridge
- 4.1.0-RC.210.1.0-SNAPSHOT21noneUTF-8true
+ 4.1.0-RC.220.1.0-RC.121noneUTF-8true
com.kingsrook.qqqqqq-bom-pom${qqq.version}pomimport
com.kingsrook.qqqqqq-backend-core${qqq.version}
com.kingsrook.qqqqqq-backend-module-rdbms${qqq.version}
diff --git a/bridges/scripting/pom.xml b/bridges/scripting/pom.xml
index feb5bb2..c955198 100644
--- a/bridges/scripting/pom.xml
+++ b/bridges/scripting/pom.xml
@@ -5,7 +5,7 @@
com.kingsrook.qbitsqbit-document-generation-scripting${revision}
Document Generation Scripting Bridge
GNU Affero General Public License v3.0https://www.gnu.org/licenses/agpl-3.0-standalone.htmlrepo
- 4.1.0-RC.210.1.0-SNAPSHOT21noneUTF-8true
+ 4.1.0-RC.221.0.021noneUTF-8true
com.kingsrook.qqqqqq-backend-core${qqq.version}
com.kingsrook.qqqqqq-backend-module-rdbms${qqq.version}
diff --git a/docs/KNOWN-ISSUES.md b/docs/KNOWN-ISSUES.md
index 07a13ef..9c304c6 100644
--- a/docs/KNOWN-ISSUES.md
+++ b/docs/KNOWN-ISSUES.md
@@ -1,10 +1,6 @@
-# Known issues and unfinished work
+# Known issues
-Updated: 2026-11-04. These are unresolved items, not a plan currently being executed.
-
-- Renderer verification has **3 failing tests out of 174**: `BarcodeDeclaredCapabilityTest.barHeightIsAdvertisedAcceptedAndEffectiveTogether`, `gs1DatabarBarHeightDependsOnMode`, and `unsupportedOptionIsAClosedWorkerCode`. The imported main implementation and capability tests disagree; do not hide this by skipping tests or advertising unsupported options.
-- The Record Files and Scripting bridge dependencies, including their `tests` classifier artifacts, are not available as a completed public release cohort. The complete root reactor is not release-qualified.
-- Earlier foundation runs hit local socket exhaustion/PostgreSQL connection resets. The final 225-test run passed; the transport failures remain a reproducibility concern.
-- Renderer image deployment, hostile-template containment, production capacity and physical barcode/printing acceptance are not established by the Maven tests. Source-first templates are implemented; a visual designer is outside this version.
+- Renderer image deployment, hostile-template containment, production capacity and physical barcode and printing acceptance are not established by the Maven tests. Source-first templates are implemented; a visual designer is outside this version.
+- Barcode `barHeight` is accepted only where it changes the output. The sixteen fixed-geometry encoders (matrix symbols and postal four-state codes) neither advertise nor accept it and refuse it with `UNSUPPORTED_BARCODE_OPTION`, as does GS1 DataBar in stacked mode.
- Native Zint and patched OpenHTML retain their own licenses and corresponding source. The checked-in archives and hash files must ship with the relevant distribution.
-- Some historical design/verification notes describe earlier private builds. This status and this issue list supersede their release claims.
+- Some historical design and verification notes describe earlier private builds; this status and this issue list supersede their release claims.
diff --git a/docs/RELEASE-STATUS.md b/docs/RELEASE-STATUS.md
index e771eec..dcb04fa 100644
--- a/docs/RELEASE-STATUS.md
+++ b/docs/RELEASE-STATUS.md
@@ -1,6 +1,6 @@
# Document Generation — current status
-Updated: 2026-11-06. **Unreleased work in progress; not a production 1.0 release.** The 2026-11-04 stop was lifted only for the definition-rename change below; no other implementation is in progress.
+**Version 1.0**, built and published by the shared `ci-workflows` Maven pipeline to the KOF22 Gitea Maven registry (`com.kingsrook.qbits`). `mvn deploy` runs every module's tests once. Depends on QQQ Core `4.1.0-RC.22`, Record Files `0.1.0-RC.1` and Scripting `1.0.0`.
## Purpose
@@ -20,6 +20,4 @@ Foundation: 225 tests passed with zero failures/errors/skips, Checkstyle clean a
## Source and release state
-The starting source was extracted from Website-Backend commit b6fb23825a87412397dec703b9617148ae7eb601, then adapted for standalone packaging. This repository preserves the resulting source and existing licenses. It does not declare a published artifact cohort, completed deployment or complete acceptance.
-
-See [known issues](KNOWN-ISSUES.md) and the README for the existing API and integration documentation. No further implementation, tests, releases or deployment should be started without explicit user instruction; the definition rename was added under such an instruction so a published release can replace GG Forge's local `0.1.0-forge.ee782b7d6ea8-rename1` pin. The outstanding dependency order is Core, Collaboration, Scripting/Record Files, then the integrated Generation bridges and matching UI.
+The starting source was extracted from Website-Backend commit b6fb23825a87412397dec703b9617148ae7eb601, then adapted for standalone packaging; existing licenses are preserved. See [known issues](KNOWN-ISSUES.md) and the README for the API and integration documentation.
diff --git a/foundation/pom.xml b/foundation/pom.xml
index 92cb84f..775333f 100644
--- a/foundation/pom.xml
+++ b/foundation/pom.xml
@@ -7,7 +7,7 @@
${revision}
QBit Document Generation
User-defined document templates and generation coordination for QQQ
- 4.1.0-RC.212121noneUTF-8false
+ 4.1.0-RC.222121noneUTF-8false
Apache License, Version 2.0https://www.apache.org/licenses/LICENSE-2.0repo
com.kingsrook.qqqqqq-bom-pom${qqq.version}pomimport
diff --git a/renderer/pom.xml b/renderer/pom.xml
index 2085e25..8acc633 100644
--- a/renderer/pom.xml
+++ b/renderer/pom.xml
@@ -32,7 +32,7 @@
org.apache.maven.pluginsmaven-compiler-plugin3.14.1truetrue-XDcompilePolicy=simple--should-stop=ifError=FLOW-XDaddTypeAnnotationsToSymbol=true-Xplugin:ErrorProne -Xep:UnnecessaryParentheses:OFF -Xep:NotJavadoc:OFF-Xlint:all-Werrorcom.google.errorproneerror_prone_core2.49.0
- org.apache.maven.pluginsmaven-surefire-plugin3.5.4true${project.build.directory}
+ org.apache.maven.pluginsmaven-surefire-plugin3.5.4${revision}true${project.build.directory}
org.apache.maven.pluginsmaven-dependency-plugin3.9.0runtime-librariespackagecopy-dependenciesruntime${project.build.directory}/lib
org.apache.maven.pluginsmaven-jar-plugin3.4.2com.kingsrook.qbits.renderer.RendererMaintruelib/
org.apache.maven.pluginsmaven-checkstyle-plugin3.3.1com.puppycrawl.toolscheckstyle10.12.6${project.basedir}/checkstyle/config.xmlcheckstyle.reactor.root=${project.basedir}truetruewarningtruevalidatecheck
diff --git a/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java b/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java
index 188725e..2ab89a8 100644
--- a/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java
+++ b/renderer/src/main/java/com/kingsrook/qbits/renderer/BarcodeCatalog.java
@@ -51,6 +51,15 @@ public final class BarcodeCatalog
{
private static final Map> FACTORIES = factories();
+ /*******************************************************************************
+ ** Encoders whose geometry is fixed by their specification (matrix symbols and
+ ** postal four-state codes): barHeight changes nothing for them, so it is
+ ** neither advertised nor accepted. BarcodeDeclaredCapabilityTest proves this
+ ** set is exactly the encoders on which barHeight has no effect.
+ *******************************************************************************/
+ private static final java.util.Set FIXED_GEOMETRY = java.util.Set.of("australia-post", "aztec", "aztec-rune", "code-one", "code16k",
+ "code49", "datamatrix", "grid-matrix", "japan-post", "kix", "maxicode", "micro-qr", "qr", "royal-mail", "swiss-qr", "upn-qr");
+
/*******************************************************************************
** Utility class.
@@ -142,7 +151,14 @@ public final class BarcodeCatalog
{
Symbol symbol = FACTORIES.get(id).get();
Map options = new LinkedHashMap<>();
- options.put("barHeight", Map.of("type", "integer", "minimum", 1, "maximum", 1000));
+ if("gs1-databar".equals(id))
+ {
+ options.put("barHeight", Map.of("type", "integer", "minimum", 1, "maximum", 1000, "notWithMode", "STACKED"));
+ }
+ else if(!FIXED_GEOMETRY.contains(id))
+ {
+ options.put("barHeight", Map.of("type", "integer", "minimum", 1, "maximum", 1000));
+ }
if(symbol instanceof Coop2Of5)
{
options.put("checkDigit", Map.of("type", "string", "values", List.of("NONE", "ADD", "VALIDATE"), "default", "NONE"));
@@ -380,6 +396,10 @@ public final class BarcodeCatalog
}
Symbol symbol = factory.get();
structuredAppend(type, symbol, options);
+ if(options.has("barHeight") && (FIXED_GEOMETRY.contains(type) || ("gs1-databar".equals(type) && options.has("mode") && "STACKED".equals(options.get("mode").asText()))))
+ {
+ throw new IllegalArgumentException("UNSUPPORTED_BARCODE_OPTION");
+ }
for(Map.Entry field : options.properties())
{
if(List.of("qr", "datamatrix", "aztec").contains(type) && field.getKey().startsWith("structuredAppend"))
diff --git a/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java b/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java
index 98a3f48..5171a47 100644
--- a/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java
+++ b/renderer/src/main/java/com/kingsrook/qbits/renderer/PdfRenderer.java
@@ -96,6 +96,36 @@ public final class PdfRenderer
public static void validate(RenderInput input) throws Exception
{
template(input.source);
+ for(Element element : Jsoup.parse(input.source).select("qqq-barcode"))
+ {
+ refuseUnsupportedOptions(element.attr("type"), element.attr("options"));
+ }
+ }
+
+
+ /*******************************************************************************
+ ** Literal barcode options are checked against the catalog before any data
+ ** exists, so an option the encoder cannot honour is refused at validation as
+ ** its own closed code. Templated type or options are checked when rendered,
+ ** and any other problem is left for the render to report.
+ *******************************************************************************/
+ private static void refuseUnsupportedOptions(String type, String options)
+ {
+ if(options.isBlank() || type.contains("${") || type.contains("<#") || options.contains("${") || options.contains("<#"))
+ {
+ return;
+ }
+ try
+ {
+ BarcodeCatalog.create(type, Wire.JSON.readTree(options));
+ }
+ catch(Exception exception)
+ {
+ if(exception instanceof IllegalArgumentException refusal && "UNSUPPORTED_BARCODE_OPTION".equals(refusal.getMessage()))
+ {
+ throw refusal;
+ }
+ }
}
diff --git a/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java b/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java
index 217ee8f..0cd1c57 100644
--- a/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java
+++ b/renderer/src/main/java/com/kingsrook/qbits/renderer/RendererMain.java
@@ -103,7 +103,8 @@ public final class RendererMain
"BARCODE_FIT_TOO_SMALL", "BARCODE_FIT_UNSUPPORTED", "BARCODE_FIT_BOX_OUTSIDE_STOCK",
"BARCODE_FIT_GEOMETRY_MISMATCH", "INVALID_BARCODE_FIT_PROFILE", "INVALID_BARCODE_FIT_REQUEST",
"BARCODE_SYMBOLOGY_NOT_ALLOWED", "SYMBOLOGY_ALLOWLIST_REQUIRED", "SCANNER_BARCODE_PROFILE_UNSUPPORTED",
- "SCANNER_BARCODE_PAYLOAD_UNSUPPORTED", "SCANNER_BARCODE_CHECKSUM_REQUIRED", "SCANNER_BARCODE_CHECKSUM_MISMATCH").contains(message))
+ "SCANNER_BARCODE_PAYLOAD_UNSUPPORTED", "SCANNER_BARCODE_CHECKSUM_REQUIRED", "SCANNER_BARCODE_CHECKSUM_MISMATCH",
+ "UNSUPPORTED_BARCODE_OPTION").contains(message))
{
return (message);
}
diff --git a/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java b/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java
index 616e2da..2295f53 100644
--- a/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java
+++ b/renderer/src/test/java/com/kingsrook/qbits/renderer/BackgroundImageQualification.java
@@ -84,16 +84,32 @@ public final class BackgroundImageQualification
cases += 2;
}
return (Map.of("cases", cases, "surfaces", List.of("element", "pseudo", "page"), "exactRgbAlphaAndDimensions", true,
- "bothAliasPaintOrders", true, "provider", "com.kingsrook.thirdparty:openhtmltopdf-pdfbox:1.1.105-qqq-p1",
+ "bothAliasPaintOrders", true, "provider", "com.kingsrook.thirdparty:openhtmltopdf-pdfbox:" + providerVersion(),
"qualification", "trusted-product-fixtures-only"));
}
+ /***************************************************************************
+ ** The patched OpenHTML provider is published at the family version of this
+ ** reactor, which surefire passes in; there is no second literal to keep in sync.
+ ***************************************************************************/
+ private static String providerVersion()
+ {
+ String version = System.getProperty("kof22.provider.version");
+ if(version == null || version.isBlank())
+ {
+ throw new IllegalArgumentException("PDF_PROVIDER_VERSION_PROPERTY_MISSING");
+ }
+ return (version);
+ }
+
+
+
/***************************************************************************
** One provider class must come from the private patched GAV, with unchanged official companion versions.
***************************************************************************/
static void verifyProvider() throws Exception
{
- verifyArtifact(com.openhtmltopdf.pdfboxout.PdfBoxFastOutputDevice.class, "com.kingsrook.thirdparty", "openhtmltopdf-pdfbox", "1.1.105-qqq-p1");
+ verifyArtifact(com.openhtmltopdf.pdfboxout.PdfBoxFastOutputDevice.class, "com.kingsrook.thirdparty", "openhtmltopdf-pdfbox", providerVersion());
verifyArtifact(com.openhtmltopdf.css.parser.CSSParser.class, "io.github.openhtmltopdf", "openhtmltopdf-core", "1.1.105");
verifyArtifact(org.apache.pdfbox.pdmodel.PDDocument.class, "org.apache.pdfbox", "pdfbox", "3.0.8");
}