Microsoft Store Automation
This runbook covers the non-secret automation pieces for publishing Dictate through the Microsoft Store for the existing Partner Center product. Deployment credential boundaries and approval requirements are tracked in deployment-security.md.
Current Partner Center Identity
- Product name:
Arc Forge Dictate - Product type:
MSIX or PWA app - Store ID / product ID:
9P5S7747V0BP - Package/Identity/Name:
ArcForgeLabs.ArcForgeDictate - Package/Identity/Publisher:
CN=56989B1A-E9FD-45E0-827B-FDB65D3C9B3C - Package/Properties/PublisherDisplayName:
Arc Forge Labs - Package Family Name (PFN):
ArcForgeLabs.ArcForgeDictate_tbf7er950vsxw - Package SID:
S-1-15-2-414942928-860362531-3808921871-2325232450-2546095560-3460849545-2812936032 - Partner Center app role:
Manager(Windows) - Store publication status changes in Partner Center. Do not hard-code transient submission IDs, draft package names, certification stages, or internal account identifiers in this public repository.
Store Package Builder
- MSIX manifest template:
packaging/msix/Package.appxmanifest.in - MSIX build script:
scripts/build-windows-msix-store.ps1 - Manual MSIX workflow:
.github/workflows/windows-msix-store-bundle.yml - Manual MSIX publish workflow:
.github/workflows/msstore-publish-msix.yml - Output pattern:
packaging/msix/out/ArcForgeDictate_<version>_x64.msix
The MSIX manifest is pinned to the reserved Partner Center identity. The builder
uses tauri build --no-bundle, stages dictate-ui-shell.exe and
engine\dictate-engine.exe, renders the four-part MSIX version from
tauri.conf.json, and packs the loose layout with Microsoft winapp.
The Store reserves the fourth version part, so it is always 0. The day and
the same-day release number share the third part: 2026.9.25 packs as
2026.9.2500.0 and 2026.9.25-1 as 2026.9.2501.0. Unstable versions are
rejected; the Store is stable-only.
A draft upload fails if Partner Center already holds a submission created by
hand there. Delete that submission in Partner Center, then rerun mode=draft.
GitHub Actions Wiring
Add these repository variables in GitHub Actions. Keep the values in repository settings, not in committed docs:
MSSTORE_TENANT_IDMSSTORE_CLIENT_IDMSSTORE_SELLER_ID
Add this repository secret:
MSSTORE_CLIENT_SECRET: the Partner Center Publisher app client secret value.
Do not store the client secret in this repository.
Current GitHub Actions state:
- Repository variables are set for tenant ID, client ID, and seller ID.
MSSTORE_CLIENT_SECRETis set as a GitHub Actions repository secret.msstore-publish-msix.ymlstatus mode verifies credentials and current Store submission status without creating or committing a package.
Smoke Workflow
Use .github/workflows/msstore-api-smoke.yml to verify credentials.
Auth-only smoke:
gh workflow run msstore-api-smoke.yml
After this workflow is committed to the default branch, query the reserved MSIX/PWA product:
gh workflow run msstore-api-smoke.yml -f product_id=9P5S7747V0BP -f query=legacy-app
gh workflow run msstore-api-smoke.yml -f query=legacy-apps
Use .github/workflows/msstore-publish-msix.yml for the guarded package update
path.
Read-only status:
gh workflow run msstore-publish-msix.yml -f mode=status -f product_id=9P5S7747V0BP
Upload a newly built MSIX into the current draft without committing it:
gh workflow run msstore-publish-msix.yml -f mode=draft -f product_id=9P5S7747V0BP
Commit the current draft to Microsoft certification:
gh workflow run msstore-publish-msix.yml -f mode=publish -f product_id=9P5S7747V0BP
mode=draft uploads a newly built MSIX into a Store draft without committing it.
Review that draft in Partner Center before running mode=publish, which commits
the current draft and polls Microsoft certification.
Updating the listing
The Store listing text and screenshots live in the repo and ship with every draft:
- Text:
docs/msstore-listing.mdsectionsShort Description,Description,Product Features,Release NotesandKeywords. - Screenshots:
docs/msstore/assets/screenshots/, in the order the README there lists them, with its captions.
mode=draft runs scripts/msstore-submit.py legacy-draft, which creates one
API submission, queues the new MSIX (the previous package is marked for
removal), replaces the en-us text and screenshots (logos are kept), uploads
the package and screenshots in one zip, and reads the draft back to check the
package and description landed. It never commits. To change only the listing,
edit those files, merge, and run a draft; the package is rebuilt from master
either way.
Local Smoke
Set the same environment variables locally, then run:
python scripts/msstore-submit.py auth-check
python scripts/msstore-submit.py legacy-auth-check
python scripts/msstore-submit.py legacy-apps
MSSTORE_PRODUCT_ID=9P5S7747V0BP python scripts/msstore-submit.py legacy-app
The script never prints access tokens or client secrets.
Submission Discipline
Microsoft warns that once a submission is created through the API, edits to that same submission should continue through the API rather than Partner Center. For Dictate:
- Use the API smoke/status workflow to confirm credentials and product access.
- Run the Windows release gate against the GitHub release you are about to
ship:
scripts/windows-vm-release-gate.sh --tag vYYYY.M.N. It installs the publishedsetup.exeon thewin11-gpuVM, launches it in the signed-in session, checks the engine's/api/healthversion, and uninstalls. Do not draft if it fails. See windows-11.md. - Use
msstore-publish-msix.ymlwithmode=draftto create/update the Store draft package. - Review the draft in Partner Center.
- Use
mode=publishonly when that draft should be submitted for Microsoft certification. - Use API-created submissions consistently for future automated updates.
Use msstore-listing.md for the first listing copy, privacy/certification notes, screenshots checklist, and remaining pre-submit requirements.
API Notes
The current helper targets the newer Store API surface documented by Microsoft
for MSI/EXE submissions. The reserved product is an MSIX or PWA app; Microsoft
still documents the older Store services API for registered UWP/MSIX apps at
https://manage.devcenter.microsoft.com/v1.0/my/applications. Validate the
correct API path for 9P5S7747V0BP after the first manual submission is
accepted, or create a separate MSI/EXE product if we choose the Tauri installer
path.
The MSIX/UWP Store services API uses:
- Token endpoint:
https://login.microsoftonline.com/<tenant-id>/oauth2/token - Resource:
https://manage.devcenter.microsoft.com - Base URL:
https://manage.devcenter.microsoft.com/v1.0/my
The newer Store Submission API uses:
- Token endpoint:
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token - Scope:
https://api.store.microsoft.com/.default - Base URL:
https://api.store.microsoft.com - Required request header:
X-Seller-Account-Id
The current helper supports:
auth-checklegacy-auth-checklegacy-appslegacy-appstatusmetadata- guarded
submit --confirm-submit legacy-draft(MSIX draft with package, listing text and screenshots; no commit)
mode=draft uploads through scripts/msstore-submit.py legacy-draft (see
"Updating the listing"). mode=publish and mode=status use the Microsoft
Store Developer CLI: msstore submission publish <productId> commits the draft
and msstore submission poll follows certification.
An earlier draft step used msstore publish --inputDirectory <dir> with no
project path. The CLI then inspected the working directory, saw package.json,
treated the repo as an Electron app and uploaded without attaching the package;
the Store re-published the previous package and reported success. That happened
with the first September 2026 submission.