Background
translate-policy-page ("translate Wikipedia:Five pillars") is the last essential task whose completion is click-based, and it is wrong in both directions:
- False negative: completion requires publishing via Content Translation AND clicking "Mark as done" (status 3). A user who starts the translation from the kit, publishes the page, and never returns stays at status 2 — never done, invisible to run counts and dashboards.
- False positive: status 4 ("the page exists, not via CT") is in completedStatuses: [3, 4] (essential-tasks.js:45), so a policy page that existed before the kit — or was created by anyone else — reads as done for every user of the wiki. This is the same wiki-global existence bug T433369: Redefine "task completion" for the Create essential articles task using on-wiki signals and make it repeatable retired for create-essential-article.
The verification machinery to fix both already exists (T433014: Redefine "task completion" for HotCat essential task using on-wiki signals's ledger + triggers, T433369's creation qualifier), and the direct metric of the /impact "Essential work done through the kit" card defines exactly the predicate this task should verify.
Proposed approach
A run completes when the user started the translation from the kit and later created the policy page on the target wiki — regardless of whether they ever return.
- Register in VERIFIABLE_TASKS (server/db/verifications.js) with openEvent: 'starterkit.essential.translate_policy_page.cta_click', openCta: 'open-cx' (the moment the user opens the translation tool — the analogue of essential-article's open-editor). Membership makes POST /tasks/complete reject the click (Done becomes UI-only) and flips the phase-5 dashboards to ledger-sourced counts for this task.
- Qualifier verifyPolicyPageRun: resolveLanglinkTarget('Wikipedia:Five pillars', <wiki code>) → getPageCreator → credit when sameUser(creator, opener) AND the creation is at/after the run's open AND not a redirect. No ns0 gate — unlike the essential-article qualifier, the target lives in the project namespace by design.
- Fixed-title pending opens: the open-cx events carry no $.title (the target is a constant), and getPendingOpens currently requires one. Add a per-task fixedTitle field to the VERIFIABLE_TASKS config and COALESCE(json_extract(properties,'$.title'), @fixedTitle) in the pending query + ledger anti-join. Ledger article_title = 'Wikipedia:Five pillars'; the existing UNIQUE key then means one credit per (wiki, user) — correct, since there is exactly one page to create.
- Status rework, ledger-first: a verified run (run_count > 0) is done for the creator. Status 4 stops meaning "done": a pre-existing page is an availability fact about the wiki, not anyone's completion. (What the card shows other users on a wiki whose page already exists — "done for this wiki" vs "unavailable" — is a UX decision; the essential-article phase-7 "already exists" states are the pattern to follow.)
- Client: "Mark as done" goes UI-only (TranslatePolicyStepTranslate.vue:137 calls api.completeTask, which will 400) and the page tracks the .complete event itself, exactly like the three sibling tasks.
- Backfill: scripts/verify-completions.js --all picks the task up once fixedTitle lands in getPendingOpens — historical open-cx events exist and need no title recovery, unlike the essential-article backfill.
- Not repeatable: one fixed page per wiki; nothing to repeat while the task covers a single title.
Deploy coupling
Acceptance criteria
- A user who opens the translation from the kit and creates the policy page is credited on the next completions read or sweep — with no "Mark as done" click, and no return visit required
- A policy page that pre-existed the run, or was created by someone else, credits nobody (creator + at-or-after-open gates)
- POST /tasks/complete returns 400 for this task; the Done click writes nothing
- The same (wiki, user) never earns credit twice (ledger UNIQUE on the fixed title)
- Status no longer reports a bare existing page (old status 4) as anyone's completion
- verify-completions.js --all dry-run reports historical qualifying runs; --apply credits them idempotently
- /impact and /analytics count this task from the ledger, and the historical backfill lands in the same deploy
Out of scope
- Repeatability / additional policy pages (would need per-title runs; nothing in the model blocks it later — the ledger key already includes the title).
- The "page already exists" step-1/step-2 UX states (the phase-7 analogue) — worth a follow-up if the current copy misleads, but verification does not depend on it.
- The /impact essential-work card itself (separate task; its tile 3 reads this ledger for free once this lands).