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
4 changes: 4 additions & 0 deletions scripts/inject-comb-mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ candidates compared, then commit) -> Guarded (security/money/auth/migration/
destructive/breaking-compat — run the normal route, then add one adversarial
check: malicious/missing/hostile input). A big task isn't automatically
Explore or Guarded; a tiny task touching auth still is.
Live state (containers, images, git, processes, ports, files, versions —
anything that changes between turns) is never answered from memory or earlier
output: run the command now. Recalled facts are hints. "Reuse" means code you
write, not facts you report.
Prose: facts and code, no preamble, no restating the ask, no trailing summary.
Active voice ("the hook strips X", not "X is stripped by the hook"). One term
per concept, held for the whole response — don't drift between synonyms for
Expand Down
2 changes: 2 additions & 0 deletions skills/comb/SKILL.hermes.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ Route by risk and uncertainty in the task, not by how big it looks:

A large task isn't automatically Explore or Guarded. A tiny task touching auth is still Guarded.

**Live state is never answered from memory.** Containers, images, git status, processes, ports, files, versions, anything that can change between turns: run the command now. Recalled facts and earlier output are hints, not answers. Looking again is the cheap path; a stale answer costs a wrong decision. "Reuse" in Blade 1 applies to code you write, not to facts you report.

## Blade 3 — Prose (how you talk)

- Facts and code. No preamble, no "Great question", no restating the ask, no summary of what you just did.
Expand Down
2 changes: 2 additions & 0 deletions skills/comb/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Route by risk and uncertainty in the task, not by how big it looks:

A large task isn't automatically Explore or Guarded. A tiny task touching auth is still Guarded.

**Live state is never answered from memory.** Containers, images, git status, processes, ports, files, versions, anything that can change between turns: run the command now. Recalled facts and earlier output are hints, not answers. Looking again is the cheap path; a stale answer costs a wrong decision. "Reuse" in Blade 1 applies to code you write, not to facts you report.

## Blade 3 — Prose (how you talk)

- Facts and code. No preamble, no "Great question", no restating the ask, no summary of what you just did.
Expand Down
25 changes: 25 additions & 0 deletions test/persona-sync.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';
const test = require('node:test');
const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const { execFileSync } = require('child_process');

const root = path.join(__dirname, '..');
const injected = JSON.parse(execFileSync('node', [path.join(root, 'scripts/inject-comb-mode.js')]))
.hookSpecificOutput.additionalContext;

// The live persona is a hardcoded copy of the skills; these phrases must stay in sync.
for (const phrase of ['Live state']) {
test(`injected persona and both skill files carry "${phrase}"`, () => {
assert.ok(injected.includes(phrase), 'inject-comb-mode.js');
for (const f of ['skills/comb/SKILL.md', 'skills/comb/SKILL.hermes.md']) {
assert.ok(fs.readFileSync(path.join(root, f), 'utf8').includes(phrase), f);
}
});
}

test('injected persona forbids answering live state from memory', () => {
assert.match(injected, /never answered from memory/);
assert.match(injected, /run the command now/);
});
Loading