WordPress / WordPress/contributor-toolkit

Parked ticket work can be lost when the checkout is modified outside the app, with no recovery path

Open
#348 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug real-world-git
Dominant language
JavaScript
Stars
36
Forks
13
Avg merge
23h 19m
Merged PRs (30d)
72

Description

Updated 15 September 2026. Written against the JavaScript Git engine, retired in v1.1.0-beta.1. The reflog point below is rewritten: the safety net it said was fictional is now real, and the gap is that the app never surfaces it. The report itself — external writer, parked work gone — is unchanged and still unreproduced.

What was reported

A contributor testing a release on a Toolkit-managed site ran an in-place core upgrade inside the checkout (the WordPress Beta Tester route — swapping core files to move between versions). Afterwards, the ticket branches they had parked work on were gone, and the app offered no way to get that work back.

That is the whole report — secondhand, without the exact sequence of steps. It is filed anyway because it has a real victim, and because the shape of the failure is one the app's current model makes possible rather than one that needs an exotic trigger.

Why the model allows it

The app assumes it is the only writer to the checkout. Everything it knows about a contributor's work lives in two places: a single work-in-progress commit on the ticket branch, rewritten in place each time work is parked, and per-branch metadata in the app's own store. Both are fragile against a writer the app did not expect:

  • When something external rewrites files in the checkout, the app's flows that respond to an unexpected tree — discard, update, re-initialise — can move or drop refs whose contents the store still believes in.
  • Because the parked commit is rewritten rather than appended, any commit that loses its ref becomes unreachable immediately. There is no reflog and no recovery surface in the app: once the branch ref is gone, the work is gone from every screen.
  • The reflog now exists, and that changed after this was written. The original third point here said the app advertised a safety net it had never had: repository initialisation wrote logallrefupdates = true and the JavaScript engine behind it never honoured it, so an empty git reflog --all was evidence of nothing. That engine is retired (#411). Sites are cloned by a real Git, which keeps a reflog for a non-bare repository by default — verified on a repository created through the app's own git-run.cjs: core.logallrefupdates is true, .git/logs is there, and git reflog --all returns the history. So a commit that loses its ref is no longer gone; it is reachable from the reflog for as long as Git's expiry keeps it. What is still missing is the app: nothing on any screen reads the reflog, so the work is recoverable by someone who opens a terminal and invisible to everyone else. That is a smaller problem than the one first filed, and a different one.

So the app can be correct at every individual step and still end at "your work is unrecoverable", because no step is charged with keeping orphaned work reachable.

What this issue asks for

  1. Reproduce it. Mutate a managed checkout from outside the app (an in-place upgrade is one way; any bulk file replacement should do) and then walk the app's ordinary flows — status, discard, trunk update, ticket switch — watching for the point where a parked branch stops being listed or its ref stops existing.
  2. Decide the recovery story. Whatever the trigger turns out to be, the durable fix is a property, not a patch: a contributor's parked work should survive the app being confused. Work that exists as commits should stay reachable even when the metadata about it is wrong, and the app should be able to say "I found work I can't explain" instead of nothing.

Related

  • #108 — the branch model whose single rewritten commit makes orphaning silent
  • #290 — the earlier observation that the checkout can hold states the app did not create

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the repository created through the app's git-run.cjs, reproduce an external checkout mutation, and walk the status, discard, trunk update, and ticket switch flows. Determine where parked work or its ref stops being listed, then define a recovery story in which existing commits remain reachable and unexplained work is surfaced.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, javascript
Domain
desktop, devtools
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.