# International Press Zone — Manual Translation Protection RC Handoff

Date: 2026-08-21
Status: **WIP — functional test stack green; PHPCS remediation in progress; not landed; not deployed**

## Purpose

This document is the durable resume point for the `international-press-zone` production-completion / PG-14 manual-translation-protection RC. It records the exact repository state, completed implementation, verified gates, current blocker, remaining work, landing policy, and immediate next commands so another conversation can continue without rediscovery.

## Non-negotiable execution constraints

- Repository root: `/home/user/Projects/Press.zone/wordpress/wp-content`
- Plugin: `/home/user/Projects/Press.zone/wordpress/wp-content/plugins/international-press-zone`
- **Implementation worktree only:** `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/manual-translation-protection-rc`
- Branch: `wt/manual-translation-protection-rc`
- Do not implement in the shared checkout.
- Assistant is the sole implementor. Do not launch Claude, Codex, Gemini CLI, or other coding agents.
- Every dependency install, test, lint, typecheck, build, static analysis, security check, browser run, smoke, screenshot, and diagnostic gate must execute on the sanctioned remote buildboxes. The workstation is for editing/filesystem/git/non-test inspection only.
- Browser/server E2E only on `debian1`, `debian2`, `debian3`. Prefer `debian3` because it passed the remote doctor and already has Composer dependencies.
- Canonical remote wrapper: `/home/user/.claude/bin/e2e-remote`
- Canonical E2E contract: `plugins/international-press-zone/.claude/skills/ipz-e2e.md`
- Landing controller: `/home/user/Projects/Press.zone/wordpress/wp-content/.claude/scripts/ship.sh`
- Do not deploy before landing.
- Do not claim landed until the final commit is proven an ancestor of current `origin/master`.
- Before removing the implementation worktree, run `lsof +D <worktree>`.
- Do not revive legacy license/PayPal/CloudPanel/JobReceiver paths. Product targets Worker `/api/*`, Connect/social auth + Stripe + per-site encrypted credential.

## Exact git state at handoff

```text
HEAD         = 01940a99240c98e6fe1d919b0815670e645fc503
branch       = wt/manual-translation-protection-rc
origin/master= cee8d2649fe47eb153d0ca5ecb47edab817ea4d3
MERGE_HEAD   = cee8d2649fe47eb153d0ca5ecb47edab817ea4d3
```

The worktree is intentionally in an **open merge state** created with a supported normal merge of current `origin/master` into the RC branch. **Do not abort this merge.** Keep it open through remediation/testing. The eventual normal `git commit` should create the correct two-parent convergence commit and run the repository pre-commit/claim gate.

Already staged from `origin/master` during the open merge:

- `plugins/international-press-zone/GOLIVE.md`
- `plugins/international-press-zone/docs/plans/2026-08-19-page-fidelity-current-master.md`
- `plugins/international-press-zone/docs/plans/INDEX.md`

The PG-14 implementation and associated tests/admin assets remain unstaged or untracked in the implementation worktree.

## Durable WIP archive refs that already exist

These older snapshots are available if recovery from an earlier checkpoint is required:

- `wip/archive/manual-protection-complete-tree-20260820` -> `f359209a714f1f4c022dcaf01e341abe5822582f`
- `wip/archive/manual-protection-reconciled-20260820` -> `f2dd458cd5269575691deda177f95db1c9b09c3a`

They do **not** contain every latest fix described below; the live implementation worktree is ahead of them.

## PG-14 contract / product requirements

Canonical settings shape:

```json
{
  "protect_manual_translations": true,
  "auto_translation": {
    "enabled": false,
    "behavior": "mark_stale",
    "triggers": {
      "edit_post": false,
      "new_post": false,
      "edit_page": false,
      "new_page": false,
      "edit_custom_post_type": false,
      "new_custom_post_type": false,
      "edit_update_plugins": false,
      "new_plugins": false,
      "edit_update_themes": false,
      "new_themes": false
    }
  }
}
```

Protection semantics:

- Provenance: `manual | generated | unknown`.
- Override: `inherit | locked | unlocked`.
- `locked` is protected. `unlocked` is writable. `inherit + generated` is writable. `inherit + manual/unknown` is protected when global protection is enabled.
- Finalization precedence: target/source changed -> `skipped_target_changed`; then protected -> `skipped_protected`; otherwise persist generated result.
- Generated saves preserve override. Manual saves set provenance `manual`.
- Force retranslate never bypasses protection.
- Terminal states include `completed`, `skipped_protected`, `skipped_target_changed`, `failed`.
- Invalid override returns HTTP 400 `invalid_lock_override`.
- Zero-trigger automation save is rejected with inline error.
- Legacy `ipz_auto_translate=true` must not silently arm paid automation.

Automation semantics:

- `AutoTranslationCoordinator`, `ContentChangeTrigger`, `ExtensionChangeTrigger`, durable queue/idempotency, bounded reconciliation.
- Defaults off / `mark_stale`.
- `mark_stale` performs zero external spend.
- `translate` queues missing + unlocked stale content; locked targets remain stale and unqueued.
- Exclude drafts/autosaves/revisions/trash/translated targets/plugin writes/unchanged fingerprints.
- Extension events scan only the changed extension.
- Removed strings become absent/orphaned; no automatic delete.
- Fail closed when lock/fingerprint/race state is uncertain.

UX semantics:

- Global controls on Settings.
- Per-translation protection in content modal, string modal, and translated editor.
- Accessible tooltip/help controls.
- List/status surface shows `Protected`.
- Generated actions disabled when the target is known protected.
- Summaries include Translated / Marked stale / Protected / Changed while queued / Failed.

## Implemented production changes

### Protection/domain/state

Implemented new/shared classes and state including:

- `includes/Translation/ProtectionDecision.php`
- `includes/Translation/TranslationProtectionPolicy.php`
- `includes/Translation/TranslationProtectionService.php`
- provenance, lock override, queue/source/target fingerprint handling
- generated-write context tracking
- manual-save provenance recording
- content mapping recovery for missing mapping rows
- finalization protection/race decisions

### Schema/migration

- Database version advanced for PG-14.
- `includes/Migrations/Migration010TranslationProtection.php` adds/backfills protection/job metadata.
- Duplicate content mappings are recovered before the unique group-language index is added.
- Job/job-item status enums include protected/changed terminal states.
- Legacy automation settings are preserved as a review-required condition rather than silently enabling paid translation.

### Automation

Implemented:

- `includes/Translation/AutoTranslationCoordinator.php`
- `includes/Translation/ContentChangeTrigger.php`
- `includes/Translation/ExtensionChangeTrigger.php`
- `includes/Translation/SourceChangeEvent.php`
- queue/reconciliation/audit paths
- content and extension change trigger scaffolding

These classes are functionally present but are also the largest current PHPCS remediation surface; see blocker section.

### REST/controller/finalizer integration

Updated production surfaces include:

- `PostsController.php`
- `SettingsController.php`
- `StringTranslateController.php`
- `TranslateController.php`
- `TranslateJobsController.php`
- `TranslationsController.php`
- `TranslationFinalizer.php`
- `TranslationJobDispatcher.php`
- `TranslationService.php`
- job recorder/sender and related persistence paths

### Site Content dispatch/poll/cancel/retry convergence

Substantial Site Content correctness work is in the current worktree:

- Callback identity parser accepts legacy `wp_<id>` and canonical site-scoped `wp_<64hex>_<id>`.
- Site-scoped callback IDs are validated exactly against `SiteIdentity::client_job_id($job_id)`; wrong-site callback fails closed.
- Polling loads actor/source/target/context metadata required for object-policy checks.
- Generic one-hour timeout excludes Site Content jobs.
- Site Content completion uses safe Site Content cache rotation rather than generic rotation.
- Broad collection sync excludes Site Content; specific Site Content sync remains possible.
- Job list visibility fails closed and applies capability + entitlement + object policy to Site Content rows.
- Site Content retry routes through the dispatcher.
- Site Content cancellation validates immutable context, cancels backend first, uses transaction + domain attempt failure + local CAS cancellation, rolls back on persistence failure, and safely rotates cache.
- `TranslationJobDispatcher` gained Site Content dispatch/retry/reconciliation support and factory dependency wiring.

Focused Site Content controller and dispatcher regressions were brought green before the full gate run.

### Dispatcher reconciliation cleanup

- Generic reconciliation uses authoritative same-idempotency-key POST replay with exact stored submit body.
- Advisory lock release failure after local insert now preserves the local job so failure/reconciliation state can be persisted rather than rolling back the only record.
- Cleanup harness was corrected to load the real `IdempotencyKey` and distinguish original dispatch from reconciliation replay.

### Admin UI

Current worktree contains updates to:

- Settings automation/protection controls
- content translate modal
- string translate modal
- translated editor metabox
- form/select/toggle/tooltip components
- new `TooltipHelp.js`
- generated admin distribution assets

A known review item remains: protection changes in content/string edit modals must preserve any unsaved textarea input and must not rerender the modal in a way that wipes it. Re-verify/fix before acceptance.

## Tests/gates already verified green

All test/build/static gates must be considered remote-only evidence. The latest successful run sequence established:

- PHP syntax gate: green before the PHPCS remediation attempt.
- Composer/PHPUnit enumerated suite: **128 tests / 898 assertions — green**.
- Mixed standalone/unit regression runner: **74 test files — green**.
- Live WordPress integration runner: green, including auto-publish behavior and **ContentManager 10 tests / 95 assertions**.
- Previously focused green regressions include:
  - `SettingsTest`
  - `TranslationProtectionPolicyTest`
  - `PostsControllerEditorStateStandaloneTest`
  - `SaveContentTranslationSeoFieldsValidationStandaloneTest`
  - `SeoFieldsSourceHoistStandaloneTest`
  - `TranslateControllerPersistenceStandaloneTest`
  - `TranslateJobsSiteContentStandaloneTest`
  - `ControllerInvalidationTest`
  - `DomainInvalidationTest`
  - `ReviewDefectsContractStandaloneTest`
  - `SiteIdentityRegressionStandaloneTest`
  - `TranslateJobsCompletionStandaloneTest`
  - `TranslatePayloadContractStandaloneTest`
  - `TranslationFinalizerCopyOnlyStandaloneTest`
  - `TranslationFinalizerTerminalRaceStandaloneTest`
  - `TranslationJobDispatcherCleanupStandaloneTest`
  - Site Content dispatcher focused regression

Do not infer PHPCS/PHPStan/admin lint/build/UI architecture/E2E acceptance from these green tests; those are still separate required gates.

## Current blocker: PHPCS

The current real blocker is **not functional tests**. It is WPCS conformance for the changed PHP surface.

A direct remote invocation of the same baseline checker used by `tools/factory-gate.sh phpcs` showed new violations beyond `phpcs-baseline.json`. The first existing-file batch showed **472 new violations**. A focused scan of the eight newly added PG-14 PHP files reported a much larger number because several of those files were authored in compact/non-WPCS style.

Dominant violation classes:

- spaces instead of tabs / compact one-line control structures
- short array syntax disallowed by this ruleset
- missing file/class/method/property docblocks
- camelCase method/property/local names where this repository requires snake_case
- Yoda-condition rules
- SQL placeholder/interpolation sniffs
- direct DB/no-cache warnings where deliberate repository-level persistence must be justified/suppressed narrowly or reworked
- nonce-verification warnings around extension file-editor request inspection
- migration dynamic-table SQL/security sniffs

Important: do **not** regenerate or loosen `phpcs-baseline.json` to hide new debt. Fix the new violations or use the narrow existing repository conventions for unavoidable dynamic-table/direct-DB cases.

### Remote PHPCBF workflow investigation

PHPCBF itself must remain remote. Attempts so far:

1. Running `vendor/bin/phpcbf` directly through `e2e-remote` on source files returned transformed content but did not mutate the workstation source tree.
2. Attempting to write a `git diff` artifact after formatting yielded an empty patch because the remote snapshot's Git/index relationship did not expose the mutation as expected.
3. Archiving the formatted paths into `tests/e2e/test-results/phpcbf-new-files.tgz` successfully round-tripped an artifact, but that archive still contained the unformatted source; the source snapshot was not writable/mutated in the expected manner.
4. The next probe was to copy one file to a writable path under `tests/e2e/test-results/phpcbf-probe/`, run PHPCBF on that copy, archive it, then apply its contents locally. The wrapper call hit a transport-level `TaskGroup` exception before a definitive result.

Resume by making this writable-copy workflow definitive. If PHPCBF can format a copied file remotely, use it only for mechanical fixes, then apply returned formatted copies locally. Handle SQL/security/docblock/naming changes manually and rerun focused tests after any API/method rename.

## Immediate next actions

1. **Do not abort the open merge.**
2. Confirm `debian3` remote execution still works with a trivial sanctioned wrapper command.
3. Complete the writable-copy PHPCBF probe on `includes/Translation/ProtectionDecision.php`:
   - remote copy to `tests/e2e/test-results/phpcbf-probe/ProtectionDecision.php`
   - `chmod u+w` the copy
   - run `vendor/bin/phpcbf --standard=phpcs.xml.dist` on the copy
   - archive the copy inside `tests/e2e/test-results/` so `e2e-remote` returns it
   - verify locally that WPCS mechanical changes are present.
4. If successful, remotely format copies of the eight new PG-14 PHP files, return them as an artifact, and replace only those files locally.
5. Manually fix remaining non-autofixable violations, especially:
   - SQL placeholders / dynamic table identifier handling
   - nonce request handling in `ExtensionChangeTrigger`
   - method/property/local naming and call sites
   - docblocks
   - direct DB sniffs using narrow, justified repository patterns only.
6. Run focused remote tests after API/method renames.
7. Run the full remote PHPCS baseline gate with the semantic base:

```bash
UI_GATE_BASE=01940a99240c98e6fe1d919b0815670e645fc503 bash tools/factory-gate.sh phpcs
```

If the remote snapshot still cannot resolve the base ref symbolically, invoke `php tools/phpcs-baseline.php check <exact changed PHP files>` directly on `debian3`; do not run PHPCS locally.
8. Once PHPCS is green, continue in this order:
   - PHPStan
   - admin JS lint
   - admin build
   - UI architecture gate
   - full factory gate
9. Re-review/fix remaining PG-14 behavioral acceptance items listed below.
10. Run migration and E2E acceptance.
11. Only then stage everything and create the normal two-parent convergence commit.
12. Push the RC branch, submit via `ship.sh`, land, fetch, and prove the resulting commit is an ancestor of `origin/master`.
13. Deployment is only after successful landing verification.

## Remaining PG-14 implementation/acceptance review

Before declaring implementation complete, explicitly verify or fix:

- content/string modal protection toggles preserve unsaved input
- legacy bulk string callbacks/sync paths carry generated-write snapshots correctly
- all save-string call sites respect strict boolean/protection return semantics
- queue/fingerprint/provenance metadata columns are populated at every production path
- automation coordinator runtime hook/action names match actual WordPress/runtime call sites after WPCS renames
- extension automation is durable and does not perform unsafe inline paid work
- nested Settings REST schema rejects invalid/zero-trigger configurations correctly
- translated-editor lock changes are atomic and fail closed
- generation UI reflects persisted lock state and disables generated actions when protected
- labels/tooltips exactly match the design contract and are accessible
- protection-service race and scanner/automation/trigger/aggregation/endpoint tests are sufficient
- `mark_stale` path has zero Worker spend
- translate behavior does not queue locked targets

## Required final gate list

Run all remotely unless the item is pure git/filesystem inspection:

1. PHP syntax over changed/new PHP and tests.
2. `composer test`.
3. mixed `tests/run-unit-tests.sh`.
4. WordPress integration runner.
5. `tools/factory-gate.sh test`.
6. PHPCS baseline.
7. PHPStan.
8. admin JS lint.
9. npm admin build.
10. UI architecture gate.
11. `tools/factory-gate.sh all`.
12. WordPress migration fixture from 1.2.7 -> 1.2.8 proving duplicate recovery/backfill/enums/columns/index and idempotent second run.
13. Remote WordPress E2E.
14. Chromium + Firefox E2E.
15. PG-14 browser acceptance: settings/tooltips/zero-trigger rejection/content modal/string modal/editor protection/input preservation/generate blocking/stale/protected/accessibility/narrow/dark/zero Worker spend/translate queue.
16. Connect -> translate -> async submit/poll/finalize/cancel against the Worker fixture.
17. Full factory gate again after any E2E-driven fixes.

## Production-completion reconciliation after PG-14 green

After PG-14 is fully green, fetch latest master carefully while preserving/understanding the open merge state, then reread:

- `plugins/international-press-zone/docs/plans/2026-08-19-plugin-production-completion.md`
- `plugins/international-press-zone/GOLIVE.md`
- `plugins/international-press-zone/docs/plans/INDEX.md`

Execute only remaining nondelegated production-completion tasks. Likely areas still requiring explicit reconciliation include language-root switching, Yoast robots/sitemap ownership, Site Content runtime/provisioning, ACF/Yoast verification, E2E wrapper/docs cleanup, and final feature gates. Do not redo already-landed Page fidelity work.

## Landing procedure

Final commit must be a **normal commit**, not `--no-verify`. With the current `MERGE_HEAD`, it should become the intended two-parent convergence commit.

Then push `wt/manual-translation-protection-rc` and submit through:

```bash
/home/user/Projects/Press.zone/wordpress/wp-content/.claude/scripts/ship.sh submit \
  wt/manual-translation-protection-rc \
  /home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/manual-translation-protection-rc
```

Add `--assets-ok` only if the ship contract requires it for the generated admin assets. Monitor/inspect/land through the supported controller.

After landing:

```bash
git fetch origin
git merge-base --is-ancestor <landed-commit> origin/master
```

Only after that returns success may the work be described as landed. Then perform any authorized deployment steps.

## Current worktree file summary

Modified production PHP includes API controllers, core database/plugin/scanner/entity surfaces, translation job recorder/sender/settings/finalizer/dispatcher/service. New PHP files are the migration and PG-14 protection/automation classes listed above. Admin source and generated distribution assets are modified. Multiple focused unit/standalone/integration tests are modified, with new `SettingsTest.php` and `TranslationProtectionPolicyTest.php`.

Use `git status --short` in the implementation worktree for the authoritative current file list.

## Completion definition

This task is **not complete** until all of the following are true:

- PHPCS/PHPStan/admin lint/build/UI architecture/full factory gates green remotely.
- PG-14 behavior and browser acceptance proven.
- migration fixture proven from 1.2.7 -> 1.2.8 and idempotent.
- Chromium and Firefox remote E2E green with clean runtime output.
- Connect -> async translate lifecycle proven.
- production-completion plan/GOLIVE reconciled with no applicable remaining task silently skipped.
- normal convergence commit created and pushed.
- `ship.sh` landing succeeds.
- landed commit is verified as ancestor of current `origin/master`.
- deployment occurs only after that landing proof.
