Skip to content

quest(ci): record publish secret copy; wait on the patch cut before deleting repo copies - #7201

Merged
kixelated merged 11 commits into
mainfrom
quest/m0/ci/read-only-secrets
Nov 7, 2026
Merged

kixelated merged 11 commits into
mainfrom
quest/m0/ci/read-only-secrets

Conversation

@kixelated

@kixelated kixelated commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Pull-request CI on this repository still sees write-capable repository secrets. Everything the maintainer owned is now done; CACHIX_AUTH_TOKEN (owned by cachix-retire) and the final throwaway-branch check remain.

Approach

Records in the quest what the maintainer did and decided on 2026-11-05 and 2026-11-06 (/quest-unblock), rewrites the quest to what remains, and drops Pullfrog's provider-key lines from .github/workflows/pullfrog.yml.

2026-11-05:

  • moq-dev/moq#7202 merged into release; publish holds the twelve release secrets.
  • ✅ Delete the repository copies only after the patch cut moq-dev/moq#7936 publishes cleanly through publish.
  • ✅ Retire Cachix instead of moving CACHIX_AUTH_TOKEN. cachix-retire is under Required.

2026-11-06:

  • Trusted publishers: npm's npm Environment is set on all 12 in-scope packages; @moq/watch and @moq/signals were set by hand after Cloudflare blocked the automated save. @moq/qmux is out of scope (published by moq-dev/web-transport), and the unpublished packages belong to npm-first-publish. PyPI (moq-rs, moq-ffi) requires pypi. pub.dev (moq, moq_ffi) requires pub.dev, as the maintainer reported.
  • ✅ Drop JSR rather than create a JSR_TOKEN. moq-dev/moq#8039 merged, so main is merged here and jsr-retire is linked under Related. Not chosen: keeping JSR behind JSR_TOKEN in the npm Environment.
  • Checked the 3 failed first attempts among chore: release #7936's 14 tag runs: a transient Environment fetch failure in run 42129037703 (publish's policy admits moq-relay-v*), a network fetch failure (run), and a brew test timeout (run). None involves the Environment's secrets.
  • Done (maintainer): re-ran those runs (Cachix for moq-relay-v0.17.13 and moq-gst-v0.4.23 passed; the macOS brew test hang is planned in moq-dev/moq#8076), then deleted 15 repository secrets: CARGO_REGISTRY_TOKEN, CLOUDFLARE_API_TOKEN, DOCKER_PASSWORD, DOCKER_USERNAME, MAVEN_CENTRAL_PASSWORD, MAVEN_CENTRAL_USERNAME, R2_ACCESS_KEY_ID, R2_ACCOUNT_ID, R2_SECRET_ACCESS_KEY, SIGNING_KEY, SIGNING_PASSWORD, WINGET_TOKEN, GCP_SERVICE_ACCOUNT_KEY, CLAUDE_CODE_OAUTH_TOKEN, and META_MODEL_API_KEY. Left: CACHIX_AUTH_TOKEN, MBX_R2_ACCESS_KEY_ID, MBX_R2_SECRET_ACCESS_KEY (confirmed with gh secret list --repo moq-dev/moq).
  • ✅ Pullfrog gets no provider keys from this repository. Not chosen: moving them into the pullfrog Environment.
  • ✅ Leave the org secret DISCORD_WEBHOOK visible to all repositories; the alert job reads the alert Environment's copy. Not chosen: narrowing it to selected repositories. The quest's final check now allows MBX_R2_* and DISCORD_WEBHOOK.

Pullfrog without provider keys

pullfrog.yml drops CLAUDE_CODE_OAUTH_TOKEN and META_MODEL_API_KEY. An env: holding only comments is invalid (actionlint: "expecting ... mapping value for "env" section"), so the block and Pullfrog's commented provider templates go with them, replaced by a one-line pointer. The pullfrog Environment holds no secrets, so its comment now says what it still gates: the job's OIDC token.

What Pullfrog needs: no new action input. Its model access docs say model access comes from Pullfrog Router ("Pullfrog mints a short-lived key for each run") or a key stored with Pullfrog at account or repository level, chosen in the Pullfrog console's Billing card. The pinned action (v0.1.110, utils/proxy.ts) mints the job's OIDC ID token for that, which id-token: write already grants. If neither Router nor a stored key is configured in the console, a run stops with No provider available. Configuring that is a Pullfrog-console setting outside this repository; I did not check or change it.

Impact

  • Public API and wire: none.
  • CI: Pullfrog dispatches no longer pass provider env vars (their secrets were already deleted, so they resolved to empty strings).
  • This PR and its agents did not touch any secrets, Environments, publisher settings, or workflow runs.

Validation

On 0936fc1:

  • git grep -n 'secrets\.\(CLAUDE_CODE_OAUTH_TOKEN\|META_MODEL_API_KEY\)' .github prints nothing.
  • nix develop --command actionlint .github/workflows/pullfrog.yml passes.
  • quest check --base origin/main --branch quest/m0/ci/read-only-secrets (605 documents ok).
  • quest gate nix develop --command just check origin/main exits 0.

Review

Round 1: Codex, gpt-6.1-sol, medium effort, quest review --base origin/main on 0936fc1. No findings.

Follow-ups

None. publish-release-only, cachix-retire, and jsr-retire own the rest.

(Written by Claude Opus 5.5)

@kixelated kixelated changed the title Keep pull-request CI read-only ci: track remaining read-only credential migration Oct 29, 2026
Keep the quest open for the maintainer-only tag policy, credential migration, publisher restrictions, and negative branch probe.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
kixelated and others added 2 commits October 30, 2026 23:33
publish now admits moq-boy-v*, moq-gst-v*, and libmoq-v* tags, and the
release tags ruleset covers libmoq-v*. The moq-bot key already moved into
the bot and publish Environments, so drop it from the remaining copy and
delete steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e deleting repo copies

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title ci: track remaining read-only credential migration quest(ci): record publish secret copy; wait on the patch cut before deleting repo copies Nov 5, 2026
kixelated and others added 2 commits November 5, 2026 13:22
Record the maintainer's 2026-11-05 decision: the planned cachix-retire
quest deletes CACHIX_AUTH_TOKEN, so this quest's deletions skip it and its
final check waits for that quest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated and others added 2 commits November 6, 2026 10:14
@kixelated
kixelated marked this pull request as ready for review November 6, 2026 23:24
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 12 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: afa57773-8203-4c44-901d-dacf6f8e878b
Commits

Reviewing files that changed from the base of the PR and between 636ba9f and 0936fc1.

Files selected for processing: 2

  • .github/workflows/pullfrog.yml
  • quest/m0/ci/read-only-secrets.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kixelated
kixelated added this pull request to the merge queue Nov 6, 2026

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head 0936fc14c9937b8b522ae6822fe3e2dea86e2a39 against base 636ba9fa33ec1b4989c0a016aac9e012cb6fb61e. Two actionable plan findings are inline: preserve the existing Cachix cache, and keep JSR trust retirement as a prerequisite for completing the read-only CI work.

The Pullfrog provider-variable removal is consistent with the pinned action's OIDC proxy-key path. Verification was GitHub-only: inspected both changed files, the related retirement plans, the JS release workflow, and the pinned Pullfrog proxy source. No local commands, workflow dispatches, or throwaway-branch checks were run. Secret inventories, deployment policies, external publisher settings, and Pullfrog console configuration were not independently verified. The exact-head Quest check passed; the main Check job was still running when inspected.

Comment on lines +74 to +76
`release-nix.yml` to `release`, drops `cachix.yml` there, and deletes
`CACHIX_AUTH_TOKEN` and the `kixelated` cache once a release tag proves
nix.moq.dev. So the deletions here leave `CACHIX_AUTH_TOKEN` to that quest,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve the Cachix cache when revoking write access

This summary says cachix-retire will delete the kixelated cache, but that quest explicitly records the opposite maintainer decision: revoke the token and retain the cache read-only because older release flakes only name kixelated.cachix.org. Following this plan would remove those tags' binary substitutes and force source builds. Change this to delete/revoke CACHIX_AUTH_TOKEN while keeping the existing cache read-only, matching quest/m0/ci/cachix-retire.md.

Comment on lines +139 to +143
Once `cachix-retire` deletes `CACHIX_AUTH_TOKEN`, an agent runs the
throwaway-branch check in the Goal, which also confirms each Environment
refuses the branch, then deletes the branch. The branch may still see
`MBX_R2_*` and `DISCORD_WEBHOOK`, by the decisions above; any other secret
fails the check.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Require JSR trust retirement before completing the final check

The replacement completion sequence waits only for cachix-retire, while jsr-retire is merely Related. However, the linked JSR quest still has to archive the packages to remove their repository-wide OIDC trust; #8039 added that plan rather than performing the retirement. If Cachix finishes first, a branch can pass the secret-presence and Environment checks here while retaining an OIDC identity JSR accepts, violating this quest's Goal. Make JSR archival/trust removal an explicit prerequisite (for example under Required) and require its verification before declaring this work complete.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The workflow cleanup is right, but three facts the quest now records disagree with the repository and its live settings, and one of them leaves a release blocker untracked. All three are doc-only fixes.

Reviewed changes

  • .github/workflows/pullfrog.yml: drops the step-level env: that supplied CLAUDE_CODE_OAUTH_TOKEN and META_MODEL_API_KEY (both already deleted from repository scope), along with the commented Bedrock, Vertex, Azure, and OpenAI-compatible templates, and points at Pullfrog's console model access instead. The pullfrog Environment comment now describes the OIDC token it gates, which matches that Environment admitting only main.
  • quest/m0/ci/read-only-secrets.md: replaces the remaining-work list with dated records of the 2026-11-05/06 unblock: #7202's release backport, #7936's tag runs publishing through publish, the deletion of 15 repository secrets, the trusted-publisher Environments on npm, PyPI, and pub.dev, the JSR drop with jsr-retire owning it, and the decisions to keep the org DISCORD_WEBHOOK and give Pullfrog no provider keys. cachix-retire is the only ## Required edge.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

Comment on lines +68 to +71
moving `CACHIX_AUTH_TOKEN`. `release`'s `cachix.yml` still reads it on
`moq-relay-v*`, `moq-cli-v*`, `moq-boy-v*`, `libmoq-v*`, and `moq-gst-v*`
tags; that job names `publish`, which lacks it, so it reads the repository
copy. (`release`'s `cache.yml` also reads it but fires only on pushes to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This describes release before the Cachix backport landed. Commit 252144833 (2026-11-06 19:53Z, about three and a half hours before this commit) deleted release's .github/workflows/cachix.yml and replaced its cache.yml with main's, so git grep CACHIX_AUTH_TOKEN origin/release is empty: nothing on main or release reads the token any more. The copy is now held only as the fallback until a tag substitutes from nix.moq.dev, which is what cachix-retire is waiting on.

Technical details
# Stale Cachix read path in the read-only-secrets record

## Affected sites
- `quest/m0/ci/read-only-secrets.md:68-71` — says `release`'s `cachix.yml` still reads the token, so the job falls back to the repository copy
- `quest/m0/ci/read-only-secrets.md:71-72` — says `release`'s `cache.yml` also reads it

## Evidence
- `252144833` (`ci: release tags push to nix.moq.dev instead of Cachix (backport)`) deleted `.github/workflows/cachix.yml` on `release` and rewrote its `cache.yml` to set `NIX_SIGNING_KEY` / `NIX_R2_*`.
- `git grep CACHIX_AUTH_TOKEN origin/release` and `git grep CACHIX_AUTH_TOKEN origin/main -- .github/ infra/` both return nothing.

## Required outcome
- The paragraph should say that no workflow reads the token, and that `cachix-retire` holds the copy only as the fallback until a release tag proves `nix.moq.dev`, so the throwaway-branch check still waits on its deletion.

Comment on lines +85 to +87
moq-dev/web-transport, so it is out of scope here; `@moq/clock`, `libav`,
`ui`, and `video` are not published yet, and
[npm-first-publish](/quest/m3/release/npm-first-publish.md) claims them with

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

npm-first-publish claims only @moq/clock, @moq/libav, and @moq/video (its Goal and checks, and quest/m3/release/README.md), not @moq/ui. @moq/ui is not private, has a release script, and 404s on npm, so the cut will attempt its first publish with no trusted publisher, which is the failure npm-first-publish exists to prevent. Add ui there (or record where its first publish is claimed) and adjust this sentence.

Technical details
# `@moq/ui` has no first-publish tracking

## Affected sites
- `quest/m0/ci/read-only-secrets.md:85-87` — lists `clock`, `libav`, `ui`, `video` as claimed by `npm-first-publish`
- `quest/m3/release/npm-first-publish.md:3-11` — Goal and checks name only `clock`, `libav`, `video`

## Evidence
- `js/ui/package.json`: no `"private": true`, `scripts.release` is `bun ../common/release.ts`, version `0.1.0`.
- `https://registry.npmjs.org/@moq/ui/latest` returns 404, so the package does not exist yet.
- `.github/workflows/release-js.yml` runs `bun --filter '*' release`, so every non-private workspace package with a `release` script publishes.
- `@moq/p2p` and `@moq/crypto` are both `private`, so excluding them is correct.

## Required outcome
- Either `@moq/ui` joins `npm-first-publish`'s Goal and checks, or this sentence stops saying that quest covers it and names where its first publish is tracked.

Comment on lines +107 to +109
passed through `publish`. `publish`'s deployment policy admits
`moq-relay-v*` tags (with `main`, `release`, and the `libmoq`, `moq-boy`,
`moq-cli`, `moq-ffi`, and `moq-gst` tag patterns), so this was a transient

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tag patterns are right, but publish no longer admits main: the live policy is release plus the six tag patterns. That also suggests publish-release-only's remaining step (dropping main) is already done, while infra/README.md still says publish keeps admitting it. Worth confirming what changed and making this sentence, that quest, and the README agree.

Technical details
# `publish` admits `release` and the tag patterns, not `main`

## Affected sites
- `quest/m0/ci/read-only-secrets.md:107-109` — "admits `moq-relay-v*` tags (with `main`, `release`, and the ... tag patterns)"
- `quest/m0/ci/publish-release-only.md` — "What remains, in order" step 2 still lists dropping `main`
- `infra/README.md:69-70` — "`publish` keeps admitting `main` until the maintainer drops it"

## Evidence
- `gh api repos/moq-dev/moq/environments/publish/deployment-branch-policies` returns `total_count: 7`: `release`, `libmoq-v*`, `moq-boy-v*`, `moq-cli-v*`, `moq-ffi-v*`, `moq-gst-v*`, `moq-relay-v*`.
- No job on `main` needs the `main` admission: every reader of a deleted secret is tag-gated or runs on `release`.

## Required outcome
- This sentence matches the live policy; if the drop was deliberate, record it (and retire that step of `publish-release-only`), otherwise restore the policy.

Merged via the queue into main with commit fb1c7c0 Nov 7, 2026
14 checks passed
@kixelated
kixelated deleted the quest/m0/ci/read-only-secrets branch November 7, 2026 03:13
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