Files
james.maesandClaude Opus 5.5 4f850c2cf3
maven / build (push) Failing after 9s
build / maven (push) Failing after 9s
build(deps): align with Gitea registry (parent 2.2.1, QQQ 4.1.0-RC.26)
bridges/printing/pom.xml: qqq.version: 4.1.0-RC.22 -> 4.1.0-RC.26
bridges/printing/pom.xml: qbit-record-files.version: 0.1.0-RC.1 -> 0.4.0-RC.1
bridges/printing/pom.xml: qbit-printing.version: 1.0.0 -> 1.2.0-RC.1
bridges/record-files/pom.xml: qqq.version: 4.1.0-RC.22 -> 4.1.0-RC.26
bridges/record-files/pom.xml: qbit-record-files.version: 0.1.0-RC.1 -> 0.4.0-RC.1
bridges/scripting/pom.xml: qqq.version: 4.1.0-RC.22 -> 4.1.0-RC.26
bridges/scripting/pom.xml: qbit-scripting.version: 1.0.0 -> 1.1.0-RC.3
foundation/pom.xml: qqq.version: 4.1.0-RC.22 -> 4.1.0-RC.26
pom.xml: parent -> 2.2.1
pom.xml: added qqq.version=4.1.0-RC.26 (parent BOM import)
pom.xml: revision -> 1.1.0-SNAPSHOT

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 18:59:01 +00:00
..

Record Files integration

Staged filename support: intake accepts the foundation's validated, already persisted final filename and verifies the exact filename returned by the retained owner. The owner fingerprint already binds it, so reusing an operation key with another filename conflicts. Existing IntakeRequest constructors retain the original generated-revision-<id> name. Two new bridge tests and the receipt-name mismatch branch await compatibility verification against the new foundation; historical results below are not evidence for this staged change.

Optional artifact com.kingsrook.qbits:qbit-document-generation-record-files:0.1.0-SNAPSHOT implements generation's retained-output boundary using Record Files' public services. Neither owner depends back on this bridge.

var retained = new RecordFilesOutputIntake();
config.withIntake(retained).withRetainedAccess(retained)
   .withDownloadAccess(new RecordFilesDownloadAccess())
   .withAssetSelection(new RetainedAssetSelection());
// When the optional renderer bridge is explicitly installed:
config.withRenderer(new IsolatedRendererBridge(rendererConfiguration, new RetainedAssetReader()));

RecordFilesOutputIntake.retain checks the initiating actor against the current QContext, validates the exact generated bytes/digest and selected canonical source, then calls RetainedFileService.intake. Stable operation ID, revision, format, filename and GENERATED provenance preserve the owner's idempotency meaning. The owner performs current permissions, source-record authorization, canonical attachment storage, durable registration/audit and quarantine. The bridge writes no foreign table, storage object, signed URL or second canonical byte store. Intake errors and audit failures propagate.

Receipt fileId is Record Files' logical fileKey; receipt versionId is the canonical positive decimal immutable retained row ID. Hash and length identify the exact bytes. QUARANTINED returns durable=true, available=false; FAILED/unknown/inconsistent owner receipts are rejected. AVAILABLE and released historical SUPERSEDED versions can be authorized. No review/quarantine bypass is introduced.

authorize rechecks the current actor and asks RetainedContentReader.reference for the exact version, then verifies its source association. It never substitutes the latest version. This is a current authorization result, not a bearer grant: printing must reauthorize and read under the initiating actor again at dispatch. It does not claim printer acceptance or physical output.

inspect uses the public retained-file get service for known-version recovery, returning quarantine as unavailable while preserving exact hash/length/source identity. It grants neither content reads nor printing. Missing/failed/unknown versions throw; this method never infers that an intake did not happen.

The optional RetainedAccess implementation verifies the complete committed generation receipt against that same public owner metadata. Install it explicitly for retained request/audit/item history after source archival. Owner get selects its authorized live-source or explicit immutable archive path; the bridge never infers archival from a missing/denied parent. Quarantine metadata visibility does not make bytes available. RecordFilesDownloadAccess obtains an exact-version owner grant after strict link-issuance audit; it makes no DOWNLOADED claim.

RetainedAssetReader implements the renderer bridge's small asset-reader port. It resolves the exact pinned version under current actor/source permissions, verifies hash/media/length against the manifest, then obtains audited, verified bytes through RetainedContentReader.read. The reference and returned receipt must retain the same correlation/identity. Fonts/images can be attached to another authorized asset record; no selected-record association is fabricated. The renderer independently limits supported formats and validates the bytes inside its sandbox.

RetainedAssetSelection supplies the native authoring selector. It uses enforced current-user queries/gets and the public exact-version content authority, includes only released PNG/JPEG/TrueType versions up to2MiB, bounds search pages to50, and reads labels through field projection. It neither reads bytes nor accepts a browser hash. The selected version is re-resolved before adding it to the draft. recordLocation returns the currently authorized immutable version's native Record Files table/ID; it supplies no storage URL.

The public owner content path currently caps reads at 20 MiB. This bridge also caps generated intake at 20 MiB; configure generation/renderer output limits accordingly, even though the generic renderer can support a larger bound. Renderer asset requests normally impose the stricter 2 MiB-per-asset limit. Original bytes remain solely in the canonical attachment store. Owner retention/Object Lock, quarantine scanning, backup/restore and runtime isolation still require their separate deployment qualification.

Use the current authenticated QQQ context throughout each call. Background jobs must resolve the initiating actor through current authentication/authorization; never synthesize a session from stored actor/reference fields. A replaced session or instance during the operation is rejected. The owner's explicit archive path preserves source identity and current tenant/security policy after authorized deletion. New generation and unknown intake still require a live source; a failed source lookup cannot authorize retained access.

Build using ./mvnw verify after installing the current generation, renderer-bridge and Record Files snapshots. The renderer dependency is optional for consumers that use only retained intake; explicitly include it when using RetainedAssetReader. Tests substitute only public facade methods and verify bridge contracts; Record Files' own integration suite covers JDBC, permissions, attachment lifecycle and canonical storage.