Keep guidance checks scoped to source and record chat regression fixes
This commit is contained in:
parent
ae7b66330d
commit
47dfb0eb32
|
|
@ -143,3 +143,21 @@ these fixes. Focused live checks additionally passed legacy Codex project reuse
|
|||
and repository handoff, legacy Claude plan revision/acceptance/handoff, and native
|
||||
Claude planning, Stop/reset/resume, fresh sessions, and multiple repositories.
|
||||
Final campaign results and broad verification are recorded below when complete.
|
||||
|
||||
The next full campaign (`34640536416`) reached 18/24 passing cells and identified
|
||||
three additional issues. Execution prompts now include the task's persisted plan
|
||||
and selected revision on both fresh and resumed runs; a plan handed off without a
|
||||
description therefore still reaches its executor. Native durable redaction keeps
|
||||
explicit literal/exact acceptance identifiers while continuing to redact actual
|
||||
credential-shaped values. Recovery for an older conversation generation or an
|
||||
already answered turn cannot block a reset or healthy idle chat. Regression tests
|
||||
also preserve recovery for current unanswered turns and unprepared failures.
|
||||
|
||||
Fixture assertions now accept concrete clarification requests without requiring a
|
||||
question mark. They check the approved revision and final execution output rather
|
||||
than rejecting an old draft quoted in plan revision history. Restart verification
|
||||
opens the canonical chat route after reconnecting, preserving the continuity and
|
||||
no-unsolicited-run checks. Stable inconsistent idle states fail promptly instead
|
||||
of waiting through a long timeout and hiding a product race behind a paid retry.
|
||||
Focused native Claude project reuse and multiple-repository handoffs, and legacy
|
||||
Claude multiple-repository handoff, passed on their first attempts with these fixes.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
|
@ -335,7 +336,14 @@ const SKIP_DIRS = new Set([
|
|||
"tmp",
|
||||
]);
|
||||
|
||||
const SKIP_PATH_PREFIXES = ["doc/logs/", "doc/plans/", "scripts/"];
|
||||
const SKIP_PATH_PREFIXES = [
|
||||
"doc/logs/",
|
||||
"doc/plans/",
|
||||
"scripts/",
|
||||
// Generated paid-run transcripts contain historical copies of instructions,
|
||||
// including escaped warning examples; they are not authored guidance.
|
||||
"tests/runner-e2e/results/",
|
||||
];
|
||||
|
||||
const SCAN_EXTENSIONS = new Set([
|
||||
".md",
|
||||
|
|
@ -355,7 +363,7 @@ function isTestFile(relPath: string): boolean {
|
|||
);
|
||||
}
|
||||
|
||||
function listGuidanceFiles(): string[] {
|
||||
function listGuidanceFiles(root = repoRoot): string[] {
|
||||
const found: string[] = [];
|
||||
|
||||
function walk(absDir: string, relDir: string): void {
|
||||
|
|
@ -364,6 +372,7 @@ function listGuidanceFiles(): string[] {
|
|||
const relPath = relDir ? `${relDir}/${entry.name}` : entry.name;
|
||||
if (entry.isDirectory()) {
|
||||
if (SKIP_DIRS.has(entry.name)) continue;
|
||||
if (SKIP_PATH_PREFIXES.some((prefix) => `${relPath}/`.startsWith(prefix))) continue;
|
||||
walk(path.join(absDir, entry.name), relPath);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -374,7 +383,7 @@ function listGuidanceFiles(): string[] {
|
|||
}
|
||||
}
|
||||
|
||||
walk(repoRoot, "");
|
||||
walk(root, "");
|
||||
return found;
|
||||
}
|
||||
|
||||
|
|
@ -466,6 +475,28 @@ function scanForBrokenExecForm(): string[] {
|
|||
}
|
||||
|
||||
describe("paperclipai CLI invocation safety", () => {
|
||||
it("excludes generated runner evidence while preserving authored runner guidance", () => {
|
||||
const root = mkdtempSync(path.join(os.tmpdir(), "paperclip-cli-guidance-"));
|
||||
const sourcePaths = [
|
||||
"doc/CLI.md",
|
||||
"tests/runner-e2e/README.md",
|
||||
"tests/runner-e2e/catalog.ts",
|
||||
];
|
||||
try {
|
||||
for (const relPath of [
|
||||
...sourcePaths,
|
||||
"tests/runner-e2e/results/campaign/attempt-1/snapshots/api-state.json",
|
||||
]) {
|
||||
const absPath = path.join(root, relPath);
|
||||
mkdirSync(path.dirname(absPath), { recursive: true });
|
||||
writeFileSync(absPath, "fixture");
|
||||
}
|
||||
expect(listGuidanceFiles(root).sort()).toEqual(sourcePaths.sort());
|
||||
} finally {
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("allows only exact-allowlist pnpm paperclipai commands on every guidance surface", () => {
|
||||
const offenders = scanForOffenders();
|
||||
expect(
|
||||
|
|
|
|||
Loading…
Reference in New Issue