-
Notifications
You must be signed in to change notification settings - Fork 4
hotfix: append "do not commit your changes." to sandbox prompts #142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import { describe, it, expect } from "vitest"; | ||
| import { appendNoCommitInstruction, NO_COMMIT_INSTRUCTION } from "../appendNoCommitInstruction"; | ||
|
|
||
| describe("appendNoCommitInstruction", () => { | ||
| it("appends the instruction to the value after --message", () => { | ||
| const result = appendNoCommitInstruction([ | ||
| "agent", | ||
| "--agent", | ||
| "main", | ||
| "--message", | ||
| "fix the bug", | ||
| ]); | ||
|
|
||
| expect(result).toEqual([ | ||
| "agent", | ||
| "--agent", | ||
| "main", | ||
| "--message", | ||
| `fix the bug ${NO_COMMIT_INSTRUCTION}`, | ||
| ]); | ||
| }); | ||
|
|
||
| it("is idempotent — does not re-append when the instruction is already present", () => { | ||
| const original = [ | ||
| "agent", | ||
| "--message", | ||
| `do something ${NO_COMMIT_INSTRUCTION}`, | ||
| ]; | ||
|
|
||
| expect(appendNoCommitInstruction(original)).toEqual(original); | ||
| }); | ||
|
|
||
| it("leaves args unchanged when there is no --message flag", () => { | ||
| const original = ["status"]; | ||
| expect(appendNoCommitInstruction(original)).toEqual(original); | ||
| }); | ||
|
|
||
| it("leaves args unchanged when --message is the last arg (no value)", () => { | ||
| const original = ["agent", "--message"]; | ||
| expect(appendNoCommitInstruction(original)).toEqual(original); | ||
| }); | ||
|
|
||
| it("returns a new array rather than mutating the input", () => { | ||
| const original = ["--message", "hi"]; | ||
| const result = appendNoCommitInstruction(original); | ||
| expect(result).not.toBe(original); | ||
| expect(original).toEqual(["--message", "hi"]); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| export const NO_COMMIT_INSTRUCTION = "do not commit your changes."; | ||
|
|
||
| /** | ||
| * Hotfix guardrail: ensure the `--message` value passed to `openclaw agent` | ||
| * (or any tool that takes `--message <prompt>`) ends with the | ||
| * {@link NO_COMMIT_INSTRUCTION} text. The task runs in a sandbox that is | ||
| * git-aware, and we push sandbox changes to GitHub after the command — we | ||
| * do NOT want the agent itself creating commits during the run. | ||
| * | ||
| * @param args - The `args` payload passed to `sandbox.runCommand`. | ||
| * @returns A new args array with the instruction appended to the `--message` | ||
| * value if one is present and the instruction isn't already there. | ||
| * Otherwise the input is returned unchanged (as a copy). | ||
| */ | ||
| export function appendNoCommitInstruction(args: readonly string[]): string[] { | ||
| const out = [...args]; | ||
| const messageIdx = out.indexOf("--message"); | ||
| if (messageIdx === -1) return out; | ||
|
|
||
| const valueIdx = messageIdx + 1; | ||
| if (valueIdx >= out.length) return out; | ||
|
|
||
| const current = out[valueIdx]; | ||
| if (current.includes(NO_COMMIT_INSTRUCTION)) return out; | ||
|
|
||
| out[valueIdx] = `${current} ${NO_COMMIT_INSTRUCTION}`; | ||
| return out; | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,6 +12,7 @@ import { ensureOrgRepos } from "../sandboxes/ensureOrgRepos"; | |||||||||||||||||||||||||||||||||
| import { ensureSetupSandbox } from "../sandboxes/ensureSetupSandbox"; | ||||||||||||||||||||||||||||||||||
| import { pushSandboxToGithub } from "../sandboxes/pushSandboxToGithub"; | ||||||||||||||||||||||||||||||||||
| import { syncOrgRepos } from "../sandboxes/git/syncOrgRepos"; | ||||||||||||||||||||||||||||||||||
| import { appendNoCommitInstruction } from "../sandboxes/appendNoCommitInstruction"; | ||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||
| runSandboxCommandPayloadSchema, | ||||||||||||||||||||||||||||||||||
| type SandboxResult, | ||||||||||||||||||||||||||||||||||
|
|
@@ -76,7 +77,7 @@ export const runSandboxCommandTask = schemaTask({ | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const commandResult = await sandbox.runCommand({ | ||||||||||||||||||||||||||||||||||
| cmd: command, | ||||||||||||||||||||||||||||||||||
| args: args || [], | ||||||||||||||||||||||||||||||||||
| args: appendNoCommitInstruction(args || []), | ||||||||||||||||||||||||||||||||||
|
Comment on lines
78
to
+80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Limit prompt mutation to OpenClaw agent invocations only. At Line [80], Proposed fix- const commandResult = await sandbox.runCommand({
+ const normalizedArgs = args ?? [];
+ const shouldAppendNoCommit =
+ command === "openclaw" && normalizedArgs[0] === "agent";
+
+ const commandResult = await sandbox.runCommand({
cmd: command,
- args: appendNoCommitInstruction(args || []),
+ args: shouldAppendNoCommit
+ ? appendNoCommitInstruction(normalizedArgs)
+ : normalizedArgs,
cwd,
env: getSandboxEnv(accountId),
});📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| cwd, | ||||||||||||||||||||||||||||||||||
| env: getSandboxEnv(accountId), | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
includes()does not enforce the required suffix behavior.At Line [24], the early return triggers even when the instruction is only a substring, so the message may still not end with the required text.
Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents