WordPress / WordPress/contributor-toolkit
Parked ticket work can be lost when the checkout is modified outside the app, with no recovery path
Nobody has claimed this yet.
- 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 = trueand the JavaScript engine behind it never honoured it, so an emptygit reflog --allwas 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 owngit-run.cjs:core.logallrefupdatesistrue,.git/logsis there, andgit reflog --allreturns 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
- 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.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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