mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-30 21:49:18 +01:00
## Thinking Path > - Paperclip manages AI agents and their execution environments. > - Managed Git helpers run next to those agents. > - Some environments keep their Node interpreter outside the agent PATH. > - The current generator always emits an env-based Node shebang. > - This pull request lets the environment select an absolute interpreter path. > - Existing callers keep the same default behavior. ## Linked Issues or Issue Description Refs #18212. **What happened?** A managed helper can fail when Node exists only as a private runtime binary. The caller must currently alter generated source or expose that runtime through PATH. **Expected behavior** The source generator accepts an optional interpreter path. The environment can keep its own runtime private. **Steps to reproduce** Generate a helper in an environment whose PATH has no usable Node. Run a local Git command through that helper. The env-based shebang cannot select the private interpreter. ## What Changed - Add optional `interpreterPath` to `githubLauncherSource`. - Preserve `/usr/bin/env node` when the option is absent. - Reject relative paths, whitespace and NUL bytes. - Document the option and test actual execution with an unusable Node on PATH. ## Verification - The affected adapter-utils package typecheck passed. - All 26 tests in `packages/adapter-utils/src/github-launcher.test.ts` passed. - The new test runs a generated helper as a child process. It proves that the selected interpreter bypasses a failing PATH-selected Node and that the helper body stays unchanged. - Invalid-path tests passed. Existing broker and local-Git tests passed. - Full checks run in GitHub CI per the user's request. No full local suite was run. ## Risks The option changes only the shebang. Callers own interpreter installation and immutability. Default behavior, PATH, credentials and permission policy stay unchanged. No schema or workflow changes. ## Model Used OpenAI GPT-6.1 Sol (`gpt-6.1-sol`), high reasoning, with source inspection and targeted execution. The host does not expose an exact context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing>
90 lines
4.6 KiB
Markdown
90 lines
4.6 KiB
Markdown
# Runner launch preparation
|
|
|
|
Core selects the provider, model, instructions, tools, and task permissions.
|
|
The execution environment supplies executable paths and filesystem locations.
|
|
|
|
The built-in TypeScript implementation constructs the provider descriptor in
|
|
`createRunnerProviderLaunch`. The transport sends this descriptor with
|
|
`run.prepare`. Provider backends keep their existing validation and session rules.
|
|
|
|
By default, the SDK prepares local files. It stages remote files through the
|
|
existing execution driver.
|
|
|
|
## Environment-owned preparation
|
|
|
|
An execution driver can supply `prepareLaunch`.
|
|
The callback receives `RunnerProviderLaunchRequirements`.
|
|
It returns `PreparedRunnerProviderLaunch`.
|
|
|
|
Requirements contain the selected provider, model, policy, run identity, and
|
|
runtime context. They do not contain task text, process callbacks, provider
|
|
credentials, or controller executable choices. Resource paths identify source
|
|
locations. They do not grant filesystem access on the execution host.
|
|
|
|
The environment resolves its resources and prepares the provider descriptor.
|
|
It can use `bindRunnerLaunchResources` to replace registered context locations.
|
|
It can use `createRunnerProviderLaunch` for the existing descriptor projection.
|
|
The transport does not perform its built-in file preparation in this mode.
|
|
The process owner supplies the Runner artifact and process lifecycle.
|
|
|
|
The result contains a configuration ID, a requirements digest, and a provider
|
|
descriptor. The transport checks Core's selected profile and policy before
|
|
registration and launch. Core still supplies authorized tools and completion
|
|
criteria through PRP. A failed preparation does not enable a fallback launch.
|
|
|
|
### Codex probe policy
|
|
|
|
Core can select `settings.disableCodexProjectInstructions` for a hello probe.
|
|
Preparation must preserve it as `project_doc_max_bytes=0` before `app-server`,
|
|
after any environment-supplied overrides. Core validates this setting alongside
|
|
`disableCodexWebSearch`. Ordinary tasks retain project instructions when the
|
|
setting is absent or false. This does not change the selected filesystem policy.
|
|
|
|
### Working directory
|
|
|
|
In this mode the environment chooses the provider working directory. Core does
|
|
not supply one. The backend uses `workingDirectoryAuthority:
|
|
"runner_prepared_launch"`, and its controller environment stays empty.
|
|
|
|
- Core authorizes the agent, task, projects, and workspace binding.
|
|
- The environment resolves that assignment into mounts and the descriptor's
|
|
`cwd`. For a projectless task it selects its own default directory.
|
|
- The transport accepts only a normalized absolute `cwd` that is not a
|
|
filesystem root. Runnerd validates the directory on its own filesystem.
|
|
- The transport reports that `cwd` to the driver. The driver records it in
|
|
session context, snapshots, and recovery, and ignores the caller's directory.
|
|
- Recovery and run attachment must keep the same `cwd`. A runner snapshot or
|
|
recovered thread that reports another directory fails recovery. Core does not
|
|
substitute a controller-local or temporary directory.
|
|
|
|
`remote_runner` remains the mode in which Core assigns the remote directory
|
|
through `PAPERCLIP_WORKSPACE_CWD`.
|
|
|
|
The transport saves the exact requirements and prepared configuration in its
|
|
private `launch-preparation.json` file. The file holds at most two records.
|
|
A new attachment keeps the active run's record. Runner commands contain the
|
|
provider descriptor once. They do not contain these recovery records.
|
|
|
|
Recovery within the same run must return the same configuration. This rule also
|
|
applies during an interrupted warm attachment. A new run uses its current
|
|
requirements. For a new run, `runtimeContext: null` removes the assigned context.
|
|
Only an omitted context can reuse the previous context.
|
|
Provider session compatibility checks remain in their existing
|
|
backends. Close waits for preparation within its deadline. A timeout retains an
|
|
unsettled checkpoint and prevents reuse.
|
|
|
|
## Plugin task protocol
|
|
|
|
The [environment task API](plugins/PLUGIN_ENVIRONMENT_TASKS.md#launch-preparation)
|
|
defines the plugin preparation exchange. The [native plugin integration](plugins/PLUGIN_RUNNER_EXECUTION.md)
|
|
connects the callback to task execution. A Launcher implementation remains the
|
|
execution owner's responsibility.
|
|
|
|
## Managed Git helper interpreter
|
|
|
|
`githubLauncherSource({ interpreterPath })` can select an absolute Node interpreter
|
|
owned by the execution environment. Without this option, generated helpers retain
|
|
`#!/usr/bin/env node`. The option changes only the shebang; it does not change PATH,
|
|
command discovery, credential handling, or helper behavior. Interpreter paths must
|
|
be absolute and contain no whitespace or NUL bytes.
|