specs/023-verified-publication-corrections/plan.md
Rama main · réplica de lectura del repositorio original.
# Implementation Plan: Verified publication corrections
**Branch**: `codex/verified-publication-corrections` | **Date**: 2026-10-04 | **Spec**: [spec.md](spec.md)
**Input**: Prospective requirements from `specs/023-verified-publication-corrections/spec.md`.
## Summary
Preserve independently verified correction knowledge so repeated publication payloads cannot regain a wrong owner through filenames, metadata or recompression. Native Mylar owns authenticated immutable evidence and final admission; worker checks are advisory until local writer/revision checks and native publication revalidation pass. Existing incorrect duplicates remain separate restore-verified operational work.
## Technical Context
**Language/Version**: Existing Python native and worker runtimes; actual pinned image gates are authoritative.
**Primary Dependencies**: Existing Mylar workflow/writer/catalog/tagger modules; immutable archiving-utils artifact already used by the normalizer; image-bundled libarchive reader. No runtime network dependency for payload verification.
**Storage**: Existing private `workflow.sqlite`, complete correction census/revision and an owned writer-protocol binding marker; worker receipts in existing state. Native application schema is unchanged. Reviewed device recovery adds a bounded private adoption ledger within the existing writer root, preserving immutable rows and original binding bytes. Stable Btrfs identifiers support prospective device-number reconciliation without relaxing per-process physical custody.
**Testing**: `unittest`, actual patched native-source branch checks, converter-backed worker fixtures, both published image build gates and `make ci-local`.
**Target Platform**: Independent portable Mylar and Komga Compose examples with the existing shared media/writer protocol.
**Project Type**: Native application adapters plus maintenance worker and authenticated operational APIs.
**Performance Goals**: No library-wide scan per import. Skip payload scans when the validated registry is empty; otherwise stream only the candidate and any matched correct-owner evidence, with fixed bounds/timeouts. Reuse only stable source/registry-bound proofs under writer exclusion.
**Constraints**: No guessed identities, archive writes during checks, automatic correction registration, false import completion, global blacklist or privilege expansion. New mounts/ports are unnecessary.
**Scale/Scope**: At most 512 immutable correction attestations per v1 registry; at most eight explicit allowed/rejected owners per admission; 4,096 archive members and 4 GiB expanded bytes per bounded inventory. Oversized or unavailable evidence remains held.
## Constitution Check
- Portable examples: private correction attestations remain runtime state; examples contain placeholders only.
- Complete contracts: Mylar image/runtime dependency, Compose/environment/preparation/ingress comments, metadata/README and module map are reviewed together; matching worker contracts document protocol, deployment and retention. Existing ports/mounts/privileges remain sufficient.
- Operations: registration and repair follow scoped consistent backup/independent restore; no privileged action while the user’s hold applies.
- Generated truth: regenerate catalog/topology only if tracked metadata changes; no manual generated edits.
- Validation: focused kernel/boundary/fixture checks, independent reviews, full local CI and actual native/worker image gates precede delivery.
Pre-research and post-design gates pass; no constitution exception is required.
## Project Structure
```text
specs/023-verified-publication-corrections/
spec.md plan.md research.md data-model.md quickstart.md tasks.md
contracts/publication-corrections.md checklists/requirements.md
stacks/mylar3/
Dockerfile
config/publication_guard.py config/publication_api.py
config/publication_identity_adoption.py config/publication_identity_maintenance.py
config/publication_identity_readers.py config/publication_filesystem_binding.py
config/patch_publication_guard.py config/patch_publication_startup.py
config/publication_fresh.py config/publication_native.py config/publication_transaction.py
config/patch_publication_processing.py config/test_publication_native.py
config/test_publication_guard.py config/test_publication_api.py
config/test_publication_startup.py
config/apply_patches.py config/verify_image.py config/MODULES.md
config/{native_writers,workflow_store,processing_guard,tagger_backend,tagger_native,
tagger_service,file_identity,converted_catalog,converted_tagging,
release_naming,tagger_supplement,patch_media_writers,library_metadata,
tagger_adapter,tagger_nfs}.py
stacks/komga/normalizer/
publication_guard.py test_publication_guard.py
import_recovery.py pack_recovery.py maintenance.py normalize.py naming_worker.py
writer_cycle.py test_writer_cycle.py
```
**Structure Decision**: Keep correction authority in the focused native SDK, authenticated protocol in its separate controller and checked build adapter, and the worker protocol adapter in its independent Docker build context. Integrate checks into owning modules and actual native branch patches. Preserve existing owner/recovery contracts instead of introducing a new general processing framework.
## Delivery and verification
Implement and verify registration as the first independent story, then every publication boundary, then scoped repeat reconciliation. Source delivery may be split at coherent reviewed milestones; do not call prevention complete until all writer boundaries and matching images pass. Native-first rollout is coordinated and restore-verified; exact existing repeats seed only reviewed evidence. Feature 022 completion remains gated by current-library repair, final protected second pass, cleanup and worker resumption.
## Owned tagging integration
T007 introduces a private typed tagging intent and internal capability under the
already admitted raw Writer. Ordinary operations and public advisory routes keep
their pending-state hold; only the exact current job may revalidate its own fence
and payload. Bind native tagger state-directory identities before producer use.
Persist source/owner/policy/census and phase-specific publication evidence with its
receipt. Recheck current authority and matched correct-owner archives before
publication, pack finalization, cleanup and acknowledgement. Clear only the
captured fence after durable verified terminal receipt; interruptions retain the
typed hold and preservation copies for explicit review. This requires shared Publisher/NFS/
handoff checkpoint work during T007; T009 subsequently covers its other direct
consumers and reviewed source-to-target/derivative recovery. No generic nested
fence bypass or automatic upgrade of unbound receipts is permitted. T010 must also
hold a retained prepared tagging intent even when its pending marker is absent.
Legacy copy/CLI/cleanup remains held before invocation in publication mode until
its temporary state and fallback placement are bound to an owned adapter.
An in-place producer may replace only a retained copy outside the registered
correction owner paths. Bind its
complete NFS before/after file and workspace facts into both the owned intent and
receipt before displacement. Preserve the current registered archives and complete
payload/owner observations throughout. Passive proof uses only the already-bound
in-process publisher; expired capabilities and lost state grant no initialization
or replay. Registered catalog paths require an explicitly adopted exact derivative relation and a typed producer; the new reviewed transition preserves original payload protection and every inherited owner claim. Unadopted SDK or automatic nested repair remains held.
Keep terminal witnesses under the existing private writer state. Bind their
complete retained predecessor to the receipt's canonical intent digest, and bind
terminal facts to a canonical proof in that same receipt before releasing the
owned marker. Revalidate witness contents through both release boundaries.
An exact closed receipt may then be read by a later job without replay or a
remaining disposable output. Its epoch must still match current authority, its
revision cannot exceed the current revision and its census keys must remain
present. The receipt binds the complete original census; changed or unbound history stays
held. These witnesses grant no current media mutation or recovery permission.
## Prospective aggregate recovery dependency
T020–T025 and T028 source review precede the T026 source/install milestone.
One shared T026/T029 isolated forward and distinct rollback then supplies the
connected criteria of feature 024 T012/T015 and isolated T027. Whole-task
completion is not a circular prerequisite for that pair. Accepted connected
proof and matching delivery precede the rollout milestone in T017;
T027 then supplies fresh live aggregate evidence before T017 reconciliation
and T018–T019 acceptance and cleanup. Original task IDs and history remain. Native `publication_negative_batch.py` owns the immutable five-source
marker, complete shared-parent phase projection, exact staged reservations,
rollback and terminal closure. `publication_reader_phase.py` owns stopped-reader
scope, main/tasks raw restore custody, typed SQL comparison and exact forward/reverse
transaction boundaries. Native/worker ordinary admission and archive PREPARE
refuse the new pending marker without a generic bypass. A durable root-owned
terminal successor hold must precede aggregate-marker removal and span final
receipt acknowledgement, including crash and lost-response boundaries. Installers and selected
image tests must verify exact classes and module provenance before use. Fresh
operational reader and NFS evidence remain separate from portable source tests.
## DDL cache growth prevention — 2026-10-12
Extend the existing intake/backpressure boundary with a configurable retained-cache byte budget and processing headroom. Inventory the cache without following symlinks, count retained and temporary payloads, and refuse new admission when capacity cannot be established. Reuse existing durable capture ownership to prevent repeated downloads of an unresolved delivery. Keep import acknowledgement and source-retirement authority unchanged; neither age nor a Completed label permits deletion. Verify boundary, concurrent reservation, restart, unreadable state and retained-pack scenarios before reviewed image delivery and live acceptance.
### T028 fixed-anchor launch follow-up
Reuse the source-reviewed root broker and existing enrollment/authentication
protocol. A revised finite profile adds only three fixed root public-anchor
read-only leaf mounts, with empty root-owned image targets. Capture host originals
before reads, authenticate their hashes to the reviewed deployment and retain
source/creator/namespace custody through launch. Keep legacy profiles strict
and ordinary service startup unchanged. Validate success and missing/empty/
symlink/replaced/key/inventory/profile/mount refusals with disposable controls;
require real image-layout smoke and configured UID1000/pipe/retained-ACK proof
before operational acceptance. No new signing framework is introduced.
Retained acceptance verifies a distinct fresh retained catalog event and ACK
against an existing catalog target. It preserves Location and Status and grants
no ordinary import ACK or source cleanup. T033 owns genuine ordinary import and
later automatic-capture acceptance. A Wanted member without a catalog Location
is excluded from the retained route; an eligible ordinary selected pass follows
its own admission and preservation checks.
The Root retained run must reserve native operations for the exact selected
request before taking its paused backup. Reuse the native mode lock and active
operation counter, and fence ordinary background work and raw
`publicationControl` Writer routes with a durable, private reservation marker.
The existing primary normal API key and POST/source checks own this finite
control; do not change `API_ENABLED` or infer authority from saved JSON. Only
the same live native process may admit the selected finalize/status calls.
Restart, expiry, foreign request, busy acquisition and lost custody hold for
review. Keep the reservation through independent terminal verification, the
actual Worker release ACK, natural child exit and guarded Reader resumption.
Close it only against the original nonce, actual final record and complete SQL
proof, then retain the closed receipt for accepted owning cleanup. This is an
implementation requirement of T028, not accepted configured execution.
Completion archives independently verified pending and closed records in the
original nonce's private history directory. The original pending marker remains
the restart fence until both copies and final business state are verified. Its
removal is the commit point; caught later failures restore a negative fence.
Live custody clears only after the Writer context exits successfully. Saved
history grants no authority and its nonce cannot be reused. A crash before
commit holds; a crash after commit retains the already verified durable history.
Reservation health reports held publication authority with current worker
liveness; it does not acquire the worker-held Writer, read SQL or grant
import/readiness authority. Actual configured completion remains T028 acceptance
work until the Root transcript, terminal checks and guarded resume are proved.
The participating worker pack stage consumes the effective native policy from the authenticated, prefetched `getHealth` reply. The snapshot binds the existing config bytes, reservation inode and physical cache roots. It is read under the shared Writer without another API call and mapped only through existing `/mylar` and `/ddl-cache` binds. Normal admitted startup initializes the native lock; health never creates it and the worker opens it existing-only through its read-only native config mount. Missing, stale or unmapped policy refuses staging without guessed defaults.
Finalize and verify conversions in independent worker state, then reserve their exact output size plus block/inode overhead before copying into shared cache. Release the cache reservation before import or handoff. Existing verified output may be reused with zero growth above capacity; positive growth still refuses. Partial stages and original payloads remain retained. Independent worker state remains outside this DDL budget and requires its own storage policy. This source design does not establish the actual configured limits or live T030 acceptance.
The effective policy separately binds the actual DDL directory even when it is a subtree of the aggregate CACHE_DIR. The worker checks the declared writable DDL alias against that exact original subtree and retains the aggregate roots for accounting; it never adds the writable alias as a duplicate budget root or permits growth in another aggregate root. Native config observation accepts the owning regular-file contract (root/current owner, no group/world write, at most 2 MiB), preserving its original mode and hash.
Each unchanged pack member/source generation has one exclusive conversion workspace. A durable finalized receipt binds the original source path/full identity/hash, workspace identity and finalized output full identity/hash. Capacity refusal retains it; a later cycle verifies the same originals and preservation before reusing it without conversion duplication. Incomplete, changed or unknown attempts remain for owning review. Minimum positive cache admission precedes a new workspace, and exact finalized-size admission still precedes cache copy. No source cleanup, budget increase or ACK follows from this receipt.
### Restricted ongoing ordinary pack recovery
FR-017 uses the existing worker entrypoint, pack-only selected executor and native
`packWork` pagination. An explicit recurring CLI branch and last Compose command
override leave the full default cycle unchanged. Discovery fetches health/work and
the existing bounded reader observation outside Writer, then validates current
scoped authority. Every selected pair gets a fresh selected preparation and owning
member/cache/import/report/ACK checks. Dispatch stays outside Writer. No general
maintenance, naming, catalog fallback, conversion sweep or reader scan runs.
Native passive discovery rotates through at most eight completed DDL rows and
eight pending captures per poll. One unknown source receives a cumulative 256 MiB
actual-read allowance, reserved before the attempt and consumed on failure.
Changed known identities produce separate review observations without rewriting
original captures, members or acknowledgements. Pending and observed source paths
remain protected across pagination. Trusted download capture keeps its existing
32 GiB bound. This does not retroactively establish legacy source birth authority
or grant automatic device-change adoption.
T033 follows delivered selected-path source and T032 control-state acceptance.
Review source and all copied current fixtures, publish and verify the matching
worker, then perform affected-state backup/restore and a selected canary before
restricted activation. Prove a later capture without a second manual invocation,
restart reconciliation, no uncertain replay, typed catalog-to-ACK completion and
original preservation. Keep full/bulk activation and configured Parent/NFS gates
separate. Capacity refusal remains a hold under FR-016.
## Explicit disposable NFS searchability
Creator request v3 and geometry v2 `searchable-common-root-nfs` address daemon
path traversal on root-squashed NFS without changing live storage or exports.
Only the fresh supplied NFS scratch parent and newly created common G use exact
UID/GID1000 mode0711. Library/retention leaves and local state stay0700, credentials
0600. Existing ancestors must already be searchable; existing failed generations
are never chmodded or adopted. The single transient G bind, exact per-role L
mounts, two-child namespace, full9/FD custody, mount-ID and role exclusions remain
unchanged. Legacy Creator v1/v2 and geometry v1 keep their exact0700 contract.
The owning source contract documents stat-visible names and the absence of
non-owner enumeration/write rights. Component tests and a separate disposable
bind probe do not establish full Creator, NFS lifecycle, import or ACK acceptance.