Skip to content

Index every package, and use canonical names for exact matching only - #8

Merged
TecharyJames merged 3 commits into
BETAfrom
fix/index-all-packages
Sep 19, 2026
Merged

TecharyJames merged 3 commits into
BETAfrom
fix/index-all-packages

Conversation

@TecharyJames

Copy link
Copy Markdown
Member

Follow-up to #7. Three defects found by testing detection against ground truth on a real machine.

Packages with no product code were undetectable

The index excluded packages whose manifests declare neither a product code nor an MSIX package family name, on the grounds that they cannot be matched by code. That also dropped their canonical display name, which is the more broadly useful field — it is what bridges a package ID to its ARP entry, and Valve.Steam never matches Steam on its own. Those packages were undetectable by any route.

Every package now gets an entry; a name-only row costs about 80 bytes.

before after
Packages indexed 8,453 14,896
File size 6.07 MB 6.92 MB
On the wire (gzip) 1.51 MB 1.68 MB

Product codes alone are not sufficient

Chrome's installed product code varies by build. The three its manifests declare did not include {237809A0-C1B6-3ABE-9AEB-BB2C80AEE802}, the code on a live install of Google Chrome 153.0.8010.52, so detection returned False for an application plainly present. The canonical name matches it exactly.

Detection now uses the index's canonical name as an exact-match candidate.

Canonical names are unsafe as substrings

Adding those names to the substring tier as well reported applications that are not installed:

Valve.Steam   installed=True   via=Msix   MSTeams      <- Steam has never been installed

Steam is a substring of the MSIX package MSTeams; Git would match GitHub CLI the same way.

Candidates are now split. Exact comparison uses the supplied name, the custom catalogue display name and the index canonical name. Substring and MSIX name matching use only the first two, which is the behaviour before the canonical name existed.

Architecture and channel folders were ranked as versions

A winget package folder can contain siblings that are not versions. Discord carries x86, arm64, Canary, PTB and Development alongside 144 real versions.

The version key extracted digits, so x86 yielded 86, which outranks the leading component of 1.0.9258 and won the sort. Resolution then looked for an installer manifest inside the x86 folder and threw — Discord.Discord could not be installed at all.

Version folders start with a digit, so names that do not are rejected. The implementation on main filtered on ^\d; that guard was lost when the sort was rewritten to handle non-[Version] formats in #2.

Verification

Against ground truth on a real machine — 7-Zip, Firefox, Chrome, Zoom, Git and Windows Terminal installed; Steam and Discord not:

7zip.7zip                    got=True   want=True   via=ProductCode        7-Zip 26.03 (x64)
Discord.Discord              got=False  want=False  via=None
Git.Git                      got=True   want=True   via=ExactName          Git
Google.Chrome                got=True   want=True   via=ExactName          Google Chrome
Microsoft.WindowsTerminal    got=True   want=True   via=PackageFamilyName  Microsoft.WindowsTerminal
Mozilla.Firefox              got=True   want=True   via=ProductCode        Mozilla Firefox (x64 en-US)
Valve.Steam                  got=False  want=False  via=None
Zoom.Zoom                    got=True   want=True   via=ProductCode        Zoom Workplace (64-bit)

failures: 0

Version selection: x86, arm64, Canary, PTB and Development rejected; 1.0.9258, v2.1 and 20240101 kept. Discord.Discord resolves to 1.0.9258, Valve.Steam to 2.10.91.91, Git.Git to 2.55.0.3 — none of which are in Index/Catalog.json, confirming install is not limited to the curated list.

The detection index excluded packages whose manifests declare neither a
product code nor an MSIX package family name, on the grounds that they
cannot be matched by code. That also dropped their canonical display name,
which is the more broadly useful field: it is what bridges a package ID to
its ARP entry, and "Valve.Steam" never matches "Steam" on its own. Those
packages were therefore undetectable by any route.

Every package now gets an entry. A name-only row costs about 80 bytes.

Detection also uses the canonical name from the index as a name candidate.
Product codes alone are not sufficient even where the index has them:
Chrome's installed product code varies by build, so the three its manifests
declare missed a live install of Google Chrome 153.0.8010.52, which the
canonical name then matched exactly.
A winget package folder can contain siblings that are not versions. Discord
carries x86, arm64, Canary, PTB and Development alongside 144 real versions.

The version key ranked those as versions because it simply extracted digits:
"x86" yields 86, which outranks the leading component of 1.0.9258 and won
the sort, so resolution then looked for an installer manifest inside the
x86 folder and threw. Discord.Discord could not be installed at all.

Version folders start with a digit, so names that do not are now rejected
outright. The original implementation on main filtered on ^\d; that guard
was lost when the sort was rewritten to handle non-[Version] formats.

Verified: Discord.Discord resolves to 1.0.9258, and x86, arm64, Canary, PTB
and Development are rejected while 1.0.9258, v2.1 and 20240101 are kept.
Adding the index's canonical display name to the substring tier as well as
the exact tier reported applications that are not installed. Those names are
short and generic: "Steam" matched the MSIX package MSTeams and reported
Valve.Steam as installed on a machine that has never had it, and "Git" would
match "GitHub CLI" the same way.

Candidates are now split. Exact comparison uses the supplied name, the
custom catalogue display name and the index canonical name. Substring and
MSIX name matching use only the first two, which is the behaviour before the
canonical name was introduced.

Verified against ground truth on a real machine, 8 packages, no failures:
7-Zip, Firefox, Chrome, Zoom, Git and Windows Terminal detected as
installed, Steam and Discord as not installed.
@TecharyJames
TecharyJames merged commit d2d9ae5 into BETA Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant