Save the current implementation and README, status, and known-issue documentation at the user-requested stop. No completed release or deployment is claimed. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: GPT-6 Codex <noreply@openai.com>
4.4 KiB
Exact retained-content contract
api.RetainedContentReader is the narrow Java integration for printing and other trusted consumers. It has no printing, generation or scripting dependency. It uses Collaboration's public AttachmentsService.readContent for the only canonical bytes.
Capture and read
- Under the authenticated initiating QContext, call
reference(fileId, requestId). The caller needsrecord-files.view, current source-record visibility, and an AVAILABLE or SUPERSEDED version. The request ID is a server-selected audit correlation (1–64 letters/digits and. _ : -). - A background host resolves the initiating actor through its current authentication/authorization system before reading. Do not persist browser credentials or synthesize a trusted session from reference fields.
- Call
read(reference, maximumBytes)under that actor. The current actor must exactly matchinitiatingActorId. The reader reauthorizes the source and checks every immutable reference field before storage, and checks again after the owner's verified, audited read. The bound cannot exceed the owner limit of 20 MiB. - Consume
RetainedContent.bytes(). Both construction and access defensively copy bytes. The result includes the exact reference, correlation ID and verification time.
fileId identifies one immutable version row. fileKey identifies the logical file across versions. versionNumber, attachmentId, source table/record, SHA-256, length and media type must all match. A historical released SUPERSEDED version is supported; no operation substitutes the latest version. Quarantine, failed/unknown state, missing registry, changed identity, revoked parent visibility or missing audit prevents return of content.
The reference is an identity claim to validate, not a bearer credential or signed authorization grant. Possession of it grants no access. The public DTO contains no storage bucket/key or credentials. Its request ID binds the CONTENT_READ_AUTHORIZED and CONTENT_READ_VERIFIED events to the returned receipt. A server read does not prove user download, printer acceptance or physical output; those are separate observations.
Dispatch failures
readForDispatch(reference, maximumBytes) preserves the same checks and returns a typed RetainedReadException on failure. Only DEPENDENCY_UNAVAILABLE is automatically retryable. ACCESS_DENIED, NOT_FOUND_OR_DENIED, NOT_RELEASED, INVALID_REFERENCE, INVALID_REQUEST, CONTENT_MISSING, INTEGRITY_FAILURE, and UNSUPPORTED_CONFIGURATION require intervention or a new authorized operation. Missing and invisible records deliberately remain indistinguishable. A retryable failure grants no authorization and does not prove the original is absent.
Public exception messages are fixed and sanitized. Internal causes are for trusted diagnostics; HTTP adapters must not serialize their messages or stack traces. Host actor resolution is outside this port: it must use current authoritative permissions and distinguish resolver unavailability from an explicit denial without manufacturing a session from reference fields.
Exact download links
issueDownload(reference) rechecks the current initiating actor, source visibility and immutable version, requests an audited link through the owner, and checks the reference again. RetainedDownloadGrant contains the exact reference, HTTP(S) URL and server issuance time. Its toString() redacts the URL. Treat the URL as a temporary bearer credential: do not persist it in audit records, logs or templates. Provider expiry is not inferred from issuance time.
The durable LINK_ISSUANCE_AUTHORIZED event permits link issuance; it does not establish completed download. A serving gateway or trusted storage observation is still required for actual transfer completion evidence.
Qualification
The 2026-10-30 focused run passed seven RetainedContentReaderTest and four RetainedDispatchTest cases, including replacement server context after browser context disposal, current actor/source permission revocation, exact historical bytes, forged references, quarantine, missing audit, corrupt/missing content, provider unavailability and audited link issuance. The host replacement-session fixture does not qualify a production identity resolver. The concurrent archive suite had one unresolved test failure, so this is not a complete release or artifact qualification. Fake object storage tests do not establish provider retention, Object Lock or disaster recovery.