theam / theam/facility

Escape the provision command for its shell context in agent prompts

Open
#269 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
71
Forks
64
Avg merge
15h 38m
Merged PRs (30d)
66

Description

Context

Raised while reviewing #220, which fixes the YAML half of this problem:
the provision command is now rendered into a block scalar, so a command
containing ": " no longer breaks the workflow document.

The same command is also interpolated raw into a shell string, and that
half is untouched.

Problem

{{PROVISION_CMD}} is substituted into the agent prompt inside a
double-quoted shell argument:

claude_args: |
  --append-system-prompt "This OVERRIDES ... provisioned the environment ('{{PROVISION_CMD}}'), and you run with ..."

A provision command containing a double quote closes that argument early.
Reproduced on a clean checkout:

facility init --yes --provision='docker compose up -d && echo "db: ready"'

renders, in .github/workflows/facility-crew.yml:

--append-system-prompt "This OVERRIDES ... provisioned the environment ('docker compose up -d && echo "db: ready"'), and you run with full byp...

The " before db: terminates the string. The rest of the system prompt —
including the security clauses about treating issue text as untrusted data and
never pushing to protected branches — is no longer part of the argument.

Affected sites, all rendering the same variable:

  • packages/cli/templates/workflows/facility-crew.yml (builder and architect lanes)
  • packages/cli/templates/workflows/facility-codex.yml
  • packages/cli/templates/workflows/facility-doctor.yml
  • packages/cli/templates/workflows/facility-address-review.yml
  • packages/cli/templates/prompts/architect.md, builder.md

This is pre-existing and was not introduced by #220. It is worth tracking now
because #220 makes it more reachable: a command containing ": " previously
produced an unparseable workflow that failed loudly and never ran, so this
truncation was masked. Those commands now produce a workflow that parses and
runs.

Proposed change

Escape the command for its shell context at render time rather than
interpolating it raw — a PROVISION_PROMPT variable alongside the existing
PROVISION_RUN, so each interpolation site gets a value already correct for
where it lands. Prompt text is documentation of what ran, so escaping (or a
conservative quoted form) is enough; it does not need to stay executable.

Why not in #220

#220 is scoped to the YAML scalar context of the run: key. This is a
different context (shell, inside a block scalar that already parses), needs a
second rendering variable, and touches templates and prompt files that PR does
not. Fixing it there would change what the PR is about.

Acceptance criteria

  • facility init --provision='docker compose up -d && echo "db: ready"' renders a prompt whose --append-system-prompt argument contains the whole system prompt, security clauses included.
  • A test renders the workflows with a quote-bearing provision command and asserts the prompt argument is intact — alongside the parse test added in #220.
  • The same holds for .github/facility/architect.md and builder.md.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing how PROVISION_RUN is rendered into the affected workflow templates and prompt files: packages/cli/templates/workflows/facility-crew.yml, facility-codex.yml, facility-doctor.yml, facility-address-review.yml, and the architect.md and builder.md prompts. Run or extend the quote-bearing render test alongside the parse test from #220. Done means the full system prompt, including security clauses, remains in the shell argument for every listed output.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, shell, typescript
Domain
ci-cd, cli, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.