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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed
- **Ambient mode**: skills not loading despite correct classification — reordered instructions so Skill tool invocations happen before any text output

---

## [1.8.1] - 2026-03-22
Expand Down
2 changes: 1 addition & 1 deletion scripts/hooks/ambient-prompt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fi

# Inject classification preamble
# SYNC: must match tests/integration/helpers.ts AMBIENT_PREAMBLE
PREAMBLE="AMBIENT MODE ACTIVE: Before responding, silently classify this prompt using the ambient-router skill already in your session context. If QUICK, respond normally without stating classification. If GUIDED or ORCHESTRATED, you MUST load the selected skills using the Skill tool before proceeding."
PREAMBLE="AMBIENT MODE ACTIVE: Before responding, silently classify this prompt using the ambient-router skill already in your session context. If QUICK, respond normally without stating classification. If GUIDED or ORCHESTRATED, your FIRST tool calls MUST be Skill tool invocations for each selected skill — before writing ANY text about the task."

jq -n --arg ctx "$PREAMBLE" '{
"hookSpecificOutput": {
Expand Down
8 changes: 5 additions & 3 deletions shared/skills/ambient-router/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,18 @@ See `references/skill-catalog.md` for the full skill-to-intent mapping with file
<IMPORTANT>
When classification is GUIDED or ORCHESTRATED, skill loading is NON-NEGOTIABLE.
Do not rationalize skipping skills. Do not respond without loading them first.
BLOCKING REQUIREMENT: Invoke each selected skill using the Skill tool before proceeding.
BLOCKING REQUIREMENT: Your FIRST tool calls MUST be Skill tool invocations — before
writing ANY text about the task. Invoke all selected skills, THEN state classification,
THEN proceed with work. Do NOT write implementation text before all Skill tools return.
For IMPLEMENT intent, enforce TDD: write the failing test before ANY production code.
NOTE: Skills loaded in the main session via ambient mode are reference patterns only —
their allowed-tools metadata does NOT restrict your tool access. You retain full access
to all tools (Edit, Write, Bash, Agent, etc.) for implementation work.
</IMPORTANT>

- **QUICK:** Respond directly. No preamble, no classification statement.
- **GUIDED:** State classification briefly: `Ambient: IMPLEMENT/GUIDED. Loading: implementation-patterns, search-first.` Then invoke each skill using the Skill tool and work directly in main session. After code changes, spawn Simplifier on changed files.
- **ORCHESTRATED:** State classification briefly: `Ambient: IMPLEMENT/ORCHESTRATED. Loading: implementation-orchestration, implementation-patterns.` Then invoke each skill using the Skill tool and follow Step 5 for agent orchestration.
- **GUIDED:** First, invoke each selected skill using the Skill tool. After all Skill tools return, state classification briefly: `Ambient: IMPLEMENT/GUIDED. Loading: implementation-patterns, search-first.` Then work directly in main session. After code changes, spawn Simplifier on changed files.
- **ORCHESTRATED:** First, invoke each selected skill using the Skill tool. After all Skill tools return, state classification briefly: `Ambient: IMPLEMENT/ORCHESTRATED. Loading: implementation-orchestration, implementation-patterns.` Then follow Step 5 for agent orchestration.

### GUIDED Behavior by Intent

Expand Down
2 changes: 1 addition & 1 deletion tests/ambient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ describe('preamble drift detection', () => {
// The helpers.ts AMBIENT_PREAMBLE is used by extractIntent/extractDepth etc.
// We verify it indirectly by checking the shell script value matches expected.
const expectedPreamble =
'AMBIENT MODE ACTIVE: Before responding, silently classify this prompt using the ambient-router skill already in your session context. If QUICK, respond normally without stating classification. If GUIDED or ORCHESTRATED, you MUST load the selected skills using the Skill tool before proceeding.';
'AMBIENT MODE ACTIVE: Before responding, silently classify this prompt using the ambient-router skill already in your session context. If QUICK, respond normally without stating classification. If GUIDED or ORCHESTRATED, your FIRST tool calls MUST be Skill tool invocations for each selected skill — before writing ANY text about the task.';

expect(shellPreamble).toBe(expectedPreamble);
});
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function isClaudeAvailable(): boolean {

// SYNC: must match scripts/hooks/ambient-prompt line 43
const AMBIENT_PREAMBLE =
'AMBIENT MODE ACTIVE: Before responding, silently classify this prompt using the ambient-router skill already in your session context. If QUICK, respond normally without stating classification. If GUIDED or ORCHESTRATED, you MUST load the selected skills using the Skill tool before proceeding.';
'AMBIENT MODE ACTIVE: Before responding, silently classify this prompt using the ambient-router skill already in your session context. If QUICK, respond normally without stating classification. If GUIDED or ORCHESTRATED, your FIRST tool calls MUST be Skill tool invocations for each selected skill — before writing ANY text about the task.';

/**
* Run a prompt through claude CLI in non-interactive mode.
Expand Down
Loading