githubnext / githubnext/ado-aw
Inject runtime parameter values into the agent prompt via ado-script (sanitization at runtime, not compile time)
- Dominant language
- Rust
- Stars
- 23
- Forks
- 8
- Avg merge
- 4d 9h
- Merged PRs (30d)
- 22
Description
# Motivation
We want authors to flag a runtime template parameter as "feed this value into the agent prompt", so its value can vary per-run (manual queue or queue-build safe output) without re-compiling the pipeline. A first attempt (#430, since reverted) put both the sanitization rules and the prompt-append logic into the Rust compiler, generating bash heredocs and validating defaults at `ado-aw` compile time. That coupled the security policy to compiler releases, duplicated work the runtime already has to do for queue-build-supplied values, and made the bash hard to test in isolation.
This issue tracks the redo: keep the compiler dumb (just pass values through env vars), and let the `ado-script` runtime bundle (the same one that ships `gate-eval.py` today, and `prompt.js` / `gate.js` going forward) own validation and prompt assembly.
# Proposed design
## Front matter (compiler)
Add an opt-in flag on `PipelineParameter`:
```yaml
parameters:
- name: focusArea
displayName: "Focus area for this run"
type: string
default: "no specific focus"
prompt-context: true
```
Compiler responsibilities, and only these:
- Parse the new `prompt-context: bool` field (kebab-case, `skip_serializing` so it never leaks into emitted ADO YAML).
- For each opted-in parameter, emit a step-level `env:` mapping `ADO_AW_CTX_: ${{ parameters. }}` on the existing "Prepare agent prompt" step.
- Emit one additional env var, `ADO_AW_PROMPT_CONTEXT_SPEC`, holding a small base64-encoded JSON spec: an ordered list of `{ envKey, displayName }` entries plus the prompt-file path. (Mirrors the `ADO_AW_PROMPT_SPEC` pattern used by `prompt.js`.)
- **No** bash generation. **No** `printf` heredocs. **No** validation of default values at compile time — the runtime will validate the same way it validates queue-build-supplied parameter values.
## Runtime (`ado-script`)
Sanitization and injection live in a new module under `scripts/ado-script/src/prompt-context/` (TypeScript, NodeNext imports with `.js`, consistent with `prompt/` and `gate/`). Wired into `prompt.js` so it runs as part of the existing prompt-render step — no new pipeline step, no extra script download.
Validation rules (applied per value at runtime; reject the run on violation):
- Bounded byte length (≤ 4 KiB) and bounded newline count (≤ 64).
- Reject ADO expression syntax: `${{`, `$(`, `$[`.
- Reject pipeline logging commands: `##vso[`, `##[`.
- Reject the compiler's template-marker delimiter `{{`.
- Reject CR and non-tab control characters.
- `displayName` (validated when the spec is decoded) rejects `"`, `\`, `` ` ``, `$`.
On success, append a clearly delimited "Additional Run Context" section to the rendered prompt — one sub-section per non-empty value, using `displayName` as the header — with a preamble that explicitly tells the agent the section is untrusted user input.
## Why `ado-script`, not the compiler
- **Single source of truth for the policy:** the same sanitizer that already gates queue-build parameter values can be reused, instead of two implementations drifting.
- **Policy updates ship as `scripts.zip` releases** (already verified via `checksums.txt` + `sha256sum`, see `src/compile/extensions/trigger_filters.rs:102-109`); no compiler release required.
- **Testable in TS** with the rest of the runtime; the compiler stays free of bash codegen.
- **Defaults that look fine statically** but resolve through ADO expression evaluation can still be caught (the runtime sees the post-evaluation string).
# Acceptance criteria
- [ ] `prompt-context: true` round-trips through front-matter and is stripped from emitted YAML.
- [ ] Compiled pipelines with no opted-in parameter are byte-equivalent to today's output.
- [ ] Compiled pipelines with ≥ 1 opted-in parameter add the `ADO_AW_CTX_*` env vars and `ADO_AW_PROMPT_CONTEXT_SPEC` to the "Prepare agent prompt" step, with no other changes.
- [ ] `prompt.js` decodes the spec, validates each value with the rules above, and either appends the section or fails the step with a clear error.
- [ ] Manual queue and queue-build paths both work end-to-end.
- [ ] Tests cover each rejection rule in TS, plus a Rust test confirming the env mapping and spec are emitted (and absent when no parameter opts in).
- [ ] `docs/parameters.md`, `docs/front-matter.md`, and `docs/ado-script.md` describe the feature and the runtime-side validation contract.
# Out of scope
- Changing how queue-build allowlists or validates parameters (already covered by `allowed-parameters` + expression-syntax rejection).
- Surfacing values to anything other than the agent prompt.
# References
- Reverted attempt: commit `131c6ed` on `copilot/optional-context-parameter` (revert in `461b443`).
- Existing `scripts.zip` delivery pattern: `src/compile/extensions/trigger_filters.rs:102-109`.
- Existing runtime spec-via-base64-env pattern: `prompt.js` and `ADO_AW_PROMPT_SPEC`.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.