Reserved number: 0468, the next free on every branch and worktree of stackra/core on 2026-10-28
(0464, 0466 and 0467 are drafted on other branches).
Context
Development already ran end to end: agents commit, branch, open pull requests and merge throughpnpm pr:merge. Every
remaining stop sat at deploy, publish, secrets or one-time infrastructure, and the rules that made those stops
disagreed with each other: 0017 rule 6 said agents never merge, release or
deploy, while 0119 and
0293 let them merge; a package release waited on two owner
acts (merging the version pull request under 0119 D7, then approving the release environment); and the guard asked
the owner before every deploy, staging included. The audit of 2026-10-28 (Session A notes,
deploy-blockers-audit-2026-10-28.md) listed them. The owner decided on 2026-10-28: agents develop and deploy end to
end; dev and staging deploy and publish without asking; production waits on one owner GitHub Environment approval;
secret values stay with the owner; and the model applies everywhere.
Decision
- Dev and staging run without asking. An agent deploys to dev and staging, publishes prereleases (a dist-tag
other than
latest, to the Stackra registry only, 0453) and pushes prerelease tags (<package>@x.y.z-<pre>), with no owner prompt. A merge to main deploys staging (0170 DP6). - Production waits on one approval. A production deploy, promote, rollback or package release runs in CI, in a
GitHub Environment whose required reviewer is the owner. That approval is the only gate: no rule adds a second owner
act in front of it. An agent may start any of them (a merge,
pnpm runway promote <sha>, a workflow dispatch); the run waits for the owner’s click. - One gate per package release. An agent merges the changesets version pull request through
pnpm pr:merge(0119 D7 retired).release.ymlruns the version pull request’s squash merge (no changeset pending, subjectchore(release): version packages) in the protectedreleaseenvironment and every other run (opening the version pull request, a push with nothing new to publish, a dry run) inrelease-pr, which has no reviewer and which the registry never accepts a publish from, so a wrong pick fails closed. The prerelease job stays inreleaseuntil the registry has a trusted publisher row for an unprotectedprereleaseenvironment (plan, below). - The guard asks only for production.
HUMAN_ASKSin.agents/hooks/_rules.mjskeeps its ids, but each deploy and release ask fires only for a production target, recognised per command; when the guard cannot tell, it asks:wrangler deploy|rollback|preview|pages deployment create: production unless every--env/-enamesdev,development,staging,stage,preview,test,qaorsandbox(the top-level Worker of awrangler.jsonchere is the production one).wrangler … deleteasks in every environment.eas update: production unless every--channel,--branchand--environmentnames one of those.eas deploy: production only with--prod.eas submit,--auto-submit,channel:edit|rollout, the update rollbacks,workflow:runand<x>:deleteask in every environment.npm|pnpm|yarn|changeset publish: a prerelease when every--tagisnext,canary,dev,staging,preview,alpha,beta,rcorsnapshotand--registrynameshttps://npm.stackra.figentra.com/; anything else asks (with no.npmrcthe default registry is npmjs, never ours).tag-push: a bot push asks unless every pushed tag is a prerelease tag;--tagsand--follow-tagsask.pnpm bot:gh -- workflow run <deploy workflow>: runs when every-f|-F|--field|--raw-field environment=names a dev or staging environment; a deploy workflow without that input deploys production, so it asks.api … /dispatchesandrelease create|edit|delete|uploadask.pnpm runway deploy|promote: unchanged, they dispatch production (core has no staging runway environment).
- Rollback. An agent may trigger a rollback (0170 DP14 amended): in dev and staging directly, in production as
pnpm runway promote <last good sha>, which waits on the same Environment approval. - Encore. A workstation
encore deploystays denied (guard and settings): it ships with the owner’s Encore login. Encore deploys run from a CI workflow that reads its token from Infisical/ciover OIDC, deploys staging on a merge to main and production behind the production Environment. Stackra core has no Encore app to ship (0170 DP1, reference apps run only in CI), so nodeploy-encore.ymlis written here; the first repository that ships an Encore app adds it with its runway target. STA-136 can close as the deploy-path question for agents; whether Encore Cloud builds the generated.stackra/encore(0170 DP2, option a or b) is settled by that first repository’s workflow. - What stays. The production GitHub Environments (0170 DP6); the secret read and write denies,
secrets:import --confirmand owner-held secret values (0257); no direct push to main, which changes only through a merged pull request; the owner-approval review of 0230; no installs or builds on the Mac (ci-box); repository deletion stays the owner’s. - Shared root files.
pnpm-workspace.yamlandturbo.jsoncare no longer owner-only: one agent edits each at a time (the round’s integration batch, or the batch that owns it), like.agents/rules.
Amended and retired
AGENTS.md and .agents/rules/concurrent-sessions.md drop the owner-only edit of pnpm-workspace.yaml and
turbo.jsonc; .agents/rules/secrets.md names the Encore CI path.
Consequences
- An agent ships a change to staging and prepares a production release without waiting; the owner clicks once per production run, in GitHub, where the run records who approved it.
- The production GitHub Environments and the secret controls are now the only real gates. The guard is an accident
guard that fails open (
_rules.mjsheader), so a production Environment without a required reviewer is a hole: every production deploy job must name one. runway promoteand a production workflow dispatch still meet a guard ask in front of the Environment approval until the owner drops it (open question 1).- Owner chores: the one-time steps below.
Enforcement
- Built (stackra-244):
release.ymlgatejob (the environment pick of decision 3); the ADR notes above; the rule source edits. - Planned, owner step: the guard of decision 4. The change to
.agents/hooks/_rules.mjsand its tests (.agents/hooks/__tests__/guard-bash.test.mjs,guard-differential.test.mjs) is specified on STA-1395; an agent’s edit of its own guard was refused as self-modification on 2026-10-28, so the owner applies it or clears an agent to. Until then the guard still asks before staging deploys. - Planned, owner step: the
.claude/settings.jsonandopencode.jsoncpermission edits listed on STA-1395 (settings asks are the floor below the guard, so a staging deploy keeps prompting until they go). - Planned, owner step: the
release-prGitHub environment (main only, no reviewer); then a registry publisher row for aprereleaseenvironment (aworkers/registrymigration, a new batch) and the prerelease job’s move to it. - Planned:
deploy-encore.ymlin the first repository that ships an Encore app (decision 6).
Open questions
- Whether the guard’s production asks (
runway-deploy, a productionworkflow run) should go once every production job sits behind a required-reviewer Environment, leaving the Environment approval as the single prompt. mcp__cloudflare-api__executestays an ask: it runs arbitrary code against the Cloudflare API, so reads cannot be told from writes by a permission pattern. Reads usemcp__cloudflare-api__searchanddocs.
One-time owner steps
- Create the
release-prenvironment (deployment branches: main; no reviewer). - Apply the settings and
opencode.jsoncedits listed on STA-1395, and the guard change (or clear an agent to). - Encore repository relink and the Infisical identity for deploy-static (STA-15), when an Encore app ships.
Supersedes and sources
Supersedes: none. Retires 0017 rule 6, 0119 D7 and 0030 decision 3; amends 0012 rule 7, 0013 rule 6, 0170 DP2 and DP14, 0325 rule 4. Sources: owner decision in Session A, 2026-10-28 (“Yes, apply it”, then “everywhere”); Session A auditdeploy-blockers-audit-2026-10-28.md (the S rows); STA-1395 (stackra-244); STA-1394 (stackra-245, the other
repositories).