Skip to content

Commit 1a2cb5a

Browse files
committed
feat(harness): apply slim rules layer to named and SDD agents
1 parent 3aba486 commit 1a2cb5a

3 files changed

Lines changed: 37 additions & 5 deletions

File tree

extensions/gentle-ai.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1970,8 +1970,17 @@ export const __testing = {
19701970
compactionPending = value;
19711971
},
19721972
getCompactionPending: () => compactionPending,
1973+
getAgentSlimRules: () => AGENT_SLIM_RULES,
19731974
};
19741975

1976+
const AGENT_SLIM_RULES = `## Gentle Agent Rules
1977+
You operate inside the el Gentleman harness as a delegated agent.
1978+
- Stay strictly within your assigned scope; do not expand the task.
1979+
- Never run destructive commands (rm -rf on broad paths, git reset --hard, force push) without explicit instruction.
1980+
- With tests present, provide TDD evidence: failing test first, then the implementation that makes it pass.
1981+
- Do not spawn further orchestration; execute your role and return.
1982+
- Report results honestly, including failures and skipped steps.`;
1983+
19751984
export default function gentleAi(pi: ExtensionAPI): void {
19761985
function runSddPreflight(ctx: ExtensionContext): Promise<SddPreflightPreferences> {
19771986
return ensureSddPreflight(ctx, {
@@ -2047,7 +2056,7 @@ export default function gentleAi(pi: ExtensionAPI): void {
20472056
}), phase)}`
20482057
: "";
20492058
const gentlePrompt = isNamedAgent || isSddAgent
2050-
? ""
2059+
? `\n\n${AGENT_SLIM_RULES}`
20512060
: `\n\n${buildGentlePrompt(readPersonaMode(ctx.cwd))}`;
20522061
return {
20532062
systemPrompt: `${event.systemPrompt}${gentlePrompt}${sddPrompt}${nativeStatusPrompt}`,

tests/gentle-ai.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,21 @@ test("compaction flag resets when applyHarnessReminder builds fresh reminder", a
211211
assert.equal(__testing.getCompactionPending(), false, "flag should be reset after applyHarnessReminder");
212212
assert(result[0].content.includes("Context was just compacted"), "reminder should include compaction content");
213213
});
214+
215+
test("agent slim rules contain expected content", async () => {
216+
const slimRules = __testing.getAgentSlimRules();
217+
assert(slimRules.includes("Gentle Agent Rules"), "should include header");
218+
assert(slimRules.includes("Stay strictly within your assigned scope"), "should include scope rule");
219+
assert(slimRules.includes("Never run destructive commands"), "should include safety rule");
220+
assert(slimRules.includes("TDD evidence"), "should include TDD rule");
221+
assert(slimRules.includes("Do not spawn further orchestration"), "should include no-orchestration rule");
222+
assert(slimRules.includes("Report results honestly"), "should include honesty rule");
223+
});
224+
225+
test("agent slim rules do not contain persona or orchestrator markers", async () => {
226+
const slimRules = __testing.getAgentSlimRules();
227+
assert(!slimRules.includes("el Gentleman Identity"), "slim rules must not contain identity contract");
228+
assert(!slimRules.includes("Persona:"), "slim rules must not contain persona marker");
229+
assert(!slimRules.includes("orchestrator.md"), "slim rules must not reference orchestrator");
230+
assert(!slimRules.includes("Harness principles"), "slim rules must not contain harness principles");
231+
});

tests/runtime-harness.mjs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,10 @@ async function run() {
213213
{ agentName: "worker", systemPrompt: "worker base" },
214214
createCtx(promptCwd),
215215
);
216-
assert.equal(subagentPromptResult.systemPrompt, "worker base");
216+
assert.match(subagentPromptResult.systemPrompt, /worker base/);
217+
assert.match(subagentPromptResult.systemPrompt, /Gentle Agent Rules/);
218+
assert.match(subagentPromptResult.systemPrompt, /Stay strictly within your assigned scope/);
219+
assert.doesNotMatch(subagentPromptResult.systemPrompt, /el Gentleman Identity/);
217220
assert.equal(
218221
existsSync(join(promptCwd, ".pi", "agents", "sdd-apply.md")),
219222
false,
@@ -504,11 +507,13 @@ async function run() {
504507
{ agentName: "worker", systemPrompt: "worker base" },
505508
ctx,
506509
);
507-
assert.equal(
510+
assert.match(
508511
workerPromptResult.systemPrompt,
509-
"worker base",
510-
"non-SDD subagents must not receive parent harness or SDD preflight prompts",
512+
/worker base/,
513+
"non-SDD subagents must receive slim rules but not parent harness or SDD preflight prompts",
511514
);
515+
assert.match(workerPromptResult.systemPrompt, /Gentle Agent Rules/);
516+
assert.doesNotMatch(workerPromptResult.systemPrompt, /el Gentleman Identity/);
512517
} finally {
513518
await rm(lazySddCwd, { recursive: true, force: true });
514519
await rm(globalModelsPath, { force: true });

0 commit comments

Comments
 (0)