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>
6.5 KiB
Correcting OPEN file collections
The initial correction focused gate passed 47 tests with Checkstyle (root 51207); the later checkpoint-ownership gate passed 49 tests with no failures/errors/skips (target/collection-checkpoint-ownership-focused-verification.log). The actual HTTPS FullNativeApiCollectionCorrectionIT and ordinary HTTP NativeApiCollectionCorrectionTest each passed in ../qbit-scripting/target/native-source-collection-corrections-verification.log. Those cases cover caption/remove/restore/details, immutable upload receipt replays, unchanged retained bytes and READY refusal. The mixed six-test run was nevertheless FAILED because the separate source-actions fixture failed during WarmRuntimeService.start; its three baseline collection cases also passed. This is scoped collection evidence, not a successful aggregate reactor gate.
Full gate 88975 executed 212 tests with 211 passing and one MySQL fixture connection reset before the changed service; preserve collection-corrections-full-verification.log. An unchanged two-case MySQL control passed the original reset case and progressed through the actual collection migration/corrections before a fresh parent-lookup connection timed out. Both provider transport failures remain unclassified; no deadline or invariant was weakened and no unchanged broad retry is claimed as a fix.
Native actions reuse CollectionService: Edit caption and confirmed Remove from collection on a Collection Item, plus Edit collection details on a File Collection. They recheck the current manage grant, source visibility, attachment feature, current credential/channel mutation ceiling and OPEN state under the collection row lock. READY collections remain immutable. Every effective change records an independently durable attempt before metadata writes, then commits the outcome event with the change. Identical caption/details and repeated removal are no-ops only after current authorization/state checks.
Removal excludes membership; it never deletes the row, original bytes, parent attachment or upload evidence. Active items retain contiguous one-based ordering. Excluded rows use their unique negative item ID as a storage position, with lastActivePosition recording the position at removal. Their native table rows remain visible under the same parent authorization, explicitly marked excluded; they remain part of historical audit. CollectionService.items() and the native reorder form return active items only. Adding a previously excluded file restores the same item ID at the end and records a distinct restoration event. Initial added-at/actor provenance remains unchanged; each removal/restoration and caption change has its own current actor/time audit. An active duplicate is refused.
maxItemsPerCollection caps all distinct retained membership rows, including excluded history. Excluding an item does not free a history slot. Restoring an existing row does not consume another slot but must also fit the current active quota. This prevents unbounded remove/add history growth. A new collection is appropriate after the retained-history quota is reached.
Removal never reduces the expected count automatically. Edit details accepts a title of 1–255 characters and a nullable expected count; a supplied count must be at least the current active size and at most the configured quota. Clearing the expected count explicitly returns to the existing unspecified-count policy, which still requires at least one released member to finalize. Details corrections never modify capture-session/device provenance or the original upload manifest/receipt.
Upload-owned collections cannot be corrected, reordered or finalized while upload finalization/recovery is incomplete. The upload finalizer still creates/adds its own checkpointed memberships. Once COMPLETE, its immutable receipt continues to describe the original retained admission, not subsequent collection title/order/membership; replay returns the exact same receipt. Current collection state is obtained separately from the native record/item APIs.
Required schema adoption
Stop/admit no traffic using the new metadata until the host migration system applies the appropriate script:
src/main/resources/db/migrations/20261101-collection-corrections-h2.sqlsrc/main/resources/db/migrations/20261101-collection-corrections-mysql.sql
Both add nullable excluded BOOLEAN and last_active_position INTEGER only. Existing NULL exclusion values mean active; no legacy rows, uniqueness indexes, bytes or receipts are rewritten. Fresh generated H2/MySQL schemas already include these columns. H2 uses IF NOT EXISTS; MySQL is an apply-once versioned migration. No destructive rollback is supplied. Existing PostgreSQL DDL remains an unqualified prospective schema, not a supported migration claim.
The staged migration tests rebuild a populated legacy schema by removing only the two new columns, execute the actual shipped script, compare all prior row values, and exercise remove/restore/finalize with the same retained original. The same helper is used by the actual MySQL provider suite. No running local application or database has been changed by staging this source.
Finalizer-owned membership append — focused/native proof
Ordinary addItem now requires linked upload completion even for a new file. An unfinished upload can no longer receive a manual extra member between checkpoints. UploadFinalizer.append retains its existing outer capture-authorization guard and upload-row lock through the actual SQL commit. It mints a private-constructor, synchronous CheckpointAppend object for the exact retained item and checkpoint. The collection-specific append method consumes it once and verifies the same thread, instance, session, actor and owned transaction, current parent/capture authority, active lease, exact manifest item/content tuple and unchanged prior checkpoint. It rechecks after append; the finalizer validates the returned membership/position before checkpoint persistence and invalidates the object in finally. There is no new serialized grant, queue, registry, native form bypass or public skip flag.
New regressions attempt manual additions during FINALIZING and FAILED without false success audit, complete a genuine append, refuse reuse/out-of-scope/current-actor mutation, recover without duplicating membership, then allow normal additions after COMPLETE while preserving the original receipt. The 49-test checkpoint gate passed. Existing capture guards still hold through transaction commit, rather than stopping at token validation.