Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/runtime/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add the reserved `[[NO_REPLY]]` harness contract for successful silent runs,
including marker leak sanitization and observability.

## [4.1.26] - 2026-07-16

### Fixed
Expand Down
5 changes: 4 additions & 1 deletion packages/runtime/src/cloud-defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import { createDefaultLlm } from './cloud-llm.js';
import { SandboxNotAvailableError } from './errors.js';
import { spawnAndCapture, spawnNonInteractiveAndCapture } from './harness-process.js';
import { appendNoReplyPromptContract } from './no-reply.js';
import type {
FilesContext,
HarnessRunArgs,
Expand Down Expand Up @@ -497,7 +498,9 @@ function createProcessHarnessRunner(args: CloudDefaultOptions & {
args.log('warn', 'harness.config.dropped', { warning });
}

const renderedSystemPrompt = renderPersonaInputs(personaSystemPrompt, inputResolution.values);
const renderedSystemPrompt = appendNoReplyPromptContract(
renderPersonaInputs(personaSystemPrompt, inputResolution.values)
);
const cwd = resolveWorkspacePath(args.workspaceRoot, run.cwd ?? args.workspaceRoot);
await assertDirectory(cwd);
const task = run.prompt;
Expand Down
145 changes: 145 additions & 0 deletions packages/runtime/src/ctx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,151 @@ test('buildCtx exposes agent and deployment metadata', () => {
});
});

test('ctx.harness.run turns an exact no-reply marker into observable silent success', async () => {
const logs: Array<{ level: string; message: string; attrs?: Record<string, unknown> }> = [];
const ctx = buildCtx({
persona: basePersona,
workspaceId: 'ws-test',
sandbox: stubSandbox,
harnessRunner: async () => ({ output: ' [[NO_REPLY]]\n', exitCode: 0, durationMs: 12 }),
agent: {
id: 'agent_123',
deployedName: 'docs-demo',
spawnedByAgentId: null
},
deployment: {
id: 'deployment_456',
triggerKind: 'inbox',
parentDeploymentId: null
},
log: (level, message, attrs) => logs.push({ level, message, attrs })
});

const result = await ctx.harness.run({ prompt: 'decide whether to reply' });
assert.deepEqual(result, {
output: '',
exitCode: 0,
durationMs: 12,
containsMarker: true,
suppressed: true
});
assert.deepEqual(logs, [
{
level: 'info',
message: 'harness.no_reply.suppressed',
attrs: { containsMarker: true }
}
]);
});

test('ctx.harness.run strips a mixed no-reply marker and logs the leak', async () => {
const logs: Array<{ level: string; message: string; attrs?: Record<string, unknown> }> = [];
const ctx = buildCtx({
persona: basePersona,
workspaceId: 'ws-test',
sandbox: stubSandbox,
harnessRunner: async () => ({
output: 'Visible before. [[NO_REPLY]] Visible after.',
exitCode: 0,
durationMs: 8
}),
agent: {
id: 'agent_123',
deployedName: 'docs-demo',
spawnedByAgentId: null
},
deployment: {
id: 'deployment_456',
triggerKind: 'inbox',
parentDeploymentId: null
},
log: (level, message, attrs) => logs.push({ level, message, attrs })
});

const result = await ctx.harness.run({ prompt: 'decide whether to reply' });
assert.deepEqual(result, {
output: 'Visible before. Visible after.',
exitCode: 0,
durationMs: 8,
containsMarker: true,
suppressed: false
});
assert.deepEqual(logs, [
{
level: 'warn',
message: 'harness.no_reply.marker_leak',
attrs: { containsMarker: true }
}
]);
});

test('ctx.harness.run strips the marker from stderr as well as output', async () => {
const logs: Array<{ level: string; message: string; attrs?: Record<string, unknown> }> = [];
const ctx = buildCtx({
persona: basePersona,
workspaceId: 'ws-test',
sandbox: stubSandbox,
harnessRunner: async () => ({
output: 'Visible response.',
stderr: 'diagnostic [[NO_REPLY]]',
exitCode: 0,
durationMs: 5
}),
agent: {
id: 'agent_123',
deployedName: 'docs-demo',
spawnedByAgentId: null
},
deployment: {
id: 'deployment_456',
triggerKind: 'inbox',
parentDeploymentId: null
},
log: (level, message, attrs) => logs.push({ level, message, attrs })
});

const result = await ctx.harness.run({ prompt: 'decide whether to reply' });
assert.equal(result.output, 'Visible response.');
assert.equal(result.stderr, 'diagnostic');
assert.equal(result.containsMarker, true);
assert.equal(result.suppressed, false);
assert.deepEqual(logs, [
{
level: 'warn',
message: 'harness.no_reply.marker_leak',
attrs: { containsMarker: true }
}
]);
});

test('ctx.harness.run does not turn a failed marker result into success', async () => {
const logs: Array<{ level: string; message: string }> = [];
const ctx = buildCtx({
persona: basePersona,
workspaceId: 'ws-test',
sandbox: stubSandbox,
harnessRunner: async () => ({ output: '[[NO_REPLY]]', exitCode: 1, durationMs: 4 }),
agent: {
id: 'agent_123',
deployedName: 'docs-demo',
spawnedByAgentId: null
},
deployment: {
id: 'deployment_456',
triggerKind: 'inbox',
parentDeploymentId: null
},
log: (level, message) => logs.push({ level, message })
});

const result = await ctx.harness.run({ prompt: 'decide whether to reply' });
assert.equal(result.output, '');
assert.equal(result.exitCode, 1);
assert.equal(result.containsMarker, true);
assert.equal(result.suppressed, true);
assert.deepEqual(logs, [{ level: 'warn', message: 'harness.no_reply.marker_leak' }]);
});

test('buildCtx exposes ctx.files as a sandbox file helper', async () => {
const reads: string[] = [];
const writes: Array<{ path: string; contents: string }> = [];
Expand Down
33 changes: 32 additions & 1 deletion packages/runtime/src/ctx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
} from './types.js';
import { attachTrajectoryRecorder, createTrajectoryRecorder } from './trajectory.js';
import { buildRelayContext } from './relay.js';
import { NO_REPLY_MARKER, sanitizeNoReplyOutput } from './no-reply.js';

type AgentInputValue = string | number | boolean | null | undefined;

Expand Down Expand Up @@ -162,7 +163,37 @@ export function buildCtx(options: CtxBuildOptions): WorkforceCtx {
workspaceId: options.workspaceId,
agentName,
llm: options.llm ?? UNAVAILABLE_LLM,
harness: { run: options.harnessRunner },
harness: {
async run(args) {
const result = await options.harnessRunner(args);
const sanitizedOutput = sanitizeNoReplyOutput(result.output);
const sanitizedStderr = result.stderr === undefined
? undefined
: sanitizeNoReplyOutput(result.stderr);
const containsMarker =
sanitizedOutput.containsMarker || (sanitizedStderr?.containsMarker ?? false);

if (containsMarker) {
const exactMarker =
result.exitCode === 0 &&
result.output.trim() === NO_REPLY_MARKER &&
!(result.stderr?.includes(NO_REPLY_MARKER) ?? false);
log(
exactMarker ? 'info' : 'warn',
exactMarker ? 'harness.no_reply.suppressed' : 'harness.no_reply.marker_leak',
{ containsMarker: true }
);
}

return {
...result,
output: sanitizedOutput.output,
...(sanitizedStderr ? { stderr: sanitizedStderr.output } : {}),
containsMarker,
suppressed: sanitizedOutput.suppressed
};
}
},
sandbox: options.sandbox,
files,
credentials: credentialsFromEnv(),
Expand Down
80 changes: 80 additions & 0 deletions packages/runtime/src/no-reply.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { buildNonInteractiveSpec, type Harness } from '@agentworkforce/persona-kit';
import {
NO_REPLY_MARKER,
NO_REPLY_PROMPT_CONTRACT,
appendNoReplyPromptContract,
sanitizeNoReplyOutput
} from './no-reply.js';

test('sanitizeNoReplyOutput suppresses an exact marker with surrounding transport whitespace', () => {
assert.deepEqual(sanitizeNoReplyOutput(` ${NO_REPLY_MARKER}\n`), {
output: '',
containsMarker: true,
suppressed: true
});
});

test('sanitizeNoReplyOutput strips a leaked marker while preserving visible prose', () => {
assert.deepEqual(
sanitizeNoReplyOutput(`Keep this paragraph.\n\n${NO_REPLY_MARKER}\n\nAnd keep this one.`),
{
output: 'Keep this paragraph.\n\n\n\nAnd keep this one.',
containsMarker: true,
suppressed: false
}
);
});

test('sanitizeNoReplyOutput leaves ordinary harness output unchanged', () => {
assert.deepEqual(sanitizeNoReplyOutput(' visible response\n'), {
output: ' visible response\n',
containsMarker: false,
suppressed: false
});
});

test('the no-reply prompt contract is appended once', () => {
const appended = appendNoReplyPromptContract('Persona instructions.');
assert.equal(appended, `Persona instructions.\n\n${NO_REPLY_PROMPT_CONTRACT}`);
assert.equal(appendNoReplyPromptContract(appended), appended);
});

for (const harness of ['claude', 'codex', 'opencode', 'grok'] as const satisfies readonly Harness[]) {
test(`${harness} receives the no-reply contract on its harness-specific prompt surface`, () => {
const spec = buildNonInteractiveSpec({
harness,
personaId: 'no-reply-test',
model: modelFor(harness),
systemPrompt: appendNoReplyPromptContract('Persona instructions.'),
task: 'Handle the event.',
name: 'no-reply-test',
workingDirectory: '/workspace'
});
const harnessVisiblePrompt = [
...spec.args,
spec.prompt.contents,
...spec.configFiles.map((file) => file.contents)
].join('\n');

assert.match(harnessVisiblePrompt, /Persona instructions\./);
assert.match(
harnessVisiblePrompt,
/When no visible reply is useful, make the final message exactly \[\[NO_REPLY\]\]\./
);
});
}

function modelFor(harness: Harness): string {
switch (harness) {
case 'claude':
return 'anthropic/claude-sonnet-4-6';
case 'codex':
return 'gpt-5.4';
case 'opencode':
return 'opencode/minimax-m2.5';
case 'grok':
return 'grok-build-0.1';
}
}
31 changes: 31 additions & 0 deletions packages/runtime/src/no-reply.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export const NO_REPLY_MARKER = '[[NO_REPLY]]';

export const NO_REPLY_PROMPT_CONTRACT =
`When no visible reply is useful, make the final message exactly ${NO_REPLY_MARKER}.`;

export interface SanitizedNoReplyOutput {
output: string;
containsMarker: boolean;
suppressed: boolean;
}

/** Append the reserved silent-success instruction without duplicating it. */
export function appendNoReplyPromptContract(systemPrompt: string): string {
if (systemPrompt.includes(NO_REPLY_PROMPT_CONTRACT)) return systemPrompt;
return systemPrompt
? `${systemPrompt}\n\n${NO_REPLY_PROMPT_CONTRACT}`
: NO_REPLY_PROMPT_CONTRACT;
}

/** Remove the reserved marker before harness output can reach a user-visible sink. */
export function sanitizeNoReplyOutput(output: string): SanitizedNoReplyOutput {
const containsMarker = output.includes(NO_REPLY_MARKER);
if (!containsMarker) return { output, containsMarker: false, suppressed: false };

const visibleOutput = output.replaceAll(NO_REPLY_MARKER, '').trim();
return {
output: visibleOutput,
containsMarker: true,
suppressed: visibleOutput.length === 0
};
}
Loading
Loading