docs: document WINGET_TOKEN must be classic PAT, not fine-grained

v1.5.13's winget release failed eight times because WINGET_TOKEN was a fine-grained PAT, which is scoped to specific repos and cannot fork microsoft/winget-pkgs (outside its scope). A classic PAT with public_repo scope is required. Document this in both AGENTS.md and the release skill. Co-Authored-By: siGit Code v1.5.12-acp <noreply@sigit.si>

Seto Elkahfi committed Oct 4, 2026 at 12:28 UTC 4295ba063b9b998697ca5a0759a01fc9a141fd45
2 files changed +7 -2
.agents/AGENTS.md
+5 -2
@@ -376,8 +376,11 @@ Three of these need credentials or a one-time manual step before they work:
376
377 - Scoop needs a `getsigit/scoop-bucket` repo and a `SCOOP_BUCKET_TOKEN` secret, mirroring the
378 Homebrew tap setup.
379 -- winget needs a `WINGET_TOKEN` (PAT with `public_repo`) so `wingetcreate` can fork
380 - `microsoft/winget-pkgs`. It is passed as `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`,
379 +- winget needs a `WINGET_TOKEN` (**classic PAT** with `public_repo` scope, not a
380 + fine-grained PAT — a fine-grained PAT is scoped to specific repos and cannot fork
381 + `microsoft/winget-pkgs`, which lives outside its scope; v1.5.13 failed eight times on
382 + this) so `wingetcreate` can fork `microsoft/winget-pkgs`. It is passed as
383 + `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`,
384 which wingetcreate warns can leak the token into logs. `wingetcreate update` only works on a
385 package that already exists in `microsoft/winget-pkgs`, so the workflow checks the
386 `manifests/g/getSigit/siGitCode` path first and falls back to rendering
.agents/skills/sigit-code-release/SKILL.md
+2
@@ -38,6 +38,7 @@ Use this skill when preparing a release for this repository.
38 - The GitHub release body is generated, not hand-written: `release-github.yml`'s release job checks out the tag, awk-extracts the `## <version>` section from `CHANGELOG.md` (a missing section is a hard failure), appends a full-changelog link and a `sigit.si/code` footnote, and publishes it via `body_path: release_notes.md`. The only file a release-prep change needs to touch is `CHANGELOG.md` — never edit release notes in the GitHub UI, because the next tag push would overwrite them.
39 - npm and NuGet publish via OIDC trusted publishing — neither has a stored token in the repo. On npm this is configured per package (each `@getsigit/*` name has a trusted publisher pointing at `release-npm.yml`), so a new package needs the same setup before its first publish will work. OIDC requires npm >= 11.5.1 and Node >= 22.14.0.
40 - The NuGet package (`SiGit.Code`, `dotnet tool install --global SiGit.Code`) bundles all six platform binaries under `native/<os>-<arch>/` behind a managed shim, rather than shipping one package per platform like npm/PyPI. Watch the nuget.org 250 MB package-size limit if it ever grows.
41 +- The winget channel (`release-winget.yml`) needs a `WINGET_TOKEN` secret that is a **classic PAT** with `public_repo` scope — not a fine-grained PAT. wingetcreate forks `microsoft/winget-pkgs` on first use and submits a PR from that fork; a fine-grained PAT scoped to `getsigit/sigit` cannot fork a repo outside its scope and every release fails with a 403/404 on the fork step. The token is passed as `WINGET_CREATE_GITHUB_TOKEN` (not `--token`) so it doesn't leak into logs. `wingetcreate update` only works on a package that already exists in `microsoft/winget-pkgs`, so the workflow checks `manifests/g/getSigit/siGitCode` first and falls back to `wingetcreate submit` with `packaging/winget/*.yaml.in` for the first release; every later release takes the `update` path. If a winget release fails with a fork/permission error, check the `WINGET_TOKEN` secret type before re-dispatching.
42 - The baked-in official MCP server is separately listed in the public MCP Registry as `si.sigit/sigit` (`release-mcp-registry.yml`, driven by `server.json` at the repo root). It's a remote Streamable-HTTP listing, so it's verified by a DNS TXT record on the `sigit.si` domain rather than the GitHub-OIDC scheme used for package listings.
43
44 ## Git release flow
@@ -84,3 +85,4 @@ Pushing the `v*.*.*` tag is what fires every release workflow, so create and pus
85 - Package names, install commands, and branding stay consistent across npm, PyPI, crates.io, Homebrew, NuGet, Scoop, winget, AUR, and the `.deb`/`.rpm` packages.
86 - Every release asset (including the new `.deb`/`.rpm`/raw binaries consumed by Scoop, winget, and AUR) has a matching `.sha256` sidecar.
87 - Any known release limitations are called out explicitly, including a dispatch failure in `release-scoop`/`release-winget`/`release-aur` (non-fatal — logged as a warning by `release-github.yml`) versus a hard failure in a directly tag-triggered workflow like `release-nuget` or `release-mcp-registry`.
88 +- The `WINGET_TOKEN` secret is a classic PAT with `public_repo` scope (not fine-grained), so wingetcreate can fork `microsoft/winget-pkgs`. If a winget release fails on the fork step, verify the token type before re-dispatching.