mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 13:46:32 +03:00
Clarify launcher fallback and completed documentation handoffs; separate bounded protocol checkpoints from opt-in browser-backed completion diagnostics. Correct fixture containment, target syntax, and artifact assertions. AI assistance: Codex, under maintainer direction.
94 lines
7.5 KiB
JavaScript
94 lines
7.5 KiB
JavaScript
import { it } from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
import { prepareWorkspace, cleanupWorkspace, runTurn, fileLoaded, ENGINE_BIN } from '../skill-behavior/harness.mjs';
|
||
import { getModel, detectProvider, hasKey } from '../skill-behavior/providers.mjs';
|
||
import { assertCompleted, assertNoChangeDocumentation, assertDocumentationArtifacts } from './assertions.mjs';
|
||
import { missingReferences } from '../skill-behavior/assertions.mjs';
|
||
|
||
// A synthetic post-review checkpoint, not another full-build simulation.
|
||
// The page and system agree. A missing sidecar predates this task and is not
|
||
// permission to repair drift or rewrite the incumbent DESIGN.md.
|
||
const DESIGN = `# Field Manual
|
||
|
||
## Overview
|
||
An established, plain reading surface. Preserve this identity.
|
||
|
||
## Colors
|
||
White background (#ffffff), near-black text (#222222), blue links (#0645ad).
|
||
|
||
## Typography
|
||
System-ui body at 16px, line-height 1.6. Headings at 24px, weight 700.
|
||
|
||
## Layout
|
||
One column, max-width 65ch, padding 24px; no decorative containers.
|
||
`;
|
||
const PAGE = '<!doctype html><html lang="en"><meta charset="utf-8"><title>Keyboard guide</title><style>body{background:#fff;color:#222;font:16px/1.6 system-ui;max-width:65ch;margin:auto;padding:24px}h1{font-size:24px;font-weight:700}a{color:#0645ad}</style><main><h1>Keyboard guide</h1><p>Use Tab to move between controls. Press Enter to activate a link.</p><a href="#top" id="top">Back to top</a></main></html>';
|
||
const BRIEF = '# Keyboard guide\n\n## Direction contract\nTHESIS: A short reading page.\nOWN-WORLD: Inherit Field Manual.\nSTORY: Read keyboard instructions.\nFIRST VIEWPORT: Title, paragraph, link.\nFORM: Direct, precisely specified page; no seed required.\nFINISH: unreviewed and undocumented is unfinished.\n';
|
||
|
||
for (const modelId of (process.env.IMPECCABLE_SKILL_BEHAVIOR_MODELS || 'claude-sonnet-5').split(',').map((id) => id.trim()).filter(Boolean)) {
|
||
for (const mode of ['extension', 'new world', 'redesign']) {
|
||
const existingSystem = mode !== 'new world';
|
||
const preserveSystem = mode === 'extension';
|
||
it(`post-review ${mode} ${preserveSystem ? 'preserves' : 'records'} its system :: ${modelId}`,
|
||
{ skip: !ENGINE_BIN || !hasKey(detectProvider(modelId)) }, async (t) => {
|
||
const files = {
|
||
'PRODUCT.md': '# Field Manual\n\n## Platform\nweb\n\nA reference guide for keyboard users.\n',
|
||
...(existingSystem ? { 'DESIGN.md': preserveSystem ? DESIGN : '# Old Field Manual\n\nBeige cards, serif body type, orange links.\n' } : {}),
|
||
'index.html': PAGE,
|
||
'.impeccable/surfaces/index-html.md': mode === 'redesign'
|
||
? BRIEF.replace('Inherit Field Manual.', 'Approved replacement: white, blue links, system-ui, single column.') : BRIEF,
|
||
};
|
||
const workspace = prepareWorkspace({ files });
|
||
try {
|
||
const reference = fs.readFileSync(path.join(workspace, '.claude/skills/impeccable/reference/new-work.md'), 'utf8');
|
||
const result = await runTurn({
|
||
workspace, model: getModel(modelId), maxSteps: 12, timeoutMs: 180000, contextOnlyBash: true,
|
||
environment: 'This is a resumed post-review checkpoint. No subagent or browser tools are available. The review is closed; no further UI edits or screenshots are needed. Read/list/write tools are available.',
|
||
priorMessages: [
|
||
{ role: 'user', content: preserveSystem
|
||
? 'Use /impeccable to add the specified keyboard guide page inside the established Field Manual world. Keep the existing visual system. Do not repair unrelated project drift.'
|
||
: mode === 'redesign'
|
||
? 'Use /impeccable to redesign the keyboard guide. I approve replacing the old beige-card/serif/orange world with the plain single-column, system-font, white-background and blue-link identity. Update the system documentation from the finished page.'
|
||
: 'Use /impeccable to create Field Manual’s first keyboard guide page. The chosen identity is plain, single-column, system fonts, white background and blue links.' },
|
||
{ role: 'assistant', content: [{ type: 'tool-call', toolCallId: 'load-new-work', toolName: 'read', input: { path: '.claude/skills/impeccable/reference/new-work.md' } }] },
|
||
{ role: 'tool', content: [{ type: 'tool-result', toolCallId: 'load-new-work', toolName: 'read', output: { type: 'text', value: reference } }] },
|
||
{ role: 'assistant', content: `Checkpoint: context and PRODUCT.md were loaded. The user confirmed the exact page and identity. The surface brief and index.html are written. Desktop/mobile captures were validated, the detector ran once, and the shipped finish reviewer returned ship with no open findings. ${preserveSystem
|
||
? 'DESIGN.md was loaded. No durable system changes were requested or introduced. The pre-existing missing .impeccable/design.json was reported but not repaired.'
|
||
: mode === 'redesign'
|
||
? 'The approved replacement world is implemented in index.html. DESIGN.md still describes the superseded identity; no design sidecar exists yet.'
|
||
: 'This is the first completed surface of the approved new world. No DESIGN.md or design sidecar exists yet.'}` },
|
||
],
|
||
userPrompt: 'Continue from this checkpoint and finish the task.',
|
||
});
|
||
assertCompleted(result);
|
||
t.diagnostic(`Documentation wrapper coverage gaps (diagnostic; contract and artifacts remain required): ${missingReferences(result.trace, ['degraded/documenter.md']).join(', ') || 'none'}`);
|
||
assert.ok(fileLoaded(result.trace, 'reference/document.md'), 'must consult the documentation contract');
|
||
for (const name of existingSystem ? ['index.html', 'DESIGN.md'] : ['index.html']) {
|
||
assert.ok(fileLoaded(result.trace, name), `documentation must check ${name}, not merely announce a no-op`);
|
||
}
|
||
for (const [name, contents] of Object.entries(files)) {
|
||
if (mode === 'redesign' && name === 'DESIGN.md') continue;
|
||
assert.equal(fs.readFileSync(path.join(workspace, name), 'utf8'), contents, `${name} must remain unchanged`);
|
||
}
|
||
if (preserveSystem) {
|
||
assertNoChangeDocumentation(result, { target: 'index.html', evidence: [/system-ui/i, /65\s*ch/i, /#0645ad/i] });
|
||
assert.equal(fs.existsSync(path.join(workspace, '.impeccable/design.json')), false, 'must not repair pre-existing sidecar drift unasked');
|
||
assert.deepEqual(result.trace.toolCalls.flatMap((call) => call.mutatedPaths || []), [], 'a no-change check must not mutate other project files');
|
||
} else {
|
||
const design = fs.readFileSync(path.join(workspace, 'DESIGN.md'), 'utf8');
|
||
if (mode === 'redesign') assert.notEqual(design, files['DESIGN.md'], 'approved redesign must replace the old system');
|
||
assertDocumentationArtifacts(design, fs.readFileSync(path.join(workspace, '.impeccable/design.json'), 'utf8'));
|
||
assert.match(design, /system-ui/);
|
||
const writes = result.trace.toolCalls.flatMap((call) => call.mutatedPaths || []);
|
||
assert.ok(writes.includes('DESIGN.md') && writes.includes('.impeccable/design.json'), 'both documentation artifacts must be written');
|
||
assert.deepEqual(writes.filter((file) => !['DESIGN.md', '.impeccable/design.json'].includes(file)), [], 'documentation must stay inside its write boundary');
|
||
}
|
||
} finally {
|
||
cleanupWorkspace(workspace);
|
||
}
|
||
});
|
||
}
|
||
}
|