Compare commits

...
Author SHA1 Message Date
suyx 693fa117b7 chore(WP7-07): 冻结第一版发布记录
Dada P0-A isolated Windows CI / validate-and-package (push) Successful in 17m46s
Dada P0-A isolated Windows CI / validate-and-package (pull_request) Successful in 17m49s
2026-08-04 23:32:51 +08:00
suyx 08f3cccae4 fix(WP7-07): 排除发布扫描器路径误报
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 23:20:40 +08:00
suyx a22b1f19e9 fix(WP7-07): 修正最终包浏览器门禁探测
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 23:15:36 +08:00
suyx 194b59d4a5 fix(WP7-07): 统一构建全部工作区依赖
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 23:07:01 +08:00
suyx 0f03b12f64 fix(WP7-07): 补齐便携包前置构建顺序
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 23:05:38 +08:00
suyx ad86b4ddcc feat(WP7-07): 增加最终发布冻结与泄漏扫描
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 23:03:11 +08:00
suyx 08e9c39e49 feat(WP7-06): 增加最终AC预冻结门禁
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 22:43:35 +08:00
suyx ffd1643848 chore(WP7-06): 合并候选环境验收基线
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
# Conflicts:
#	package.json
2026-08-04 22:39:26 +08:00
suyx 95ab0cb93b chore(WP7-06): 合并高德发布门禁基线
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
# Conflicts:
#	package.json
#	supervisor/Dada.Supervisor/OfflineCommandRouter.cs
2026-08-04 22:38:29 +08:00
suyx b2793a2392 chore(WP7-06): 合并Resend发布门禁基线
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
# Conflicts:
#	package.json
2026-08-04 22:37:15 +08:00
suyx a7140e99e1 chore(WP7-06): 合并WP4视觉验收与资源迁移修复
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 22:36:08 +08:00
suyx 76b4f93709 chore(WP7-06): 合并WP6整合验收基线
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 22:35:43 +08:00
suyx bc6fa3d517 fix(WP6): 稳定整合门禁的资源路径与测试超时
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 19:07:55 +08:00
suyx 5631ef80f9 fix(wp7-02): route stable Gemini through secure broker
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:55:32 +08:00
suyx 6bd5364d95 test(wp7-02): require stable model secure routing
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:53:59 +08:00
suyx 604c524298 fix(wp7-02): review replacement model evidence
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:48:28 +08:00
suyx 898679dd59 test(wp7-02): require two-model evidence review
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:47:49 +08:00
suyx 79ef17b7f0 fix(wp7-02): replace preview Gemini routes
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:46:01 +08:00
suyx 0328aa8ef5 test(wp7-02): require stable Gemini replacement set
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:45:04 +08:00
suyx a54efb146a feat(wp7-02): support Gemini chat image relay
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:38:33 +08:00
suyx 6e5313e283 test(wp7-02): require Gemini chat image relay
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:37:37 +08:00
suyx 03500bf47e feat(wp7-02): map provider image model ids
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:30:31 +08:00
suyx e3c21b63a5 test(wp7-02): require provider image model mapping
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:29:57 +08:00
suyx f4fabb66e5 fix(WP4-07): 兼容迁移后的字体资源路径
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:29:17 +08:00
suyx 4aaba9f2bb feat(wp7-02): support Gemini image interactions
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:28:44 +08:00
suyx d7a24a5ecb test(wp7-02): require Gemini interactions image contract
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:27:55 +08:00
suyx 4a0fb1bfae fix(WP4-07): 支持新的贴纸资源根目录
Dada P0-A isolated Windows CI / validate-and-package (push) Canceled after 0s
2026-08-04 18:22:28 +08:00
suyx f931c04853 fix(wp7-02): classify Gemini response text safely
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m33s
2026-08-04 18:04:40 +08:00
suyx 3093c4470a test(wp7-02): require safe Gemini text classification
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 5m50s
2026-08-04 18:03:52 +08:00
suyx 75a589dad8 fix(wp7-02): restore native Gemini image routing
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m45s
2026-08-04 17:58:33 +08:00
suyx 534c82678a test(wp7-02): require native Gemini gateway contract
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m48s
2026-08-04 17:57:52 +08:00
suyx 05949230ca fix(wp7-02): preserve independent mixed model evidence
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m11s
2026-08-04 17:35:38 +08:00
suyx 382d50058c test(wp7-02): require independent mixed evidence review
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m8s
2026-08-04 17:33:51 +08:00
suyx f7bed92e61 test: cover Amap production security gates
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m43s
2026-08-04 17:31:25 +08:00
suyx d03b491d2f fix: harden controlled Amap probe
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m46s
2026-08-04 17:28:24 +08:00
suyx 63de0917a0 fix(wp7-02): use GPT image edit route for references
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m53s
2026-08-04 17:24:22 +08:00
suyx fa925bfe12 test(wp7-02): require GPT reference edit route
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m55s
2026-08-04 17:23:34 +08:00
suyx 0201c3e896 fix(wp7-02): retry one transient image timeout
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m38s
2026-08-04 17:22:26 +08:00
suyx 8337906dd2 test(wp7-02): require bounded timeout retry evidence
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m25s
2026-08-04 17:21:10 +08:00
suyx ae725a2d01 fix(wp7-02): normalize generated image dimensions
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m17s
2026-08-04 17:19:41 +08:00
suyx 9d6f4ac24b test(wp7-02): require exact image normalization
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m11s
2026-08-04 17:15:25 +08:00
suyx 0938997327 fix(wp7-02): update Gemini routes to v1
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m12s
2026-08-04 17:09:58 +08:00
suyx 8c349fb56c fix: wire production Amap adapter
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m47s
2026-08-04 17:09:04 +08:00
suyx 55646ba1b4 feat: build sanitized WP7-05 coverage evidence
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m49s
2026-08-04 17:08:44 +08:00
suyx b8e30ab0b2 test(wp7-02): require current Gemini v1 routes
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m51s
2026-08-04 17:08:25 +08:00
suyx 66295287ce fix(wp7-02): use current Gemini image response contract
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m53s
2026-08-04 17:05:59 +08:00
suyx 0ed7b3f0ce test(wp7-02): require current Gemini image contract
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 11m33s
2026-08-04 17:05:23 +08:00
suyx 8abf1397a6 test: require WP7-05 state evidence
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 3m17s
2026-08-04 17:02:52 +08:00
suyx e0e101ef28 fix: align WP7-05 candidate record schema
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m30s
2026-08-04 16:59:31 +08:00
suyx 33f87f8db3 test: scaffold WP7-05 candidate UI gate
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m18s
2026-08-04 16:58:15 +08:00
suyx 84a845136e test(wp7-02): enforce exact image dimensions
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 51s
2026-08-04 16:28:31 +08:00
suyx 470d243b5b feat: execute WP7-02 independent model matrices
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 54s
2026-08-04 16:01:31 +08:00
suyx a7772a7e92 test: harden WP7-04 release gate evidence
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 3m1s
2026-08-04 15:49:25 +08:00
suyx c2f89453a2 feat: add secure WP7-02 external executor
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 48s
2026-08-04 15:46:38 +08:00
suyx 2bfb5f2953 test: prove Amap monthly egress hard stop
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 50s
2026-08-04 15:39:46 +08:00
suyx 597f4647ef test: define WP7-02 controlled executor contract
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m51s
2026-08-04 15:38:29 +08:00
suyx 68a1991255 test: configure WP7-02 OneAPI model routes
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 3m5s
2026-08-04 15:29:26 +08:00
suyx 4ec8327f5e feat: add controlled Amap credential probe
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m0s
2026-08-04 14:52:23 +08:00
suyx 28e6f66a1d test: add WP7-02 controlled real contract gate
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 1m36s
2026-08-04 14:06:52 +08:00
suyx d474768a2b test: record WP7-04 Amap external blocker
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 57s
2026-08-04 13:35:10 +08:00
54 changed files with 4256 additions and 71 deletions
+29
View File
@@ -0,0 +1,29 @@
{
"appVersion": "0.0.0",
"browsers": [
{
"brand": "Google Chrome",
"fullVersion": "150.0.7871.187"
},
{
"brand": "Microsoft Edge",
"fullVersion": "151.0.4129.59"
}
],
"buildCommit": "08f3cccae4a1e75e2f2292eef14611313523916d",
"deferredExternalTasks": [
"TASK-WP7-03",
"TASK-WP7-04"
],
"finalRelease": true,
"fixedPort": 43121,
"frozenFromCommit": "08e9c39e49d68f8642d5acfe22b0fdb40a3a08fa",
"recordedAt": "2026-08-04T15:20:54.271Z",
"releaseStatus": "first_version_internal",
"schemaVersion": "1.0",
"windows": {
"arch": "x64",
"build": "26200.8875",
"displayVersion": "25H2"
}
}
+150 -1
View File
@@ -1,5 +1,31 @@
import { request as httpsRequest } from "node:https";
const amapHostname = "restapi.amap.com" as const;
const amapMaxResponseBytes = 65_536;
const amapTimeoutMs = 15_000;
export interface AmapHttpRequest {
allowRedirects: false;
hostname: typeof amapHostname;
maxResponseBytes: number;
method: "GET";
path: string;
protocol: "https:";
rejectUnauthorized: true;
timeoutMs: number;
}
type AmapRequester = (request: AmapHttpRequest) => Promise<unknown>;
export class AmapAdapterError extends Error {
constructor(readonly code: "amap_adapter_disposed" | "amap_invalid_request" | "amap_invalid_response" | "amap_provider_rejected" | "amap_provider_unavailable" | "amap_redirect_rejected" | "amap_request_timeout" | "amap_response_too_large") {
super(code);
}
}
export interface AmapAdapter {
reverseGeocode(coordinates: { latitude: number; longitude: number }): Promise<{ formattedValue: string; serviceMode: "mock" }>;
dispose?(): void;
reverseGeocode(coordinates: { latitude: number; longitude: number }): Promise<{ formattedValue: string; serviceMode: "mock" | "real" }>;
}
export class MockAmapAdapter implements AmapAdapter {
@@ -13,3 +39,126 @@ export class MockAmapAdapter implements AmapAdapter {
};
}
}
function requestAmapJson(input: AmapHttpRequest) {
return new Promise<unknown>((resolve, reject) => {
if (input.protocol !== "https:" || input.hostname !== amapHostname || input.allowRedirects || !input.rejectUnauthorized) {
reject(new AmapAdapterError("amap_invalid_request"));
return;
}
let settled = false;
const finish = (callback: () => void) => {
if (settled) return;
settled = true;
callback();
};
const request = httpsRequest({
headers: { Accept: "application/json" },
hostname: input.hostname,
method: input.method,
path: input.path,
port: 443,
protocol: input.protocol,
rejectUnauthorized: input.rejectUnauthorized,
servername: input.hostname,
}, (response) => {
const statusCode = response.statusCode ?? 0;
if (statusCode >= 300 && statusCode < 400) {
response.resume();
finish(() => reject(new AmapAdapterError("amap_redirect_rejected")));
return;
}
if (statusCode !== 200) {
response.resume();
finish(() => reject(new AmapAdapterError("amap_provider_unavailable")));
return;
}
const declaredLength = Number(response.headers["content-length"] ?? 0);
if (Number.isFinite(declaredLength) && declaredLength > input.maxResponseBytes) {
response.destroy();
finish(() => reject(new AmapAdapterError("amap_response_too_large")));
return;
}
const chunks: Buffer[] = [];
let receivedBytes = 0;
response.on("data", (chunk: Buffer | string) => {
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
receivedBytes += bytes.length;
if (receivedBytes > input.maxResponseBytes) {
response.destroy();
finish(() => reject(new AmapAdapterError("amap_response_too_large")));
return;
}
chunks.push(bytes);
});
response.on("end", () => {
finish(() => {
try {
resolve(JSON.parse(Buffer.concat(chunks).toString("utf8")));
} catch {
reject(new AmapAdapterError("amap_invalid_response"));
} finally {
for (const chunk of chunks) chunk.fill(0);
chunks.length = 0;
}
});
});
});
request.setTimeout(input.timeoutMs, () => request.destroy(new AmapAdapterError("amap_request_timeout")));
request.on("error", (error) => finish(() => reject(error instanceof AmapAdapterError ? error : new AmapAdapterError("amap_provider_unavailable"))));
request.end();
});
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
export class RealAmapAdapter implements AmapAdapter {
private readonly credential: Buffer;
private readonly requester: AmapRequester;
private disposed = false;
constructor(value: string, options: { request?: AmapRequester } = {}) {
if (!value.trim()) throw new AmapAdapterError("amap_invalid_request");
this.credential = Buffer.from(value, "utf8");
this.requester = options.request ?? requestAmapJson;
}
async reverseGeocode(coordinates: { latitude: number; longitude: number }) {
if (this.disposed) throw new AmapAdapterError("amap_adapter_disposed");
if (!Number.isFinite(coordinates.latitude) || coordinates.latitude < -90 || coordinates.latitude > 90
|| !Number.isFinite(coordinates.longitude) || coordinates.longitude < -180 || coordinates.longitude > 180) {
throw new AmapAdapterError("amap_invalid_request");
}
const query = new URLSearchParams({
extensions: "base",
key: this.credential.toString("utf8"),
location: `${coordinates.longitude},${coordinates.latitude}`,
});
const response = await this.requester({
allowRedirects: false,
hostname: amapHostname,
maxResponseBytes: amapMaxResponseBytes,
method: "GET",
path: `/v3/geocode/regeo?${query.toString()}`,
protocol: "https:",
rejectUnauthorized: true,
timeoutMs: amapTimeoutMs,
});
if (!isRecord(response) || response.status !== "1" || !isRecord(response.regeocode)) {
throw new AmapAdapterError("amap_provider_rejected");
}
const formattedValue = typeof response.regeocode.formatted_address === "string"
? response.regeocode.formatted_address.trim()
: "";
if (!formattedValue || formattedValue.length > 200) throw new AmapAdapterError("amap_invalid_response");
return { formattedValue, serviceMode: "real" as const };
}
dispose() {
if (this.disposed) return;
this.disposed = true;
this.credential.fill(0);
}
}
+7 -2
View File
@@ -17,7 +17,7 @@ import { readSecureConfigCandidate } from "./secure-config.js";
import { StructuredJsonlLogger } from "./structured-log.js";
import { attachApiSupervisorControl, initializeApiCredentialClients, receiveApiCredentials } from "./supervisor-channel.js";
import { ModelConfigurationService } from "./model-configuration.js";
import { MockAmapAdapter } from "./amap-adapter.js";
import { MockAmapAdapter, type AmapAdapter } from "./amap-adapter.js";
import { StickerReleaseService } from "./sticker-releases.js";
import { createAdminDiagnosticsProvider, createAdminServicesStorageProvider } from "./admin-state.js";
@@ -30,10 +30,12 @@ let latestExports: LatestExportService | undefined;
let models: ModelConfigurationService | undefined;
let recentAssets: RecentAssetService | undefined;
let stickers: StickerReleaseService | undefined;
let amap: AmapAdapter = new MockAmapAdapter();
const instanceConfigPath = process.env.DADA_INSTANCE_CONFIG_PATH ?? defaultInstanceConfigPath();
if (credentialChannelEnabled) {
const clients = initializeApiCredentialClients(await receiveApiCredentials());
try {
amap = clients.amap;
const derivePepper = (purpose: string) => createHmac("sha256", clients.adminAllowlistPepper)
.update(`Dada/P0A/${purpose}/v1`, "utf8")
.digest();
@@ -57,6 +59,8 @@ if (credentialChannelEnabled) {
recentAssets = new RecentAssetService({ database: registration.database });
registration.applySecureConfig(readSecureConfigCandidate(instanceConfigPath));
} catch (error) {
amap.dispose?.();
amap = new MockAmapAdapter();
stickers?.close();
stickers = undefined;
latestExports?.close();
@@ -92,7 +96,7 @@ const adminDiagnostics = adminServicesStorage
const app = await createApp({
...(adminServicesStorage ? { adminServicesStorage } : {}),
...(adminDiagnostics ? { adminDiagnostics } : {}),
amap: new MockAmapAdapter(),
amap,
...(browserSupportRelease ? { browserSupportRelease } : {}),
...(credits ? { credits } : {}),
...(latestExports ? { latestExports } : {}),
@@ -115,6 +119,7 @@ if (controlPipeIndex >= 0) {
if (!controlPipe) throw new Error("Supervisor control pipe name is required.");
const control = attachApiSupervisorControl(controlPipe, async () => {
await app.close();
amap.dispose?.();
latestExports?.close();
credits?.close();
projects?.close();
+11 -4
View File
@@ -1,5 +1,7 @@
import { createConnection } from "node:net";
import { RealAmapAdapter } from "./amap-adapter.js";
const API_CREDENTIALS = ["Dada/P0A/api/resend", "Dada/P0A/api/amap", "Dada/P0A/admin/pepper"] as const;
export async function receiveApiCredentials(input: NodeJS.ReadableStream = process.stdin) {
@@ -26,10 +28,15 @@ export async function receiveApiCredentials(input: NodeJS.ReadableStream = proce
export function initializeApiCredentialClients(credentials: Record<(typeof API_CREDENTIALS)[number], string>) {
const configured = API_CREDENTIALS.every((name) => credentials[name].length > 0);
const adminPepperValue = credentials["Dada/P0A/admin/pepper"];
for (const name of API_CREDENTIALS) credentials[name] = "";
if (!configured) throw new Error("API credential client initialization failed.");
return { adminAllowlistPepper: Buffer.from(adminPepperValue, "utf8") };
try {
if (!configured) throw new Error("API credential client initialization failed.");
return {
adminAllowlistPepper: Buffer.from(credentials["Dada/P0A/admin/pepper"], "utf8"),
amap: new RealAmapAdapter(credentials["Dada/P0A/api/amap"]),
};
} finally {
for (const name of API_CREDENTIALS) credentials[name] = "";
}
}
export function attachApiSupervisorControl(pipeName: string, shutdown: () => Promise<void>) {
+1 -1
View File
@@ -922,7 +922,7 @@ export type ReverseGeocodeRequest = {
export type ReverseGeocodeResponse = {
"formatted_value": string;
"service_mode": "mock";
"service_mode": "mock" | "real";
"status": "resolved";
};
+2 -1
View File
@@ -9,7 +9,8 @@
},
"dependencies": {
"better-sqlite3": "13.0.1",
"drizzle-orm": "0.45.2"
"drizzle-orm": "0.45.2",
"sharp": "0.35.3"
},
"devDependencies": {
"@types/better-sqlite3": "7.6.13",
+3 -1
View File
@@ -1,4 +1,5 @@
import type { GenerationAdapterRequest, NormalizedGenerationOutput } from "./ai-adapter-contract.js";
import { normalizeImageOutputToRatio } from "./image-output-normalizer.mjs";
import {
AdapterContractError, type AdapterStartResult, type AdapterTransport, balanceSignalFromResponse,
classifyAdapterError, dimensionsForRatio, mockPngBytes, validateAdapterRequest, validateMockContract,
@@ -41,7 +42,8 @@ export class GeminiFlashAdapter implements ModelAdapter {
const classified = this.classifyError("error" in response ? response.error : undefined, (request.configSnapshot.error_mapping_profile as Record<string, string> | undefined) ?? {});
return { ...classified, status: "failed" };
}
return { outputs: [this.normalizeOutput(response)], status: "completed" };
const output = this.normalizeOutput(response);
return { outputs: [await normalizeImageOutputToRatio({ ...output, ratio: request.ratio })], status: "completed" };
} catch (error) {
const classified = error instanceof AdapterContractError
? { category: "gateway_contract_invalid" as const, sourceCategory: error.sourceCategory }
+6 -4
View File
@@ -1,4 +1,5 @@
import type { GenerationAdapterRequest, NormalizedGenerationOutput } from "./ai-adapter-contract.js";
import { normalizeImageOutputToRatio } from "./image-output-normalizer.mjs";
import {
AdapterContractError, type AdapterStartResult, type AdapterTransport, balanceSignalFromResponse,
classifyAdapterError, dimensionsForRatio, mockPngBytes, validateAdapterRequest, validateMockContract,
@@ -37,7 +38,7 @@ export class GeminiProAdapter implements ModelAdapter {
try {
validateAdapterRequest(request, this.modelId);
const response = await this.transport.start({ operation: "start", modelId: this.modelId, prompt: request.prompt, ratio: request.ratio, referenceAssetIds: request.referenceAssetIds });
return this.interpret(response, request.configSnapshot.error_mapping_profile as Record<string, string> ?? {});
return await this.interpret(response, request.configSnapshot.error_mapping_profile as Record<string, string> ?? {}, request.ratio);
} catch (error) {
const classified = error instanceof AdapterContractError
? { category: "gateway_contract_invalid" as const, sourceCategory: error.sourceCategory }
@@ -49,7 +50,7 @@ export class GeminiProAdapter implements ModelAdapter {
async poll(upstreamJobReference: string): Promise<AdapterStartResult> {
try {
const response = await this.transport.poll({ operation: "poll", modelId: this.modelId, upstreamJobReference });
return this.interpret(response, {});
return await this.interpret(response, {});
} catch (error) {
const classified = error instanceof AdapterContractError
? { category: "gateway_contract_invalid" as const, sourceCategory: error.sourceCategory }
@@ -58,7 +59,7 @@ export class GeminiProAdapter implements ModelAdapter {
}
}
private interpret(response: unknown, mappingProfile: Readonly<Record<string, string>>): AdapterStartResult {
private async interpret(response: unknown, mappingProfile: Readonly<Record<string, string>>, ratio?: GenerationAdapterRequest["ratio"]): Promise<AdapterStartResult> {
if (!response || typeof response !== "object" || !("operation" in response) || !response.operation || typeof response.operation !== "object") {
return { category: "gateway_contract_invalid", sourceCategory: "response_shape_invalid", status: "failed" };
}
@@ -72,7 +73,8 @@ export class GeminiProAdapter implements ModelAdapter {
return reference ? { status: "pending", upstreamJobReference: reference } : { category: "gateway_contract_invalid", sourceCategory: "upstream_reference_missing", status: "failed" };
}
try {
return { outputs: [this.normalizeOutput("response" in operation ? operation.response : undefined)], status: "completed" };
const output = this.normalizeOutput("response" in operation ? operation.response : undefined);
return { outputs: [ratio ? await normalizeImageOutputToRatio({ ...output, ratio }) : output], status: "completed" };
} catch (error) {
return { category: "gateway_contract_invalid", sourceCategory: error instanceof AdapterContractError ? error.sourceCategory : "response_shape_invalid", status: "failed" };
}
+3 -1
View File
@@ -1,4 +1,5 @@
import type { GenerationAdapterRequest, NormalizedGenerationOutput } from "./ai-adapter-contract.js";
import { normalizeImageOutputToRatio } from "./image-output-normalizer.mjs";
import {
AdapterContractError, type AdapterStartResult, type AdapterTransport, balanceSignalFromResponse,
classifyAdapterError, dimensionsForRatio, mockPngBytes, validateAdapterRequest, validateMockContract,
@@ -41,7 +42,8 @@ export class GptImageAdapter implements ModelAdapter {
const classified = this.classifyError("error" in response ? response.error : undefined, (request.configSnapshot.error_mapping_profile as Record<string, string> | undefined) ?? {});
return { ...classified, status: "failed" };
}
return { outputs: [this.normalizeOutput(response)], status: "completed" };
const output = this.normalizeOutput(response);
return { outputs: [await normalizeImageOutputToRatio({ ...output, ratio: request.ratio })], status: "completed" };
} catch (error) {
const classified = error instanceof AdapterContractError
? { category: "gateway_contract_invalid" as const, sourceCategory: error.sourceCategory }
@@ -0,0 +1,74 @@
import sharp from "sharp";
const productDimensions = Object.freeze({
"3:4": Object.freeze({ pixelHeight: 1440, pixelWidth: 1080 }),
"1:1": Object.freeze({ pixelHeight: 1080, pixelWidth: 1080 }),
"4:3": Object.freeze({ pixelHeight: 1080, pixelWidth: 1440 }),
"9:16": Object.freeze({ pixelHeight: 1920, pixelWidth: 1080 }),
});
const gptImageRequestSizes = Object.freeze({
"3:4": "1056x1408",
"1:1": "1088x1088",
"4:3": "1408x1056",
"9:16": "1008x1792",
});
const allowedMimeTypes = new Set(["image/jpeg", "image/png", "image/webp"]);
const maximumInputBytes = 20 * 1024 * 1024;
function assertRatio(ratio) {
if (!(ratio in productDimensions)) throw new Error("image_output_ratio_unsupported");
return ratio;
}
export function productDimensionsForRatio(ratio) {
return { ...productDimensions[assertRatio(ratio)] };
}
export function gptImageRequestSizeForRatio(ratio) {
return gptImageRequestSizes[assertRatio(ratio)];
}
export async function normalizeImageOutputToRatio(input) {
const ratio = assertRatio(input?.ratio);
if (!Buffer.isBuffer(input?.bytes) || input.bytes.length === 0 || input.bytes.length > maximumInputBytes
|| !allowedMimeTypes.has(input?.mimeType)) {
throw new Error("image_output_media_invalid");
}
const target = productDimensions[ratio];
if (input.pixelWidth === target.pixelWidth && input.pixelHeight === target.pixelHeight) {
return {
bytes: Buffer.from(input.bytes),
mimeType: input.mimeType,
normalized: false,
...target,
upstreamPixelHeight: input.pixelHeight,
upstreamPixelWidth: input.pixelWidth,
};
}
const image = sharp(input.bytes, { failOn: "error", limitInputPixels: 40_000_000 });
const metadata = await image.metadata();
if (!metadata.width || !metadata.height) throw new Error("image_output_dimensions_missing");
const requestedRatio = target.pixelWidth / target.pixelHeight;
const upstreamRatio = metadata.width / metadata.height;
if (Math.abs(upstreamRatio - requestedRatio) / requestedRatio > 0.02) {
throw new Error("image_output_aspect_ratio_mismatch");
}
const { data, info } = await image
.resize(target.pixelWidth, target.pixelHeight, { fit: "fill", kernel: sharp.kernel.lanczos3 })
.png({ compressionLevel: 9 })
.toBuffer({ resolveWithObject: true });
if (info.width !== target.pixelWidth || info.height !== target.pixelHeight || info.format !== "png") {
throw new Error("image_output_normalization_failed");
}
return {
bytes: data,
mimeType: "image/png",
normalized: true,
...target,
upstreamPixelHeight: metadata.height,
upstreamPixelWidth: metadata.width,
};
}
+1
View File
@@ -1,6 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2024"],
+29
View File
@@ -0,0 +1,29 @@
{
"config_set_version": 8,
"gateway_account_ref": "oneapi-intelligrow-test",
"models": [
{
"config_version": 7,
"gateway_account_ref": "oneapi-intelligrow-test",
"model_id": "gemini-3.1-flash-image",
"route_profile": {
"endpoint": "https://oneapi.intelligrow.cn/v1/chat/completions",
"mode": "sync",
"protocol_version": "gemini-openai-chat-v1",
"provider_model_id": "gemini-3.1-flash-image"
}
},
{
"config_version": 2,
"gateway_account_ref": "oneapi-intelligrow-test",
"model_id": "gpt-image-2",
"route_profile": {
"endpoint": "https://oneapi.intelligrow.cn/v1/images/generations",
"mode": "sync",
"protocol_version": "openai-images-v1",
"reference_endpoint": "https://oneapi.intelligrow.cn/v1/images/edits"
}
}
],
"schema_version": "1.0"
}
+14 -4
View File
@@ -5621,10 +5621,20 @@
"type": "string"
},
"service_mode": {
"enum": [
"mock"
],
"type": "string"
"anyOf": [
{
"enum": [
"mock"
],
"type": "string"
},
{
"enum": [
"real"
],
"type": "string"
}
]
},
"status": {
"enum": [
+11 -1
View File
@@ -107,8 +107,18 @@
"test:wp6-05": "pnpm exec vitest run tests/api/wp6-05-state.test.ts && pnpm exec playwright test tests/e2e/wp6-05-state.spec.ts --config playwright.config.ts",
"test:wp7-01": "node scripts/run-wp7-01-validation.mjs",
"review:wp7-01": "node scripts/record-wp7-01-manual-review.mjs",
"test:wp7-02": "node scripts/run-wp7-02-validation.mjs",
"test:wp7-02:controlled": "node scripts/run-wp7-02-validation.mjs --controlled-real",
"review:wp7-02": "node scripts/record-wp7-02-manual-review.mjs",
"test:wp7-03": "node scripts/run-wp7-03-validation.mjs --phase green",
"test:wp7-03:red": "node scripts/run-wp7-03-validation.mjs --phase red"
"test:wp7-03:red": "node scripts/run-wp7-03-validation.mjs --phase red",
"test:wp7-04": "node scripts/run-wp7-04-validation.mjs",
"test:wp7-05": "node scripts/run-wp7-05-validation.mjs",
"test:wp7-05:unit": "node --test tests/package/wp7-05-ui-gate.test.mjs tests/package/wp7-05-coverage.test.mjs",
"test:wp7-06": "node scripts/run-wp7-06-validation.mjs",
"test:wp7-06:unit": "node --test tests/package/wp7-06-prefreeze.test.mjs",
"test:wp7-07": "node scripts/run-wp7-07-validation.mjs",
"test:wp7-07:unit": "node --test tests/package/wp7-07-final-release.test.mjs"
},
"devDependencies": {
"@playwright/test": "1.62.0",
+7 -1
View File
@@ -228,7 +228,13 @@ function readCsv(tracker: SourceTracker, path: string, label: string): CsvRow[]
function itemDirectoryFor(collection: CollectionConfig, catalogPath: string, row: CsvRow): { directory: string; metadataPath: string } {
if (collection.id === "font_panel") {
const resourceDir = requireString(row.resource_dir, "font resource_dir");
const configuredResourceDir = requireString(row.resource_dir, "font resource_dir");
const normalizedResourceDir = configuredResourceDir.replaceAll("\\", "/");
const relocationMarker = "/resources/font_packages/";
const markerIndex = normalizedResourceDir.lastIndexOf(relocationMarker);
const resourceDir = isAbsolute(configuredResourceDir) && !inside(configuredResourceDir, collection.root.path) && markerIndex >= 0
? relativeReference(normalizedResourceDir.slice(markerIndex + 1), "font resource_dir relocation")
: configuredResourceDir;
const directory = resolveSourcePath(resourceDir, collection.root.path, collection.root.path, "font resource_dir");
return { directory, metadataPath: resolveSourcePath("metadata.json", directory, collection.root.path, "font metadata") };
}
+1 -1
View File
@@ -7,7 +7,7 @@ export const ReverseGeocodeRequestSchema = Type.Object({
export const ReverseGeocodeResponseSchema = Type.Object({
formatted_value: Type.String({ maxLength: 200, minLength: 1 }),
service_mode: Type.Literal("mock"),
service_mode: Type.Union([Type.Literal("mock"), Type.Literal("real")]),
status: Type.Literal("resolved"),
}, { additionalProperties: false, $id: "ReverseGeocodeResponse" });
+3
View File
@@ -133,6 +133,9 @@ importers:
drizzle-orm:
specifier: 0.45.2
version: 0.45.2(@types/better-sqlite3@7.6.13)(better-sqlite3@13.0.1)
sharp:
specifier: 0.35.3
version: 0.35.3(@types/node@24.13.3)
devDependencies:
'@types/better-sqlite3':
specifier: 7.6.13
+25 -5
View File
@@ -1,7 +1,7 @@
import { createHash } from "node:crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { homedir } from "node:os";
import { join, resolve } from "node:path";
import { dirname, join, resolve } from "node:path";
import { compileAssetArchive, compileStaticStickerCatalog } from "../packages/asset-compiler/dist/index.js";
import { createP0aColorCardRenderPlans } from "../packages/asset-renderer/dist/index.js";
@@ -18,18 +18,38 @@ import {
const runDirectory = resolve(process.env.DADA_WP5_03_RUN_DIRECTORY ?? "artifacts/tdd/wp5-03-local");
const whiteDirectory = resolve(process.env.DADA_WP5_03_WHITE_EVIDENCE_DIR ?? join(runDirectory, "cases", "TDD-WP5-WHITE-001-p0a-allowlist"));
const colorDirectory = resolve(process.env.DADA_WP5_03_COLOR_EVIDENCE_DIR ?? join(runDirectory, "cases", "TDD-WP5-COL-001-four-layouts"));
const handoffManifest = resolve(process.env.DADA_COMPLEX_ASSET_MANIFEST ?? join(homedir(), "Desktop", "sticker_web_handoff", "sticker_web_catalog_manifest.json"));
const stickerRoot = resolve(process.env.DADA_STATIC_STICKER_ROOT ?? join(homedir(), "Desktop", "贴纸素材"));
const replicationRoot = resolve(process.env.DADA_REPLICATION_ASSET_ROOT ?? join(homedir(), "Desktop", "sticker_web_replication_assets"));
const handoffManifest = resolve(process.env.DADA_COMPLEX_ASSET_MANIFEST ?? join(replicationRoot, "sticker_web_handoff", "sticker_web_catalog_manifest.json"));
const stickerRoot = resolve(process.env.DADA_STATIC_STICKER_ROOT ?? join(replicationRoot, "sticker_normal"));
if (!existsSync(handoffManifest)) throw new Error("normalized complex asset handoff is unavailable");
if (!existsSync(stickerRoot)) throw new Error("static sticker source is unavailable");
const complexDirectory = resolve(runDirectory, "inputs", "complex");
const staticDirectory = resolve(runDirectory, "inputs", "static");
const normalizedHandoffDirectory = resolve(runDirectory, "inputs", "normalized-handoff");
mkdirSync(whiteDirectory, { recursive: true });
mkdirSync(colorDirectory, { recursive: true });
const sourceHandoff = JSON.parse(readFileSync(handoffManifest, "utf8"));
const normalizedHandoff = {
...sourceHandoff,
web_handoff: "STICKER_WEB_REPLICATION_HANDOFF.md",
validation: "sticker_archive_validation_20260722.json",
collections: sourceHandoff.collections
.filter((collection) => collection.id !== "normal_stickers")
.map((collection) => ({
...collection,
root: resolve(dirname(handoffManifest), collection.root),
})),
};
const normalizedHandoffPath = resolve(normalizedHandoffDirectory, "sticker_web_catalog_manifest.normalized.json");
mkdirSync(normalizedHandoffDirectory, { recursive: true });
copyFileSync(resolve(dirname(handoffManifest), sourceHandoff.web_handoff), resolve(normalizedHandoffDirectory, normalizedHandoff.web_handoff));
copyFileSync(resolve(dirname(handoffManifest), sourceHandoff.validation), resolve(normalizedHandoffDirectory, normalizedHandoff.validation));
writeFileSync(normalizedHandoffPath, `${JSON.stringify(normalizedHandoff, null, 2)}\n`);
const complex = compileAssetArchive({
manifestPath: handoffManifest,
manifestPath: normalizedHandoffPath,
outputDirectory: complexDirectory,
releaseVersion: P0A_COMPLEX_RELEASE_VERSION,
});
+1
View File
@@ -44,6 +44,7 @@ export const frozenPackages = {
dependencies: {
"better-sqlite3": "13.0.1",
"drizzle-orm": "0.45.2",
sharp: "0.35.3",
},
devDependencies: {
typescript: "7.0.2",
+46 -14
View File
@@ -165,7 +165,7 @@ function copyApplication(source, destination, runtimeDependencies) {
function buildArtifacts(stagingRoot) {
debug("build workspace artifacts");
run("pnpm", ["--filter", "@dada/shared-contracts", "build"]);
run("pnpm", ["build:workspace-packages"]);
run("pnpm", ["--filter", "@dada/web", "build"]);
run("pnpm", ["--filter", "@dada/api", "build"]);
run("pnpm", ["--filter", "@dada/worker", "build"]);
@@ -208,7 +208,7 @@ async function waitForHealth(child) {
throw new Error("Packaged API did not become healthy on fixed port 43121.", { cause: lastError });
}
async function verifyExtractedPackage(zipPath, packageName) {
export async function verifyExtractedPackage(zipPath, packageName, expectedSupport) {
const extractRoot = mkdtempSync(join(tmpdir(), "dada-wp0-09-"));
try {
const escapedZip = zipPath.replaceAll("'", "''");
@@ -235,21 +235,37 @@ async function verifyExtractedPackage(zipPath, packageName) {
});
try {
const health = await waitForHealth(api);
const brands = [
{ brand: "Not_A Brand", version: "99" },
{ brand: "Chromium", version: String(expectedSupport.major) },
{ brand: expectedSupport.brand, version: String(expectedSupport.major) },
];
const fullVersionList = [
{ brand: "Not_A Brand", version: "99.0.0.0" },
{ brand: "Chromium", version: expectedSupport.fullVersion },
{ brand: expectedSupport.brand, version: expectedSupport.fullVersion },
];
const serializeBrands = (values) => values.map(({ brand, version }) => `"${brand}";v="${version}"`).join(", ");
const releaseGate = await fetch(`http://127.0.0.1:${fixedPort}/api/v1/support/check`, {
body: JSON.stringify({
brands: [{ brand: "Google Chrome", version: "150" }],
full_version_list: [{ brand: "Google Chrome", version: "150.0.0.0" }],
brands,
full_version_list: fullVersionList,
platform: "Windows",
}),
headers: {
"content-type": "application/json",
"sec-ch-ua": '"Google Chrome";v="150"',
"sec-ch-ua-full-version-list": '"Google Chrome";v="150.0.0.0"',
host: `127.0.0.1:${fixedPort}`,
origin: `http://127.0.0.1:${fixedPort}`,
"sec-ch-ua": serializeBrands(brands),
"sec-ch-ua-full-version-list": serializeBrands(fullVersionList),
"sec-ch-ua-platform": '"Windows"',
},
method: "POST",
});
if (releaseGate.status !== 426) throw new Error(`Candidate RELEASE.json unexpectedly passed with ${releaseGate.status}.`);
if (releaseGate.status !== expectedSupport.statusCode) {
const responseBody = await releaseGate.text();
throw new Error(`Packaged RELEASE.json support gate returned ${releaseGate.status}; expected ${expectedSupport.statusCode}: ${responseBody}`);
}
return {
api: { executable: "runtime/node.exe", health, pid: api.pid, release_gate: { status_code: releaseGate.status }, status: "passed" },
native,
@@ -291,7 +307,7 @@ function scanPackage(packageDirectory) {
return { disallowed_matches: disallowedMatches, reparse_points: reparsePoints, scanned_files: files.length, status: disallowedMatches.length === 0 && reparsePoints.length === 0 ? "passed" : "failed" };
}
export async function buildAndValidatePortablePackage({ evidenceDirectory, outputRoot }) {
export async function buildAndValidatePortablePackage({ evidenceDirectory, outputRoot, releaseRecord }) {
if (process.platform !== frozenRuntime.os || process.arch !== frozenRuntime.arch || process.version.slice(1) !== frozenRuntime.node) {
throw new Error("Portable package build requires frozen Node 24.13.0 on win-x64.");
}
@@ -351,7 +367,8 @@ export async function buildAndValidatePortablePackage({ evidenceDirectory, outpu
writeJson(join(packageDirectory, "LICENSES", "third-party.json"), { api: apiDependencies, runtime: { node: frozenRuntime.node }, schema_version: "1.0", worker: workerDependencies });
const commit = run("git", ["rev-parse", "HEAD"]);
writeJson(join(packageDirectory, "RELEASE.json"), {
const finalRelease = releaseRecord !== undefined;
writeJson(join(packageDirectory, "RELEASE.json"), releaseRecord ?? {
app_version: appVersion,
browsers: [],
build_commit: commit,
@@ -360,16 +377,20 @@ export async function buildAndValidatePortablePackage({ evidenceDirectory, outpu
windows_build: null,
});
writeFileSync(join(packageDirectory, "START-HERE.txt"), [
"Dada P0-A candidate package",
finalRelease ? "Dada P0-A first-version portable package" : "Dada P0-A candidate package",
"",
"This candidate is unsigned and is not a final P0-A release.",
finalRelease
? "This unsigned first-version package passed the local P0-A release gates recorded in RELEASE.json."
: "This candidate is unsigned and is not a final P0-A release.",
"Verify the adjacent SHA-256 file before first launch.",
"Windows SmartScreen may warn on first launch because the executable is unsigned.",
"For an antivirus alert, compare the package hash with the Gitea build record.",
"Do not disable antivirus protection, add broad exclusions, or skip hash verification.",
"To update, exit Dada from the tray and replace the complete program directory.",
"Dada uses 127.0.0.1:43121 and does not support LAN or remote access.",
"A final RELEASE.json is created only after WP-7 acceptance.",
finalRelease
? "Resend and Amap real-provider validation remain explicitly deferred and are not recorded as passed."
: "A final RELEASE.json is created only after WP-7 acceptance.",
"",
].join("\r\n"));
@@ -381,7 +402,18 @@ export async function buildAndValidatePortablePackage({ evidenceDirectory, outpu
const zipSha256 = fileSha256(zipPath);
const shaPath = `${zipPath}.sha256`;
writeFileSync(shaPath, `${zipSha256} ${basename(zipPath)}\n`);
const processTree = await verifyExtractedPackage(zipPath, packageName);
const supportBrowser = finalRelease ? releaseRecord.browsers[0] : undefined;
const processTree = await verifyExtractedPackage(zipPath, packageName, finalRelease ? {
brand: supportBrowser.brand,
fullVersion: supportBrowser.fullVersion,
major: Number.parseInt(supportBrowser.fullVersion.split(".")[0], 10),
statusCode: 200,
} : {
brand: "Google Chrome",
fullVersion: "150.0.0.0",
major: 150,
statusCode: 426,
});
const fileEntries = listFiles(packageDirectory).files.map((path) => ({
path: relative(packageDirectory, path).replaceAll("\\", "/"),
sha256: fileSha256(path),
@@ -392,7 +424,7 @@ export async function buildAndValidatePortablePackage({ evidenceDirectory, outpu
files: fileEntries,
fixed_port: fixedPort,
package_name: packageName,
release_status: "candidate_unvalidated",
release_status: finalRelease ? releaseRecord.releaseStatus : "candidate_unvalidated",
schema_version: "1.0",
zip_sha256: zipSha256,
};
+418
View File
@@ -0,0 +1,418 @@
import { createHash } from "node:crypto";
import {
gptImageRequestSizeForRatio,
normalizeImageOutputToRatio,
} from "../../apps/worker/src/image-output-normalizer.mjs";
import { WP7_02_MODEL_IDS, buildModelContractPlan } from "./wp7-02-external-contract.mjs";
export const WP7_02_CONTROLLED_REAL_LIMIT = 120;
const ratios = ["3:4", "1:1", "4:3", "9:16"];
const allowedMimeTypes = new Set(["image/jpeg", "image/png", "image/webp"]);
const forbiddenEvidenceKeys = /(?:^|_)(?:absolute_path|authorization|body|credential|credential_value|image_bytes|image_data|original_image|password|path|prompt|raw|raw_provider_payload|raw_prompt|secret|token)(?:_|$)/i;
function sha256(value) {
return createHash("sha256").update(value).digest("hex").toUpperCase();
}
function assertModelConfig(modelConfig) {
if (!modelConfig || typeof modelConfig !== "object" || !WP7_02_MODEL_IDS.includes(modelConfig.model_id)) {
throw new Error("WP7_02_MODEL_CONFIG_INVALID");
}
if (!Number.isSafeInteger(modelConfig.config_version) || modelConfig.config_version <= 0) {
throw new Error("WP7_02_MODEL_CONFIG_VERSION_INVALID");
}
const profile = modelConfig.route_profile;
if (!profile || typeof profile !== "object" || typeof profile.endpoint !== "string"
|| !profile.endpoint.startsWith("https://oneapi.intelligrow.cn/")
|| !["gemini-interactions-v1beta", "gemini-native-v1beta", "gemini-openai-chat-v1", "openai-images-v1"].includes(profile.protocol_version)) {
throw new Error("WP7_02_ROUTE_PROFILE_INVALID");
}
if (profile.protocol_version === "gemini-interactions-v1beta"
&& (profile.endpoint !== "https://oneapi.intelligrow.cn/v1beta/interactions"
|| profile.provider_model_id !== "gemini-3.1-flash-image")) {
throw new Error("WP7_02_ROUTE_PROFILE_INVALID");
}
if (profile.protocol_version === "gemini-openai-chat-v1"
&& (profile.endpoint !== "https://oneapi.intelligrow.cn/v1/chat/completions"
|| profile.provider_model_id !== "gemini-3.1-flash-image")) {
throw new Error("WP7_02_ROUTE_PROFILE_INVALID");
}
if (profile.protocol_version === "openai-images-v1"
&& (profile.reference_endpoint !== "https://oneapi.intelligrow.cn/v1/images/edits")) {
throw new Error("WP7_02_REFERENCE_ROUTE_PROFILE_INVALID");
}
if (profile.protocol_version === "openai-images-v1" && profile.provider_model_id !== undefined
&& profile.provider_model_id !== "gemini-3.1-flash-image") {
throw new Error("WP7_02_ROUTE_PROFILE_INVALID");
}
return modelConfig;
}
export function buildControlledExecutionPlan(modelConfig) {
const config = assertModelConfig(modelConfig);
const contractPlan = buildModelContractPlan(config.model_id);
const realScenarios = [
...ratios.map((ratio) => ({ input: "pure_text", ratio, source: "real_gateway" })),
{ input: "reference_image", ratio: "1:1", source: "real_gateway" },
];
return {
config_version: config.config_version,
error_scenarios: contractPlan.error_categories.map((name) => ({
expected: contractPlan.error_expectations[name], name, source: "deterministic_local",
})),
execution_modes: [
{ mode: "sync", source: "real_gateway" },
{ mode: "async", source: "deterministic_local" },
{ mode: "poll", source: "deterministic_local" },
],
model_id: config.model_id,
planned_real_calls: realScenarios.length,
quota_impact: "authorized_test_key_up_to_120_requests",
real_scenarios: realScenarios,
response_checks: ["single_image", "mime", "dimensions", "sanitized_usage", "evidence_hash"],
state_scenarios: contractPlan.state_checks.map((name) => ({ name, source: "deterministic_local" })),
};
}
export function buildProviderRequest({ modelConfig, prompt, ratio, reference }) {
const config = assertModelConfig(modelConfig);
if (typeof prompt !== "string" || !prompt.trim() || !ratios.includes(ratio)) throw new Error("WP7_02_REQUEST_FIXTURE_INVALID");
if (reference && (!Buffer.isBuffer(reference.bytes) || reference.bytes.length === 0 || !allowedMimeTypes.has(reference.mime_type))) {
throw new Error("WP7_02_REFERENCE_FIXTURE_INVALID");
}
const headers = { "content-type": "application/json" };
if (config.route_profile.protocol_version === "gemini-interactions-v1beta") {
const input = [{ text: prompt, type: "text" }];
if (reference) input.push({ data: reference.bytes.toString("base64"), mime_type: reference.mime_type, type: "image" });
return {
body: {
input,
model: config.route_profile.provider_model_id,
response_format: { aspect_ratio: ratio, image_size: "1K", type: "image" },
},
headers,
method: "POST",
url: config.route_profile.endpoint,
};
}
if (config.route_profile.protocol_version === "gemini-native-v1beta") {
const parts = [{ text: prompt }];
if (reference) parts.push({ inlineData: { data: reference.bytes.toString("base64"), mimeType: reference.mime_type } });
return {
body: {
contents: [{ parts, role: "user" }],
generationConfig: {
imageConfig: { aspectRatio: ratio, imageSize: "1K" },
responseModalities: ["IMAGE"],
},
},
headers,
method: "POST",
url: config.route_profile.endpoint,
};
}
if (config.route_profile.protocol_version === "gemini-openai-chat-v1") {
const content = reference
? [
{ text: prompt, type: "text" },
{
image_url: { url: `data:${reference.mime_type};base64,${reference.bytes.toString("base64")}` },
type: "image_url",
},
]
: prompt;
return {
body: {
extra_body: { google: { image_config: { aspect_ratio: ratio, image_size: "1K" } } },
messages: [{ content, role: "user" }],
model: config.route_profile.provider_model_id,
stream: false,
},
headers,
method: "POST",
url: config.route_profile.endpoint,
};
}
const providerModelId = config.route_profile.provider_model_id ?? config.model_id;
const body = {
model: providerModelId,
prompt,
response_format: "b64_json",
size: gptImageRequestSizeForRatio(ratio),
};
if (reference) {
const form = new FormData();
form.append("model", providerModelId);
form.append("prompt", prompt);
form.append("response_format", "b64_json");
form.append("size", gptImageRequestSizeForRatio(ratio));
form.append("image[]", new Blob([reference.bytes], { type: reference.mime_type }), "reference.png");
return { body: form, headers: {}, method: "POST", url: config.route_profile.reference_endpoint };
}
return { body, headers, method: "POST", url: config.route_profile.endpoint };
}
function pngDimensions(bytes) {
const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
if (bytes.length < 24 || !bytes.subarray(0, 8).equals(signature)) return undefined;
return { height: bytes.readUInt32BE(20), width: bytes.readUInt32BE(16) };
}
function jpegDimensions(bytes) {
if (bytes.length < 4 || bytes[0] !== 0xff || bytes[1] !== 0xd8) return undefined;
let offset = 2;
while (offset + 9 < bytes.length) {
if (bytes[offset] !== 0xff) { offset += 1; continue; }
const marker = bytes[offset + 1];
if ([0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf].includes(marker)) {
return { height: bytes.readUInt16BE(offset + 5), width: bytes.readUInt16BE(offset + 7) };
}
if (marker === 0xd8 || marker === 0xd9 || (marker >= 0xd0 && marker <= 0xd7)) { offset += 2; continue; }
const length = bytes.readUInt16BE(offset + 2);
if (length < 2) return undefined;
offset += length + 2;
}
return undefined;
}
function webpDimensions(bytes) {
if (bytes.length < 30 || bytes.toString("ascii", 0, 4) !== "RIFF" || bytes.toString("ascii", 8, 12) !== "WEBP") return undefined;
const kind = bytes.toString("ascii", 12, 16);
if (kind === "VP8X") {
return {
height: 1 + bytes.readUIntLE(27, 3),
width: 1 + bytes.readUIntLE(24, 3),
};
}
if (kind === "VP8 " && bytes.length >= 30) return { height: bytes.readUInt16LE(28) & 0x3fff, width: bytes.readUInt16LE(26) & 0x3fff };
if (kind === "VP8L" && bytes.length >= 25) {
const bits = bytes.readUInt32LE(21);
return { height: 1 + ((bits >> 14) & 0x3fff), width: 1 + (bits & 0x3fff) };
}
return undefined;
}
function inspectImage(bytes, declaredMime) {
const png = pngDimensions(bytes);
if (png && declaredMime === "image/png") return { ...png, mime: declaredMime };
const jpeg = jpegDimensions(bytes);
if (jpeg && declaredMime === "image/jpeg") return { ...jpeg, mime: declaredMime };
const webp = webpDimensions(bytes);
if (webp && declaredMime === "image/webp") return { ...webp, mime: declaredMime };
throw new Error("WP7_02_RESPONSE_MEDIA_INVALID");
}
function integerOrZero(value) {
return Number.isSafeInteger(value) && value >= 0 ? value : 0;
}
function geminiUsage(response) {
const usage = response?.usageMetadata;
return {
input_units: integerOrZero(usage?.promptTokenCount),
output_units: integerOrZero(usage?.candidatesTokenCount),
total_units: integerOrZero(usage?.totalTokenCount),
};
}
function openAiUsage(response) {
const usage = response?.usage;
return {
input_units: integerOrZero(usage?.input_tokens ?? usage?.inputTokens ?? usage?.prompt_tokens ?? usage?.promptTokens),
output_units: integerOrZero(usage?.output_tokens ?? usage?.outputTokens ?? usage?.completion_tokens ?? usage?.completionTokens),
total_units: integerOrZero(usage?.total_tokens ?? usage?.totalTokens),
};
}
function openAiChatImage(response) {
const content = response?.choices?.[0]?.message?.content;
if (typeof content !== "string") throw new Error("WP7_02_RESPONSE_SINGLE_IMAGE_REQUIRED");
const matches = [...content.matchAll(/!\[[^\]]*\]\(\s*data:(image\/(?:jpeg|png|webp));base64,([A-Za-z0-9+/=\r\n]+)\s*\)/gi)];
if (matches.length !== 1) throw new Error("WP7_02_RESPONSE_SINGLE_IMAGE_REQUIRED");
return { data: matches[0][2], mime: matches[0][1].toLowerCase() };
}
function interactionUsage(response) {
const usage = response?.usage;
return {
input_units: integerOrZero(usage?.total_input_tokens),
output_units: integerOrZero(usage?.total_output_tokens),
total_units: integerOrZero(usage?.total_tokens),
};
}
export function normalizeProviderResponse(modelConfig, response) {
const config = assertModelConfig(modelConfig);
let bytes;
let mime;
let usageSummary;
if (config.route_profile.protocol_version === "gemini-interactions-v1beta") {
const stepImages = response?.steps?.flatMap((step) => step?.type === "model_output" ? step?.content ?? [] : [])
.filter((content) => content?.type === "image" && content?.data) ?? [];
const images = stepImages.length > 0
? stepImages
: [response?.output_image].filter((content) => content?.data);
if (images.length !== 1) throw new Error("WP7_02_RESPONSE_SINGLE_IMAGE_REQUIRED");
mime = images[0].mime_type ?? images[0].mimeType;
bytes = Buffer.from(images[0].data, "base64");
usageSummary = interactionUsage(response);
} else if (config.route_profile.protocol_version === "gemini-native-v1beta") {
const parts = response?.candidates?.flatMap((candidate) => candidate?.content?.parts ?? []) ?? [];
const images = parts.map((part) => part?.inlineData ?? part?.inline_data).filter((entry) => entry?.data);
if (images.length !== 1) throw new Error("WP7_02_RESPONSE_SINGLE_IMAGE_REQUIRED");
mime = images[0].mimeType ?? images[0].mime_type;
bytes = Buffer.from(images[0].data, "base64");
usageSummary = geminiUsage(response);
} else if (config.route_profile.protocol_version === "gemini-openai-chat-v1") {
const image = openAiChatImage(response);
bytes = Buffer.from(image.data, "base64");
mime = image.mime;
usageSummary = openAiUsage(response);
} else {
if (!Array.isArray(response?.data) || response.data.length !== 1 || typeof response.data[0]?.b64_json !== "string") {
throw new Error("WP7_02_RESPONSE_SINGLE_IMAGE_REQUIRED");
}
bytes = Buffer.from(response.data[0].b64_json, "base64");
mime = "image/png";
usageSummary = openAiUsage(response);
}
const media = inspectImage(bytes, mime);
return {
bytes,
dimensions: { height: media.height, width: media.width },
evidence_hash: `sha256:${sha256(bytes)}`,
mime: media.mime,
usage_summary: usageSummary,
};
}
export function describeProviderResponseShape(value, depth = 0) {
if (typeof value === "string") {
const trimmed = value.trim();
const representation = /^data:image\/(?:jpeg|png|webp);base64,/i.test(trimmed)
? "inline_media"
: /!\[[^\]]*\]\(\s*https?:\/\/[^)\s]+\s*\)/i.test(trimmed)
? "markdown_uri"
: /^https?:\/\/\S+$/i.test(trimmed)
? "uri"
: "plain_text";
return {
kind: "string",
representation,
size: value.length === 0 ? "empty" : value.length > 256 ? "large" : "small",
};
}
if (typeof value === "number") return { kind: "number" };
if (typeof value === "boolean") return { kind: "boolean" };
if (value === null || value === undefined) return { kind: value === null ? "null" : "undefined" };
if (depth >= 6) return { kind: "depth_limit" };
if (Array.isArray(value)) {
return {
item: value.length > 0 ? describeProviderResponseShape(value[0], depth + 1) : { kind: "empty" },
kind: "array",
length: value.length,
};
}
if (value && typeof value === "object") {
return {
fields: Object.keys(value).toSorted().map((name) => ({ name, shape: describeProviderResponseShape(value[name], depth + 1) })),
kind: "object",
};
}
return { kind: "undefined" };
}
export function buildSanitizedResponseEvidence(normalized) {
const evidence = {
dimensions: structuredClone(normalized.dimensions),
evidence_hash: normalized.evidence_hash,
mime: normalized.mime,
...(normalized.normalization ? { normalization: structuredClone(normalized.normalization) } : {}),
usage_summary: structuredClone(normalized.usage_summary),
};
return validateSanitizedEvidence(evidence);
}
function inspectEvidenceValue(value, seen = new Set()) {
if (value && typeof value === "object") {
if (seen.has(value)) throw new Error("WP7_02_EVIDENCE_CYCLE_FORBIDDEN");
seen.add(value);
for (const [key, entry] of Object.entries(value)) {
if (key === "verified") throw new Error("WP7_02_SHARED_VERIFIED_FORBIDDEN");
if (key !== "secret_scan" && forbiddenEvidenceKeys.test(key)) throw new Error(`WP7_02_SENSITIVE_EVIDENCE_FORBIDDEN:${key}`);
inspectEvidenceValue(entry, seen);
}
seen.delete(value);
} else if (typeof value === "string" && /[A-Za-z]:\\Users\\/i.test(value)) {
throw new Error("WP7_02_SENSITIVE_EVIDENCE_FORBIDDEN");
}
}
export function validateSanitizedEvidence(evidence) {
inspectEvidenceValue(evidence);
return evidence;
}
export async function executeProviderRequest({ fetchImpl = fetch, modelConfig, prompt, ratio, reference, token, timeoutMs = 180_000 }) {
if (typeof token !== "string" || token.length < 8) throw new Error("WP7_02_CREDENTIAL_INVALID");
const request = buildProviderRequest({ modelConfig, prompt, ratio, reference });
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
const startedAt = performance.now();
try {
const response = await fetchImpl(request.url, {
body: request.body instanceof FormData ? request.body : JSON.stringify(request.body),
headers: { ...request.headers, authorization: `Bearer ${token}` },
method: request.method,
signal: controller.signal,
});
const durationMs = Math.round(performance.now() - startedAt);
if (!response.ok) throw new Error(`WP7_02_UPSTREAM_HTTP_${response.status}`);
const providerResponse = await response.json();
let normalized;
try {
const providerNormalized = normalizeProviderResponse(modelConfig, providerResponse);
const adapted = await normalizeImageOutputToRatio({
bytes: providerNormalized.bytes,
mimeType: providerNormalized.mime,
pixelHeight: providerNormalized.dimensions.height,
pixelWidth: providerNormalized.dimensions.width,
ratio,
});
normalized = {
...providerNormalized,
bytes: adapted.bytes,
dimensions: { height: adapted.pixelHeight, width: adapted.pixelWidth },
evidence_hash: `sha256:${sha256(adapted.bytes)}`,
mime: adapted.mimeType,
normalization: {
applied: adapted.normalized,
upstream_dimensions: { height: adapted.upstreamPixelHeight, width: adapted.upstreamPixelWidth },
},
};
} catch (error) {
if (error instanceof Error && /^WP7_02_[A-Z0-9_]+$/.test(error.message)) {
error.safe_response_shape = describeProviderResponseShape(providerResponse);
} else if (error instanceof Error && error.message === "image_output_media_invalid") {
throw new Error("WP7_02_RESPONSE_MEDIA_INVALID");
} else if (error instanceof Error && /^image_output_(?:aspect_ratio_mismatch|dimensions_missing|normalization_failed)$/.test(error.message)) {
throw new Error("WP7_02_RESPONSE_DIMENSIONS_INVALID");
}
throw error;
}
return {
duration_ms: durationMs,
http_status: response.status,
normalized,
response_evidence: buildSanitizedResponseEvidence(normalized),
};
} catch (error) {
if (error?.name === "AbortError") throw new Error("WP7_02_UPSTREAM_TIMEOUT");
if (error instanceof Error && /^WP7_02_[A-Z0-9_]+$/.test(error.message)) throw error;
throw new Error("WP7_02_UPSTREAM_FAILED");
} finally {
clearTimeout(timeout);
}
}
+261
View File
@@ -0,0 +1,261 @@
import { createHash } from "node:crypto";
import { deflateSync } from "node:zlib";
import {
WP7_02_CONTROLLED_REAL_LIMIT,
buildControlledExecutionPlan,
executeProviderRequest,
validateSanitizedEvidence,
} from "./wp7-02-controlled-executor.mjs";
const productDimensions = Object.freeze({
"3:4": { height: 1440, width: 1080 },
"1:1": { height: 1080, width: 1080 },
"4:3": { height: 1080, width: 1440 },
"9:16": { height: 1920, width: 1080 },
});
function sha256(value) {
return createHash("sha256").update(value).digest("hex").toUpperCase();
}
function crc32(bytes) {
let crc = 0xffffffff;
for (const byte of bytes) {
crc ^= byte;
for (let bit = 0; bit < 8; bit += 1) crc = (crc >>> 1) ^ (0xedb88320 & -(crc & 1));
}
return (crc ^ 0xffffffff) >>> 0;
}
function pngChunk(type, data) {
const name = Buffer.from(type, "ascii");
const length = Buffer.alloc(4);
length.writeUInt32BE(data.length);
const checksum = Buffer.alloc(4);
checksum.writeUInt32BE(crc32(Buffer.concat([name, data])));
return Buffer.concat([length, name, data, checksum]);
}
export function createControlledReferencePng() {
const width = 64;
const height = 64;
const rows = [];
for (let y = 0; y < height; y += 1) {
const row = Buffer.alloc(1 + width * 4);
for (let x = 0; x < width; x += 1) {
const offset = 1 + x * 4;
const bright = (Math.floor(x / 8) + Math.floor(y / 8)) % 2 === 0;
row[offset] = bright ? 32 : 220;
row[offset + 1] = bright ? 180 : 48;
row[offset + 2] = bright ? 220 : 140;
row[offset + 3] = 255;
}
rows.push(row);
}
const header = Buffer.alloc(13);
header.writeUInt32BE(width, 0);
header.writeUInt32BE(height, 4);
header[8] = 8;
header[9] = 6;
return Buffer.concat([
Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
pngChunk("IHDR", header),
pngChunk("IDAT", deflateSync(Buffer.concat(rows))),
pngChunk("IEND", Buffer.alloc(0)),
]);
}
function promptForScenario(scenario) {
const subject = scenario.input === "reference_image" ? "use the supplied geometric color reference" : "use a geometric color study";
return `Create one safe abstract test image; ${subject}; no text, logos, people, or real places; aspect ratio ${scenario.ratio}.`;
}
function dimensionsMatch(dimensions, ratio) {
const expected = productDimensions[ratio];
return dimensions.width === expected.width && dimensions.height === expected.height;
}
function safeErrorCode(error) {
return error instanceof Error && /^WP7_02_[A-Z0-9_]+$/.test(error.message)
? error.message
: "WP7_02_UPSTREAM_FAILED";
}
export async function runControlledRealScenarios({ fetchImpl = fetch, maxRealCalls, modelConfig, token }) {
const plan = buildControlledExecutionPlan(modelConfig);
if (maxRealCalls !== WP7_02_CONTROLLED_REAL_LIMIT || plan.planned_real_calls > maxRealCalls) {
throw new Error("WP7_02_REAL_CALL_LIMIT_INVALID");
}
const referenceBytes = createControlledReferencePng();
const attempts = [];
const calls = [];
let timeoutRetriesRemaining = 1;
let stop = false;
for (let index = 0; index < plan.real_scenarios.length; index += 1) {
const scenario = plan.real_scenarios[index];
const scenarioId = `real-${index + 1}`;
let attemptNo = 0;
while (true) {
attemptNo += 1;
try {
const result = await executeProviderRequest({
fetchImpl,
modelConfig,
prompt: promptForScenario(scenario),
ratio: scenario.ratio,
reference: scenario.input === "reference_image" ? { bytes: referenceBytes, mime_type: "image/png" } : undefined,
token,
});
attempts.push(validateSanitizedEvidence({
attempt_no: attemptNo, duration_ms: result.duration_ms, http_status: result.http_status,
scenario_id: scenarioId, status: "passed",
}));
const dimensionsPassed = dimensionsMatch(result.normalized.dimensions, scenario.ratio);
calls.push(validateSanitizedEvidence({
duration_ms: result.duration_ms,
http_status: result.http_status,
input: scenario.input,
requested_ratio: scenario.ratio,
response: result.response_evidence,
scenario_id: scenarioId,
source: "real_gateway",
status: dimensionsPassed ? "passed" : "failed",
validation: { dimensions: dimensionsPassed ? "passed" : "failed", response: "passed" },
}));
break;
} catch (error) {
const errorCode = safeErrorCode(error);
attempts.push(validateSanitizedEvidence({ attempt_no: attemptNo, error_code: errorCode, scenario_id: scenarioId, status: "failed" }));
if (errorCode === "WP7_02_UPSTREAM_TIMEOUT" && timeoutRetriesRemaining > 0) {
timeoutRetriesRemaining -= 1;
continue;
}
const failed = {
error_code: errorCode,
input: scenario.input,
requested_ratio: scenario.ratio,
scenario_id: scenarioId,
source: "real_gateway",
status: "failed",
...(error?.safe_response_shape ? { response_shape: error.safe_response_shape } : {}),
};
calls.push(validateSanitizedEvidence(failed));
if (["WP7_02_RESPONSE_SINGLE_IMAGE_REQUIRED", "WP7_02_RESPONSE_MEDIA_INVALID", "WP7_02_CREDENTIAL_INVALID",
"WP7_02_UPSTREAM_HTTP_401", "WP7_02_UPSTREAM_HTTP_403", "WP7_02_UPSTREAM_HTTP_404", "WP7_02_UPSTREAM_HTTP_429"].includes(failed.error_code)) stop = true;
break;
}
}
if (stop) break;
}
referenceBytes.fill(0);
const blockers = calls.filter((call) => call.status !== "passed").map((call) => `${call.scenario_id}:${call.error_code ?? "dimensions_or_response_invalid"}`);
return validateSanitizedEvidence({
blockers,
attempts,
calls,
maximum_real_calls: plan.planned_real_calls + 1,
model_id: modelConfig.model_id,
planned_real_calls: plan.planned_real_calls,
real_calls: attempts.length,
status: blockers.length === 0 ? "passed" : "externally_blocked",
});
}
export function buildDeterministicExecutionEvidence(modelId, runId) {
const operationRef = `sha256:${sha256(`${modelId}:${runId}:operation`)}`;
let state = "created";
const trace = [];
const start = () => {
if (state !== "created") throw new Error("WP7_02_ASYNC_STATE_INVALID");
state = "pending";
trace.push({ action: "start", after: state, before: "created", status: "passed" });
return operationRef;
};
const poll = (reference) => {
if (reference !== operationRef || !["pending", "completed"].includes(state)) throw new Error("WP7_02_POLL_REFERENCE_INVALID");
const before = state;
state = "completed";
trace.push({ action: "poll", after: state, before, replay: before === "completed", status: "passed" });
return state;
};
const reference = start();
poll(reference);
poll(reference);
return validateSanitizedEvidence({
modes: [
{ mode: "sync", source: "real_gateway", status: "covered_by_real_calls" },
{ mode: "async", source: "deterministic_local", status: "passed", transition: "created_to_pending" },
{ mode: "poll", operation_ref: operationRef, replay_count: 1, source: "deterministic_local", status: "passed", transition: "pending_to_completed" },
],
model_id: modelId,
status: "passed",
trace,
});
}
function passedCall(calls, predicate) {
return calls.some((call) => call.status === "passed" && predicate(call));
}
export function assembleControlledModelEvidence({ deterministicState, modelConfig, realExecution, runId }) {
if (deterministicState?.model_id !== modelConfig.model_id || deterministicState?.status !== "passed") {
throw new Error("WP7_02_DETERMINISTIC_STATE_INCOMPLETE");
}
const execution = buildDeterministicExecutionEvidence(modelConfig.model_id, runId);
const ratioRows = Object.keys(productDimensions).map((ratio) => ({
outputs: passedCall(realExecution.calls, (call) => call.requested_ratio === ratio) ? 1 : 0,
ratio,
status: passedCall(realExecution.calls, (call) => call.requested_ratio === ratio) ? "passed" : "failed",
}));
const pureTextPassed = ratioRows.every((row) => row.status === "passed")
&& passedCall(realExecution.calls, (call) => call.input === "pure_text");
const referencePassed = passedCall(realExecution.calls, (call) => call.input === "reference_image");
const deterministicPassed = deterministicState.error_scenarios?.length === 9
&& deterministicState.error_scenarios.every((entry) => entry.status === "passed")
&& deterministicState.settlements?.length === 3
&& deterministicState.contract_change?.full_matrix_reapplied === true;
const status = realExecution.status === "passed" && pureTextPassed && referencePassed
&& ratioRows.every((row) => row.status === "passed") && deterministicPassed ? "passed" : "externally_blocked";
const evidenceId = `sha256:${sha256(`${modelConfig.model_id}:${modelConfig.config_version}:${runId}`)}`;
return validateSanitizedEvidence({
evidence_id: evidenceId,
external_calls: {
approved_real_call_limit: WP7_02_CONTROLLED_REAL_LIMIT,
attempts: realExecution.attempts,
calls: realExecution.calls,
maximum_real_calls: realExecution.maximum_real_calls,
mode: "controlled_real",
planned_real_calls: realExecution.planned_real_calls,
real_calls: realExecution.real_calls,
service: "ai-gateway-service-id",
status: realExecution.status,
},
manual_review: {
decision: status === "passed" ? "Review sanitized matrix before recording the model as passed." : "Resolve all failed scenarios before review.",
status: status === "passed" ? "pending" : "blocked",
},
matrix: {
config_version: modelConfig.config_version,
contract_change: deterministicState.contract_change,
error_scenarios: deterministicState.error_scenarios,
execution_modes: execution.modes,
model_id: modelConfig.model_id,
pure_text: { outputs: pureTextPassed ? 1 : 0, status: pureTextPassed ? "passed" : "failed" },
ratios: ratioRows,
reference_image: { outputs: referencePassed ? 1 : 0, status: referencePassed ? "passed" : "failed" },
response_checks: ["single_image", "mime", "dimensions", "sanitized_usage", "evidence_hash"].map((name) => ({ name, status: realExecution.status })),
settlements: deterministicState.settlements,
status,
},
model_id: modelConfig.model_id,
redaction: {
forbidden_fields_absent: true,
retained_fields: ["status", "category", "duration_ms", "mime", "dimensions", "usage_summary", "evidence_hash", "time"],
secret_scan: "passed",
status: "passed",
},
run_id: runId,
status,
});
}
+249
View File
@@ -0,0 +1,249 @@
import { createHash } from "node:crypto";
import { mkdirSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
export const AI_GATEWAY_CREDENTIAL_TARGET = "Dada/P0A/worker/ai-gateway";
export const WP7_02_MODEL_IDS = Object.freeze([
"gemini-3.1-flash-image",
"gpt-image-2",
]);
const controlledStateProductModelIds = Object.freeze({
"gemini-3.1-flash-image": "gemini-3.1-flash-image-preview",
"gpt-image-2": "gpt-image-2",
});
const expectedCandidateCommit = "623cad25b2a2a9a003502c9a92ebd318dad06248";
const expectedBrowsers = Object.freeze({
"Google Chrome": "150.0.7871.187",
"Microsoft Edge": "151.0.4129.59",
});
const ratios = Object.freeze(["3:4", "1:1", "4:3", "9:16"]);
const errorCategories = Object.freeze([
"upstream_timeout", "upstream_failed", "safety_rejected", "model_disabled",
"gateway_balance_insufficient", "gateway_contract_invalid", "reference_invalid",
"unknown_retryable", "unknown_non_retryable",
]);
const errorExpectations = Object.freeze({
upstream_timeout: { credit_effect: "release_once", job_outcome: "failed", user_action: "retry_original_input" },
upstream_failed: { credit_effect: "release_once", job_outcome: "failed", user_action: "retry_later" },
safety_rejected: { credit_effect: "release_once", job_outcome: "rejected", user_action: "modify_prompt_or_reference" },
model_disabled: { credit_effect: "no_reserve", job_outcome: "not_created", user_action: "choose_other_model_or_wait" },
gateway_balance_insufficient: { credit_effect: "no_reserve_or_release_once", job_outcome: "not_created_or_failed", user_action: "choose_unaffected_model_or_contact_admin" },
gateway_contract_invalid: { credit_effect: "no_reserve_or_release_once", job_outcome: "not_created_or_failed", user_action: "choose_other_model_or_contact_admin" },
reference_invalid: { credit_effect: "no_reserve_or_release_once", job_outcome: "not_created_or_failed", user_action: "replace_or_remove_reference" },
unknown_retryable: { credit_effect: "release_once", job_outcome: "failed", user_action: "retry_later" },
unknown_non_retryable: { credit_effect: "release_once", job_outcome: "failed", user_action: "contact_admin" },
});
function stableJson(value) {
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
if (value && typeof value === "object") {
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right))
.map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`).join(",")}}`;
}
return JSON.stringify(value);
}
function sha256(value) {
return createHash("sha256").update(typeof value === "string" ? value : stableJson(value)).digest("hex").toUpperCase();
}
function assertModelId(modelId) {
if (!WP7_02_MODEL_IDS.includes(modelId)) throw new Error("WP7_02_MODEL_NOT_ALLOWED");
return modelId;
}
export function productModelIdForControlledState(modelId) {
assertModelId(modelId);
return controlledStateProductModelIds[modelId];
}
export function buildModelContractPlan(modelId) {
assertModelId(modelId);
const plannedRequestBreakdown = {
contract_change_full_revalidation: 20,
error_categories: 9,
execution_modes_and_poll: 3,
input_and_ratio_success: 6,
settlement_boundaries: 2,
};
return {
error_categories: [...errorCategories],
error_expectations: structuredClone(errorExpectations),
execution_modes: ["sync", "async", "poll"],
inputs: ["pure_text", "reference_image"],
model_id: modelId,
planned_provider_requests_max: Object.values(plannedRequestBreakdown).reduce((total, count) => total + count, 0),
planned_request_breakdown: plannedRequestBreakdown,
quota_impact: "unknown_requires_operator_review",
ratios: [...ratios],
response_checks: ["single_image", "mime", "dimensions", "sanitized_usage"],
state_checks: [
"credit_commit_once", "credit_release_once_per_terminal_failure",
"contract_change_invalidation", "full_revalidation",
],
};
}
export function validateCandidateDependency(record) {
if (!record || typeof record !== "object") throw new Error("WP7_02_CANDIDATE_RECORD_REQUIRED");
if (record.final_release !== false || record.status !== "candidate_unvalidated"
|| record.candidate_package?.release_status !== "candidate_unvalidated") {
throw new Error("WP7_02_CANDIDATE_FINAL_RELEASE_FORBIDDEN");
}
if (record.build_commit !== expectedCandidateCommit || record.fixed_port !== 43121) {
throw new Error("WP7_02_CANDIDATE_BASELINE_MISMATCH");
}
const browsers = Array.isArray(record.browsers) ? record.browsers : [];
if (browsers.length !== 2 || Object.entries(expectedBrowsers).some(([brand, version]) => {
const browser = browsers.find((entry) => entry?.brand === brand);
return !browser || browser.full_version !== version || browser.major !== Number(version.split(".")[0])
|| browser.source !== "installed_executable";
})) throw new Error("WP7_02_CANDIDATE_BROWSER_MISMATCH");
if (!/^[A-F0-9]{64}$/.test(record.candidate_package?.sha256 ?? "")) throw new Error("WP7_02_CANDIDATE_PACKAGE_HASH_INVALID");
return {
browsers: Object.entries(expectedBrowsers).map(([brand, full_version]) => ({ brand, full_version })),
build_commit: record.build_commit,
candidate_package_sha256: record.candidate_package.sha256,
fixed_port: record.fixed_port,
record_sha256: sha256(record),
status: record.status,
};
}
function validateRealModelConfig(modelConfig, modelId) {
if (!modelConfig || typeof modelConfig !== "object") return { blocker: "real_model_config_absent" };
const endpoint = modelConfig.route_profile?.endpoint;
const validEndpoint = typeof endpoint === "string" && endpoint.startsWith("https://")
&& !/\.(?:invalid)(?:\/|$)/i.test(endpoint) && !/https:\/\/(?:localhost|127\.0\.0\.1)(?:[:/]|$)/i.test(endpoint);
if (modelConfig.model_id !== modelId || !Number.isSafeInteger(modelConfig.config_version) || modelConfig.config_version <= 0
|| !validEndpoint || typeof modelConfig.gateway_account_ref !== "string" || /mock/i.test(modelConfig.gateway_account_ref)) {
return { blocker: "real_model_config_invalid" };
}
return {
config: {
config_version: modelConfig.config_version,
endpoint_sha256: sha256(endpoint),
gateway_account_ref_sha256: sha256(modelConfig.gateway_account_ref),
model_id: modelId,
route_profile_sha256: sha256(modelConfig.route_profile),
},
};
}
export function inspectAiGatewayReadiness({ candidateRecord, confirmed, credentialTargets, modelConfig, modelId }) {
const candidate = validateCandidateDependency(candidateRecord);
assertModelId(modelId);
const blockers = [];
if (confirmed !== true) blockers.push("explicit_confirmation_absent");
if (!Array.isArray(credentialTargets) || !credentialTargets.includes(AI_GATEWAY_CREDENTIAL_TARGET)) {
blockers.push("real_gateway_credentials_absent");
}
const checkedConfig = validateRealModelConfig(modelConfig, modelId);
if (checkedConfig.blocker) blockers.push(checkedConfig.blocker);
return {
blockers,
candidate,
model_config: checkedConfig.config ?? null,
model_id: modelId,
plan: buildModelContractPlan(modelId),
real_calls: 0,
status: blockers.length > 0 ? "externally_blocked" : "ready_for_controlled_execution",
};
}
function blockedScenarios(plan) {
return [
...plan.inputs.map((name) => ({ kind: "input", name, status: "not_run" })),
...plan.ratios.map((name) => ({ kind: "ratio", name, status: "not_run" })),
...plan.execution_modes.map((name) => ({ kind: "execution_mode", name, status: "not_run" })),
...plan.response_checks.map((name) => ({ kind: "response_check", name, status: "not_run" })),
...plan.error_categories.map((name) => ({
expected: plan.error_expectations[name], kind: "error_category", name, status: "not_run",
})),
...plan.state_checks.map((name) => ({ kind: "state_check", name, status: "not_run" })),
];
}
export function buildBlockedModelEvidence({ blockers, candidateRecord, modelId, modelConfig = null, runId }) {
const candidate = validateCandidateDependency(candidateRecord);
const plan = buildModelContractPlan(modelId);
if (!Array.isArray(blockers) || blockers.length === 0) throw new Error("WP7_02_EXTERNAL_BLOCKER_REQUIRED");
const evidenceId = `sha256:${sha256({ model_id: modelId, run_id: runId })}`;
return {
blockers: [...new Set(blockers)],
candidate,
evidence_id: evidenceId,
external_calls: {
mode: "controlled_real_not_executed",
planned_provider_requests_max: plan.planned_provider_requests_max,
planned_request_breakdown: plan.planned_request_breakdown,
quota_impact: plan.quota_impact,
real_calls: 0,
service: "ai-gateway-service-id",
},
manual_review: {
decision: "Do not mark this model verified until every controlled-real scenario passes against the listed config version.",
status: "blocked",
},
matrix: {
config_version: modelConfig?.config_version ?? null,
model_id: modelId,
scenarios: blockedScenarios(plan),
status: "not_run",
},
model_id: modelId,
redaction: {
retained_fields: ["status", "category", "duration_ms", "mime", "dimensions", "usage_summary", "evidence_hash", "time"],
secret_scan: "passed",
},
run_id: runId,
status: "externally_blocked",
};
}
export function validateIndependentEvidenceSet(evidence) {
if (!Array.isArray(evidence) || evidence.length !== WP7_02_MODEL_IDS.length) throw new Error("WP7_02_MODEL_EVIDENCE_SET_REQUIRED");
const ids = evidence.map((entry) => entry.model_id).toSorted();
if (JSON.stringify(ids) !== JSON.stringify([...WP7_02_MODEL_IDS].toSorted())) throw new Error("WP7_02_MODEL_EVIDENCE_SET_INVALID");
if (new Set(evidence.map((entry) => entry.evidence_id)).size !== evidence.length) throw new Error("WP7_02_SHARED_EVIDENCE_FORBIDDEN");
for (const entry of evidence) {
const blocked = entry.status === "externally_blocked"
&& Number.isSafeInteger(entry.external_calls?.real_calls) && entry.external_calls.real_calls >= 0
&& entry.manual_review?.status === "blocked";
const passed = entry.status === "passed" && entry.matrix?.status === "passed"
&& entry.external_calls?.status === "passed" && entry.external_calls.real_calls > 0
&& entry.manual_review?.status === "passed" && entry.redaction?.status === "passed";
const pendingReview = entry.status === "passed" && entry.matrix?.status === "passed"
&& entry.external_calls?.status === "passed" && entry.external_calls.real_calls > 0
&& entry.manual_review?.status === "pending" && entry.redaction?.status === "passed";
if (entry.matrix?.model_id !== entry.model_id || (!blocked && !passed && !pendingReview)
|| /\"verified\"\s*:/i.test(JSON.stringify(entry))) {
throw new Error("WP7_02_BLOCKED_EVIDENCE_INVALID");
}
}
return evidence;
}
export function writeBlockedModelEvidence(directory, evidence) {
mkdirSync(resolve(directory), { recursive: true });
const files = {
"contract-matrix.json": evidence.matrix,
"external-calls.json": evidence.external_calls,
"manual-review.json": evidence.manual_review,
"readiness.json": {
blockers: evidence.blockers,
candidate: evidence.candidate,
evidence_id: evidence.evidence_id,
model_id: evidence.model_id,
run_id: evidence.run_id,
status: evidence.status,
},
"redaction.json": evidence.redaction,
};
for (const [name, value] of Object.entries(files)) {
writeFileSync(resolve(directory, name), `${JSON.stringify(value, null, 2)}\n`);
}
return Object.keys(files);
}
+59
View File
@@ -0,0 +1,59 @@
import { WP7_02_MODEL_IDS } from "./wp7-02-external-contract.mjs";
const productDimensions = Object.freeze({
"3:4": [1080, 1440],
"1:1": [1080, 1080],
"4:3": [1440, 1080],
"9:16": [1080, 1920],
});
function modelEvidenceComplete(entry) {
const { externalCalls, matrix, modelId, readiness, redaction } = entry;
return matrix.model_id === modelId && Number.isSafeInteger(matrix.config_version) && matrix.config_version > 0 && matrix.status === "passed"
&& matrix.pure_text?.status === "passed" && matrix.reference_image?.status === "passed"
&& matrix.ratios?.length === 4 && matrix.ratios.every((row) => row.status === "passed")
&& matrix.execution_modes?.length === 3 && matrix.execution_modes.every((row) => ["passed", "covered_by_real_calls"].includes(row.status))
&& matrix.error_scenarios?.length === 9 && matrix.error_scenarios.every((row) => row.status === "passed")
&& matrix.settlements?.length === 3 && matrix.contract_change?.full_matrix_reapplied === true
&& externalCalls.status === "passed" && externalCalls.real_calls >= 5 && externalCalls.real_calls <= 6
&& externalCalls.planned_real_calls === 5 && externalCalls.maximum_real_calls === 6
&& externalCalls.attempts?.length === externalCalls.real_calls
&& externalCalls.calls?.length === 5 && new Set(externalCalls.calls.map((row) => row.scenario_id)).size === 5
&& externalCalls.calls.every((row) => row.status === "passed" && row.source === "real_gateway")
&& externalCalls.calls.every((row) => {
const [width, height] = productDimensions[row.requested_ratio] ?? [];
return row.response?.dimensions?.width === width && row.response?.dimensions?.height === height;
})
&& externalCalls.approved_real_call_limit === 120
&& readiness.status === "passed" && redaction.status === "passed" && redaction.secret_scan === "passed";
}
export function reviewIndependentModelEvidence(entries, { reviewedAt, runId }) {
const entryIds = Array.isArray(entries) ? entries.map((entry) => entry?.modelId).toSorted() : [];
if (!Array.isArray(entries) || entries.length !== WP7_02_MODEL_IDS.length
|| JSON.stringify(entryIds) !== JSON.stringify([...WP7_02_MODEL_IDS].toSorted())
|| !runId || !reviewedAt) {
throw new Error("WP7_02_MANUAL_REVIEW_EVIDENCE_INVALID");
}
const evidenceIds = entries.map((entry) => entry.readiness?.evidence_id);
if (evidenceIds.some((id) => typeof id !== "string") || new Set(evidenceIds).size !== entries.length) {
throw new Error("WP7_02_MANUAL_REVIEW_EVIDENCE_NOT_INDEPENDENT");
}
const reviews = entries.map((entry) => modelEvidenceComplete(entry) ? {
basis: ["independent_model_evidence", "five_scenarios_bounded_attempts", "four_ratios", "reference_input", "nine_errors", "settlement", "contract_change", "redaction"],
decision: "Sanitized controlled-real and deterministic evidence is complete for this config version.",
model_id: entry.modelId,
reviewed_at: reviewedAt,
reviewer_role: "dada_editor_quality_group",
run_id: runId,
status: "passed",
} : {
decision: "Independent model evidence remains incomplete or externally blocked.",
model_id: entry.modelId,
reviewed_at: reviewedAt,
reviewer_role: "dada_editor_quality_group",
run_id: runId,
status: "blocked",
});
return { reviews, status: reviews.every((review) => review.status === "passed") ? "passed" : "externally_blocked" };
}
+45
View File
@@ -0,0 +1,45 @@
import path from 'node:path';
import { REQUIRED_COVERAGE_UNITS } from './wp7-05-ui-gate.mjs';
const ABSOLUTE_PATH = /^(?:[A-Za-z]:[\\/]|[\\/]{2}|\\\\)/;
function assertSafeRelative(value, field) {
if (typeof value !== 'string' || !value || ABSOLUTE_PATH.test(value) || path.isAbsolute(value)) {
throw new Error(`WP7_05_UNSAFE_${field}`);
}
const normalized = value.replaceAll('\\', '/');
if (normalized.split('/').includes('..')) throw new Error(`WP7_05_UNSAFE_${field}`);
return normalized;
}
export function buildCoverageEvidence({ runId, candidateSha256, coverageUnits, viewports }) {
if (!runId || !/^[A-Za-z0-9._-]+$/.test(runId)) throw new Error('WP7_05_INVALID_RUN_ID');
if (!/^[A-Fa-f0-9]{64}$/.test(candidateSha256 ?? '')) throw new Error('WP7_05_INVALID_CANDIDATE_HASH');
if (!Array.isArray(coverageUnits)) throw new Error('WP7_05_COVERAGE_UNITS_REQUIRED');
const byPage = new Map();
for (const unit of coverageUnits) {
if (!REQUIRED_COVERAGE_UNITS.includes(unit.page_id)) throw new Error('WP7_05_UNKNOWN_PAGE');
if (byPage.has(unit.page_id)) throw new Error('WP7_05_DUPLICATE_PAGE');
if (!Array.isArray(unit.states) || unit.states.length === 0) throw new Error('WP7_05_STATES_REQUIRED');
const states = unit.states.map((state) => ({
state: assertSafeRelative(state.state, 'STATE'),
screenshot_100pct: assertSafeRelative(state.screenshot_100pct, 'SCREENSHOT'),
screenshot_200pct: assertSafeRelative(state.screenshot_200pct, 'SCREENSHOT'),
trace: assertSafeRelative(state.trace, 'TRACE'),
}));
byPage.set(unit.page_id, { page_id: unit.page_id, states });
}
const missing = REQUIRED_COVERAGE_UNITS.filter((page) => !byPage.has(page));
if (missing.length) throw new Error(`WP7_05_MISSING_PAGES:${missing.join(',')}`);
if (!Array.isArray(viewports) || viewports.length !== 2) throw new Error('WP7_05_VIEWPORTS_REQUIRED');
return {
schema_version: '1.0',
task: 'TASK-WP7-05',
run_id: runId,
candidate_sha256: candidateSha256.toUpperCase(),
viewports,
coverage_units: REQUIRED_COVERAGE_UNITS.map((page) => byPage.get(page)),
};
}
+71
View File
@@ -0,0 +1,71 @@
import fs from 'node:fs';
export const REQUIRED_COVERAGE_UNITS = Object.freeze([
'support-gate', 'user-auth', 'workspace', 'current-task', 'projects',
'project-detail', 'editor', 'export', 'credits', 'settings',
'preview-user-variant', 'admin-auth', 'admin-overview', 'admin-users',
'admin-invites', 'admin-models', 'admin-assets', 'admin-preview',
'admin-generations', 'admin-services-storage', 'admin-audit', 'system-ui',
]);
const REQUIRED_VIEWPORTS = Object.freeze([
{ width: 1920, height: 1080, deviceScaleFactor: 1, zoom: 100 },
{ width: 1920, height: 1080, deviceScaleFactor: 1, zoom: 200 },
]);
function blocked(code, details = {}) {
return { status: 'externally_blocked', code, ...details };
}
export function loadCandidateRecord(path) {
if (!path || !fs.existsSync(path)) return blocked('candidate_record_missing');
try {
const record = JSON.parse(fs.readFileSync(path, 'utf8'));
if (!Array.isArray(record.browsers) || record.browsers.length !== 2) {
return blocked('candidate_browser_record_incomplete');
}
const brands = new Set(record.browsers.map((browser) => browser.brand));
if (brands.size !== 2 || !brands.has('Google Chrome') || !brands.has('Microsoft Edge')) {
return blocked('candidate_browser_pair_invalid');
}
if (record.windows?.build == null || !record.candidate_package?.sha256 || !record.candidate_package?.fixed_port) {
return blocked('candidate_identity_incomplete');
}
if (record.browsers.some((browser) => !browser.full_version || !browser.major)) {
return blocked('candidate_full_version_missing');
}
return { status: 'ready', record };
} catch {
return blocked('candidate_record_invalid');
}
}
export function validateCoverageEvidence(evidence) {
if (!evidence || !Array.isArray(evidence.coverage_units)) {
return blocked('coverage_evidence_missing');
}
const actual = new Set(evidence.coverage_units.map((unit) => unit.page_id));
const missing = REQUIRED_COVERAGE_UNITS.filter((unit) => !actual.has(unit));
if (missing.length) return blocked('coverage_units_incomplete', { missing });
const missingStates = evidence.coverage_units
.filter((unit) => REQUIRED_COVERAGE_UNITS.includes(unit.page_id))
.filter((unit) => !Array.isArray(unit.states) || unit.states.length === 0)
.map((unit) => unit.page_id);
if (missingStates.length) return blocked('coverage_states_incomplete', { missingStates });
const viewportKeys = new Set((evidence.viewports ?? []).map((viewport) => JSON.stringify(viewport)));
const missingViewports = REQUIRED_VIEWPORTS.filter((viewport) => !viewportKeys.has(JSON.stringify(viewport)));
if (missingViewports.length) return blocked('candidate_viewports_incomplete', { missingViewports });
return { status: 'ready' };
}
export function runWp705Gate({ candidatePath, evidence, dependencies = {} }) {
const candidate = loadCandidateRecord(candidatePath);
if (candidate.status !== 'ready') return candidate;
const coverage = validateCoverageEvidence(evidence);
if (coverage.status !== 'ready') return coverage;
const externalBlockers = Object.entries(dependencies)
.filter(([, status]) => status === 'externally_blocked')
.map(([task]) => task);
if (externalBlockers.length) return blocked('upstream_external_blocked', { externalBlockers });
return { status: 'ready_for_execution' };
}
+62
View File
@@ -0,0 +1,62 @@
const EXPECTED_TRACE_SUMMARY = Object.freeze({
acceptanceCriteria: 52,
errorCategories: 9,
featureModules: 13,
parentFamilies: 89,
penProductFrames: 18,
productContracts: 19,
requirements: 109,
tasks: 52,
testCases: 117,
uiPages: 22,
});
const REQUIRED_UPSTREAM = Object.freeze({
"TASK-WP7-01": "passed",
"TASK-WP7-02": "passed",
"TASK-WP7-03": "deferred_nonblocking_first_version",
"TASK-WP7-04": "deferred_nonblocking_first_version",
"TASK-WP7-05": "passed",
});
const shaPattern = /^[0-9a-f]{40}$/i;
export function buildWp706PrefreezeReport({ currentCommit, releaseExists, trace, upstream }) {
if (releaseExists) throw new Error("WP7_06_RELEASE_WRITTEN_PREMATURELY");
if (!shaPattern.test(currentCommit ?? "")) throw new Error("WP7_06_CURRENT_COMMIT_INVALID");
if (trace?.status !== "passed" || !Array.isArray(trace?.errors) || trace.errors.length > 0) {
throw new Error("WP7_06_TRACE_VALIDATION_FAILED");
}
for (const [key, expected] of Object.entries(EXPECTED_TRACE_SUMMARY)) {
if (trace.summary?.[key] !== expected) throw new Error(`WP7_06_TRACE_COUNT_MISMATCH:${key}`);
}
for (const [taskId, expectedStatus] of Object.entries(REQUIRED_UPSTREAM)) {
const item = upstream?.[taskId];
if (!item || !shaPattern.test(item.head ?? "")) throw new Error(`WP7_06_UPSTREAM_HEAD_INVALID:${taskId}`);
if (item.merged !== true) throw new Error(`WP7_06_UPSTREAM_NOT_MERGED:${taskId}`);
if (item.status !== expectedStatus) throw new Error(`WP7_06_UNSUPPORTED_STATUS:${taskId}`);
}
return {
schema_version: "1.0",
task_id: "TASK-WP7-06",
status: "passed",
current_commit: currentCommit.toLowerCase(),
release_json_written: false,
trace_summary: { ...EXPECTED_TRACE_SUMMARY },
upstream: Object.fromEntries(Object.entries(REQUIRED_UPSTREAM).map(([taskId]) => [taskId, {
branch: upstream[taskId].branch,
head: upstream[taskId].head.toLowerCase(),
merged: true,
status: upstream[taskId].status,
}])),
deferred_external_tasks: Object.entries(REQUIRED_UPSTREAM)
.filter(([, status]) => status === "deferred_nonblocking_first_version")
.map(([taskId]) => taskId),
final_release_allowed: false,
next_task: "TASK-WP7-07",
};
}
export { EXPECTED_TRACE_SUMMARY, REQUIRED_UPSTREAM };
+96
View File
@@ -0,0 +1,96 @@
import { createHash } from "node:crypto";
import { readFileSync, readdirSync, statSync } from "node:fs";
import { extname, join, relative } from "node:path";
const SHA40 = /^[a-f0-9]{40}$/i;
const SHA64 = /^[a-f0-9]{64}$/i;
const VERSION = /^[1-9][0-9]*\.[0-9]+\.[0-9]+\.[0-9]+$/;
const ABSOLUTE_PATH = /(?:[A-Za-z]:[\\/](?:Users|Documents)[\\/][^\\/"'\s]+[\\/]|\/Users\/[^/"'\s]+\/|\/home\/[^/"'\s]+\/)/;
const CREDENTIAL = /\b(?:sk|key)-[A-Za-z0-9_-]{16,}\b|-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/i;
const TEXT_EXTENSIONS = new Set([".cjs", ".cs", ".css", ".html", ".js", ".json", ".mjs", ".ts", ".tsx", ".txt", ".xml", ".yaml", ".yml"]);
export const DEFERRED_EXTERNAL_TASKS = Object.freeze(["TASK-WP7-03", "TASK-WP7-04"]);
export function buildFinalReleaseRecord({ appVersion, browsers, buildCommit, frozenFromCommit, recordedAt, windows }) {
const record = {
appVersion,
browsers: browsers.map(({ brand, fullVersion }) => ({ brand, fullVersion })),
buildCommit: buildCommit.toLowerCase(),
deferredExternalTasks: [...DEFERRED_EXTERNAL_TASKS],
finalRelease: true,
fixedPort: 43121,
frozenFromCommit: frozenFromCommit.toLowerCase(),
recordedAt,
releaseStatus: "first_version_internal",
schemaVersion: "1.0",
windows: { arch: windows.arch, build: windows.build, displayVersion: windows.displayVersion },
};
return validateFinalReleaseRecord(record);
}
export function validateFinalReleaseRecord(record) {
const errors = [];
if (record?.schemaVersion !== "1.0") errors.push("schemaVersion");
if (record?.releaseStatus !== "first_version_internal") errors.push("releaseStatus");
if (record?.finalRelease !== true) errors.push("finalRelease");
if (record?.fixedPort !== 43121) errors.push("fixedPort");
if (!SHA40.test(record?.buildCommit ?? "")) errors.push("buildCommit");
if (!SHA40.test(record?.frozenFromCommit ?? "")) errors.push("frozenFromCommit");
if (!Number.isFinite(Date.parse(record?.recordedAt ?? ""))) errors.push("recordedAt");
if (!Array.isArray(record?.deferredExternalTasks) || record.deferredExternalTasks.join("|") !== DEFERRED_EXTERNAL_TASKS.join("|")) errors.push("deferredExternalTasks");
if (record?.windows?.arch !== "x64" || !/^\d+\.\d+$/.test(record?.windows?.build ?? "")) errors.push("windows");
if (!Array.isArray(record?.browsers) || record.browsers.length !== 2) {
errors.push("browsers");
} else {
const brands = record.browsers.map(({ brand }) => brand).sort();
if (brands.join("|") !== "Google Chrome|Microsoft Edge") errors.push("browserBrands");
for (const browser of record.browsers) {
if (!VERSION.test(browser.fullVersion ?? "")) errors.push(`${browser.brand}.fullVersion`);
if ("path" in browser || "executablePath" in browser || "executableSha256" in browser) errors.push(`${browser.brand}.privateMetadata`);
}
}
const serialized = JSON.stringify(record);
if (ABSOLUTE_PATH.test(serialized) || CREDENTIAL.test(serialized)) errors.push("sensitiveValue");
if (errors.length > 0) throw new Error(`WP7_07_RELEASE_INVALID:${[...new Set(errors)].join(",")}`);
return record;
}
export function sha256File(path) {
return createHash("sha256").update(readFileSync(path)).digest("hex").toUpperCase();
}
export function scanReleaseFiles({ roots, allowedFixturePaths = [] }) {
const allowed = new Set(allowedFixturePaths.map((value) => value.replaceAll("\\", "/")));
const findings = [];
let scannedFiles = 0;
function visit(root, current = root) {
for (const entry of readdirSync(current, { withFileTypes: true })) {
if ([".git", ".pnpm-store", "node_modules", "bin", "obj"].includes(entry.name)) continue;
const path = join(current, entry.name);
if (entry.isDirectory()) {
visit(root, path);
continue;
}
if (!entry.isFile()) continue;
scannedFiles += 1;
if (!TEXT_EXTENSIONS.has(extname(entry.name).toLowerCase())) continue;
const logicalPath = relative(root, path).replaceAll("\\", "/");
const content = readFileSync(path, "utf8");
if (!allowed.has(logicalPath) && ABSOLUTE_PATH.test(content)) findings.push({ path: logicalPath, rule: "absolute_user_path" });
if (!allowed.has(logicalPath) && CREDENTIAL.test(content)) findings.push({ path: logicalPath, rule: "credential_shape" });
}
}
for (const root of roots) {
if (!statSync(root).isDirectory()) throw new Error(`WP7_07_SCAN_ROOT_INVALID:${root}`);
visit(root);
}
return { findings, scanned_files: scannedFiles, status: findings.length === 0 ? "passed" : "failed" };
}
export function validateFinalEvidence({ packageManifest, release, releaseSha256, scan }) {
validateFinalReleaseRecord(release);
if (!SHA64.test(releaseSha256 ?? "")) throw new Error("WP7_07_RELEASE_HASH_INVALID");
if (packageManifest?.release_status !== release.releaseStatus || !SHA64.test(packageManifest?.zip_sha256 ?? "")) throw new Error("WP7_07_PACKAGE_MANIFEST_INVALID");
if (scan?.status !== "passed" || scan.findings?.length !== 0) throw new Error("WP7_07_LEAK_SCAN_FAILED");
return { release_sha256: releaseSha256.toUpperCase(), status: "passed", zip_sha256: packageManifest.zip_sha256.toUpperCase() };
}
+47
View File
@@ -0,0 +1,47 @@
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
import { WP7_02_MODEL_IDS } from "./lib/wp7-02-external-contract.mjs";
import { validateSanitizedEvidence } from "./lib/wp7-02-controlled-executor.mjs";
import { reviewIndependentModelEvidence } from "./lib/wp7-02-manual-review.mjs";
const caseDirectory = process.env.DADA_WP7_02_CASE_DIR;
const runId = process.env.DADA_TDD_RUN_ID;
const confirmed = process.argv.includes("--confirm-manual-review");
function readJson(path) {
return validateSanitizedEvidence(JSON.parse(readFileSync(path, "utf8")));
}
function output(value, error = false) {
const serialized = JSON.stringify(validateSanitizedEvidence(value));
if (error) console.error(serialized); else console.log(serialized);
}
try {
if (!confirmed || !caseDirectory || !runId) throw new Error("WP7_02_MANUAL_REVIEW_CONFIRMATION_REQUIRED");
const entries = [];
for (const modelId of WP7_02_MODEL_IDS) {
const directory = resolve(caseDirectory, modelId.replaceAll(".", "_"));
const paths = ["contract-matrix.json", "external-calls.json", "readiness.json", "redaction.json"]
.map((name) => resolve(directory, name));
if (paths.some((path) => !existsSync(path))) throw new Error("WP7_02_MANUAL_REVIEW_EVIDENCE_MISSING");
const matrix = readJson(paths[0]);
const externalCalls = readJson(paths[1]);
const readiness = readJson(paths[2]);
const redaction = readJson(paths[3]);
entries.push({ directory, externalCalls, matrix, modelId, readiness, redaction });
}
const result = reviewIndependentModelEvidence(entries, { reviewedAt: new Date().toISOString(), runId });
for (let index = 0; index < entries.length; index += 1) {
const review = validateSanitizedEvidence(result.reviews[index]);
writeFileSync(resolve(entries[index].directory, "manual-review.json"), `${JSON.stringify(review, null, 2)}\n`);
}
output({ reviewed: result.reviews.map(({ model_id, status }) => ({ model_id, status })), run_id: runId, status: result.status }, result.status !== "passed");
if (result.status !== "passed") process.exitCode = 3;
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
const code = /^WP7_02_[A-Z0-9_:]+$/.test(message) ? message : "WP7_02_MANUAL_REVIEW_FAILED";
output({ code, run_id: runId, status: "externally_blocked" }, true);
process.exitCode = 3;
}
+8 -3
View File
@@ -1,7 +1,8 @@
import { createHash } from "node:crypto";
import { spawnSync } from "node:child_process";
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
import { homedir } from "node:os";
import { join, resolve } from "node:path";
const phaseIndex = process.argv.indexOf("--phase");
const phase = phaseIndex >= 0 ? process.argv[phaseIndex + 1] : "green";
@@ -10,6 +11,7 @@ if (!new Set(["red", "green"]).has(phase)) throw new Error(`Unsupported phase: $
const runId = process.env.DADA_TDD_RUN_ID ?? `wp6-04-${phase}-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
const runDirectory = resolve("artifacts", "tdd", runId);
const caseDirectory = resolve(runDirectory, "cases", "TDD-WP6-AUD-001-sensitive-operations");
const replicationRoot = resolve(process.env.DADA_REPLICATION_ASSET_ROOT ?? join(homedir(), "Desktop", "sticker_web_replication_assets"));
if (existsSync(runDirectory)) throw new Error(`Evidence run already exists: ${runId}`);
mkdirSync(caseDirectory, { recursive: true });
@@ -17,6 +19,9 @@ const environment = {
...process.env,
DADA_EVIDENCE_DIR_WP6_AUD: caseDirectory,
DADA_PLAYWRIGHT_OUTPUT_DIR: resolve(runDirectory, "playwright-output"),
DADA_STATIC_STICKER_ROOT: process.env.DADA_STATIC_STICKER_ROOT ?? join(replicationRoot, "sticker_normal"),
DADA_DYNAMIC_ASSET_ROOT: process.env.DADA_DYNAMIC_ASSET_ROOT ?? join(replicationRoot, "sticker_interactive", "单模板归档", "templates"),
DADA_TEXT_ASSET_ROOT: process.env.DADA_TEXT_ASSET_ROOT ?? join(replicationRoot, "sticker_text"),
};
const commands = phase === "red"
? [
@@ -25,8 +30,8 @@ const commands = phase === "red"
["e2e-red", ".\\node_modules\\.bin\\playwright.CMD test tests/e2e/wp6-04-audit.spec.ts --config playwright.config.ts"],
]
: [
["integration", "pnpm.cmd test:integration"],
["api", "pnpm.cmd test:api"],
["integration", "pnpm.cmd exec vitest run tests/integration --testTimeout=20000"],
["api", "pnpm.cmd check:openapi && pnpm.cmd exec vitest run tests/api --testTimeout=20000"],
["worker", "pnpm.cmd test:worker"],
["e2e", "pnpm.cmd test:e2e"],
["tdd-trace", "pnpm.cmd validate:tdd-trace"],
+239
View File
@@ -0,0 +1,239 @@
import { createHash } from "node:crypto";
import { spawnSync } from "node:child_process";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
import {
WP7_02_MODEL_IDS,
validateCandidateDependency,
validateIndependentEvidenceSet,
} from "./lib/wp7-02-external-contract.mjs";
import { validateSanitizedEvidence } from "./lib/wp7-02-controlled-executor.mjs";
const wp701Sha = "623cad25b2a2a9a003502c9a92ebd318dad06248";
const candidateRunId = "wp7-01-candidate-20260804052447717";
const controlledReal = process.argv.includes("--controlled-real");
const runId = process.env.DADA_TDD_RUN_ID ?? `wp7-02-${controlledReal ? "controlled" : "readiness"}-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
const runDirectory = resolve("artifacts", "tdd", runId);
const caseDirectory = resolve(runDirectory, "cases", "TDD-WP7-EXT-001-three-real-models");
const candidatePath = process.env.DADA_WP7_01_CANDIDATE_RECORD;
const configPath = resolve(process.env.DADA_WP7_02_MODEL_CONFIG_MANIFEST ?? "config/wp7-02-oneapi-test.json");
process.on("uncaughtException", (error) => {
const message = error instanceof Error ? error.message : String(error);
const code = /^WP7_02_[A-Z0-9_:]+$/.test(message) ? message : "WP7_02_VALIDATION_FAILED";
console.error(JSON.stringify({ code, real_calls: 0, run_id: runId, status: "failed" }));
process.exit(1);
});
if (existsSync(runDirectory)) throw new Error("WP7_02_EVIDENCE_RUN_ALREADY_EXISTS");
if (!candidatePath || !existsSync(candidatePath)) throw new Error("WP7_02_CANDIDATE_RECORD_REQUIRED");
if (!existsSync(configPath)) throw new Error("WP7_02_MODEL_CONFIG_MANIFEST_REQUIRED");
if (controlledReal && process.env.DADA_WP7_02_CONTROLLED_REAL_CONFIRMATION !== "authorized-120") {
throw new Error("WP7_02_CONTROLLED_REAL_CONFIRMATION_REQUIRED");
}
mkdirSync(caseDirectory, { recursive: true });
function sha256(path) {
return createHash("sha256").update(readFileSync(path)).digest("hex").toUpperCase();
}
function gitOutput(args) {
const result = spawnSync("git", args, { encoding: "utf8", timeout: 60_000 });
if ((result.status ?? 1) !== 0) throw new Error(`WP7_02_GIT_COMMAND_FAILED:${args[0]}`);
return result.stdout.trim();
}
function remoteSha(branch) {
const result = spawnSync("git", ["ls-remote", "--heads", "origin", `refs/heads/${branch}`], { encoding: "utf8", timeout: 60_000 });
if ((result.status ?? 1) !== 0) throw new Error("WP7_02_REMOTE_UNREADABLE");
return result.stdout.trim().split(/\s+/)[0];
}
function verifyUpstream() {
const remote = remoteSha("codex/wp7-01");
if (remote !== wp701Sha) throw new Error("WP7_02_WP7_01_REMOTE_SHA_MISMATCH");
const ancestry = spawnSync("git", ["merge-base", "--is-ancestor", wp701Sha, "HEAD"], { timeout: 30_000 });
if ((ancestry.status ?? 1) !== 0) throw new Error("WP7_02_WP7_01_NOT_ANCESTOR");
return remote;
}
function run(name, command, args, options = {}) {
const started_at = new Date().toISOString();
const result = spawnSync(command, args, {
encoding: "utf8",
env: { ...process.env, ...(options.env ?? {}) },
maxBuffer: 64 * 1024 * 1024,
timeout: options.timeout ?? 300_000,
windowsHide: true,
});
return {
command: options.logicalCommand ?? [command, ...args].join(" "),
exit_code: result.status ?? 1,
finished_at: new Date().toISOString(),
name,
started_at,
};
}
function pnpmRun(name, commandLine, options = {}) {
const command = process.platform === "win32" ? (process.env.ComSpec ?? "cmd.exe") : "pnpm";
const args = process.platform === "win32" ? ["/d", "/c", commandLine] : commandLine.replace(/^pnpm\s+/, "").split(" ");
return run(name, command, args, { ...options, logicalCommand: commandLine });
}
function readJson(path) {
return validateSanitizedEvidence(JSON.parse(readFileSync(path, "utf8")));
}
const upstreamRemoteSha = verifyUpstream();
const candidate = validateCandidateDependency(JSON.parse(readFileSync(candidatePath, "utf8")));
const commands = [
run("contract-harness", process.execPath, ["--test", "tests/package/wp7-02-external-contract.test.mjs", "tests/package/wp7-02-controlled-executor.test.mjs"], {
logicalCommand: "node --test tests/package/wp7-02-external-contract.test.mjs tests/package/wp7-02-controlled-executor.test.mjs",
}),
pnpmRun("deterministic-state", "pnpm exec vitest run tests/integration/wp7-02-controlled-state.test.ts", {
env: { DADA_WP7_02_STATE_EVIDENCE_ROOT: caseDirectory }, timeout: 120_000,
}),
run("supervisor-build", "dotnet", ["build", "supervisor/Dada.Supervisor/Dada.Supervisor.csproj", "--no-restore"], {
logicalCommand: "dotnet build supervisor/Dada.Supervisor/Dada.Supervisor.csproj --no-restore", timeout: 120_000,
}),
pnpmRun("tdd-trace", "pnpm validate:tdd-trace"),
pnpmRun("security", "pnpm test:security"),
];
const firstAutomationFailure = commands.find((command) => command.exit_code !== 0);
if (firstAutomationFailure) {
writeFileSync(resolve(caseDirectory, "commands.json"), `${JSON.stringify({ commands, run_id: runId }, null, 2)}\n`);
console.error(JSON.stringify({ code: "WP7_02_AUTOMATED_PREREQUISITE_FAILED", command: firstAutomationFailure.command, exit_code: firstAutomationFailure.exit_code, real_calls: 0, run_id: runId, status: "failed" }));
process.exit(1);
}
const externalCommands = [];
for (const modelId of WP7_02_MODEL_IDS) {
const modelDirectoryName = modelId.replaceAll(".", "_");
const modelDirectory = resolve(caseDirectory, modelDirectoryName);
const flags = controlledReal
? `--max-real-calls 120 --confirm-controlled-real --execute-controlled-real`
: "--confirm-controlled-real --readiness-only";
const commandLine = `pnpm validate:external -- --service ai-gateway-service-id --model ${modelId} --run-id ${runId} ${flags}`;
externalCommands.push(pnpmRun(`${controlledReal ? "controlled" : "readiness"}-${modelId}`, commandLine, {
env: {
DADA_WP7_01_CANDIDATE_RECORD: candidatePath,
DADA_WP7_02_EVIDENCE_DIR: modelDirectory,
DADA_WP7_02_MODEL_CONFIG_MANIFEST: configPath,
},
timeout: 20 * 60_000,
}));
}
commands.push(...externalCommands);
const externalExitCodesValid = controlledReal
? externalCommands.every((command) => command.exit_code === 0 || command.exit_code === 3)
: externalCommands.every((command) => command.exit_code === 3);
if (!externalExitCodesValid) {
writeFileSync(resolve(caseDirectory, "commands.json"), `${JSON.stringify({ commands, run_id: runId }, null, 2)}\n`);
const failed = externalCommands.find((command) => ![0, 3].includes(command.exit_code));
console.error(JSON.stringify({ code: "WP7_02_EXTERNAL_COMMAND_FAILED", command: failed?.command, exit_code: failed?.exit_code, real_calls: 0, run_id: runId, status: "failed" }));
process.exit(1);
}
if (controlledReal) {
const manualConfirmed = process.env.DADA_WP7_02_MANUAL_REVIEW_CONFIRMATION === "confirmed";
const manual = run("manual-review", process.execPath, ["scripts/record-wp7-02-manual-review.mjs", ...(manualConfirmed ? ["--confirm-manual-review"] : [])], {
env: { DADA_TDD_RUN_ID: runId, DADA_WP7_02_CASE_DIR: caseDirectory },
logicalCommand: `pnpm review:wp7-02${manualConfirmed ? " -- --confirm-manual-review" : ""}`,
});
commands.push(manual);
if (![0, 3].includes(manual.exit_code)) {
writeFileSync(resolve(caseDirectory, "commands.json"), `${JSON.stringify({ commands, run_id: runId }, null, 2)}\n`);
console.error(JSON.stringify({ code: "WP7_02_MANUAL_REVIEW_COMMAND_FAILED", command: manual.command, exit_code: manual.exit_code, real_calls: 0, run_id: runId, status: "failed" }));
process.exit(1);
}
}
const modelEvidence = WP7_02_MODEL_IDS.map((modelId) => {
const directory = resolve(caseDirectory, modelId.replaceAll(".", "_"));
const readiness = readJson(resolve(directory, "readiness.json"));
return {
blockers: readiness.blockers,
candidate: readiness.candidate,
evidence_id: readiness.evidence_id,
external_calls: readJson(resolve(directory, "external-calls.json")),
manual_review: readJson(resolve(directory, "manual-review.json")),
matrix: readJson(resolve(directory, "contract-matrix.json")),
model_id: readiness.model_id,
redaction: readJson(resolve(directory, "redaction.json")),
run_id: readiness.run_id,
status: readiness.status,
};
});
validateIndependentEvidenceSet(modelEvidence);
const requiredModelEvidence = WP7_02_MODEL_IDS.flatMap((modelId) => {
const directory = modelId.replaceAll(".", "_");
return ["contract-matrix.json", "deterministic-state.json", "external-calls.json", "manual-review.json", "readiness.json", "redaction.json"]
.map((name) => `${directory}/${name}`);
});
writeFileSync(resolve(caseDirectory, "candidate-dependency.json"), `${JSON.stringify({
candidate_run_id: candidateRunId,
record: candidate,
remote_branch: "codex/wp7-01",
remote_commit: upstreamRemoteSha,
status: "passed",
}, null, 2)}\n`);
writeFileSync(resolve(caseDirectory, "commands.json"), `${JSON.stringify({ commands, run_id: runId }, null, 2)}\n`);
const evidenceRefs = ["candidate-dependency.json", "commands.json", ...requiredModelEvidence];
const missingEvidence = evidenceRefs.filter((path) => !existsSync(resolve(caseDirectory, path)));
const allModelsPassed = modelEvidence.every((entry) => entry.status === "passed" && entry.manual_review.status === "passed");
const commit = gitOutput(["rev-parse", "HEAD"]);
const remoteCommit = remoteSha("codex/wp7-02");
const dirty = gitOutput(["status", "--porcelain"]).length > 0;
const deliveryMatched = !dirty && commit === remoteCommit;
const status = missingEvidence.length > 0 ? "failed"
: allModelsPassed && deliveryMatched ? "passed"
: allModelsPassed ? "green"
: "externally_blocked";
const blockersByModel = Object.fromEntries(modelEvidence.map((entry) => [entry.model_id, entry.blockers]));
const realCalls = modelEvidence.reduce((total, entry) => total + entry.external_calls.real_calls, 0);
if (realCalls > 120) throw new Error("WP7_02_REAL_CALL_LIMIT_EXCEEDED");
const result = {
acceptance_criteria: ["AC-40", "AC-41"],
automation: ["controlled_real", "manual_review"],
blockers_by_model: blockersByModel,
candidate_run_id: candidateRunId,
commit,
evidence_refs: evidenceRefs,
fixture_ids: ["FX-WP7-CONTROLLED-REFERENCE"],
layer: ["EXT-REAL", "MANUAL"],
manifest: { path: "tasks.manifest.json", sha256: sha256("tasks.manifest.json") },
missing_evidence: missingEvidence,
phase: controlledReal ? "controlled_real" : "controlled_real_readiness",
real_calls: realCalls,
red_reason: "任一模型缺独立真实契约证据",
release_gate: ["release:P0-A"],
remote_branch: "codex/wp7-02",
remote_commit: remoteCommit,
requirements: ["GEN-13"],
run_id: runId,
status,
task_id: "TASK-WP7-02",
test_id: "TDD-WP7-EXT-001-three-real-models",
work_package: "WP-7",
worktree_under_test: dirty ? "uncommitted implementation" : "clean committed implementation",
};
writeFileSync(resolve(caseDirectory, "result.json"), `${JSON.stringify(result, null, 2)}\n`);
writeFileSync(resolve(runDirectory, "evidence.json"), `${JSON.stringify({
cases: [{ blockers_by_model: blockersByModel, missing_evidence: missingEvidence, status, test_id: result.test_id }],
candidate_run_id: candidateRunId,
commit,
phase: result.phase,
real_calls: realCalls,
redaction_scan: "passed",
remote_commit: remoteCommit,
run_id: runId,
status,
task_id: result.task_id,
}, null, 2)}\n`);
console.log(JSON.stringify({ blockers_by_model: blockersByModel, candidate_run_id: candidateRunId, real_calls: realCalls, run_id: runId, status }));
if (status === "failed") process.exit(1);
+261
View File
@@ -0,0 +1,261 @@
import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
const runId = process.env.DADA_TDD_RUN_ID ?? `wp7-04-amap-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
const runDirectory = resolve("artifacts", "tdd", runId);
const caseDirectory = resolve(runDirectory, "cases", "TDD-WP7-EXT-003-real-amap");
if (existsSync(runDirectory)) throw new Error(`Evidence run already exists: ${runId}`);
mkdirSync(caseDirectory, { recursive: true });
function run(command, args, evidenceCommand = [command, ...args].join(" ")) {
const startedAt = new Date().toISOString();
const executable = process.platform === "win32" ? (process.env.ComSpec ?? "cmd.exe") : command;
const actualArgs = process.platform === "win32" ? ["/d", "/s", "/c", [command, ...args].join(" ")] : args;
const result = spawnSync(executable, actualArgs, { encoding: "utf8" });
return {
command: evidenceCommand,
exit_code: result.status ?? 1,
finished_at: new Date().toISOString(),
stderr: result.stderr ?? "",
stdout: result.stdout ?? "",
started_at: startedAt,
};
}
function skipped(command) {
const timestamp = new Date().toISOString();
return { command, exit_code: 1, finished_at: timestamp, started_at: timestamp, stderr: "prerequisite_failed", stdout: "" };
}
function readConsoleReview() {
const raw = process.env.DADA_AMAP_CONSOLE_REVIEW_JSON;
const fallback = {
allowlist: "not_verified",
auto_scaling: "not_verified",
paid_fallback: "not_verified",
qps: "not_verified",
qps_limit_per_second: null,
reviewed_at: null,
security_restriction: "not_verified",
service_binding: "not_verified",
source: "not_supplied",
valid: true,
};
if (!raw) return fallback;
try {
const parsed = JSON.parse(raw);
const requiredKeys = ["allowlist", "auto_scaling", "paid_fallback", "qps", "qps_limit_per_second", "reviewed_at", "security_restriction", "service_binding", "source"];
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || Object.keys(parsed).sort().join("|") !== requiredKeys.sort().join("|")) {
return { ...fallback, source: "invalid_input", valid: false };
}
const statusFields = ["allowlist", "qps", "security_restriction", "service_binding"];
const statusValid = statusFields.every((field) => ["failed", "not_verified", "passed"].includes(parsed[field]));
const disabledFieldsValid = ["auto_scaling", "paid_fallback"].every((field) => ["disabled", "not_verified"].includes(parsed[field]));
const qpsLimitValid = parsed.qps === "passed"
? Number.isSafeInteger(parsed.qps_limit_per_second) && parsed.qps_limit_per_second >= 1 && parsed.qps_limit_per_second <= 1_000
: parsed.qps_limit_per_second === null;
const reviewedAtValid = typeof parsed.reviewed_at === "string" && Number.isFinite(Date.parse(parsed.reviewed_at));
if (!statusValid || !disabledFieldsValid || !qpsLimitValid || !reviewedAtValid || parsed.source !== "amap_console_manual_review") {
return { ...fallback, source: "invalid_input", valid: false };
}
return { ...parsed, valid: true };
} catch {
return { ...fallback, source: "invalid_input", valid: false };
}
}
function writeJson(path, value) {
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
}
function probeCode(value) {
return typeof value === "string" && /^[a-z0-9_]{1,64}$/.test(value) ? value : "invalid_output";
}
function containsForbiddenEvidence(value) {
const serialized = JSON.stringify(value);
return [
/[A-Za-z]:[\\/](?:Users|Documents)[\\/]/i,
/"(?:api[_-]?key|credential|secret_value|latitude|longitude|coordinates|email_address|ip_address)"\s*:/i,
/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/,
].some((pattern) => pattern.test(serialized));
}
const consoleReview = readConsoleReview();
const build = run("pnpm", ["build:workspace-packages"]);
const locationRegression = build.exit_code === 0
? run("pnpm", ["exec", "vitest", "run", "tests/api/wp4-04-location.test.ts"])
: skipped("pnpm exec vitest run tests/api/wp4-04-location.test.ts");
const serviceRegression = build.exit_code === 0
? run("pnpm", ["exec", "vitest", "run", "tests/api/wp6-03-services.test.ts"])
: skipped("pnpm exec vitest run tests/api/wp6-03-services.test.ts");
const localHardStop = build.exit_code === 0
? run("pnpm", ["exec", "vitest", "run", "tests/api/wp7-04-amap-release-gate.test.ts"])
: skipped("pnpm exec vitest run tests/api/wp7-04-amap-release-gate.test.ts");
const productionAdapter = build.exit_code === 0
? run("pnpm", ["exec", "vitest", "run", "tests/api/wp7-04-amap-production-adapter.test.ts"])
: skipped("pnpm exec vitest run tests/api/wp7-04-amap-production-adapter.test.ts");
const consentFlow = build.exit_code === 0
? run("pnpm", ["exec", "vitest", "run", "tests/unit/wp4-04-palette-dynamic.test.ts"])
: skipped("pnpm exec vitest run tests/unit/wp4-04-palette-dynamic.test.ts");
const supervisorBuild = run("dotnet", ["build", "supervisor/Dada.Supervisor/Dada.Supervisor.csproj", "--configuration", "Release"]);
const supervisorSecurity = supervisorBuild.exit_code === 0
? run("dotnet", ["run", "--project", "supervisor/Dada.Supervisor.Tests/Dada.Supervisor.Tests.csproj", "--configuration", "Release"])
: skipped("dotnet run --project supervisor/Dada.Supervisor.Tests/Dada.Supervisor.Tests.csproj --configuration Release");
const supervisorExe = resolve("supervisor", "Dada.Supervisor", "bin", "Release", "net8.0-windows", "Dada.Supervisor.exe");
const external = supervisorBuild.exit_code === 0 && existsSync(supervisorExe)
? run(supervisorExe, ["secrets", "probe", "api-amap"], "Dada.Supervisor.exe secrets probe api-amap")
: skipped("Dada.Supervisor.exe secrets probe api-amap");
const trace = run("pnpm", ["validate:tdd-trace"]);
const security = run("pnpm", ["test:security"]);
const commands = [build, locationRegression, serviceRegression, localHardStop, productionAdapter, consentFlow, supervisorBuild, supervisorSecurity, external, trace, security]
.map(({ command, exit_code, finished_at, started_at }) => ({ command, exit_code, finished_at, started_at }));
const parsedExternal = (() => {
try { return JSON.parse(external.stdout.trim().split(/\r?\n/).at(-1) ?? ""); } catch { return {}; }
})();
const safeProbeCode = probeCode(parsedExternal.code);
const realCalls = Number.isSafeInteger(parsedExternal.real_calls) && parsedExternal.real_calls >= 0 && parsedExternal.real_calls <= 2
? parsedExternal.real_calls
: 0;
const probePassed = external.exit_code === 0 && safeProbeCode === "amap_probe_passed" && realCalls === 2;
const hardStopPassed = localHardStop.exit_code === 0;
const productionAdapterPassed = productionAdapter.exit_code === 0;
const consentPassed = consentFlow.exit_code === 0;
const supervisorSecurityPassed = supervisorSecurity.exit_code === 0;
const regressionPassed = locationRegression.exit_code === 0 && serviceRegression.exit_code === 0;
const automatedPassed = build.exit_code === 0 && hardStopPassed && productionAdapterPassed && consentPassed && supervisorSecurityPassed && regressionPassed && trace.exit_code === 0 && security.exit_code === 0;
const manualReviewPassed = consoleReview.valid
&& consoleReview.service_binding === "passed"
&& consoleReview.qps === "passed"
&& consoleReview.allowlist === "passed"
&& consoleReview.security_restriction === "passed"
&& consoleReview.paid_fallback === "disabled"
&& consoleReview.auto_scaling === "disabled";
const requiredBeforeRelease = [];
if (!probePassed) requiredBeforeRelease.push("real_location_and_reverse_geocode");
if (consoleReview.service_binding !== "passed") requiredBeforeRelease.push("service_binding");
if (consoleReview.qps !== "passed") requiredBeforeRelease.push("qps_confirmation");
if (consoleReview.allowlist !== "passed") requiredBeforeRelease.push("allowlist_confirmation");
if (consoleReview.security_restriction !== "passed") requiredBeforeRelease.push("security_restriction");
if (consoleReview.paid_fallback !== "disabled") requiredBeforeRelease.push("paid_fallback_disabled");
if (consoleReview.auto_scaling !== "disabled") requiredBeforeRelease.push("auto_scaling_disabled");
if (!hardStopPassed) requiredBeforeRelease.push("monthly_1000_hard_stop");
if (!productionAdapterPassed) requiredBeforeRelease.push("production_amap_adapter");
if (!consentPassed) requiredBeforeRelease.push("dyn004_confirmation");
if (!supervisorSecurityPassed) requiredBeforeRelease.push("controlled_probe_security");
const blocker = !automatedPassed
? "automated_regression_failed"
: !probePassed
? safeProbeCode
: !consoleReview.valid
? "manual_review_invalid"
: consoleReview.allowlist === "failed"
? "amap_allowlist_unconfigured"
: consoleReview.security_restriction === "failed"
? "amap_security_restriction_unconfigured"
: !manualReviewPassed
? "manual_acceptance_required"
: null;
const status = !automatedPassed ? "failed" : probePassed && manualReviewPassed ? "passed" : "externally_blocked";
const contractEvidence = {
blocker,
checks: {
allowlist: consoleReview.allowlist === "passed" ? "manual_console_passed" : consoleReview.allowlist,
auto_scaling: consoleReview.auto_scaling,
client_security_controls: productionAdapterPassed && supervisorSecurityPassed ? "automated_passed" : "failed",
controlled_probe_security: supervisorSecurityPassed ? "automated_passed" : "failed",
dyn004_hard_stop: consentPassed ? "confirmation_contract_passed" : "failed",
location_and_reverse_geocode: probePassed ? "real_probe_passed" : "not_verified",
monthly_hard_limit_1000: hardStopPassed ? "local_pre_egress_passed" : "failed",
paid_fallback: consoleReview.paid_fallback,
production_adapter: productionAdapterPassed ? "credential_channel_real_adapter_passed" : "failed",
provider_qps: consoleReview.qps === "passed" ? "manual_console_passed" : consoleReview.qps,
provider_qps_limit_per_second: consoleReview.qps_limit_per_second,
security_binding: consoleReview.security_restriction === "passed" ? "manual_console_passed" : consoleReview.security_restriction,
service_binding: consoleReview.service_binding === "passed" ? "manual_console_passed" : consoleReview.service_binding,
},
mode: probePassed ? "controlled_real" : "blocked",
real_calls: realCalls,
status,
schema_version: "1.1",
};
const externalCallsEvidence = {
blocker,
mode: probePassed ? "controlled_real" : "blocked",
real_calls: realCalls,
request_scope: ["geocoding", "reverse_geocoding"],
service: "amap",
source_command_status: safeProbeCode,
status,
schema_version: "1.1",
};
const manualReviewEvidence = {
blocker,
checks: {
allowlist: consoleReview.allowlist,
auto_scaling: consoleReview.auto_scaling,
paid_fallback: consoleReview.paid_fallback,
qps: consoleReview.qps,
qps_limit_per_second: consoleReview.qps_limit_per_second,
security_restriction: consoleReview.security_restriction,
service_binding: consoleReview.service_binding,
},
required_before_release: requiredBeforeRelease,
reviewed_at: consoleReview.reviewed_at,
source: consoleReview.source,
status,
schema_version: "1.1",
};
const result = {
acceptance_criteria: ["AC-17", "AC-41", "AC-47"],
automation: ["controlled_real", "manual_review"],
blocker,
contract_regression: automatedPassed ? "passed" : "failed",
external_calls: realCalls,
finished_at: new Date().toISOString(),
manifest: { path: "tasks.manifest.json", sha256: createHash("sha256").update(readFileSync("tasks.manifest.json")).digest("hex").toUpperCase() },
missing_evidence: requiredBeforeRelease,
parent_family: "TDD-WP7-EXT-003",
phase: "green",
release_gate: ["release:P0-A"],
requirements: ["DYN-04", "PRIV-03"],
run_id: runId,
schema_version: "1.1",
status,
task_id: "TASK-WP7-04",
test_id: "TDD-WP7-EXT-003-real-amap",
work_package: "WP-7",
};
const commandsEvidence = { commands, run_id: runId, schema_version: "1.1" };
const evidenceIndex = { cases: [{ status: result.status, test_id: result.test_id }], run_id: runId, status: result.status, schema_version: "1.1" };
const redactionInputs = [contractEvidence, externalCallsEvidence, manualReviewEvidence, result, commandsEvidence, evidenceIndex];
const evidenceRedactionPassed = !redactionInputs.some(containsForbiddenEvidence);
const redactionEvidence = {
findings: evidenceRedactionPassed ? [] : ["forbidden_evidence_field"],
forbidden_fields_present: !evidenceRedactionPassed,
source_security_scan: security.exit_code === 0 ? "passed" : "failed",
status: evidenceRedactionPassed && security.exit_code === 0 ? "passed" : "failed",
stored_fields: ["service", "status", "logical_limit", "manual_review_status", "qps_limit_per_second"],
schema_version: "1.1",
};
if (redactionEvidence.status !== "passed") {
result.status = "failed";
result.blocker = "redaction_failed";
evidenceIndex.status = "failed";
evidenceIndex.cases[0].status = "failed";
}
writeJson(resolve(caseDirectory, "amap-contract.json"), contractEvidence);
writeJson(resolve(caseDirectory, "external-calls.json"), externalCallsEvidence);
writeJson(resolve(caseDirectory, "redaction.json"), redactionEvidence);
writeJson(resolve(caseDirectory, "manual-review.json"), manualReviewEvidence);
writeJson(resolve(caseDirectory, "commands.json"), commandsEvidence);
writeJson(resolve(caseDirectory, "result.json"), result);
writeJson(resolve(runDirectory, "evidence.json"), evidenceIndex);
console.log(JSON.stringify(result, null, 2));
if (result.status === "failed") process.exit(1);
+13
View File
@@ -0,0 +1,13 @@
import { runWp705Gate } from './lib/wp7-05-ui-gate.mjs';
const result = runWp705Gate({
candidatePath: process.env.WP7_01_CANDIDATE_RECORD,
evidence: null,
dependencies: {
'TASK-WP7-03': 'externally_blocked',
'TASK-WP7-04': 'externally_blocked',
},
});
console.log(JSON.stringify({ task: 'TASK-WP7-05', ...result }));
process.exitCode = result.status === 'ready_for_execution' ? 0 : 3;
+108
View File
@@ -0,0 +1,108 @@
import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
import { validateTddTrace } from "./lib/tdd-trace.mjs";
import { buildWp706PrefreezeReport, REQUIRED_UPSTREAM } from "./lib/wp7-06-prefreeze.mjs";
const runId = process.env.DADA_TDD_RUN_ID ?? `wp7-06-prefreeze-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
const runDirectory = resolve("artifacts", "tdd", runId);
const caseDirectory = resolve(runDirectory, "cases", "TDD-WP7-AC-001-trace-structure");
if (existsSync(runDirectory)) throw new Error(`Evidence run already exists: ${runId}`);
mkdirSync(caseDirectory, { recursive: true });
function writeJson(path, value) {
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
}
function git(args) {
const result = spawnSync("git", args, { encoding: "utf8", timeout: 60_000 });
if ((result.status ?? 1) !== 0) throw new Error(`WP7_06_GIT_COMMAND_FAILED:${args[0]}`);
return result.stdout.trim();
}
function runCommand(name, command) {
const startedAt = new Date().toISOString();
const result = spawnSync(process.env.ComSpec ?? "cmd.exe", ["/d", "/s", "/c", command], {
encoding: "utf8",
env: process.env,
maxBuffer: 64 * 1024 * 1024,
});
if (result.stdout) process.stdout.write(result.stdout);
if (result.stderr) process.stderr.write(result.stderr);
return {
command,
exit_code: result.status ?? 1,
finished_at: new Date().toISOString(),
name,
started_at: startedAt,
};
}
const commands = [
runCommand("prefreeze-unit", "node --test tests/package/wp7-06-prefreeze.test.mjs"),
runCommand("tdd-trace", "pnpm validate:tdd-trace"),
];
if (commands.some((command) => command.exit_code !== 0)) {
writeJson(resolve(caseDirectory, "commands.json"), { commands, run_id: runId, schema_version: "1.0" });
process.exit(1);
}
const trace = validateTddTrace();
const currentCommit = git(["rev-parse", "HEAD"]);
const remoteLines = git(["ls-remote", "--heads", "origin", "codex/wp7-01", "codex/wp7-02", "codex/wp7-03", "codex/wp7-04", "codex/wp7-05"])
.split(/\r?\n/)
.filter(Boolean);
const remoteHeads = Object.fromEntries(remoteLines.map((line) => {
const [head, reference] = line.split(/\s+/);
return [reference.replace("refs/heads/", ""), head];
}));
const upstream = Object.fromEntries(Object.entries(REQUIRED_UPSTREAM).map(([taskId, status]) => {
const branch = taskId.replace("TASK-", "codex/").toLowerCase();
const head = remoteHeads[branch];
const ancestry = spawnSync("git", ["merge-base", "--is-ancestor", head ?? "missing", "HEAD"], { encoding: "utf8", timeout: 30_000 });
return [taskId, { branch, head, merged: ancestry.status === 0, status }];
}));
const report = buildWp706PrefreezeReport({
currentCommit,
releaseExists: existsSync(resolve("RELEASE.json")),
trace,
upstream,
});
const result = {
acceptance_criteria: Array.from({ length: 56 }, (_, index) => index + 1)
.filter((number) => ![8, 26, 37, 54].includes(number))
.map((number) => `AC-${String(number).padStart(2, "0")}`),
automation: ["automated", "manual_review"],
commit: currentCommit,
evidence_refs: ["commands.json", "trace-summary.json", "upstream-lineage.json", "deferred-external.json"],
finished_at: new Date().toISOString(),
manifest: {
path: "tasks.manifest.json",
sha256: createHash("sha256").update(readFileSync("tasks.manifest.json")).digest("hex").toUpperCase(),
},
missing_evidence: [],
release_gate: ["release:P0-A"],
requirements: ["NFR-05"],
run_id: runId,
schema_version: "1.0",
status: report.status,
task_id: "TASK-WP7-06",
test_id: "TDD-WP7-AC-001-trace-structure",
work_package: "WP-7",
};
writeJson(resolve(caseDirectory, "commands.json"), { commands, run_id: runId, schema_version: "1.0" });
writeJson(resolve(caseDirectory, "trace-summary.json"), { status: trace.status, summary: trace.summary, schema_version: "1.0" });
writeJson(resolve(caseDirectory, "upstream-lineage.json"), { current_commit: currentCommit, tasks: report.upstream, schema_version: "1.0" });
writeJson(resolve(caseDirectory, "deferred-external.json"), {
policy: "product_owner_first_version_nonblocking",
tasks: report.deferred_external_tasks,
treated_as_real_provider_pass: false,
schema_version: "1.0",
});
writeJson(resolve(caseDirectory, "result.json"), result);
writeJson(resolve(runDirectory, "evidence.json"), { cases: [{ missing_evidence: [], status: result.status, test_id: result.test_id }], run_id: runId, status: result.status, schema_version: "1.0" });
console.log(JSON.stringify({ deferred_external_tasks: report.deferred_external_tasks, next_task: report.next_task, run_id: runId, status: report.status }, null, 2));
+157
View File
@@ -0,0 +1,157 @@
import { spawnSync } from "node:child_process";
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { basename, join, resolve } from "node:path";
import { buildAndValidatePortablePackage } from "./lib/portable-package.mjs";
import { readCandidateEnvironment } from "./lib/release-candidate.mjs";
import {
buildFinalReleaseRecord,
scanReleaseFiles,
sha256File,
validateFinalEvidence,
} from "./lib/wp7-07-final-release.mjs";
const runId = process.env.DADA_TDD_RUN_ID ?? `wp7-07-final-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
const runDirectory = resolve("artifacts", "tdd", runId);
const releaseCase = resolve(runDirectory, "cases", "TDD-WP7-REL-001-final-release-record");
const securityCase = resolve(runDirectory, "cases", "TDD-WP7-SEC-001-artifact-leak-scan");
const outputRoot = resolve(".build", "wp7-07-final-release");
if (existsSync(runDirectory)) throw new Error(`Evidence run already exists: ${runId}`);
mkdirSync(releaseCase, { recursive: true });
mkdirSync(securityCase, { recursive: true });
function writeJson(path, value) {
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
}
function git(args) {
const result = spawnSync("git", args, { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, timeout: 120_000 });
if ((result.status ?? 1) !== 0) throw new Error(`WP7_07_GIT_FAILED:${args.join(" ")}`);
return result.stdout.trim();
}
function gitGrep(args) {
const result = spawnSync("git", ["grep", ...args], { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, timeout: 120_000 });
if (![0, 1].includes(result.status ?? 2)) throw new Error("WP7_07_GIT_GREP_FAILED");
return result.status === 0 ? result.stdout.trim() : "";
}
function run(name, command) {
const startedAt = new Date().toISOString();
const result = spawnSync(process.env.ComSpec ?? "cmd.exe", ["/d", "/s", "/c", command], {
encoding: "utf8",
env: process.env,
maxBuffer: 64 * 1024 * 1024,
});
if (result.stdout) process.stdout.write(result.stdout);
if (result.stderr) process.stderr.write(result.stderr);
return { command, exit_code: result.status ?? 1, finished_at: new Date().toISOString(), name, started_at: startedAt };
}
const currentCommit = git(["rev-parse", "HEAD"]);
const prefreezeCommit = git(["ls-remote", "origin", "refs/heads/codex/wp7-06"]).split(/\s+/)[0];
if (!prefreezeCommit || spawnSync("git", ["merge-base", "--is-ancestor", prefreezeCommit, "HEAD"]).status !== 0) {
throw new Error("WP7_07_PREFREEZE_LINEAGE_INVALID");
}
const commands = [
run("unit", "node --test tests/package/wp7-07-final-release.test.mjs"),
run("security", "pnpm test:security"),
run("trace", "pnpm validate:tdd-trace"),
];
if (commands.some(({ exit_code }) => exit_code !== 0)) {
writeJson(join(releaseCase, "commands.json"), { commands, run_id: runId, schema_version: "1.0" });
process.exit(1);
}
const environment = readCandidateEnvironment();
const packageJson = JSON.parse(readFileSync("package.json", "utf8"));
const release = buildFinalReleaseRecord({
appVersion: packageJson.version,
browsers: environment.browsers.map(({ brand, full_version }) => ({ brand, fullVersion: full_version })),
buildCommit: currentCommit,
frozenFromCommit: prefreezeCommit,
recordedAt: new Date().toISOString(),
windows: {
arch: environment.windows.arch,
build: environment.windows.build,
displayVersion: environment.windows.display_version,
},
});
writeJson(resolve("RELEASE.json"), release);
const packageResult = await buildAndValidatePortablePackage({ evidenceDirectory: releaseCase, outputRoot, releaseRecord: release });
const packageDirectory = join(outputRoot, packageResult.packageManifest.package_name);
const zipPath = join(outputRoot, `${packageResult.packageManifest.package_name}.zip`);
const releaseSha256 = sha256File(resolve("RELEASE.json"));
const packageReleaseSha256 = sha256File(join(packageDirectory, "RELEASE.json"));
if (releaseSha256 !== packageReleaseSha256) throw new Error("WP7_07_PACKAGE_RELEASE_DRIFT");
const finalScan = scanReleaseFiles({ roots: [packageDirectory, releaseCase] });
const trackedSensitive = gitGrep(["-I", "-n", "-E", "C:\\\\Users\\\\[^\\\\]+|sk-[A-Za-z0-9_-]{24,}", "HEAD", "--", ":!tests", ":!scripts/lib/wp7-07-final-release.mjs"]);
const scan = {
...finalScan,
git_current_findings: trackedSensitive ? trackedSensitive.split(/\r?\n/).filter(Boolean) : [],
status: finalScan.status === "passed" && !trackedSensitive ? "passed" : "failed",
};
writeJson(join(securityCase, "scan-report.json"), scan);
writeJson(join(securityCase, "allowlist.json"), {
entries: ["tests/**:synthetic security traps", "scripts/lib/wp7-07-final-release.mjs:scanner patterns"],
real_values_allowed: false,
schema_version: "1.0",
});
if (scan.status !== "passed") throw new Error("WP7_07_LEAK_SCAN_FAILED");
const finalEvidence = validateFinalEvidence({ packageManifest: packageResult.packageManifest, release, releaseSha256, scan });
copyFileSync(resolve("RELEASE.json"), join(releaseCase, "RELEASE.json"));
copyFileSync(join(packageDirectory, "START-HERE.txt"), join(releaseCase, "START-HERE.txt"));
writeJson(join(releaseCase, "environment.json"), {
browsers: release.browsers,
fixed_port: release.fixedPort,
windows: release.windows,
schema_version: "1.0",
});
writeJson(join(releaseCase, "final-package.json"), {
file_name: basename(zipPath),
release_sha256: finalEvidence.release_sha256,
release_status: release.releaseStatus,
zip_sha256: finalEvidence.zip_sha256,
schema_version: "1.0",
});
writeJson(join(releaseCase, "commands.json"), { commands, run_id: runId, schema_version: "1.0" });
writeJson(join(releaseCase, "result.json"), {
acceptance_criteria: ["AC-24", "AC-41", "AC-48", "AC-56"],
deferred_external_tasks: release.deferredExternalTasks,
evidence_refs: ["RELEASE.json", "START-HERE.txt", "environment.json", "package-manifest.json", "final-package.json"],
release_gate: ["release:P0-A"],
requirements: ["NFR-01", "NFR-09", "PRIV-01", "PRIV-02"],
status: "passed",
task_id: "TASK-WP7-07",
test_id: "TDD-WP7-REL-001-final-release-record",
});
writeJson(join(securityCase, "result.json"), {
evidence_refs: ["scan-report.json", "allowlist.json"],
status: "passed",
task_id: "TASK-WP7-07",
test_id: "TDD-WP7-SEC-001-artifact-leak-scan",
});
writeJson(join(runDirectory, "evidence.json"), {
cases: [
{ missing_evidence: [], status: "passed", test_id: "TDD-WP7-REL-001-final-release-record" },
{ missing_evidence: [], status: "passed", test_id: "TDD-WP7-SEC-001-artifact-leak-scan" },
],
deferred_external_tasks: release.deferredExternalTasks,
release_sha256: finalEvidence.release_sha256,
run_id: runId,
status: "passed",
zip_sha256: finalEvidence.zip_sha256,
schema_version: "1.0",
});
console.log(JSON.stringify({
deferred_external_tasks: release.deferredExternalTasks,
release_sha256: finalEvidence.release_sha256,
run_id: runId,
status: "passed",
zip_sha256: finalEvidence.zip_sha256,
}, null, 2));
+209 -13
View File
@@ -1,3 +1,23 @@
import { spawnSync } from "node:child_process";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
import {
WP7_02_CONTROLLED_REAL_LIMIT,
validateSanitizedEvidence,
} from "./lib/wp7-02-controlled-executor.mjs";
import {
assembleControlledModelEvidence,
runControlledRealScenarios,
} from "./lib/wp7-02-controlled-matrix.mjs";
import {
AI_GATEWAY_CREDENTIAL_TARGET,
WP7_02_MODEL_IDS,
buildBlockedModelEvidence,
inspectAiGatewayReadiness,
writeBlockedModelEvidence,
} from "./lib/wp7-02-external-contract.mjs";
const allowedServices = new Set(["ai", "ai-gateway-service-id", "resend", "amap"]);
function argument(name) {
@@ -5,23 +25,199 @@ function argument(name) {
return index >= 0 ? process.argv[index + 1] : undefined;
}
function output(value, error = false) {
const serialized = JSON.stringify(validateSanitizedEvidence(value));
if (error) console.error(serialized); else console.log(serialized);
}
const service = argument("--service");
const runId = argument("--run-id");
const model = argument("--model");
const candidatePath = argument("--candidate-record") ?? process.env.DADA_WP7_01_CANDIDATE_RECORD;
const configPath = argument("--config-manifest") ?? process.env.DADA_WP7_02_MODEL_CONFIG_MANIFEST;
const evidenceDirectory = argument("--evidence-dir") ?? process.env.DADA_WP7_02_EVIDENCE_DIR;
const maxRealCalls = Number(argument("--max-real-calls"));
const confirmed = process.argv.includes("--confirm-controlled-real");
const executeControlledReal = process.argv.includes("--execute-controlled-real");
const credentialStdin = process.argv.includes("--credential-stdin");
const readinessOnly = process.argv.includes("--readiness-only");
if (!allowedServices.has(service) || !runId || ((service === "ai" || service === "ai-gateway-service-id") && !model)) {
console.error("Usage: pnpm validate:external -- --service <ai|ai-gateway-service-id|resend|amap> --run-id <id> [--model <model-id>]");
if (!allowedServices.has(service) || !runId || ((service === "ai" || service === "ai-gateway-service-id") && !WP7_02_MODEL_IDS.includes(model))) {
console.error("Usage: pnpm validate:external -- --service <ai|ai-gateway-service-id|resend|amap> --run-id <id> [--model <model-id>] [--readiness-only]");
process.exit(2);
}
console.log(
JSON.stringify({
blocker: service === "ai" || service === "ai-gateway-service-id" ? "real_gateway_credentials_absent" : undefined,
mode: "mock",
model,
real_calls: 0,
run_id: runId,
service,
status: service === "ai" || service === "ai-gateway-service-id" ? "not_applicable" : "not_applicable_for_TASK-WP0-01",
}),
);
if (service !== "ai" && service !== "ai-gateway-service-id") {
console.log(JSON.stringify({ mode: "mock", real_calls: 0, run_id: runId, service, status: "not_applicable_for_TASK-WP0-01" }));
process.exit(0);
}
function parseInputs() {
const candidateRecord = candidatePath && existsSync(candidatePath) ? JSON.parse(readFileSync(candidatePath, "utf8")) : undefined;
const configManifest = configPath && existsSync(configPath) ? JSON.parse(readFileSync(configPath, "utf8")) : undefined;
const modelConfig = Array.isArray(configManifest?.models)
? configManifest.models.find((entry) => entry?.model_id === model)
: undefined;
return { candidateRecord, modelConfig };
}
function delegateToSecureBroker() {
if (!candidatePath || !configPath || !evidenceDirectory || !confirmed || maxRealCalls !== WP7_02_CONTROLLED_REAL_LIMIT) {
output({ code: "WP7_02_CONTROLLED_EXECUTION_ARGUMENTS_REQUIRED", model, real_calls: 0, run_id: runId, service, status: "failed" }, true);
return 2;
}
const args = [
"run", "--no-build", "--project", "supervisor/Dada.Supervisor/Dada.Supervisor.csproj", "--",
"validate-external",
"--service", "ai-gateway-service-id",
"--model", model,
"--run-id", runId,
"--max-real-calls", String(maxRealCalls),
"--confirm-controlled-real",
"--execute-controlled-real",
];
const result = spawnSync("dotnet", args, {
encoding: "utf8",
env: {
...process.env,
DADA_WP7_01_CANDIDATE_RECORD: candidatePath,
DADA_WP7_02_EVIDENCE_DIR: evidenceDirectory,
DADA_WP7_02_MODEL_CONFIG_MANIFEST: configPath,
},
maxBuffer: 64 * 1024 * 1024,
timeout: 20 * 60_000,
windowsHide: true,
});
const stdout = result.stdout?.trim() ?? "";
const stderr = result.stderr?.trim() ?? "";
const selected = stdout || stderr;
try {
if (!selected || (stdout && stderr)) throw new Error("invalid_output");
const parsed = validateSanitizedEvidence(JSON.parse(selected));
output(parsed, !stdout);
} catch {
output({ code: "WP7_02_SECURE_BROKER_FAILED", model, real_calls: 0, run_id: runId, service, status: "failed" }, true);
return 1;
}
return result.status ?? 1;
}
async function readCredentialFromStdin() {
let serialized = "";
for await (const chunk of process.stdin) {
serialized += chunk.toString("utf8");
if (serialized.length > 16_384) throw new Error("WP7_02_CREDENTIAL_CHANNEL_INVALID");
}
const payload = JSON.parse(serialized);
serialized = "";
if (!payload || typeof payload !== "object" || Array.isArray(payload)
|| Object.keys(payload).length !== 1 || typeof payload[AI_GATEWAY_CREDENTIAL_TARGET] !== "string"
|| payload[AI_GATEWAY_CREDENTIAL_TARGET].length < 8) {
throw new Error("WP7_02_CREDENTIAL_CHANNEL_INVALID");
}
const token = payload[AI_GATEWAY_CREDENTIAL_TARGET];
payload[AI_GATEWAY_CREDENTIAL_TARGET] = "";
return token;
}
function readDeterministicState() {
const path = evidenceDirectory && resolve(evidenceDirectory, "deterministic-state.json");
if (!path || !existsSync(path)) throw new Error("WP7_02_DETERMINISTIC_STATE_REQUIRED");
return validateSanitizedEvidence(JSON.parse(readFileSync(path, "utf8")));
}
function writeControlledEvidence(directory, evidence, readiness) {
mkdirSync(resolve(directory), { recursive: true });
const files = {
"contract-matrix.json": evidence.matrix,
"external-calls.json": evidence.external_calls,
"manual-review.json": evidence.manual_review,
"readiness.json": {
blockers: evidence.status === "passed" ? [] : evidence.external_calls.calls.filter((call) => call.status !== "passed").map((call) => call.error_code ?? call.scenario_id),
candidate: readiness.candidate,
evidence_id: evidence.evidence_id,
model_id: evidence.model_id,
run_id: evidence.run_id,
status: evidence.status,
},
"redaction.json": evidence.redaction,
};
for (const [name, value] of Object.entries(files)) {
writeFileSync(resolve(directory, name), `${JSON.stringify(validateSanitizedEvidence(value), null, 2)}\n`);
}
}
async function main() {
const { candidateRecord, modelConfig } = parseInputs();
if (!candidateRecord) {
output({ blockers: ["candidate_record_absent", ...(confirmed ? [] : ["explicit_confirmation_absent"])], mode: "controlled_real_not_executed", model, real_calls: 0, run_id: runId, service, status: "externally_blocked" });
return 3;
}
if (executeControlledReal && !credentialStdin) return delegateToSecureBroker();
let token = "";
try {
if (credentialStdin) token = await readCredentialFromStdin();
const readiness = inspectAiGatewayReadiness({
candidateRecord,
confirmed,
credentialTargets: credentialStdin ? [AI_GATEWAY_CREDENTIAL_TARGET] : [],
modelConfig,
modelId: model,
});
if (!credentialStdin) {
readiness.blockers = readiness.blockers.filter((blocker) => blocker !== "real_gateway_credentials_absent");
readiness.blockers.push("secure_credential_check_requires_execution");
}
readiness.status = readiness.blockers.length > 0 ? "externally_blocked" : "ready_for_controlled_execution";
if (!executeControlledReal || readinessOnly || readiness.blockers.length > 0) {
if (readiness.blockers.length > 0 && evidenceDirectory) {
writeBlockedModelEvidence(evidenceDirectory, buildBlockedModelEvidence({
blockers: readiness.blockers, candidateRecord, modelConfig: readiness.model_config, modelId: model, runId,
}));
}
output({
blockers: readiness.blockers,
candidate_build_commit: readiness.candidate.build_commit,
mode: readinessOnly ? "readiness_only" : "controlled_real_not_executed",
model,
planned_provider_requests_max: readiness.plan.planned_provider_requests_max,
planned_request_breakdown: readiness.plan.planned_request_breakdown,
real_calls: 0,
run_id: runId,
service,
status: readiness.status,
});
return readiness.blockers.length > 0 ? 3 : 0;
}
const deterministicState = readDeterministicState();
const realExecution = await runControlledRealScenarios({ maxRealCalls, modelConfig, token });
const evidence = assembleControlledModelEvidence({ deterministicState, modelConfig, realExecution, runId });
writeControlledEvidence(evidenceDirectory, evidence, readiness);
output({
blockers: realExecution.blockers,
config_version: modelConfig.config_version,
model,
planned_real_calls: realExecution.planned_real_calls,
real_calls: realExecution.real_calls,
run_id: runId,
service,
status: evidence.status === "passed" ? "controlled_real_passed_pending_manual_review" : "externally_blocked",
});
return evidence.status === "passed" ? 0 : 3;
} finally {
token = "";
}
}
try {
process.exitCode = await main();
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
const code = /^WP7_02_[A-Z0-9_:]+$/.test(message) ? message : "WP7_02_EXTERNAL_VALIDATION_FAILED";
output({ code, model, real_calls: 0, run_id: runId, service, status: "failed" }, true);
process.exitCode = 1;
}
+65 -9
View File
@@ -16,6 +16,12 @@ internal static class Program
return await RunCredentialChildAsync();
}
if (args.FirstOrDefault() == "--credential-echo")
{
Console.Write(await Console.In.ReadToEndAsync());
return 0;
}
if (args.FirstOrDefault() == "--instance-probe")
{
using var instance = await SingleInstanceCoordinator.TryAcquireAsync(args[1], args[2]);
@@ -32,6 +38,7 @@ internal static class Program
{
var security = await TestCredentialBoundaryAsync();
var supervisor = await TestSupervisorLifecycleAsync();
await TestAmapProbeSecurityAsync();
TestSecureConfigurationPersistence();
TestStructuredLogging();
WriteEvidence(Environment.GetEnvironmentVariable("DADA_EVIDENCE_DIR_SEC"), security);
@@ -46,6 +53,20 @@ internal static class Program
}
}
private static async Task TestAmapProbeSecurityAsync()
{
using var handler = AmapProbe.CreateHandler();
False(handler.AllowAutoRedirect, "Amap probe redirects disabled");
Equal(1, handler.MaxConnectionsPerServer, "Amap probe per-server connection cap");
True(AmapProbe.IsAllowedEndpoint(new Uri("https://restapi.amap.com/v3/geocode/regeo")), "Amap fixed HTTPS endpoint accepted");
False(AmapProbe.IsAllowedEndpoint(new Uri("http://restapi.amap.com/v3/geocode/regeo")), "Amap HTTP endpoint rejected");
False(AmapProbe.IsAllowedEndpoint(new Uri("https://example.invalid/v3/geocode/regeo")), "Amap alternate host rejected");
using var oversized = new ByteArrayContent(new byte[AmapProbe.MaximumResponseBytes + 1]);
await ThrowsAsync<InvalidDataException>(
() => AmapProbe.ReadBoundedJsonAsync(oversized),
"Amap oversized response must be rejected before parsing");
}
private static void TestStructuredLogging()
{
Equal(10 * 1024 * 1024L, StructuredJsonlLogger.SizeLimitBytes, "Supervisor log byte limit");
@@ -120,6 +141,33 @@ internal static class Program
var workerProbe = await LaunchCredentialProbeAsync(ChildRole.Worker, store);
EqualSequence(new[] { CredentialCatalog.WorkerAiGateway }, workerProbe.Names, "Worker credential scope");
var leakProbe = await CredentialProcessLauncher.RunToCompletionAsync(
new ProcessStartInfo(Environment.ProcessPath!, "--credential-echo"), ChildRole.Worker, store);
True(leakProbe.SensitiveOutputDetected, "credential echo must be detected");
Equal(string.Empty, leakProbe.StandardOutput, "credential echo output discarded");
Equal(string.Empty, leakProbe.StandardError, "credential echo error discarded");
var externalArguments = new[]
{
"--service", "ai-gateway-service-id",
"--model", "gpt-image-2",
"--run-id", "wp7-02-supervisor-probe",
"--max-real-calls", "120",
"--confirm-controlled-real",
"--execute-controlled-real",
};
EqualSequence(externalArguments, ControlledExternalValidationLauncher.ValidateArguments(externalArguments), "controlled external argument allowlist");
var stableGeminiArguments = externalArguments.ToArray();
stableGeminiArguments[3] = "gemini-3.1-flash-image";
EqualSequence(stableGeminiArguments, ControlledExternalValidationLauncher.ValidateArguments(stableGeminiArguments), "stable Gemini external argument allowlist");
var previewGeminiArguments = externalArguments.ToArray();
previewGeminiArguments[3] = "gemini-3.1-flash-image-preview";
Throws<ArgumentException>(
() => ControlledExternalValidationLauncher.ValidateArguments(previewGeminiArguments),
"preview Gemini external argument rejected");
Throws<ArgumentException>(
() => ControlledExternalValidationLauncher.ValidateArguments(externalArguments.Where(value => value != "--confirm-controlled-real").ToArray()),
"controlled external confirmation required");
store.Delete(CredentialCatalog.WorkerAiGateway);
await ThrowsAsync<MissingCredentialException>(
@@ -166,15 +214,10 @@ internal static class Program
private static async Task<CredentialProbe> LaunchCredentialProbeAsync(ChildRole role, ICredentialStore store)
{
var startInfo = new ProcessStartInfo(Environment.ProcessPath!, "--credential-child")
{
RedirectStandardOutput = true,
};
using var process = await CredentialProcessLauncher.StartAsync(startInfo, role, store);
var output = await process.StandardOutput.ReadToEndAsync();
await process.WaitForExitAsync();
Equal(0, process.ExitCode, "credential child exit code");
return JsonSerializer.Deserialize<CredentialProbe>(output, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })
var result = await CredentialProcessLauncher.RunToCompletionAsync(new ProcessStartInfo(Environment.ProcessPath!, "--credential-child"), role, store);
Equal(0, result.ExitCode, "credential child exit code");
False(result.SensitiveOutputDetected, "credential child output contains injected value");
return JsonSerializer.Deserialize<CredentialProbe>(result.StandardOutput, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })
?? throw new InvalidOperationException("Credential child returned invalid JSON.");
}
@@ -355,6 +398,19 @@ internal static class Program
throw new InvalidOperationException(message);
}
private static void Throws<TException>(Action action, string message) where TException : Exception
{
try
{
action();
}
catch (TException)
{
return;
}
throw new InvalidOperationException(message);
}
private sealed record CredentialProbe(string[] Names, bool EnvironmentContainsMarker, bool ArgumentsContainMarker);
private sealed class TestCredentialStore : ICredentialStore
+107
View File
@@ -0,0 +1,107 @@
using System.Buffers;
using System.Net;
using System.Text.Json;
namespace Dada.Supervisor;
internal static class AmapProbe
{
internal const int MaximumResponseBytes = 65_536;
private const string ProviderHostname = "restapi.amap.com";
private static readonly HttpClient Client = new(CreateHandler()) { Timeout = TimeSpan.FromSeconds(15) };
internal static SocketsHttpHandler CreateHandler() => new()
{
AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.None,
ConnectTimeout = TimeSpan.FromSeconds(10),
MaxConnectionsPerServer = 1,
};
internal static bool IsAllowedEndpoint(Uri endpoint) =>
endpoint.Scheme == Uri.UriSchemeHttps
&& endpoint.Host.Equals(ProviderHostname, StringComparison.OrdinalIgnoreCase)
&& (endpoint.IsDefaultPort || endpoint.Port == 443)
&& string.IsNullOrEmpty(endpoint.UserInfo)
&& endpoint.AbsolutePath is "/v3/geocode/regeo" or "/v3/geocode/geo";
internal static int Run(string? key)
{
if (string.IsNullOrWhiteSpace(key))
{
Write("amap_credentials_missing", false, 0, null, null);
return 3;
}
var realCalls = 0;
try
{
realCalls += 1;
var reverse = Call("https://restapi.amap.com/v3/geocode/regeo?location=120.6994,27.9943&extensions=base", key).GetAwaiter().GetResult();
realCalls += 1;
var geocode = Call($"https://restapi.amap.com/v3/geocode/geo?address={Uri.EscapeDataString("")}", key).GetAwaiter().GetResult();
var success = reverse.Status == "1" && geocode.Status == "1";
Write(success ? "amap_probe_passed" : "amap_provider_rejected", success, realCalls, reverse.Status, geocode.Status);
return success ? 0 : 3;
}
catch (TaskCanceledException)
{
Write("amap_probe_timeout", false, realCalls, null, null);
return 3;
}
catch (HttpRequestException exception)
{
Write($"amap_probe_network_{exception.StatusCode?.ToString() ?? "error"}", false, realCalls, null, null);
return 3;
}
catch (Exception exception) when (exception is JsonException or InvalidDataException)
{
Write("amap_probe_invalid_response", false, realCalls, null, null);
return 3;
}
}
private static async Task<ProbeResponse> Call(string endpoint, string key)
{
var requestUri = new Uri($"{endpoint}&key={Uri.EscapeDataString(key)}", UriKind.Absolute);
if (!IsAllowedEndpoint(requestUri)) throw new InvalidDataException("amap_endpoint_rejected");
using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
using var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
using var document = await ReadBoundedJsonAsync(response.Content);
var root = document.RootElement;
return new ProbeResponse(root.GetProperty("status").GetString() ?? "", root.TryGetProperty("infocode", out var code) ? code.GetString() : null);
}
internal static async Task<JsonDocument> ReadBoundedJsonAsync(HttpContent content)
{
if (content.Headers.ContentLength is > MaximumResponseBytes) throw new InvalidDataException("amap_response_too_large");
await using var stream = await content.ReadAsStreamAsync();
using var buffered = new MemoryStream();
var buffer = ArrayPool<byte>.Shared.Rent(4_096);
try
{
var total = 0;
while (true)
{
var read = await stream.ReadAsync(buffer);
if (read == 0) break;
total += read;
if (total > MaximumResponseBytes) throw new InvalidDataException("amap_response_too_large");
await buffered.WriteAsync(buffer.AsMemory(0, read));
}
buffered.Position = 0;
return await JsonDocument.ParseAsync(buffered);
}
finally
{
Array.Clear(buffer);
ArrayPool<byte>.Shared.Return(buffer);
}
}
private static void Write(string code, bool success, int realCalls, string? reverseStatus, string? geocodeStatus) =>
Console.WriteLine(JsonSerializer.Serialize(new { code, success, real_calls = realCalls, reverse_status = reverseStatus, geocode_status = geocodeStatus }));
private sealed record ProbeResponse(string Status, string? InfoCode);
}
@@ -0,0 +1,131 @@
using System.Diagnostics;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace Dada.Supervisor;
internal static partial class ControlledExternalValidationLauncher
{
private static readonly HashSet<string> AllowedModels =
[
"gemini-3.1-flash-image",
"gpt-image-2",
];
private static readonly HashSet<string> ValueOptions =
[
"--max-real-calls",
"--model",
"--run-id",
"--service",
];
private static readonly HashSet<string> SwitchOptions =
[
"--confirm-controlled-real",
"--execute-controlled-real",
];
internal static async Task<int> RunAsync(string[] args, ICredentialStore credentials, CancellationToken cancellationToken = default)
{
var validated = ValidateArguments(args);
var script = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "scripts", "validate-external.mjs"));
if (!File.Exists(script)) throw new InvalidOperationException("external_validator_not_found");
var startInfo = new ProcessStartInfo("node") { WorkingDirectory = Environment.CurrentDirectory };
startInfo.ArgumentList.Add(script);
foreach (var value in validated) startInfo.ArgumentList.Add(value);
startInfo.ArgumentList.Add("--credential-stdin");
var result = await CredentialProcessLauncher.RunToCompletionAsync(startInfo, ChildRole.Worker, credentials, cancellationToken);
if (result.SensitiveOutputDetected || !TrySelectSanitizedJson(result, out var output, out var useError))
{
Console.Error.WriteLine("{\"code\":\"external_validator_output_invalid\",\"real_calls\":0,\"status\":\"failed\"}");
return 1;
}
if (useError) Console.Error.WriteLine(output); else Console.WriteLine(output);
return result.ExitCode;
}
internal static string[] ValidateArguments(string[] args)
{
var values = new Dictionary<string, string>(StringComparer.Ordinal);
var switches = new HashSet<string>(StringComparer.Ordinal);
for (var index = 0; index < args.Length; index++)
{
var option = args[index];
if (SwitchOptions.Contains(option))
{
if (!switches.Add(option)) throw new ArgumentException("external_validator_argument_duplicate");
continue;
}
if (!ValueOptions.Contains(option) || index + 1 >= args.Length || !values.TryAdd(option, args[++index]))
{
throw new ArgumentException("external_validator_argument_invalid");
}
}
if (values.GetValueOrDefault("--service") != "ai-gateway-service-id"
|| !AllowedModels.Contains(values.GetValueOrDefault("--model") ?? string.Empty)
|| !SafeRunId().IsMatch(values.GetValueOrDefault("--run-id") ?? string.Empty)
|| values.GetValueOrDefault("--max-real-calls") != "120"
|| !switches.SetEquals(SwitchOptions))
{
throw new ArgumentException("external_validator_argument_invalid");
}
if (values.Values.Any(value => value.Length == 0 || value.IndexOfAny(['\r', '\n', '\0']) >= 0))
{
throw new ArgumentException("external_validator_argument_invalid");
}
return args.ToArray();
}
private static bool TrySelectSanitizedJson(CredentialProcessResult result, out string output, out bool useError)
{
var stdout = result.StandardOutput.Trim();
var stderr = result.StandardError.Trim();
useError = stdout.Length == 0;
output = useError ? stderr : stdout;
if (output.Length == 0 || (stdout.Length > 0 && stderr.Length > 0)) return false;
try
{
using var document = JsonDocument.Parse(output);
return IsSanitized(document.RootElement);
}
catch (JsonException)
{
return false;
}
}
private static bool IsSanitized(JsonElement element)
{
if (element.ValueKind == JsonValueKind.Object)
{
foreach (var property in element.EnumerateObject())
{
if (ForbiddenKey().IsMatch(property.Name) || property.NameEquals("verified") || !IsSanitized(property.Value)) return false;
}
}
else if (element.ValueKind == JsonValueKind.Array)
{
foreach (var item in element.EnumerateArray()) if (!IsSanitized(item)) return false;
}
else if (element.ValueKind == JsonValueKind.String)
{
var value = element.GetString() ?? string.Empty;
if (WindowsUserPath().IsMatch(value) || BearerValue().IsMatch(value)) return false;
}
return true;
}
[GeneratedRegex("^[A-Za-z0-9][A-Za-z0-9._-]{0,119}$", RegexOptions.CultureInvariant)]
private static partial Regex SafeRunId();
[GeneratedRegex("(?:^|_)(?:absolute_path|authorization|body|credential|image|password|path|prompt|raw|secret|token)(?:_|$)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
private static partial Regex ForbiddenKey();
[GeneratedRegex("[A-Za-z]:\\\\Users\\\\", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
private static partial Regex WindowsUserPath();
[GeneratedRegex("(?:Bearer\\s+|\\bsk-[A-Za-z0-9_-]{8,})", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
private static partial Regex BearerValue();
}
+50
View File
@@ -37,8 +37,58 @@ internal interface ICredentialStore
internal sealed class MissingCredentialException(string target)
: InvalidOperationException($"Required credential is not configured: {target}");
internal sealed record CredentialProcessResult(int ExitCode, string StandardOutput, string StandardError, bool SensitiveOutputDetected);
internal static class CredentialProcessLauncher
{
internal static async Task<CredentialProcessResult> RunToCompletionAsync(
ProcessStartInfo startInfo,
ChildRole role,
ICredentialStore store,
CancellationToken cancellationToken = default)
{
var credentials = new Dictionary<string, string>(StringComparer.Ordinal);
foreach (var target in CredentialCatalog.RequiredFor(role))
{
credentials[target] = store.Read(target) ?? throw new MissingCredentialException(target);
}
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
using var process = Process.Start(startInfo) ?? throw new InvalidOperationException("Unable to start credential child process.");
var outputTask = process.StandardOutput.ReadToEndAsync(cancellationToken);
var errorTask = process.StandardError.ReadToEndAsync(cancellationToken);
var payload = JsonSerializer.SerializeToUtf8Bytes(credentials);
try
{
await process.StandardInput.BaseStream.WriteAsync(payload, cancellationToken);
await process.StandardInput.BaseStream.FlushAsync(cancellationToken);
process.StandardInput.Close();
await process.WaitForExitAsync(cancellationToken);
var output = await outputTask;
var error = await errorTask;
var sensitive = credentials.Values.Where(value => value.Length > 0).Any(value =>
output.Contains(value, StringComparison.Ordinal) || error.Contains(value, StringComparison.Ordinal));
return sensitive
? new CredentialProcessResult(1, string.Empty, string.Empty, true)
: new CredentialProcessResult(process.ExitCode, output, error, false);
}
catch
{
if (!process.HasExited) process.Kill(entireProcessTree: true);
throw;
}
finally
{
Array.Clear(payload);
foreach (var target in credentials.Keys.ToArray()) credentials[target] = string.Empty;
credentials.Clear();
}
}
internal static async Task<Process> StartAsync(
ProcessStartInfo startInfo,
ChildRole role,
@@ -29,6 +29,7 @@ internal static class OfflineCommandRouter
"secrets" => RunSecrets(args.Skip(1).ToArray(), credentials),
"admin-allowlist" => RunAdminAllowlist(args.Skip(1).ToArray(), credentials),
"doctor" when args.Length == 1 => RunDoctor(credentials),
"validate-external" => await ControlledExternalValidationLauncher.RunAsync(args.Skip(1).ToArray(), credentials),
_ => Usage(),
};
}
@@ -83,6 +84,8 @@ internal static class OfflineCommandRouter
store.Write(target, value);
WriteResult("credential_saved", true);
return 0;
case "probe" when target == CredentialCatalog.ApiAmap:
return AmapProbe.Run(store.Read(target));
default:
return Usage();
}
@@ -198,7 +201,7 @@ internal static class OfflineCommandRouter
private static int Usage()
{
WriteResult("usage: configure init|data-root|asset-root; secrets set|status|clear; admin-allowlist add|remove|status; doctor", false);
WriteResult("usage: configure init|data-root|asset-root; secrets set|status|clear|probe; admin-allowlist add|remove|status; doctor; validate-external", false);
return 2;
}
}
@@ -0,0 +1,47 @@
import { describe, expect, it, vi } from "vitest";
import { RealAmapAdapter } from "../../apps/api/src/amap-adapter.js";
import { initializeApiCredentialClients } from "../../apps/api/src/supervisor-channel.js";
describe("TDD-WP7-EXT-003 production Amap adapter", () => {
it("uses the fixed HTTPS provider boundary and returns only the formatted location", async () => {
const request = vi.fn(async () => ({
regeocode: { formatted_address: "模拟省模拟市" },
status: "1",
}));
const adapter = new RealAmapAdapter("fixture-amap-value", { request });
await expect(adapter.reverseGeocode({ latitude: 12.3456, longitude: 65.4321 })).resolves.toEqual({
formattedValue: "模拟省模拟市",
serviceMode: "real",
});
expect(request).toHaveBeenCalledOnce();
expect(request.mock.calls[0]?.[0]).toMatchObject({
allowRedirects: false,
hostname: "restapi.amap.com",
maxResponseBytes: 65_536,
method: "GET",
protocol: "https:",
rejectUnauthorized: true,
timeoutMs: 15_000,
});
expect(request.mock.calls[0]?.[0].path).toContain("/v3/geocode/regeo?");
expect(request.mock.calls[0]?.[0].path).toContain("location=65.4321%2C12.3456");
adapter.dispose();
await expect(adapter.reverseGeocode({ latitude: 0, longitude: 0 })).rejects.toThrow("amap_adapter_disposed");
});
it("constructs the real client from the API credential channel and clears the source values", () => {
const credentials = {
"Dada/P0A/admin/pepper": "fixture-admin-value",
"Dada/P0A/api/amap": "fixture-amap-value",
"Dada/P0A/api/resend": "fixture-resend-value",
};
const clients = initializeApiCredentialClients(credentials);
expect(clients.amap).toBeInstanceOf(RealAmapAdapter);
expect(Object.values(credentials)).toEqual(["", "", ""]);
clients.amap.dispose();
clients.adminAllowlistPepper.fill(0);
});
});
@@ -0,0 +1,85 @@
import { randomUUID } from "node:crypto";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { MockAmapAdapter } from "../../apps/api/src/amap-adapter.js";
import { createApp } from "../../apps/api/src/app.js";
import { RegistrationService } from "../../apps/api/src/registration.js";
import { MockResendAdapter } from "../../apps/api/src/resend-adapter.js";
const roots: string[] = [];
const registrations: RegistrationService[] = [];
afterEach(() => {
for (const registration of registrations.splice(0)) registration.close();
for (const root of roots.splice(0)) rmSync(root, { force: true, recursive: true });
});
function createRegistration() {
const now = Date.parse("2026-08-04T09:00:00.000Z");
const root = mkdtempSync(join(tmpdir(), "dada-wp7-04-amap-"));
roots.push(root);
const registration = new RegistrationService({
challengePepper: Buffer.alloc(32, 0xa1),
clock: () => now,
currentPrivacyNoticeVersion: "p0a-registration-notice-v1",
databasePath: join(root, "dada.sqlite3"),
invitePepper: Buffer.alloc(32, 0xa2),
resend: new MockResendAdapter(),
sessionPepper: Buffer.alloc(32, 0xa3),
});
registrations.push(registration);
const userId = randomUUID();
registration.database.prepare(`
INSERT INTO users (user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at)
VALUES (?, ?, 'user', 'active', 1, ?, ?)
`).run(userId, `${userId}@example.invalid`, randomUUID(), now);
registration.database.prepare("INSERT INTO user_profiles (user_id, creator_name, social_id) VALUES (?, 'Release Gate User', '@release_gate')").run(userId);
registration.database.prepare("INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at) VALUES (?, 10, 0, ?)").run(userId, now);
return { registration, session: registration.issueAuthenticatedSession(userId, "user") };
}
describe("TDD-WP7-EXT-003 Amap release hard stop", () => {
it("admits the simulated 1000th request and blocks the 1001st before provider egress", async () => {
const { registration, session } = createRegistration();
registration.database.prepare(`
UPDATE external_service_usage
SET used_count = 999, service_status = 'active', pause_reason = NULL
WHERE service_id = 'amap_web_service' AND period_type = 'monthly'
`).run();
const amap = new MockAmapAdapter();
const app = await createApp({ amap, browserGate: false, networkBoundary: { allowTestPort: true }, registration });
const headers = {
cookie: `dada_session=${session.sessionToken}`,
host: "127.0.0.1:43121",
origin: "http://127.0.0.1:43121",
"x-csrf-token": registration.issueUserCsrfToken(session.sessionToken),
};
const thousandth = await app.inject({
headers,
method: "POST",
payload: { latitude: 0, longitude: 0 },
url: "/api/v1/location/reverse-geocode",
});
const thousandAndFirst = await app.inject({
headers,
method: "POST",
payload: { latitude: 0, longitude: 0 },
url: "/api/v1/location/reverse-geocode",
});
expect(thousandth.statusCode).toBe(200);
expect(thousandAndFirst.statusCode).toBe(503);
expect(amap.calls).toHaveLength(1);
expect(registration.serviceUsage.read("amap_web_service")).toEqual([
expect.objectContaining({ hardLimit: 1_000, status: "paused_quota", usedCount: 1_000 }),
]);
await app.close();
});
});
@@ -0,0 +1,154 @@
import { createHash, randomUUID } from "node:crypto";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { describe, expect, it } from "vitest";
import { CreditService } from "../../apps/api/src/credits.js";
import { ModelConfigurationService, modelIds, type ModelConfigCandidate } from "../../apps/api/src/model-configuration.js";
import { ModelContractEvidenceService } from "../../apps/api/src/model-contract-evidence.js";
import { ProjectService } from "../../apps/api/src/projects.js";
import { RegistrationService } from "../../apps/api/src/registration.js";
import { MockResendAdapter } from "../../apps/api/src/resend-adapter.js";
import { settleGenerationCredits } from "../../apps/worker/src/credit-settlement.js";
import { generationErrorCategories, generationErrorRegistry } from "../../apps/worker/src/generation-error-registry.js";
import { WP7_02_MODEL_IDS, productModelIdForControlledState } from "../../scripts/lib/wp7-02-external-contract.mjs";
const now = Date.parse("2026-08-04T08:00:00.000Z");
function matrix(modelId: string) {
return {
error_mapping: [...generationErrorCategories],
execution_modes: ["sync", "async", "poll"],
model_id: modelId,
pure_text: { outputs: 1, status: "passed" },
ratios: ["3:4", "1:1", "4:3", "9:16"].map((ratio) => ({ outputs: 1, ratio, status: "passed" })),
reference_image: { outputs: 1, status: "passed" },
};
}
function editable(models: ReturnType<ModelConfigurationService["read"]>["models"]): ModelConfigCandidate[] {
return models.map(({ config_version: _version, runtime_availability: _runtime, ...candidate }) => structuredClone(candidate));
}
function writeModelEvidence(modelId: string, value: unknown) {
const root = process.env.DADA_WP7_02_STATE_EVIDENCE_ROOT;
if (!root) return;
const directory = resolve(root, modelId.replaceAll(".", "_"));
mkdirSync(directory, { recursive: true });
writeFileSync(resolve(directory, "deterministic-state.json"), `${JSON.stringify(value, null, 2)}\n`);
}
describe("TDD-WP7-EXT-001 controlled deterministic state boundaries", () => {
it("proves nine errors, settlement replay, invalidation and full revalidation independently per model", () => {
const evidenceIds = new Set<string>();
for (const externalModelId of WP7_02_MODEL_IDS) {
const modelId = productModelIdForControlledState(externalModelId);
expect(modelIds).toContain(modelId);
const root = mkdtempSync(join(tmpdir(), "dada-wp7-02-state-"));
const databasePath = join(root, "dada.sqlite3");
const registration = new RegistrationService({
challengePepper: Buffer.alloc(32, 0xd1), clock: () => now,
currentPrivacyNoticeVersion: "p0a-registration-notice-v1", databasePath,
invitePepper: Buffer.alloc(32, 0xd2), resend: new MockResendAdapter(), sessionPepper: Buffer.alloc(32, 0xd3),
});
const projects = new ProjectService({ clock: () => now, databasePath });
let credits = new CreditService({ clock: () => now, databasePath });
try {
const settlements = [];
for (const outcome of ["succeeded", "failed", "rejected"] as const) {
const userId = randomUUID();
registration.database.prepare(`INSERT INTO users (
user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at
) VALUES (?, ?, 'user', 'active', 1, ?, ?)`).run(userId, `${userId}@example.invalid`, randomUUID(), now);
registration.database.prepare("INSERT INTO user_profiles (user_id, creator_name, social_id) VALUES (?, 'WP7 User', '@wp7')").run(userId);
registration.database.prepare("INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at) VALUES (?, 1, 0, ?)").run(userId, now);
const generationId = projects.createProjectForGeneration({ ownerId: userId, prompt: "controlled fixture", ratio: "1:1", status: "queued" }).generation.generationId;
credits.reserveGeneration({ creditCost: 1, generationId, modelId, operationKey: `generation:${generationId}:reserve`, userId });
const input = { generationId, operationKey: `generation:${generationId}:finalize`, outcome };
const first = settleGenerationCredits(credits, input);
const replay = settleGenerationCredits(credits, input);
credits.close();
credits = new CreditService({ clock: () => now, databasePath });
const restartReplay = settleGenerationCredits(credits, input);
expect(replay).toEqual(first);
expect(restartReplay).toEqual(first);
const account = credits.readAccount(userId);
const ledger = registration.database.prepare(`SELECT entry_type, COUNT(*) AS count FROM credit_ledger
WHERE user_id = ? AND entry_type IN ('generation_commit', 'generation_release') GROUP BY entry_type`).get(userId);
expect(account).toMatchObject({ availableBalance: outcome === "succeeded" ? 0 : 1, reservedBalance: 0 });
expect(ledger).toEqual({ count: 1, entry_type: outcome === "succeeded" ? "generation_commit" : "generation_release" });
settlements.push({
available_after: account.availableBalance,
ledger_entries: 1,
outcome,
reserved_after: account.reservedBalance,
replay_count: 2,
});
}
const models = new ModelConfigurationService({ clock: () => now, database: registration.database });
const contracts = new ModelContractEvidenceService({ clock: () => now, database: registration.database, models });
const firstEvidenceHash = `sha256:${createHash("sha256").update(`${modelId}:v1`).digest("hex")}`;
const first = contracts.recordVerified({
actorId: "wp7-02-controlled", expectedConfigSetVersion: 1,
evidence: {
evidence_hash: firstEvidenceHash,
evidence_ref: `wp7-02:${modelId}:first`,
matrix: matrix(modelId), model_id: modelId,
verified_at: new Date(now).toISOString(), verifier_ref: "wp7-02-controlled",
},
idempotencyKey: `wp7-02:${modelId}:first`,
});
expect(first.model.contract_validation_status).toBe("verified");
const candidates = editable(first.configuration.models);
const target = candidates.find((candidate) => candidate.model_id === modelId)!;
target.route_profile = { ...target.route_profile, contract_revision: 2 };
const changed = models.replace({
actorId: "wp7-02-controlled", expectedConfigSetVersion: 2,
idempotencyKey: `wp7-02:${modelId}:change`, models: candidates,
});
const invalidated = changed.models.find((model) => model.model_id === modelId)!;
expect(invalidated.contract_validation_status).toBe("unverified");
const secondEvidenceHash = `sha256:${createHash("sha256").update(`${modelId}:v2`).digest("hex")}`;
const revalidated = contracts.recordVerified({
actorId: "wp7-02-controlled", expectedConfigSetVersion: 3,
evidence: {
evidence_hash: secondEvidenceHash,
evidence_ref: `wp7-02:${modelId}:second`,
matrix: matrix(modelId), model_id: modelId,
verified_at: new Date(now + 1_000).toISOString(), verifier_ref: "wp7-02-controlled",
},
idempotencyKey: `wp7-02:${modelId}:second`,
});
expect(revalidated.model.contract_validation_status).toBe("verified");
expect(contracts.read(modelId, first.model.config_version)?.evidence_hash).toBe(firstEvidenceHash);
expect(contracts.read(modelId, revalidated.model.config_version)?.evidence_hash).toBe(secondEvidenceHash);
const evidenceId = `sha256:${createHash("sha256").update(`${externalModelId}:deterministic-state`).digest("hex")}`;
expect(evidenceIds.has(evidenceId)).toBe(false);
evidenceIds.add(evidenceId);
writeModelEvidence(externalModelId, {
contract_change: {
after_change: { config_set_version: 3, config_version: invalidated.config_version, status: invalidated.contract_validation_status },
after_revalidation: { config_set_version: 4, config_version: revalidated.model.config_version, status: revalidated.model.contract_validation_status },
before_change: { config_set_version: 2, config_version: first.model.config_version, status: first.model.contract_validation_status },
full_matrix_reapplied: true,
},
error_scenarios: generationErrorCategories.map((category) => ({ category, ...generationErrorRegistry[category], source: "deterministic_local", status: "passed" })),
evidence_id: evidenceId,
model_id: externalModelId,
settlements,
status: "passed",
});
} finally {
credits.close();
projects.close();
registration.close();
rmSync(root, { force: true, recursive: true });
}
}
expect(evidenceIds.size).toBe(WP7_02_MODEL_IDS.length);
});
});
@@ -0,0 +1,381 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import {
WP7_02_CONTROLLED_REAL_LIMIT,
buildControlledExecutionPlan,
buildProviderRequest,
buildSanitizedResponseEvidence,
describeProviderResponseShape,
executeProviderRequest,
normalizeProviderResponse,
validateSanitizedEvidence,
} from "../../scripts/lib/wp7-02-controlled-executor.mjs";
import {
assembleControlledModelEvidence,
buildDeterministicExecutionEvidence,
createControlledReferencePng,
runControlledRealScenarios,
} from "../../scripts/lib/wp7-02-controlled-matrix.mjs";
const models = [
{
config_version: 7,
model_id: "gemini-3.1-flash-image",
route_profile: {
endpoint: "https://oneapi.intelligrow.cn/v1beta/models/gemini-3.1-flash-image:generateContent",
mode: "sync",
protocol_version: "gemini-native-v1beta",
},
},
{
config_version: 2,
model_id: "gpt-image-2",
route_profile: {
endpoint: "https://oneapi.intelligrow.cn/v1/images/generations",
mode: "sync",
protocol_version: "openai-images-v1",
reference_endpoint: "https://oneapi.intelligrow.cn/v1/images/edits",
},
},
];
const stableFlashInteractionModel = {
config_version: 4,
model_id: "gemini-3.1-flash-image",
route_profile: {
endpoint: "https://oneapi.intelligrow.cn/v1beta/interactions",
mode: "sync",
protocol_version: "gemini-interactions-v1beta",
provider_model_id: "gemini-3.1-flash-image",
},
};
const stableFlashOpenAiImageModel = {
config_version: 6,
model_id: "gemini-3.1-flash-image",
route_profile: {
endpoint: "https://oneapi.intelligrow.cn/v1/images/generations",
mode: "sync",
protocol_version: "openai-images-v1",
provider_model_id: "gemini-3.1-flash-image",
reference_endpoint: "https://oneapi.intelligrow.cn/v1/images/edits",
},
};
const stableFlashOpenAiChatModel = {
config_version: 7,
model_id: "gemini-3.1-flash-image",
route_profile: {
endpoint: "https://oneapi.intelligrow.cn/v1/chat/completions",
mode: "sync",
protocol_version: "gemini-openai-chat-v1",
provider_model_id: "gemini-3.1-flash-image",
},
};
const onePixelPng = Buffer.from(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
"base64",
);
test("TDD-WP7-EXT-001 caps real calls and separates real from deterministic scenarios", () => {
const plans = models.map((model) => buildControlledExecutionPlan(model));
assert.equal(WP7_02_CONTROLLED_REAL_LIMIT, 120);
assert.equal(plans.reduce((total, plan) => total + plan.planned_real_calls, 0) <= WP7_02_CONTROLLED_REAL_LIMIT, true);
for (const plan of plans) {
assert.deepEqual(plan.real_scenarios.map((entry) => entry.ratio), ["3:4", "1:1", "4:3", "9:16", "1:1"]);
assert.deepEqual(plan.real_scenarios.map((entry) => entry.input), ["pure_text", "pure_text", "pure_text", "pure_text", "reference_image"]);
assert.deepEqual(plan.execution_modes, [
{ mode: "sync", source: "real_gateway" },
{ mode: "async", source: "deterministic_local" },
{ mode: "poll", source: "deterministic_local" },
]);
assert.equal(plan.error_scenarios.length, 9);
assert.equal(plan.error_scenarios.every((entry) => entry.source === "deterministic_local"), true);
assert.deepEqual(plan.state_scenarios.map((entry) => entry.name), [
"credit_commit_once",
"credit_release_once_per_terminal_failure",
"contract_change_invalidation",
"full_revalidation",
]);
}
});
test("TDD-WP7-EXT-001 builds protocol-specific requests without auth in arguments", () => {
const reference = { bytes: onePixelPng, mime_type: "image/png" };
const gemini = buildProviderRequest({ modelConfig: models[0], prompt: "controlled fixture prompt", ratio: "3:4", reference });
assert.equal(gemini.method, "POST");
assert.equal(gemini.body.contents[0].parts.some((part) => part.inlineData?.data), true);
assert.deepEqual(gemini.body.generationConfig.responseModalities, ["IMAGE"]);
assert.deepEqual(gemini.body.generationConfig.imageConfig, {
aspectRatio: "3:4",
imageSize: "1K",
});
assert.equal("responseFormat" in gemini.body.generationConfig, false);
assert.equal("authorization" in gemini.headers, false);
const interaction = buildProviderRequest({
modelConfig: stableFlashInteractionModel,
prompt: "controlled fixture prompt",
ratio: "3:4",
reference,
});
assert.deepEqual(interaction.body, {
input: [
{ text: "controlled fixture prompt", type: "text" },
{ data: onePixelPng.toString("base64"), mime_type: "image/png", type: "image" },
],
model: "gemini-3.1-flash-image",
response_format: { aspect_ratio: "3:4", image_size: "1K", type: "image" },
});
assert.equal(interaction.url, "https://oneapi.intelligrow.cn/v1beta/interactions");
assert.equal("authorization" in interaction.headers, false);
const stableOpenAiImage = buildProviderRequest({
modelConfig: stableFlashOpenAiImageModel,
prompt: "controlled fixture prompt",
ratio: "4:3",
});
assert.deepEqual(stableOpenAiImage.body, {
model: "gemini-3.1-flash-image",
prompt: "controlled fixture prompt",
response_format: "b64_json",
size: "1408x1056",
});
const stableOpenAiChat = buildProviderRequest({
modelConfig: stableFlashOpenAiChatModel,
prompt: "controlled fixture prompt",
ratio: "4:3",
reference,
});
assert.deepEqual(stableOpenAiChat.body, {
extra_body: { google: { image_config: { aspect_ratio: "4:3", image_size: "1K" } } },
messages: [{
content: [
{ text: "controlled fixture prompt", type: "text" },
{ image_url: { url: `data:image/png;base64,${onePixelPng.toString("base64")}` }, type: "image_url" },
],
role: "user",
}],
model: "gemini-3.1-flash-image",
stream: false,
});
assert.equal(stableOpenAiChat.url, "https://oneapi.intelligrow.cn/v1/chat/completions");
assert.equal("authorization" in stableOpenAiChat.headers, false);
const openai = buildProviderRequest({ modelConfig: models[1], prompt: "controlled fixture prompt", ratio: "9:16" });
assert.deepEqual(openai.body, {
model: "gpt-image-2",
prompt: "controlled fixture prompt",
response_format: "b64_json",
size: "1008x1792",
});
assert.equal("authorization" in openai.headers, false);
const openaiEdit = buildProviderRequest({ modelConfig: models[1], prompt: "controlled fixture prompt", ratio: "1:1", reference });
assert.equal(openaiEdit.url, "https://oneapi.intelligrow.cn/v1/images/edits");
assert.equal(openaiEdit.body instanceof FormData, true);
assert.equal(openaiEdit.body.get("model"), "gpt-image-2");
assert.equal(openaiEdit.body.get("size"), "1088x1088");
assert.equal(openaiEdit.body.get("image[]") instanceof Blob, true);
assert.equal("content-type" in openaiEdit.headers, false);
});
test("TDD-WP7-EXT-001 retains only response metadata and hashes", () => {
const geminiResponse = {
candidates: [{ content: { parts: [{ inlineData: { data: onePixelPng.toString("base64"), mimeType: "image/png" } }] } }],
usageMetadata: { candidatesTokenCount: 7, promptTokenCount: 5, totalTokenCount: 12 },
};
const normalized = normalizeProviderResponse(models[0], geminiResponse);
const evidence = buildSanitizedResponseEvidence(normalized);
assert.deepEqual(evidence.dimensions, { height: 1, width: 1 });
assert.equal(evidence.mime, "image/png");
assert.match(evidence.evidence_hash, /^sha256:[A-F0-9]{64}$/);
assert.deepEqual(evidence.usage_summary, { input_units: 5, output_units: 7, total_units: 12 });
assert.doesNotMatch(JSON.stringify(evidence), /iVBOR|bytes|data|prompt|authorization|token/i);
assert.equal(validateSanitizedEvidence(evidence), evidence);
const interactionNormalized = normalizeProviderResponse(stableFlashInteractionModel, {
status: "completed",
steps: [{ content: [{ data: onePixelPng.toString("base64"), mime_type: "image/png", type: "image" }], type: "model_output" }],
usage: { total_input_tokens: 11, total_output_tokens: 13, total_tokens: 24 },
});
assert.deepEqual(interactionNormalized.dimensions, { height: 1, width: 1 });
assert.equal(interactionNormalized.mime, "image/png");
assert.deepEqual(interactionNormalized.usage_summary, { input_units: 11, output_units: 13, total_units: 24 });
const chatNormalized = normalizeProviderResponse(stableFlashOpenAiChatModel, {
choices: [{ message: { content: `![image](data:image/png;base64,${onePixelPng.toString("base64")})` } }],
usage: { completion_tokens: 17, prompt_tokens: 15, total_tokens: 32 },
});
assert.deepEqual(chatNormalized.dimensions, { height: 1, width: 1 });
assert.equal(chatNormalized.mime, "image/png");
assert.deepEqual(chatNormalized.usage_summary, { input_units: 15, output_units: 17, total_units: 32 });
});
test("TDD-WP7-EXT-001 rejects sensitive or shared evidence fields", () => {
for (const key of ["raw_prompt", "raw_provider_payload", "credential_value", "authorization", "absolute_path"]) {
assert.throws(() => validateSanitizedEvidence({ [key]: "forbidden", status: "passed" }), /WP7_02_SENSITIVE_EVIDENCE_FORBIDDEN/);
}
assert.throws(() => validateSanitizedEvidence({ status: "passed", verified: true }), /WP7_02_SHARED_VERIFIED_FORBIDDEN/);
});
test("TDD-WP7-EXT-001 confines the credential to the request header and discards provider error bodies", async () => {
const credentialMarker = "controlled-secret-value-for-test-only";
const success = await executeProviderRequest({
fetchImpl: async (_url, init) => {
assert.equal(init.headers.authorization, `Bearer ${credentialMarker}`);
return new Response(JSON.stringify({
candidates: [{ content: { parts: [{ inlineData: { data: onePixelPng.toString("base64"), mimeType: "image/png" } }] } }],
}), { headers: { "content-type": "application/json" }, status: 200 });
},
modelConfig: models[0],
prompt: "controlled fixture prompt",
ratio: "1:1",
token: credentialMarker,
});
assert.equal(success.http_status, 200);
assert.deepEqual(success.response_evidence.dimensions, { height: 1080, width: 1080 });
assert.deepEqual(success.response_evidence.normalization, {
applied: true,
upstream_dimensions: { height: 1, width: 1 },
});
assert.doesNotMatch(JSON.stringify({ ...success, normalized: undefined }), new RegExp(credentialMarker));
await assert.rejects(() => executeProviderRequest({
fetchImpl: async () => new Response(JSON.stringify({ provider_body: credentialMarker }), { status: 502 }),
modelConfig: models[0],
prompt: "controlled fixture prompt",
ratio: "1:1",
token: credentialMarker,
}), (error) => {
assert.equal(error.message, "WP7_02_UPSTREAM_HTTP_502");
assert.doesNotMatch(error.message, new RegExp(credentialMarker));
return true;
});
});
test("TDD-WP7-EXT-001 executes only five real success probes per model and keeps failed ratios blocking", async () => {
let fetchCalls = 0;
const execution = await runControlledRealScenarios({
fetchImpl: async () => {
fetchCalls += 1;
return new Response(JSON.stringify({
candidates: [{ content: { parts: [{ inlineData: { data: onePixelPng.toString("base64"), mimeType: "image/png" } }] } }],
}), { status: 200 });
},
maxRealCalls: 120,
modelConfig: models[0],
token: "controlled-secret-value-for-test-only",
});
assert.equal(fetchCalls, 5);
assert.equal(execution.real_calls, 5);
assert.equal(execution.attempts.length, 5);
assert.equal(execution.status, "externally_blocked");
assert.equal(execution.calls.filter((call) => call.status === "passed").length, 2);
assert.doesNotMatch(JSON.stringify(execution), /controlled-secret|fixture prompt|iVBOR/i);
await assert.rejects(() => runControlledRealScenarios({ maxRealCalls: 121, modelConfig: models[0], token: "not-used" }), /WP7_02_REAL_CALL_LIMIT_INVALID/);
});
test("TDD-WP7-EXT-001 retries one timeout once and records every real attempt", async () => {
let fetchCalls = 0;
const execution = await runControlledRealScenarios({
fetchImpl: async () => {
fetchCalls += 1;
if (fetchCalls === 1) {
const timeout = new Error("sanitized timeout fixture");
timeout.name = "AbortError";
throw timeout;
}
return new Response(JSON.stringify({
candidates: [{ content: { parts: [{ inlineData: { data: onePixelPng.toString("base64"), mimeType: "image/png" } }] } }],
}), { status: 200 });
},
maxRealCalls: 120,
modelConfig: models[0],
token: "controlled-secret-value-for-test-only",
});
assert.equal(fetchCalls, 6);
assert.equal(execution.real_calls, 6);
assert.equal(execution.calls.length, 5);
assert.equal(execution.attempts.length, 6);
assert.deepEqual(execution.attempts.slice(0, 2).map((attempt) => [attempt.scenario_id, attempt.attempt_no, attempt.error_code ?? attempt.status]), [
["real-1", 1, "WP7_02_UPSTREAM_TIMEOUT"],
["real-1", 2, "WP7_02_RESPONSE_DIMENSIONS_INVALID"],
]);
});
test("TDD-WP7-EXT-001 describes only protocol structure and stops repeated contract-shape calls", async () => {
const uriShape = describeProviderResponseShape({ candidates: [{ content: { parts: [{ text: "https://first.invalid/generated" }] } }] });
const equivalentUriShape = describeProviderResponseShape({ candidates: [{ content: { parts: [{ text: "https://other.invalid/result" }] } }] });
assert.deepEqual(uriShape, equivalentUriShape);
assert.match(JSON.stringify(uriShape), /"representation":"uri"/);
assert.doesNotMatch(JSON.stringify(uriShape), /first\.invalid|other\.invalid/);
assert.match(JSON.stringify(describeProviderResponseShape({ candidates: [{ content: { parts: [{ text: "![result](https:\/\/example.invalid\/generated)" }] } }] })), /"representation":"markdown_uri"/);
assert.match(JSON.stringify(describeProviderResponseShape({ candidates: [{ content: { parts: [{ text: "data:image\/png;base64,AAAA" }] } }] })), /"representation":"inline_media"/);
assert.match(JSON.stringify(describeProviderResponseShape({ candidates: [{ content: { parts: [{ text: "ordinary explanation" }] } }] })), /"representation":"plain_text"/);
let fetchCalls = 0;
const execution = await runControlledRealScenarios({
fetchImpl: async () => {
fetchCalls += 1;
return new Response(JSON.stringify({ envelope: { outputs: [{ binary: "private-response-value" }] } }), { status: 200 });
},
maxRealCalls: 120,
modelConfig: models[0],
token: "controlled-secret-value-for-test-only",
});
assert.equal(fetchCalls, 1);
assert.equal(execution.real_calls, 1);
assert.equal(execution.calls[0].error_code, "WP7_02_RESPONSE_SINGLE_IMAGE_REQUIRED");
assert.deepEqual(execution.calls[0].response_shape, describeProviderResponseShape({ envelope: { outputs: [{ binary: "different-private-value" }] } }));
assert.doesNotMatch(JSON.stringify(execution.calls[0].response_shape), /private-response-value|different-private-value/);
});
test("TDD-WP7-EXT-001 assembles independent complete evidence without retaining reference bytes", () => {
const reference = createControlledReferencePng();
assert.equal(reference.subarray(0, 8).toString("hex"), "89504e470d0a1a0a");
const calls = ["3:4", "1:1", "4:3", "9:16"].map((ratio, index) => ({
duration_ms: 1,
http_status: 200,
input: "pure_text",
requested_ratio: ratio,
response: { dimensions: { height: 1, width: 1 }, evidence_hash: `sha256:${"A".repeat(64)}`, mime: "image/png", usage_summary: { input_units: 0, output_units: 0, total_units: 0 } },
scenario_id: `real-${index + 1}`,
source: "real_gateway",
status: "passed",
}));
calls.push({ ...calls[1], input: "reference_image", scenario_id: "real-5" });
const deterministicState = {
contract_change: { full_matrix_reapplied: true },
error_scenarios: Array.from({ length: 9 }, (_, index) => ({ category: `category-${index}`, status: "passed" })),
model_id: models[0].model_id,
settlements: ["succeeded", "failed", "rejected"].map((outcome) => ({ outcome })),
status: "passed",
};
const evidence = assembleControlledModelEvidence({
deterministicState,
modelConfig: models[0],
realExecution: {
attempts: calls.map((call, index) => ({ attempt_no: 1, http_status: 200, scenario_id: call.scenario_id, status: "passed" })),
calls, maximum_real_calls: 6, planned_real_calls: 5, real_calls: 5, status: "passed",
},
runId: "wp7-02-assembly-test",
});
assert.equal(evidence.status, "passed");
assert.equal(evidence.manual_review.status, "pending");
assert.equal(evidence.external_calls.attempts.length, 5);
assert.equal(evidence.external_calls.maximum_real_calls, 6);
assert.equal(evidence.matrix.error_scenarios.length, 9);
assert.doesNotMatch(JSON.stringify(evidence), /iVBOR|image_bytes|raw_prompt|authorization/i);
const execution = buildDeterministicExecutionEvidence(models[0].model_id, "wp7-02-assembly-test");
assert.deepEqual(execution.modes.map((entry) => entry.mode), ["sync", "async", "poll"]);
assert.deepEqual(execution.trace.map((entry) => `${entry.action}:${entry.before}->${entry.after}`), [
"start:created->pending",
"poll:pending->completed",
"poll:completed->completed",
]);
assert.equal(execution.trace[2].replay, true);
});
@@ -0,0 +1,151 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { test } from "node:test";
import {
AI_GATEWAY_CREDENTIAL_TARGET,
WP7_02_MODEL_IDS,
buildBlockedModelEvidence,
buildModelContractPlan,
inspectAiGatewayReadiness,
productModelIdForControlledState,
validateCandidateDependency,
validateIndependentEvidenceSet,
} from "../../scripts/lib/wp7-02-external-contract.mjs";
const candidate = () => ({
browsers: [
{ brand: "Google Chrome", full_version: "150.0.7871.187", major: 150, source: "installed_executable" },
{ brand: "Microsoft Edge", full_version: "151.0.4129.59", major: 151, source: "installed_executable" },
],
build_commit: "623cad25b2a2a9a003502c9a92ebd318dad06248",
candidate_package: { release_status: "candidate_unvalidated", sha256: "A".repeat(64) },
final_release: false,
fixed_port: 43121,
recorded_at: "2026-08-04T05:28:11.257Z",
schema_version: "1.0",
status: "candidate_unvalidated",
});
test("TDD-WP7-EXT-001 fixes the user-approved replacement model set", () => {
assert.deepEqual(WP7_02_MODEL_IDS, [
"gemini-3.1-flash-image",
"gpt-image-2",
]);
assert.equal(productModelIdForControlledState("gemini-3.1-flash-image"), "gemini-3.1-flash-image-preview");
assert.equal(productModelIdForControlledState("gpt-image-2"), "gpt-image-2");
assert.throws(() => productModelIdForControlledState("gemini-3-pro-image-preview"), /WP7_02_MODEL_NOT_ALLOWED/);
for (const modelId of WP7_02_MODEL_IDS) {
const plan = buildModelContractPlan(modelId);
assert.equal(plan.model_id, modelId);
assert.deepEqual(plan.inputs, ["pure_text", "reference_image"]);
assert.deepEqual(plan.ratios, ["3:4", "1:1", "4:3", "9:16"]);
assert.deepEqual(plan.execution_modes, ["sync", "async", "poll"]);
assert.deepEqual(plan.response_checks, ["single_image", "mime", "dimensions", "sanitized_usage"]);
assert.deepEqual(plan.planned_request_breakdown, {
contract_change_full_revalidation: 20,
error_categories: 9,
execution_modes_and_poll: 3,
input_and_ratio_success: 6,
settlement_boundaries: 2,
});
assert.equal(Object.values(plan.planned_request_breakdown).reduce((total, count) => total + count, 0), 40);
assert.deepEqual(plan.error_categories, [
"upstream_timeout", "upstream_failed", "safety_rejected", "model_disabled",
"gateway_balance_insufficient", "gateway_contract_invalid", "reference_invalid",
"unknown_retryable", "unknown_non_retryable",
]);
assert.deepEqual(plan.error_expectations.safety_rejected, {
credit_effect: "release_once",
job_outcome: "rejected",
user_action: "modify_prompt_or_reference",
});
assert.deepEqual(plan.error_expectations.reference_invalid, {
credit_effect: "no_reserve_or_release_once",
job_outcome: "not_created_or_failed",
user_action: "replace_or_remove_reference",
});
assert.deepEqual(plan.state_checks, [
"credit_commit_once", "credit_release_once_per_terminal_failure",
"contract_change_invalidation", "full_revalidation",
]);
}
});
test("TDD-WP7-EXT-001 rejects candidate drift and final-release substitution", () => {
assert.equal(validateCandidateDependency(candidate()).build_commit, candidate().build_commit);
assert.throws(() => validateCandidateDependency({ ...candidate(), final_release: true }), /WP7_02_CANDIDATE_FINAL_RELEASE_FORBIDDEN/);
const drifted = candidate();
drifted.browsers[0].full_version = "150.0.7871.188";
assert.throws(() => validateCandidateDependency(drifted), /WP7_02_CANDIDATE_BROWSER_MISMATCH/);
});
test("TDD-WP7-EXT-001 remains externally blocked without confirmation, config and credential", () => {
const readiness = inspectAiGatewayReadiness({
candidateRecord: candidate(),
confirmed: false,
credentialTargets: [],
modelConfig: undefined,
modelId: WP7_02_MODEL_IDS[0],
});
assert.equal(AI_GATEWAY_CREDENTIAL_TARGET, "Dada/P0A/worker/ai-gateway");
assert.equal(readiness.status, "externally_blocked");
assert.equal(readiness.real_calls, 0);
assert.deepEqual(readiness.blockers, [
"explicit_confirmation_absent",
"real_gateway_credentials_absent",
"real_model_config_absent",
]);
assert.equal("verified" in readiness, false);
});
test("TDD-WP7-EXT-001 fixes independent OneAPI routes without embedding credentials", () => {
const manifest = JSON.parse(readFileSync("config/wp7-02-oneapi-test.json", "utf8"));
assert.equal(manifest.config_set_version, 8);
assert.equal(manifest.gateway_account_ref, "oneapi-intelligrow-test");
assert.deepEqual(manifest.models.map((entry) => entry.model_id), WP7_02_MODEL_IDS);
assert.deepEqual(manifest.models.map((entry) => entry.route_profile.protocol_version), [
"gemini-openai-chat-v1",
"openai-images-v1",
]);
assert.deepEqual(manifest.models.map((entry) => entry.config_version), [7, 2]);
assert.equal(manifest.models[0].route_profile.endpoint, "https://oneapi.intelligrow.cn/v1/chat/completions");
assert.equal(manifest.models[0].route_profile.provider_model_id, "gemini-3.1-flash-image");
assert.equal(manifest.models[1].route_profile.reference_endpoint, "https://oneapi.intelligrow.cn/v1/images/edits");
assert.equal(manifest.models.every((entry) => entry.route_profile.endpoint.startsWith("https://oneapi.intelligrow.cn/")), true);
assert.doesNotMatch(JSON.stringify(manifest), /api[_-]?key|authorization|bearer|sk-[A-Za-z0-9]/i);
});
test("TDD-WP7-EXT-001 writes blocked evidence without mock or sensitive payloads", () => {
const evidence = WP7_02_MODEL_IDS.map((modelId) => buildBlockedModelEvidence({
blockers: ["real_gateway_credentials_absent", "real_model_config_absent"],
candidateRecord: candidate(),
modelId,
runId: "wp7-02-red-test",
}));
validateIndependentEvidenceSet(evidence);
assert.equal(new Set(evidence.map((entry) => entry.evidence_id)).size, 2);
for (const entry of evidence) {
assert.equal(entry.status, "externally_blocked");
assert.equal(entry.external_calls.real_calls, 0);
assert.equal(entry.external_calls.mode, "controlled_real_not_executed");
assert.equal(entry.matrix.scenarios.every((scenario) => scenario.status === "not_run"), true);
assert.equal(entry.manual_review.status, "blocked");
assert.equal(entry.redaction.secret_scan, "passed");
assert.doesNotMatch(JSON.stringify(entry), /raw_prompt|raw_provider|credential_value|[A-Za-z]:\\\\Users\\\\/i);
}
const shared = structuredClone(evidence);
shared[1].evidence_id = shared[0].evidence_id;
assert.throws(() => validateIndependentEvidenceSet(shared), /WP7_02_SHARED_EVIDENCE_FORBIDDEN/);
const mixed = structuredClone(evidence);
mixed[1].status = "passed";
mixed[1].matrix = { model_id: mixed[1].model_id, status: "passed" };
mixed[1].external_calls = { real_calls: 5, status: "passed" };
mixed[1].manual_review = { status: "pending" };
mixed[1].redaction = { status: "passed" };
assert.doesNotThrow(() => validateIndependentEvidenceSet(mixed));
mixed[1].manual_review = { status: "passed" };
assert.doesNotThrow(() => validateIndependentEvidenceSet(mixed));
});
@@ -0,0 +1,48 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import { reviewIndependentModelEvidence } from "../../scripts/lib/wp7-02-manual-review.mjs";
const modelIds = ["gemini-3.1-flash-image", "gpt-image-2"];
const dimensions = { "3:4": [1080, 1440], "1:1": [1080, 1080], "4:3": [1440, 1080], "9:16": [1080, 1920] };
function entry(modelId, complete) {
const calls = Object.entries(dimensions).map(([ratio, [width, height]], index) => ({
input: "pure_text", requested_ratio: ratio, response: { dimensions: { height, width } },
scenario_id: `real-${index + 1}`, source: "real_gateway", status: "passed",
}));
calls.push({ ...calls[1], input: "reference_image", scenario_id: "real-5" });
return {
externalCalls: complete ? {
approved_real_call_limit: 120,
attempts: calls.map((call) => ({ attempt_no: 1, scenario_id: call.scenario_id, status: "passed" })),
calls, maximum_real_calls: 6, planned_real_calls: 5, real_calls: 5, status: "passed",
} : { attempts: [{ attempt_no: 1, scenario_id: "real-1", status: "failed" }], calls: [], maximum_real_calls: 6, planned_real_calls: 5, real_calls: 1, status: "externally_blocked" },
matrix: complete ? {
config_version: 2,
contract_change: { full_matrix_reapplied: true },
error_scenarios: Array.from({ length: 9 }, () => ({ status: "passed" })),
execution_modes: ["covered_by_real_calls", "passed", "passed"].map((status) => ({ status })),
model_id: modelId,
pure_text: { status: "passed" },
ratios: Object.keys(dimensions).map((ratio) => ({ ratio, status: "passed" })),
reference_image: { status: "passed" },
settlements: [{}, {}, {}],
status: "passed",
} : { config_version: 2, model_id: modelId, status: "externally_blocked" },
modelId,
readiness: { evidence_id: `sha256:${modelId}`, status: complete ? "passed" : "externally_blocked" },
redaction: { secret_scan: "passed", status: "passed" },
};
}
test("TDD-WP7-EXT-001 reviews each model independently when the set is mixed", () => {
const result = reviewIndependentModelEvidence(modelIds.map((modelId, index) => entry(modelId, index === 1)), {
reviewedAt: "2026-08-04T09:30:00.000Z",
runId: "wp7-02-mixed-review",
});
assert.equal(result.status, "externally_blocked");
assert.deepEqual(result.reviews.map((review) => [review.model_id, review.status]), [
[modelIds[0], "blocked"], [modelIds[1], "passed"],
]);
});
+41
View File
@@ -0,0 +1,41 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { buildCoverageEvidence } from '../../scripts/lib/wp7-05-coverage.mjs';
import { REQUIRED_COVERAGE_UNITS } from '../../scripts/lib/wp7-05-ui-gate.mjs';
const viewports = [
{ width: 1920, height: 1080, deviceScaleFactor: 1, zoom: 100 },
{ width: 1920, height: 1080, deviceScaleFactor: 1, zoom: 200 },
];
function completeUnits() {
return REQUIRED_COVERAGE_UNITS.map((page_id) => ({
page_id,
states: [{
state: 'normal',
screenshot_100pct: `ui/${page_id}/normal/100pct.png`,
screenshot_200pct: `ui/${page_id}/normal/200pct.png`,
trace: `ui/${page_id}/normal/trace.zip`,
}],
}));
}
test('builds ordered, sanitized evidence for all 22 coverage units', () => {
const evidence = buildCoverageEvidence({
runId: 'wp7-05-red-001',
candidateSha256: 'a'.repeat(64),
coverageUnits: completeUnits(),
viewports,
});
assert.equal(evidence.coverage_units.length, 22);
assert.equal(evidence.coverage_units[0].page_id, 'support-gate');
assert.equal(evidence.candidate_sha256, 'A'.repeat(64));
});
test('rejects absolute evidence paths and incomplete page state', () => {
const units = completeUnits();
units[0].states[0].trace = 'C:\\secret\\trace.zip';
assert.throws(() => buildCoverageEvidence({
runId: 'wp7-05-red-001', candidateSha256: 'a'.repeat(64), coverageUnits: units, viewports,
}), /WP7_05_UNSAFE_TRACE/);
});
+47
View File
@@ -0,0 +1,47 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { loadCandidateRecord, validateCoverageEvidence, runWp705Gate, REQUIRED_COVERAGE_UNITS } from '../../scripts/lib/wp7-05-ui-gate.mjs';
test('WP7-05 accepts the WP7-01 candidate record schema', () => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'wp7-05-'));
const file = path.join(directory, 'release-candidate.json');
fs.writeFileSync(file, JSON.stringify({
browsers: [
{ brand: 'Google Chrome', full_version: '150.0.0', major: 150 },
{ brand: 'Microsoft Edge', full_version: '151.0.0', major: 151 },
],
windows: { build: '26200.8875' },
candidate_package: { fixed_port: 43121, sha256: 'A'.repeat(64) },
}));
assert.equal(loadCandidateRecord(file).status, 'ready');
fs.rmSync(directory, { recursive: true, force: true });
});
test('WP7-05 requires all 22 coverage units and both exact candidate viewports', () => {
const result = validateCoverageEvidence({ coverage_units: [], viewports: [] });
assert.equal(result.status, 'externally_blocked');
assert.equal(result.code, 'coverage_units_incomplete');
assert.equal(result.missing.length, REQUIRED_COVERAGE_UNITS.length);
});
test('WP7-05 requires state evidence for every listed coverage unit', () => {
const result = validateCoverageEvidence({
coverage_units: REQUIRED_COVERAGE_UNITS.map((page_id) => ({ page_id, states: [] })),
viewports: [],
});
assert.equal(result.code, 'coverage_states_incomplete');
assert.equal(result.missingStates.length, REQUIRED_COVERAGE_UNITS.length);
});
test('WP7-05 preserves upstream external blockers instead of declaring Green', () => {
const result = runWp705Gate({
candidatePath: 'missing-release-candidate.json',
evidence: null,
dependencies: { 'TASK-WP7-03': 'externally_blocked' },
});
assert.equal(result.status, 'externally_blocked');
assert.equal(result.code, 'candidate_record_missing');
});
+75
View File
@@ -0,0 +1,75 @@
import assert from "node:assert/strict";
import test from "node:test";
import { buildWp706PrefreezeReport } from "../../scripts/lib/wp7-06-prefreeze.mjs";
const expectedTrace = {
errors: [],
status: "passed",
summary: {
acceptanceCriteria: 52,
errorCategories: 9,
featureModules: 13,
parentFamilies: 89,
penProductFrames: 18,
productContracts: 19,
requirements: 109,
tasks: 52,
testCases: 117,
uiPages: 22,
},
};
const upstream = {
"TASK-WP7-01": { branch: "codex/wp7-01", head: "1".repeat(40), merged: true, status: "passed" },
"TASK-WP7-02": { branch: "codex/wp7-02", head: "2".repeat(40), merged: true, status: "passed" },
"TASK-WP7-03": { branch: "codex/wp7-03", head: "3".repeat(40), merged: true, status: "deferred_nonblocking_first_version" },
"TASK-WP7-04": { branch: "codex/wp7-04", head: "4".repeat(40), merged: true, status: "deferred_nonblocking_first_version" },
"TASK-WP7-05": { branch: "codex/wp7-05", head: "5".repeat(40), merged: true, status: "passed" },
};
test("builds the exact WP7-06 pre-freeze closure without pretending deferred suppliers passed", () => {
const report = buildWp706PrefreezeReport({
currentCommit: "a".repeat(40),
releaseExists: false,
trace: expectedTrace,
upstream,
});
assert.equal(report.status, "passed");
assert.equal(report.release_json_written, false);
assert.deepEqual(report.trace_summary, expectedTrace.summary);
assert.deepEqual(report.deferred_external_tasks, ["TASK-WP7-03", "TASK-WP7-04"]);
});
test("rejects missing lineage and premature RELEASE.json", () => {
assert.throws(() => buildWp706PrefreezeReport({
currentCommit: "a".repeat(40),
releaseExists: false,
trace: expectedTrace,
upstream: { ...upstream, "TASK-WP7-05": { ...upstream["TASK-WP7-05"], merged: false } },
}), /WP7_06_UPSTREAM_NOT_MERGED:TASK-WP7-05/);
assert.throws(() => buildWp706PrefreezeReport({
currentCommit: "a".repeat(40),
releaseExists: true,
trace: expectedTrace,
upstream,
}), /WP7_06_RELEASE_WRITTEN_PREMATURELY/);
});
test("rejects trace drift and unsupported upstream statuses", () => {
assert.throws(() => buildWp706PrefreezeReport({
currentCommit: "a".repeat(40),
releaseExists: false,
trace: { ...expectedTrace, summary: { ...expectedTrace.summary, testCases: 116 } },
upstream,
}), /WP7_06_TRACE_COUNT_MISMATCH:testCases/);
assert.throws(() => buildWp706PrefreezeReport({
currentCommit: "a".repeat(40),
releaseExists: false,
trace: expectedTrace,
upstream: { ...upstream, "TASK-WP7-03": { ...upstream["TASK-WP7-03"], status: "passed" } },
}), /WP7_06_UNSUPPORTED_STATUS:TASK-WP7-03/);
});
@@ -0,0 +1,47 @@
import assert from "node:assert/strict";
import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";
import { buildFinalReleaseRecord, scanReleaseFiles, validateFinalEvidence } from "../../scripts/lib/wp7-07-final-release.mjs";
function release() {
return buildFinalReleaseRecord({
appVersion: "0.0.0",
browsers: [
{ brand: "Google Chrome", fullVersion: "150.0.7871.187" },
{ brand: "Microsoft Edge", fullVersion: "151.0.4129.59" },
],
buildCommit: "a".repeat(40),
frozenFromCommit: "b".repeat(40),
recordedAt: "2026-08-04T06:00:00.000Z",
windows: { arch: "x64", build: "26200.8875", displayVersion: "25H2" },
});
}
test("TDD-WP7-REL-001 creates a browser-gate compatible first-version record", () => {
const record = release();
assert.equal(record.finalRelease, true);
assert.equal(record.fixedPort, 43121);
assert.deepEqual(record.deferredExternalTasks, ["TASK-WP7-03", "TASK-WP7-04"]);
assert.deepEqual(record.browsers.map(({ brand }) => brand).sort(), ["Google Chrome", "Microsoft Edge"]);
});
test("TDD-WP7-SEC-001 rejects credential shapes and absolute user paths", () => {
const root = mkdtempSync(join(tmpdir(), "dada-wp7-07-scan-"));
mkdirSync(join(root, "logs"));
writeFileSync(join(root, "logs", "diagnostic.txt"), "credential=key-abcdefghijklmnop C:\\Users\\person\\private.txt\n");
const scan = scanReleaseFiles({ roots: [root] });
assert.equal(scan.status, "failed");
assert.deepEqual(new Set(scan.findings.map(({ rule }) => rule)), new Set(["absolute_user_path", "credential_shape"]));
});
test("TDD-WP7-REL-001 binds release and package hashes only after a zero-finding scan", () => {
assert.deepEqual(validateFinalEvidence({
packageManifest: { release_status: "first_version_internal", zip_sha256: "C".repeat(64) },
release: release(),
releaseSha256: "D".repeat(64),
scan: { findings: [], status: "passed" },
}), { release_sha256: "D".repeat(64), status: "passed", zip_sha256: "C".repeat(64) });
});
+21
View File
@@ -190,6 +190,27 @@ describe("TDD-WP5-MAN-001 readonly asset compiler", () => {
expect(repeated.report.derived_files).toEqual({ created: 0, reused: 4, total: 4 });
});
it("safely relocates legacy absolute font package paths after an archive move", () => {
const fixture = createFixture();
const catalogPath = join(fixture.sourceRoot, "fonts", "reports", "font_panel_catalog.csv");
const metadata = JSON.parse(readFileSync(join(fixture.sourceRoot, "fonts", "resources", "font_packages", "FONT001_Test", "metadata.json"), "utf8")) as { local_sha256: string };
csv(catalogPath, [{
candidate_id: "FONT001",
display_name: "Test Font",
font_family: "Dada Test",
local_sha256: metadata.local_sha256,
panel_order: "1",
resource_dir: "C:/Users/legacy/Desktop/sticker_text/fonts/resources/font_packages/FONT001_Test",
resource_status: "verified_extracted",
}]);
expect(() => compileAssetArchive({
manifestPath: fixture.manifestPath,
outputDirectory: fixture.outputRoot,
releaseVersion: "fixture-v1",
})).not.toThrow();
});
it("rejects evidence collections, traversal and output inside a source root", () => {
const fixture = createFixture();
const manifest = JSON.parse(readFileSync(fixture.manifestPath, "utf8")) as { collections: unknown[] };
@@ -0,0 +1,70 @@
import { describe, expect, it } from "vitest";
import { GeminiFlashAdapter } from "../../apps/worker/src/ai-adapter-gemini-flash.js";
import { GeminiProAdapter } from "../../apps/worker/src/ai-adapter-gemini-pro.js";
import { GptImageAdapter } from "../../apps/worker/src/ai-adapter-gpt-image.js";
import {
gptImageRequestSizeForRatio,
normalizeImageOutputToRatio,
productDimensionsForRatio,
} from "../../apps/worker/src/image-output-normalizer.mjs";
const onePixelPng = Buffer.from(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
"base64",
);
describe("TDD-WP7-EXT-001 exact image output normalization", () => {
it("uses only GPT Image 2 request sizes allowed by the upstream API", () => {
expect(["3:4", "1:1", "4:3", "9:16"].map((ratio) => gptImageRequestSizeForRatio(ratio))).toEqual([
"1056x1408",
"1088x1088",
"1408x1056",
"1008x1792",
]);
for (const ratio of ["3:4", "1:1", "4:3", "9:16"] as const) {
const [width, height] = gptImageRequestSizeForRatio(ratio).split("x").map(Number);
expect(width % 16).toBe(0);
expect(height % 16).toBe(0);
}
});
it("normalizes provider output to the frozen product dimensions", async () => {
const output = await normalizeImageOutputToRatio({ bytes: onePixelPng, mimeType: "image/png", ratio: "1:1" });
expect(output).toMatchObject({
mimeType: "image/png",
normalized: true,
pixelHeight: 1080,
pixelWidth: 1080,
upstreamPixelHeight: 1,
upstreamPixelWidth: 1,
});
expect(output.bytes.subarray(0, 8).toString("hex")).toBe("89504e470d0a1a0a");
expect(productDimensionsForRatio("9:16")).toEqual({ pixelHeight: 1920, pixelWidth: 1080 });
});
it("is used by all three production adapter boundaries", async () => {
const encoded = onePixelPng.toString("base64");
const adapters = [
new GeminiFlashAdapter({ transport: {
async start() { return { candidates: [{ inline_data: { data: encoded, mime_type: "image/png" }, pixelHeight: 1, pixelWidth: 1 }] }; },
async poll() { return {}; },
} }),
new GeminiProAdapter({ transport: {
async start() { return { operation: { done: true, response: { candidates: [{ inline_data: { data: encoded, mime_type: "image/png" }, pixelHeight: 1, pixelWidth: 1 }] } } }; },
async poll() { return {}; },
} }),
new GptImageAdapter({ transport: {
async start() { return { data: [{ b64_json: encoded, pixelHeight: 1, pixelWidth: 1 }] }; },
async poll() { return {}; },
} }),
];
for (const adapter of adapters) {
const result = await adapter.start({
configSnapshot: {}, generationId: `normalization-${adapter.modelId}`, modelId: adapter.modelId,
prompt: "sanitized fixture", ratio: "1:1", referenceAssetIds: [],
});
expect(result).toMatchObject({ status: "completed", outputs: [{ mimeType: "image/png", pixelHeight: 1080, pixelWidth: 1080 }] });
}
});
});
@@ -1,7 +1,7 @@
import { createHash } from "node:crypto";
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
import { homedir } from "node:os";
import { basename, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
import { WP4_07_REAL_RESOURCE_VERSIONS } from "./wp4-07-fixture.mjs";
@@ -74,15 +74,16 @@ function assetRecord(assetId, path, sourceReference, expectedSha256) {
export function loadWp407RealAssets() {
const manifestPath = resolve(process.env.DADA_WP4_07_FINAL_ASSET_MANIFEST ?? "");
if (!process.env.DADA_WP4_07_FINAL_ASSET_MANIFEST || !existsSync(manifestPath)) throw new Error("WP4_07_FINAL_ASSET_MANIFEST_REQUIRED");
const handoffPath = resolve(process.env.DADA_COMPLEX_ASSET_MANIFEST ?? join(homedir(), "Desktop", "sticker_web_handoff", "sticker_web_catalog_manifest.json"));
const staticRoot = resolve(process.env.DADA_STATIC_STICKER_ROOT ?? join(homedir(), "Desktop", "贴纸素材"));
const replicationRoot = resolve(process.env.DADA_REPLICATION_ASSET_ROOT ?? join(homedir(), "Desktop", "sticker_web_replication_assets"));
const handoffPath = resolve(process.env.DADA_COMPLEX_ASSET_MANIFEST ?? join(replicationRoot, "sticker_web_handoff", "sticker_web_catalog_manifest.json"));
const staticRoot = resolve(process.env.DADA_STATIC_STICKER_ROOT ?? join(replicationRoot, "sticker_normal"));
const backgroundPath = resolve(process.env.DADA_WP4_07_BACKGROUND_PATH ?? join(homedir(), "Documents", "贴纸脚本", "time_01_input_20260716.png"));
if (!existsSync(handoffPath) || !existsSync(staticRoot)) throw new Error("WP4_07_REAL_ARCHIVE_ROOT_REQUIRED");
const manifestRaw = readFileSync(manifestPath, "utf8");
const manifest = JSON.parse(manifestRaw);
const handoff = JSON.parse(readFileSync(handoffPath, "utf8"));
const collectionRoots = Object.fromEntries(handoff.collections.map((collection) => [collection.id, resolve(collection.root)]));
const collectionRoots = Object.fromEntries(handoff.collections.map((collection) => [collection.id, resolve(dirname(handoffPath), collection.root)]));
const fontRoot = collectionRoots.font_panel;
const dynamicRoot = collectionRoots.interactive_stickers;
if (!fontRoot || !dynamicRoot) throw new Error("WP4_07_REAL_ARCHIVE_COLLECTION_REQUIRED");