Add /impeccable generate: agent-initiated live variants (Node-era squash)

Squash of the ten commits reviewed on PR #626, plus the last review
round's connection-aware roll call, before the rebase onto the Rust
engine: the generate command reference and router row, the overlay's
agent-target handling (roll call, leases, replay, rescue), the Node-era
live-server routes and live-generate CLI, the hook stand-down, the pricing
cards e2e fixture, and the unit, contract, e2e, and skill-behavior tests.
The server, CLI, hook, and pin halves are ported to the engine crates in
the commits that follow.

AI-assisted: implemented and tested with Claude Code under maintainer
direction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Abdul Wahab
2026-09-15 05:45:49 +05:00
committed by Abdul Wahab
co-authored by Claude Fable 5
parent 1c043ea7c9
commit fc89b0ed62
27 changed files with 1851 additions and 16 deletions
+3
View File
@@ -322,6 +322,9 @@ results remain the completed measurements.
| 17 | existing surface; asks whether critique is required before polish | completes read-only advice distinguishing assessment from implementation and explaining critique is optional; reference coverage is diagnostic |
| 18 | existing surface; explicitly requests polish followed by a next-command recommendation | loads `polish.md` rather than substituting workflow advice for the requested work |
| 19 | tiny spacing edit with PRODUCT.md + DESIGN.md; Bash denied, a real-loader success control, a denied-launcher planning-only case, and a denied-launcher documentation case (PRODUCT.md + index.html, no DESIGN.md) | edits require successful playbook/craft-floor reads and a pre-edit denial warning; planning stays read-only and skips craft-floor; documentation requires successful document.md and source reads before any DESIGN.md write, with the denial disclosed before the first tool call after the denied launcher |
| 20 | PRODUCT.md + DESIGN.md + `index.html`; prompt is `/impeccable generate 2 bold variants of the hero heading` | loads `reference/generate.md`, and before any `live.md` read (live.md alone is the misroute) |
| 21 | same fixture; prompt is natural language with no command word ("Show me a few quieter versions of the hero heading in the browser so I can pick one.") | infers `reference/generate.md` before any `live.md` read |
| 22 | same fixture; prompt is `Make the hero heading bolder.` | does **not** load `reference/generate.md` (a plain refinement stays out of live); which playbook the refinement lands on is existing routing's business, not this guard's |
## Setup launcher-failure branch (2026-09-06, PR #750)
+116
View File
@@ -14,6 +14,7 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import path from 'node:path';
import { execFileSync } from 'node:child_process';
import {
prepareWorkspace,
@@ -79,6 +80,40 @@ function loadedBeforeImplementationWrite(trace, filename) {
return loadIndex >= 0 && (writeIndex < 0 || loadIndex < writeIndex);
}
/**
* True when `first` was loaded, and loaded before `second` whenever `second`
* was loaded at all. generate.md hands off to live.md, so a run that reaches
* live.md must have gone through generate.md first; live.md alone is the
* misroute.
*/
function loadedBefore(trace, first, second) {
const indexOf = (filename) => {
const needle = filename.toLowerCase();
return trace.toolCalls.findIndex(({ name, input }) => {
if (name === 'read') return input?.path?.toLowerCase().includes(needle);
if (name === 'bash') return input?.command?.toLowerCase().includes(needle);
return false;
});
};
const firstIndex = indexOf(first);
const secondIndex = indexOf(second);
return firstIndex >= 0 && (secondIndex < 0 || firstIndex < secondIndex);
}
/**
* A generate scenario that reaches the boot leaves a detached live helper
* behind; stop it (idempotent) before the workspace goes away.
*/
function stopLiveHelper(workspace) {
try {
execFileSync(
process.execPath,
[path.join(workspace, '.claude/skills/impeccable/scripts/live-server.mjs'), 'stop'],
{ cwd: workspace, stdio: 'ignore', timeout: 10_000 },
);
} catch { /* nothing was running */ }
}
function executedUpdateCommands(trace) {
const executableSegments = trace.bashCommands.flatMap((command) =>
command
@@ -782,5 +817,86 @@ for (const modelId of resolveModelList()) {
cleanupWorkspace(workspace);
}
});
it('scenario 20: explicit generate request routes to generate.md', async () => {
// "generate N <direction> variants of <element>" is the command's whole
// grammar. The route must land on generate.md; bolder.md is the
// direction's own playbook and live.md loads it later, so neither
// counts as the route.
const workspace = prepareWorkspace({
files: { 'PRODUCT.md': PRODUCT_MD_SAMPLE, 'DESIGN.md': DESIGN_MD_SAMPLE, 'index.html': MINIMAL_LANDING_HTML },
});
try {
const { trace, text } = await runTurn({
workspace,
model,
userPrompt: '/impeccable generate 2 bold variants of the hero heading',
maxSteps: 6,
});
logTrace('S20', 'generate-explicit', modelId, trace, { textSample: text.slice(0, 400) });
assert.ok(
loadedBefore(trace, 'generate.md', 'live.md'),
`agent should load generate.md for an explicit generate request, before any live.md read.\n` +
`Trace: ${JSON.stringify(summarizeTrace(trace), null, 2)}`,
);
} finally {
stopLiveHelper(workspace);
cleanupWorkspace(workspace);
}
});
it('scenario 21: natural-language variant request infers generate', async () => {
// No command word and no "generate": the intent is carried by
// "versions", "in the browser", and "pick one". A model that reads
// that as a source-side bolder or quieter edit misroutes.
const workspace = prepareWorkspace({
files: { 'PRODUCT.md': PRODUCT_MD_SAMPLE, 'DESIGN.md': DESIGN_MD_SAMPLE, 'index.html': MINIMAL_LANDING_HTML },
});
try {
const { trace, text } = await runTurn({
workspace,
model,
userPrompt: 'Show me a few quieter versions of the hero heading in the browser so I can pick one.',
maxSteps: 6,
});
logTrace('S21', 'generate-implicit', modelId, trace, { textSample: text.slice(0, 400) });
assert.ok(
loadedBefore(trace, 'generate.md', 'live.md'),
`agent should infer generate.md from a versions-to-pick-from request, before any live.md read.\n` +
`Trace: ${JSON.stringify(summarizeTrace(trace), null, 2)}`,
);
} finally {
stopLiveHelper(workspace);
cleanupWorkspace(workspace);
}
});
it('scenario 22: a plain refinement request stays out of generate', async () => {
// The inverse guard: "make it bolder" asks for one edit in source, not
// for variants to choose from in a browser. Over-triggering generate
// here would drag every refinement into a live session. Which playbook
// the refinement itself lands on is the existing sub-command routing's
// business, not this guard's.
const workspace = prepareWorkspace({
files: { 'PRODUCT.md': PRODUCT_MD_SAMPLE, 'DESIGN.md': DESIGN_MD_SAMPLE, 'index.html': MINIMAL_LANDING_HTML },
});
try {
const { trace, text } = await runTurn({
workspace,
model,
userPrompt: 'Make the hero heading bolder.',
maxSteps: 6,
});
logTrace('S22', 'refinement-not-generate', modelId, trace, { textSample: text.slice(0, 400) });
assert.equal(
fileLoaded(trace, 'generate.md'),
false,
`a plain refinement must not route into generate.md.\n` +
`Trace: ${JSON.stringify(summarizeTrace(trace), null, 2)}`,
);
} finally {
cleanupWorkspace(workspace);
}
});
});
}