Files
pikasTech-unidesk/scripts/code-queue-gh-auth-redaction-contract-test.ts
T
2026-05-23 04:22:42 +00:00

122 lines
4.7 KiB
TypeScript

import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { appendOutput, configureTaskOutput, taskFullOutput } from "../src/components/microservices/code-queue/src/task-output";
import { sanitizeTaskOutputText } from "../src/components/microservices/code-queue/src/output-redaction";
import type { JsonValue, QueueTask } from "../src/components/microservices/code-queue/src/types";
type JsonRecord = Record<string, unknown>;
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
}
function fixtureTask(): QueueTask {
const at = "2026-05-23T00:00:00.000Z";
return {
id: "codex_gh_auth_redaction_contract",
queueId: "default",
queueEnteredAt: at,
prompt: "redaction fixture",
basePrompt: "redaction fixture",
referenceTaskIds: [],
referenceInjection: null,
providerId: "D601",
cwd: "/workspace",
model: "gpt-5.5",
reasoningEffort: null,
executionMode: "default",
maxAttempts: 1,
status: "running",
createdAt: at,
updatedAt: at,
startedAt: at,
finishedAt: null,
readAt: null,
currentAttempt: 1,
currentMode: "initial",
codexThreadId: null,
activeTurnId: null,
finalResponse: "",
lastError: null,
lastJudge: null,
judgeFailCount: 0,
promptHistory: [],
output: [],
events: [],
attempts: [],
cancelRequested: false,
nextPrompt: null,
nextMode: null,
};
}
function assertNoTokenFragments(value: string, label: string): void {
assertCondition(!/\bgh[pousr]_[A-Za-z0-9_]{6,}\b/u.test(value), `${label} must redact gh token-like values`, value);
assertCondition(!/\bgithub_pat_[A-Za-z0-9_]{6,}\b/u.test(value), `${label} must redact GitHub PAT-like values`, value);
assertCondition(!/Token:\s*\S+/iu.test(value), `${label} must not expose raw gh auth token lines`, value);
assertCondition(!/Token scopes?:\s*\S+/iu.test(value), `${label} must not expose raw gh auth scope lines`, value);
}
export function runCodeQueueGhAuthRedactionContract(): JsonRecord {
const tmp = mkdtempSync(join(tmpdir(), "code-queue-gh-auth-redaction-"));
const task = fixtureTask();
let seq = 0;
try {
configureTaskOutput({
config: { maxInMemoryOutputRecords: 1000, outputArchiveDir: tmp },
allocateSeq: () => {
seq += 1;
return seq;
},
errorToJson: (error: unknown): JsonValue => error instanceof Error ? { message: error.message } : String(error),
logger: () => undefined,
markTaskDirty: () => undefined,
nowIso: () => "2026-05-23T00:00:01.000Z",
schedulePersistState: () => undefined,
});
const rawGhAuth = [
"github.com",
" \u2713 Logged in to github.com account example (keyring)",
" - Active account: true",
" - Git operations protocol: ssh",
" - Token: ghp_abcdef1234567890abcdef1234567890",
" - Token scopes: 'repo', 'read:org'",
"generic token=github_pat_abcdef1234567890abcdef1234567890",
].join("\n");
const sanitized = sanitizeTaskOutputText(rawGhAuth);
assertNoTokenFragments(sanitized, "direct sanitizer output");
assertCondition(sanitized.includes("[redacted gh auth status line]"), "sanitizer must redact gh auth status lines", sanitized);
assertCondition(sanitized.includes("bun scripts/cli.ts gh auth status"), "sanitizer must include UniDesk gh wrapper hint", sanitized);
appendOutput(task, "command", `${rawGhAuth}\n`, "item/commandExecution/outputDelta", "call-gh-auth", true);
const retained = JSON.stringify(task.output);
const archived = readFileSync(join(tmp, `${task.id}.jsonl`), "utf8");
const full = JSON.stringify(taskFullOutput(task));
assertNoTokenFragments(retained, "retained output");
assertNoTokenFragments(archived, "archived output");
assertNoTokenFragments(full, "full output replay");
assertCondition(full.includes("bun scripts/cli.ts gh auth status"), "full output replay must keep wrapper hint", full);
return {
ok: true,
checks: [
"raw gh auth status token and scope lines are redacted",
"token-like GitHub values are redacted before retained output persistence",
"output archive replay remains redacted",
"redacted output nudges runner toward bun scripts/cli.ts gh auth status",
],
};
} finally {
rmSync(tmp, { recursive: true, force: true });
}
}
try {
process.stdout.write(`${JSON.stringify(runCodeQueueGhAuthRedactionContract(), null, 2)}\n`);
} catch (error) {
process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
process.exit(1);
}