Agent triggers do work for senders without write access: refused requests still provision, and prose fails the run
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 71
- Forks
- 64
- Avg merge
- 15h 38m
- Merged PRs (30d)
- 66
Description
Summary
Two defects in the Resolve requested agent step region of facility-crew.yml and
facility-codex.yml. Both let a GitHub account with read permission only cause work on a
public repository that has Facility's repo lane installed.
- A refused request still checks out the repository and installs dependencies. The job reports
success. - A comment that merely mentions a command fails the run before the permission gate is
consulted. The job reports failure.
The authorization gate itself is correct and does refuse the request. The problem is what
happens around it.
1. A refused request still provisions, and reports success
The toolchain steps rendered by {{TOOLCHAIN_STEPS}} carry no if:, while the steps on either
side of them do:
- name: Start agent receipt clock
if: steps.requested-agent.outputs.run == 'true' # guarded
...
- uses: pnpm/action-setup@… # NOT guarded
- uses: actions/setup-node@… # NOT guarded
- run: pnpm install --frozen-lockfile # NOT guarded
- name: Provision environment
if: steps.requested-agent.outputs.run == 'true' # guarded
actions/checkout in facility-crew.yml is likewise unguarded.
An account with read commented /architect. The gate refused it, and the job then did the
work anyway:
##[warning]Skipping crew: @cdottaaux has repository permission 'read',
but /builder and /architect require write access.
...
Run pnpm/action-setup → Done in 749ms
Run pnpm install --frozen-lockfile → Progress: resolved …
Step outcomes for that run:
job: success
success Resolve requested agent
success Run actions/checkout@…
skipped Start agent receipt clock
success Run pnpm/action-setup@…
success Run actions/setup-node@…
success Run pnpm install --frozen-lockfile
skipped Provision environment
skipped Run /builder
skipped Run /architect
Run: https://github.com/cdotta/remote-mcp-starter/actions/runs/33229949990
No agent runs and no model spend occurs, which is the important boundary and it holds. But any
account on the internet can trigger a full checkout, toolchain setup, and dependency install on
demand, repeatedly, and every one of those runs is green. On a repository with a real provision
command the same path would also execute that command — for a request that was explicitly
refused.
facility-codex.yml guards its checkout but not its toolchain block, so the same event fails
instead: no checkout means no package.json, and pnpm/action-setup dies with
Error: No pnpm version is specified.
Run: https://github.com/cdotta/remote-mcp-starter/actions/runs/33229801124
2. Command-shape validation runs before the permission gate
In facility-crew.yml the resolve step validates shape first and exits non-zero:
- line 110 —
::error::No supported agent command found.→exit 1 - line 160 —
gh api …/collaborators/$sender/permission
Fifty lines apart, in that order. The job-level prefilter matches /architect anywhere in a
comment body, so any sender reaches this step. The same read-only account commented
ask /architect about it before you start:
##[error]No supported agent command found. Use /builder or /architect at the start of a line.
##[error]Process completed with exit code 1.
Run: https://github.com/cdotta/remote-mcp-starter/actions/runs/33229955947
This also affects maintainers: writing about the commands in an issue turns the repository's
checks red. The step's own comment says the line-anchored pattern "ignores prose examples
(ask /architect about it)" — it does ignore them for dispatch, but the run still fails loudly
rather than skipping.
facility-codex.yml already handles this case the way I would expect:
##[notice]No Codex command starts a line; treating the mention as prose.
so the two sibling workflows disagree about identical input. That is what makes this look like
an oversight rather than a deliberate choice.
Suggested direction
Two independent changes, and I would value your view before opening a PR — the second is more
opinionated than the first:
-
Guard the toolchain and checkout steps on the resolve step's
runoutput, so a refused
or skipped request does no work.toolchainSteps()already takes aconditionaloption, but
it guards onsteps.workflow-change.outputs.changed, so it is not a drop-in; the crew and
codex lanes need a guard on their own resolve output. -
Move the authorization gate above the command-shape checks, and make "no command at the
start of a line" arun=falseskip rather thanexit 1— matching whatfacility-codex.yml
already does. Then no sender without write access can produce a red run regardless of what
they type. The genuinely ambiguous case (both/builderand/architectline-anchored from
an authorized user) can stay a hard error.
I have both changes written with tests that execute the rendered workflow rather than asserting
on its text, and can open a PR if you want them.
Environment
- Facility
main@ca1c9df, repo lane installed viafacility init - Public repository, GitHub-hosted
ubuntu-latest - Workflows byte-identical to what
initgenerated, except for the block-scalar fix from issue A
(without it neither workflow parses at all)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Resolve requested agent regions in facility-crew.yml and facility-codex.yml, then inspect toolchainSteps() and the rendered-workflow tests mentioned in the issue. Verify refused requests skip checkout, toolchain setup, and dependency installation, while prose mentions skip without failing; authorized ambiguous commands should retain their existing hard error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions
- Domain
- ci-cd
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100