# TITK legacy 13 compatibility package

Status: **source prepared and statically reviewed; NOT installed or run** (2026-10-29). PHP lint, the prepared converter tests, TYPO3 DI compilation and database integration tests are still required. No Composer, database, container, build or migration job was run for this package.

This GPL-2.0-or-later extension restores selected data transformations removed from TYPO3 14. It is for the isolated TITK working copy only. It contains no schema file, automatic schema prerequisite, cleanup operation, SQL DELETE/DROP/TRUNCATE, account creation or privilege change. It starts disabled and cannot write without a separate reviewed policy.

## Relation to the master task

`MASTER-AUFTRAG-REDAKTIERT.md`, section 10.2, forbids blind wizard runs, generic cleanup/DROP and removing legacy fields before verified conversion. Sections 10.3–10.4 expressly allow small isolated stages or own converters, without running each historical release as a complete website. The package follows that execution logic. It supplements the WapplerSystems upgrader; it does not call its registered cleanup wizards.

The final C4 checkpoint must not be reported complete merely because this package installs or a CLI invocation returns 0. The template visibility gate, DENY/unknown permission cases, incomplete historical prerequisites and required extension-specific transformations must be resolved and separately recorded.

## Eight distinct identifiers and scope

| Identifier | Exact behavior and prerequisites |
|---|---|
| `titkLegacy13Compat_fileMountIdentifier` | Fill only empty/NULL `sys_filemounts.identifier` from positive `base` + nonempty `path`; preserve both originals; require referenced storage and target columns. |
| `titkLegacy13Compat_fileCollectionIdentifier` | Fill only empty/NULL `sys_file_collection.folder_identifier` for folder collections from storage + folder; preserve originals; require storage record. |
| `titkLegacy13Compat_backendModulePermissions` | Preserve the number/intention of granted modules through frozen official v13 aliases and loaded v14 aliases. Every changed token additionally needs an exact reviewed source→target policy pair. Unknown/wildcard/unloaded targets block the whole plan; no token is silently removed or a new unrelated token added. Only groupMods/userMods change; never admin, groups or other access fields. |
| `titkLegacy13Compat_explicitAllowPermissions` | Remove `:ALLOW` only for reviewed exact tuples whose target select value exists in TCA. Any DENY, malformed or unreviewed legacy tuple blocks the entire wizard before writes. Dynamic/unregistered target values require separate review. **No DENY tuple is removed.** |
| `titkLegacy13Compat_sysLogJson` | Convert PHP-serialized arrays in `sys_log.log_data` to JSON after historical log/history prerequisites. Objects, malformed serialized values, unsupported JSON values, invalid UTF-8 and oversized values block; never replace them with `[]`. Other legacy serialization formats are preserved and need separate inventory. |
| `titkLegacy13Compat_templateVersionsReview` | **Inspection-only safety gate.** If undeleted workspace templates remain, return HUMAN_NEEDED. No `deleted` flags change. The original Core wizard's soft-delete behavior is intentionally not implemented under the current no-cleanup instruction. |
| `titkLegacy13Compat_siteSettings` | Create a new settings.yaml only after exact YAML round-trip and pinned source configuration. Existing differing files/import-dependent settings block. Never overwrite a file or remove inline settings. |
| `titkLegacy13Compat_redirectRootPages` | Update sys_redirect.pid only through an explicit old-PID→Site-ID map matching SiteFinder, reviewed rootpage IDs and config file hashes. No site-not-found fallback to pid=0. All nonzero PIDs, including resulting rootpage PIDs, must be covered. |

All eight implement RepeatableInterface through `GuardedWizard`: data conditions are re-evaluated, independently of renamed historical Done markers. Batch completion is not full migration completion. Blocked states remain visible and do not masquerade as “not needed”.

## Actual dependencies

`CheckedPrerequisite` implements Core PrerequisiteInterface. Each concrete prerequisite's `ensure()` only checks and returns false when not fulfilled; it performs no repairs.

- Every wizard: `ScopePrerequisite`, validating target project, DB host/name, unchanged checkpoint manifest and private audit destination.
- Log JSON: `HistoricalLogPrerequisite`, checking the channel schema/population and absence of outstanding sys_history.sys_log_uid references.
- Template gate: `HistoricalWorkspacePrerequisite`, checking no outstanding workspace PID=-1 records in sys_template.
- Settings/redirects: `SiteMappingPrerequisite`, checking all loaded Site-IDs against reviewed rootpage IDs, original config file hashes and existing nondeleted default-language root records.

Each plan also checks its exact source **and target** columns. A missing old field blocks instead of silently marking a migration done. There is no native DatabaseUpdatedPrerequisite: schema preparation must be additive, separately reviewed and completed before these data converters. The guards do not reconstruct unsupported original extension TCA or prove that an already removed legacy column was historically migrated correctly.

Recommended ordering after C3: required historical history/workspace conversions; file identifiers; reviewed module/explicit-ALLOW transformations; log JSON; template visibility decision; site settings and verified redirect roots. Run only explicit IDs. Never invoke `upgrade:run` without an identifier.

## Policy and installation handoff

1. On a disposable target copy, complete syntax, pure converter and DI checks first. No composer.json elsewhere has been modified by this work. Install as a local path package only in the intended TYPO3-14.3 project after review; no private repository or extra license is needed for this package.
2. Create a complete C3/pre-write checkpoint with corresponding DB, files, composer.lock, package sources and restore instructions. Stop other writers for the selected copy.
3. Copy `Configuration/policy.example.json` to a private regular file outside the public path. Set `TITK_LEGACY13_POLICY_FILE` to that file path. It contains no credentials. Supply exact expected project/DB host/name, checkpoint manifest path+SHA256, checkpoint ID, a private `.jsonl` audit path and only the selected wizard IDs. Keep enabled=false until all values are reviewed. The protected original host/database is explicitly rejected.
4. For permissions, add only evidence-backed `reviewedModuleAliases` and `reviewedExplicitAllowTuples`. An example shape is `{ "oldCoreAlias": "verifiedCurrentModuleId" }` and `["tt_content:CType:verifiedExistingType"]`; these placeholders are not ready to execute. No arbitrary source→target permission mapping is accepted: module targets must also derive from the frozen v13/actual v14 Core alias maps and be loaded target modules.
5. For sites use this shape, with actual source review and hashes; do not copy this placeholder as real data:

```json
{
  "sites": {
    "reviewed-site-id": {
      "rootPageId": 123,
      "configSha256": "<64 hex SHA256 of config/sites/reviewed-site-id/config.yaml>"
    }
  },
  "redirectPidToSite": {
    "123": "reviewed-site-id",
    "456": "reviewed-site-id"
  }
}
```

All loaded sites need policy entries. Include every nonzero redirect PID and every resulting root PID. A source page or configured root that is missing/ambiguous is a stop condition. The code does not guess a Site-ID from a hostname and does not rewrite redirect hosts/targets.

6. With a complete preflight and the chosen ID enabled, a later explicit invocation is:

```bash
TITK_LEGACY13_POLICY_FILE=/private/reviewed-policy.json php vendor/bin/typo3 upgrade:run titkLegacy13Compat_fileMountIdentifier
```

Set the environment variable in the controlled CLI process only. Do not make policy editing or credentials part of a public backend workflow. TYPO3's own CLI bootstrap may itself write its configuration/charset or run other boot hooks; package isolation does not suppress native application bootstrap behavior. Use only the intended writable working-copy configuration and separately verify that bootstrap scope first.

## Integrity, audit and rollback limits

`Executor` takes a nonblocking exclusive lock on the shared private audit file, rebuilds the plan, and persists a prepared entry before writes. It verifies each target table is InnoDB, locks each source row with SELECT FOR UPDATE, compares its full inspected source fields, updates only a fixed per-wizard field allowlist, then reads back exact target values. A mismatch or failure rolls back that database batch. No schema changes, truncation, old field removal, record removal or privilege operations are available in the write allowlist.

Audits contain IDs, field names, hashes, counts, checkpoint/policy hashes and controlled error reasons, not old/new log or settings content. Use one audit file for this package and no concurrent external writers. Data remains in the checkpoint; hashes are evidence, not a substitute for a restorable backup. Batch size is bounded (default 10, maximum 250), and batchSize × maxValueBytes must not exceed 16 MiB. Oversized log values are checked before payload loading; nesting, expanded bytes and visited values are bounded under the 4-GB VM limit.

A final audit failure after database commit is explicitly a `failed_or_partial` condition; do not assume rollback or rerun blindly. Inspect data and prepared hashes. Settings-file creation is separate from DB transactions and uses exclusive creation, with no replacement or cleanup. A partial disk write is retained as evidence and blocks the next run; recover that site's new file from the checkpoint under a separate controlled repair. The converter never deletes a partial file itself.

Verify row counts/UIDs, source column values, changed target values, relations, rootpage mappings and permission semantics against C3. Existing nonempty file identifiers are deliberately not overwritten and need a separate conflict review. Zero/empty old storage/path cases are not inferred. Keep original tables, fields, files, C3 and its restore path.

## Provenance and license

The eight unmodified reference classes in `Upstream/TYPO3-v13.4.37/` come from official TYPO3 commit **05ec0d9f02600d6dae262ab870e75e2f60fdeb06**, tag v13.4.37. They are reference-only and outside the autoload/services paths. `upstream-provenance.json` lists the direct commit URLs, SHA256 hashes, license and official module-definition sources. Only official TYPO3/Core sources were fetched. The root `LICENSE` is the official upstream license text; new/derived code is GPL-2.0-or-later as declared in composer.json.

Changes from upstream are deliberate: separate namespaces/IDs, explicit scope policy, checked prerequisites, bounded transactions, strict source/target verification, audited permission mapping, DENY blocking, template visibility blocking, pinned Site-ID mapping and exclusive settings creation. No claim of complete migration or runtime compatibility is made before the listed tests and a reversible-copy rehearsal pass.
