Class: Ace::Test::EndToEndRunner::Molecules::PipelinePromptBundler
- Inherits:
-
Object
- Object
- Ace::Test::EndToEndRunner::Molecules::PipelinePromptBundler
- Defined in:
- lib/ace/test/end_to_end_runner/molecules/pipeline_prompt_bundler.rb
Overview
Prepares deterministic runner/verifier prompt files for pipeline execution.
Constant Summary collapse
- RUNNER_SYSTEM_PROMPT =
<<~PROMPT You are an E2E test executor working in a sandbox directory. Rules: - Execute each goal in order - Treat the initial working directory as SANDBOX_ROOT; if a goal needs commands in a created worktree, cd there for execution but keep any declared outcome artifacts under SANDBOX_ROOT/results - Preserve the sandbox runtime environment; do not reset PATH, HOME, or other provided env vars - If `ACE_E2E_SANDBOX_RUNTIME_ROOT` is set, make sure command execution uses `$ACE_E2E_SANDBOX_RUNTIME_ROOT/bin` on PATH in the shell where you run scenario commands - Run `ace-*` commands directly; do not wrap them with `timeout`, `env -i`, or other execution wrappers that can change behavior or hide diagnostics - Do not bypass the public CLI with repo-local executables such as `./exe/ace-*`, `bin/ace-*`, or `ruby .../exe/ace-*` - Do not fabricate output - all artifacts must come from real tool execution - Never background commands or start dependent verification captures before the command they verify has completed - When a goal requires command captures, keep stdout and stderr separate; do not merge streams and do not use `2>&1` - A command capture set is incomplete unless the matching `.stdout`, `.stderr`, and `.exit` files all exist - Persist each command's `.stdout`, `.stderr`, and `.exit` files immediately after that command finishes, before starting the next command - For commands that establish state, write that command's `.exit` file before running any list/status/fs-check/tmux verification for the same goal - When a successful command prints a filesystem path to a generated artifact, copy that artifact into `results/` if the goal asks for supporting evidence from the generated file - If a goal fails, note the failure and continue to the next goal - Do not create synthetic helper reports or temp input files under results/ unless the scenario explicitly treats them as product outcomes - After all goals, return concise runner observations describing what you did and what happened PROMPT
- VERIFIER_SYSTEM_PROMPT =
<<~PROMPT You are an E2E test verifier. You inspect artifacts and render PASS/FAIL verdicts. Rules: - Evaluate each goal independently based on sandbox state first, then runner observations, then raw debug captures only when needed - Treat declared artifacts and helper filenames as hints, not as the source of truth - If a helper file is missing or stale, inspect the sandbox directly before failing the goal - Use artifact mtimes to detect runner ordering mistakes; if postcondition captures are older than the primary command's stdout/stderr/exit, classify the goal as `runner-error` unless direct sandbox state proves a product failure after the command completed - Use read-only commands in the sandbox when they materially improve confidence (for example: git log/status/show, ls/find/cat) - Do not speculate beyond the provided sandbox evidence and runner observations - For each failed goal, include a category: test-spec-error | tool-bug | runner-error | infrastructure-error | missing-artifact - For each goal, cite specific evidence (filenames, content snippets) - Follow the output format exactly PROMPT
Instance Method Summary collapse
- #prepare_runner(scenario:, sandbox_path:, test_cases: nil) ⇒ Hash
- #prepare_verifier(scenario:, sandbox_path:, test_cases: nil, runner_observations: nil, artifact_contract: nil) ⇒ Hash
Instance Method Details
#prepare_runner(scenario:, sandbox_path:, test_cases: nil) ⇒ Hash
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/ace/test/end_to_end_runner/molecules/pipeline_prompt_bundler.rb', line 56 def prepare_runner(scenario:, sandbox_path:, test_cases: nil) cache_dir = ensure_cache_dir(sandbox_path) system_path = File.join(cache_dir, "runner-system.md") prompt_path = File.join(cache_dir, "runner-prompt.md") File.write(system_path, RUNNER_SYSTEM_PROMPT) bundled = bundle_markdown_file(File.join(scenario.dir_path, "runner.yml.md"), test_cases: test_cases) bundled = bundled.gsub("Workspace root: (current directory)", "Workspace root: #{File.(sandbox_path)}") File.write(prompt_path, bundled) { system_path: system_path, prompt_path: prompt_path, output_path: File.join(cache_dir, "runner-output.md") } end |
#prepare_verifier(scenario:, sandbox_path:, test_cases: nil, runner_observations: nil, artifact_contract: nil) ⇒ Hash
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ace/test/end_to_end_runner/molecules/pipeline_prompt_bundler.rb', line 78 def prepare_verifier(scenario:, sandbox_path:, test_cases: nil, runner_observations: nil, artifact_contract: nil) cache_dir = ensure_cache_dir(sandbox_path) system_path = File.join(cache_dir, "verifier-system.md") prompt_path = File.join(cache_dir, "verifier-prompt.md") File.write(system_path, VERIFIER_SYSTEM_PROMPT) project_context = build_project_context_section(scenario) sandbox_context = build_sandbox_context_section(sandbox_path) artifacts = build_artifact_section(sandbox_path) contract = build_artifact_contract_section(artifact_contract) observations = build_runner_observation_section(runner_observations) criteria = bundle_markdown_file(File.join(scenario.dir_path, "verifier.yml.md"), test_cases: test_cases) File.write(prompt_path, [project_context, sandbox_context, artifacts, contract, observations, criteria].join("\n\n---\n\n")) { system_path: system_path, prompt_path: prompt_path, output_path: File.join(cache_dir, "verifier-output.md") } end |