@resolveio/server-lib 22.3.124 → 22.3.125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/collections/ai-run.collection.d.ts +3 -0
- package/collections/ai-run.collection.js +170 -0
- package/collections/ai-run.collection.js.map +1 -0
- package/managers/ai-run-evidence.manager.d.ts +36 -0
- package/managers/ai-run-evidence.manager.js +377 -0
- package/managers/ai-run-evidence.manager.js.map +1 -0
- package/managers/openai-usage-ledger.manager.d.ts +1 -0
- package/managers/openai-usage-ledger.manager.js +5 -56
- package/managers/openai-usage-ledger.manager.js.map +1 -1
- package/models/ai-run.model.d.ts +19 -0
- package/models/ai-run.model.js +4 -0
- package/models/ai-run.model.js.map +1 -0
- package/package.json +3 -1
- package/public_api.d.ts +7 -0
- package/public_api.js +7 -0
- package/public_api.js.map +1 -1
- package/util/ai-run-evidence-adapters.d.ts +33 -0
- package/util/ai-run-evidence-adapters.js +660 -0
- package/util/ai-run-evidence-adapters.js.map +1 -0
- package/util/ai-run-evidence-dashboard.d.ts +67 -0
- package/util/ai-run-evidence-dashboard.js +309 -0
- package/util/ai-run-evidence-dashboard.js.map +1 -0
- package/util/ai-run-evidence-eval.d.ts +86 -0
- package/util/ai-run-evidence-eval.js +854 -0
- package/util/ai-run-evidence-eval.js.map +1 -0
- package/util/ai-run-evidence.d.ts +212 -0
- package/util/ai-run-evidence.js +649 -0
- package/util/ai-run-evidence.js.map +1 -0
- package/util/ai-runner-qa-tools.d.ts +1 -0
- package/util/ai-runner-qa-tools.js +129 -10
- package/util/ai-runner-qa-tools.js.map +1 -1
- package/util/openai-usage-cost.d.ts +6 -0
- package/util/openai-usage-cost.js +92 -0
- package/util/openai-usage-cost.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/ai-run-evidence.ts"],"names":[],"mappings":"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","file":"ai-run-evidence.js","sourcesContent":["export type AIRunSource =\n\t| 'support_ticket'\n\t| 'aicoder_app'\n\t| 'ai_assistant'\n\t| 'qa_runner'\n\t| 'unknown';\n\nexport type AIRunOutcomeLabel =\n\t| 'accepted'\n\t| 'rejected'\n\t| 'qa_incomplete'\n\t| 'qa_infra_failed'\n\t| 'build_failed'\n\t| 'release_blocked'\n\t| 'manual_handoff'\n\t| 'false_pass'\n\t| 'stopped'\n\t| 'unknown';\n\nexport type AIRunEventType =\n\t| 'model_call'\n\t| 'log'\n\t| 'qa_infra'\n\t| 'qa_compile'\n\t| 'qa_route_probe'\n\t| 'qa_business_assertion'\n\t| 'scorecard'\n\t| 'deploy'\n\t| 'publish'\n\t| 'assistant_message'\n\t| 'git_commit'\n\t| 'usage'\n\t| 'human_intervention';\n\nexport type AIRunGateStatus = 'pass' | 'fail' | 'warn' | 'blocked' | 'skipped';\n\nexport type AIQaCheckStatus = 'pass' | 'fail' | 'blocked' | 'warn' | 'skipped' | 'unknown';\n\nexport type AIQaCompileStatus = 'pass' | 'fail' | 'blocked' | 'stale' | 'skipped' | 'unknown';\n\nexport type AIQaOutcome =\n\t| 'infra_failed'\n\t| 'compile_failed'\n\t| 'route_failed'\n\t| 'route_only_pass'\n\t| 'business_assertion_passed'\n\t| 'business_assertion_failed'\n\t| 'incomplete';\n\nexport interface AIRunEvent {\n\tid?: string;\n\ttype: AIRunEventType;\n\tsource?: AIRunSource | string;\n\tmessage?: string;\n\tcategory?: string;\n\tartifactPaths?: string[];\n\tmetadata?: Record<string, any>;\n\trecordedAt?: Date | string;\n}\n\nexport interface AIRunGateResult {\n\tkey: string;\n\tlabel: string;\n\tstatus: AIRunGateStatus;\n\treason: string;\n\tevidenceRefs: string[];\n\trecordedAt: string;\n\tmetadata?: Record<string, any>;\n}\n\nexport interface AIRunCost {\n\tinputTokens: number;\n\tcachedInputTokens: number;\n\toutputTokens: number;\n\ttotalTokens: number;\n\testimatedUsd: number;\n\tmodels: string[];\n\tcategories: Record<string, {\n\t\tinputTokens: number;\n\t\tcachedInputTokens: number;\n\t\toutputTokens: number;\n\t\ttotalTokens: number;\n\t\testimatedUsd: number;\n\t\tcount: number;\n\t}>;\n\twallTimeMs?: number;\n\tretries?: number;\n}\n\nexport interface OpenAIUsageCostEntry {\n\tmodel?: string;\n\tcategory?: string;\n\tid_request?: string;\n\tidRequest?: string;\n\tid_conversation?: string;\n\tidConversation?: string;\n\ttimestamp?: Date | string;\n\tinput_tokens?: number;\n\tinputTokens?: number;\n\tcached_input_tokens?: number;\n\tcachedInputTokens?: number;\n\toutput_tokens?: number;\n\toutputTokens?: number;\n\ttotal_tokens?: number;\n\ttotalTokens?: number;\n\tcost_estimate?: number;\n\testimatedUsd?: number;\n\t[key: string]: any;\n}\n\nexport interface AIQaInfraCheck {\n\tname: string;\n\tstatus: AIQaCheckStatus;\n\tmessage?: string;\n\tpath?: string;\n\tdurationMs?: number;\n\tmetadata?: Record<string, any>;\n\tcheckedAt?: Date | string;\n}\n\nexport interface AIQaCompileResult {\n\tstatus: AIQaCompileStatus;\n\tcommand?: string;\n\tartifactPath?: string;\n\tmessage?: string;\n\tdurationMs?: number;\n\tstaleEvidence?: boolean;\n\trecordedAt?: Date | string;\n\tmetadata?: Record<string, any>;\n}\n\nexport interface AIQaRouteProbe {\n\troute: string;\n\tstatus: AIQaCheckStatus;\n\tscreenshot?: string;\n\tcaption?: string;\n\tshellOnly?: boolean;\n\tauthenticated?: boolean;\n\tconsoleErrors?: string[];\n\tnetworkErrors?: string[];\n\tmessage?: string;\n\trecordedAt?: Date | string;\n\tmetadata?: Record<string, any>;\n}\n\nexport interface AIQaBusinessAssertion {\n\tassertion: string;\n\tstatus: AIQaCheckStatus;\n\tworkflow?: string;\n\troute?: string;\n\taction?: string;\n\texpected?: string;\n\tobserved?: string;\n\tdataProof?: string;\n\tmongoDelta?: Record<string, any>;\n\tartifactPaths?: string[];\n\tmessage?: string;\n\trecordedAt?: Date | string;\n\tmetadata?: Record<string, any>;\n}\n\nexport interface AIQaArtifact {\n\ttype: 'screenshot' | 'trace' | 'console_log' | 'network_log' | 'coverage_matrix' | 'seed_data' | 'script' | 'other';\n\tpath?: string;\n\turl?: string;\n\ttitle?: string;\n\tcaption?: string;\n\tmetadata?: Record<string, any>;\n}\n\nexport interface AIQaRun {\n\toutcome: AIQaOutcome;\n\tinfraChecks: AIQaInfraCheck[];\n\tcompile?: AIQaCompileResult;\n\trouteProbes: AIQaRouteProbe[];\n\tbusinessAssertions: AIQaBusinessAssertion[];\n\tartifacts: AIQaArtifact[];\n\tgateResults: AIRunGateResult[];\n\tupdatedAt: string;\n}\n\nexport interface AIRun {\n\tid?: string;\n\tsource: AIRunSource;\n\tsourceIds: Record<string, string>;\n\ttitle?: string;\n\tstatus?: string;\n\tphase?: string;\n\tstartedAt?: Date | string;\n\tcompletedAt?: Date | string;\n\toutcome: AIRunOutcomeLabel;\n\tevents: AIRunEvent[];\n\tgates: AIRunGateResult[];\n\tqa?: AIQaRun;\n\tcost?: AIRunCost;\n\tnextAction?: string;\n\twarnings?: string[];\n\tmetadata?: Record<string, any>;\n}\n\nexport interface AIRunTrainingExample {\n\trunId: string;\n\tsource: AIRunSource;\n\tinputSummary: string;\n\tactionSummary: string;\n\toutcome: AIRunOutcomeLabel;\n\tevidence: string[];\n\tcost?: AIRunCost;\n\tmetadata?: Record<string, any>;\n}\n\nexport interface AIQaEvaluationInput {\n\tinfraChecks?: AIQaInfraCheck[];\n\tcompile?: AIQaCompileResult;\n\trouteProbes?: AIQaRouteProbe[];\n\tbusinessAssertions?: AIQaBusinessAssertion[];\n\tartifacts?: AIQaArtifact[];\n\tnow?: Date | string;\n}\n\nexport interface AIRunOutcomeInput {\n\tsource?: AIRunSource;\n\tstatus?: string;\n\tphase?: string;\n\tqa?: AIQaRun | AIQaEvaluationInput;\n\tgates?: AIRunGateResult[];\n\tscorecardPassed?: boolean;\n\tscorecardStatus?: string;\n\tdeployStatus?: string;\n\tpublishStatus?: string;\n\tsampleDataStatus?: string;\n\tmanualHandoff?: boolean;\n\tstopped?: boolean;\n\trejected?: boolean;\n\texplicitAccepted?: boolean;\n\tterminal?: boolean;\n\tnow?: Date | string;\n}\n\nexport interface AIRunOutcomeDecision {\n\toutcome: AIRunOutcomeLabel;\n\treason: string;\n\tnextAction: string;\n\tgates: AIRunGateResult[];\n\twarnings: string[];\n\trecordedAt: string;\n}\n\nfunction isoNow(value?: Date | string): string {\n\tif (value instanceof Date) {\n\t\treturn value.toISOString();\n\t}\n\tconst parsed = value ? new Date(value) : new Date();\n\tif (Number.isFinite(parsed.getTime())) {\n\t\treturn parsed.toISOString();\n\t}\n\treturn new Date().toISOString();\n}\n\nfunction cleanText(value: any, max = 1000): string {\n\treturn String(value || '').replace(/\\s+/g, ' ').trim().slice(0, max);\n}\n\nfunction cleanUsageNumber(value: any): number {\n\tconst parsed = Number(value);\n\treturn Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction cleanUsageDate(value: any): Date | undefined {\n\tif (!value) {\n\t\treturn undefined;\n\t}\n\tconst date = value instanceof Date ? value : new Date(value);\n\treturn Number.isFinite(date.getTime()) ? date : undefined;\n}\n\nexport function isCumulativeCodexUsageEntry(entry: OpenAIUsageCostEntry): boolean {\n\treturn cleanText(entry?.category, 180).toLowerCase().startsWith('ai-dashboard-codex:');\n}\n\nexport function resolveOpenAIUsageThreadKey(entry: OpenAIUsageCostEntry): string {\n\tconst conversationId = cleanText(entry?.id_conversation ?? entry?.idConversation, 240);\n\tif (conversationId) {\n\t\treturn conversationId;\n\t}\n\treturn cleanText(entry?.id_request ?? entry?.idRequest, 240);\n}\n\nexport function normalizeOpenAIUsageRowsForCosting<T extends OpenAIUsageCostEntry>(rows: T[] = []): T[] {\n\tif (!Array.isArray(rows) || !rows.length) {\n\t\treturn [];\n\t}\n\tconst sortedRows = rows\n\t\t.map((row, index) => ({\n\t\t\t...row,\n\t\t\t_sortIndex: index\n\t\t}))\n\t\t.sort((a, b) => {\n\t\t\tconst timeA = cleanUsageDate(a.timestamp)?.getTime() || 0;\n\t\t\tconst timeB = cleanUsageDate(b.timestamp)?.getTime() || 0;\n\t\t\tif (timeA !== timeB) {\n\t\t\t\treturn timeA - timeB;\n\t\t\t}\n\t\t\tconst requestCompare = cleanText(a.id_request ?? a.idRequest, 240)\n\t\t\t\t.localeCompare(cleanText(b.id_request ?? b.idRequest, 240));\n\t\t\tif (requestCompare) {\n\t\t\t\treturn requestCompare;\n\t\t\t}\n\t\t\tconst conversationCompare = cleanText(a.id_conversation ?? a.idConversation, 240)\n\t\t\t\t.localeCompare(cleanText(b.id_conversation ?? b.idConversation, 240));\n\t\t\tif (conversationCompare) {\n\t\t\t\treturn conversationCompare;\n\t\t\t}\n\t\t\treturn cleanUsageNumber(a._sortIndex) - cleanUsageNumber(b._sortIndex);\n\t\t});\n\tconst previousByThread = new Map<string, {\n\t\tinputTokens: number;\n\t\tcachedInputTokens: number;\n\t\toutputTokens: number;\n\t\ttotalTokens: number;\n\t\testimatedUsd: number;\n\t}>();\n\treturn sortedRows.map((row) => {\n\t\tconst inputTokens = cleanUsageNumber(row.input_tokens ?? row.inputTokens);\n\t\tconst cachedInputTokens = cleanUsageNumber(row.cached_input_tokens ?? row.cachedInputTokens);\n\t\tconst outputTokens = cleanUsageNumber(row.output_tokens ?? row.outputTokens);\n\t\tconst totalTokens = cleanUsageNumber(row.total_tokens ?? row.totalTokens ?? (inputTokens + outputTokens));\n\t\tconst estimatedUsd = cleanUsageNumber(row.cost_estimate ?? row.estimatedUsd);\n\t\tconst threadKey = isCumulativeCodexUsageEntry(row) ? resolveOpenAIUsageThreadKey(row) : '';\n\t\tlet normalizedInputTokens = inputTokens;\n\t\tlet normalizedCachedInputTokens = cachedInputTokens;\n\t\tlet normalizedOutputTokens = outputTokens;\n\t\tlet normalizedTotalTokens = totalTokens;\n\t\tlet normalizedEstimatedUsd = estimatedUsd;\n\t\tif (threadKey) {\n\t\t\tconst previous = previousByThread.get(threadKey);\n\t\t\tif (previous\n\t\t\t\t&& inputTokens >= previous.inputTokens\n\t\t\t\t&& cachedInputTokens >= previous.cachedInputTokens\n\t\t\t\t&& outputTokens >= previous.outputTokens\n\t\t\t\t&& totalTokens >= previous.totalTokens\n\t\t\t\t&& estimatedUsd >= previous.estimatedUsd\n\t\t\t) {\n\t\t\t\tnormalizedInputTokens = Math.max(0, inputTokens - previous.inputTokens);\n\t\t\t\tnormalizedCachedInputTokens = Math.max(0, cachedInputTokens - previous.cachedInputTokens);\n\t\t\t\tnormalizedOutputTokens = Math.max(0, outputTokens - previous.outputTokens);\n\t\t\t\tnormalizedTotalTokens = Math.max(0, totalTokens - previous.totalTokens);\n\t\t\t\tnormalizedEstimatedUsd = Math.max(0, estimatedUsd - previous.estimatedUsd);\n\t\t\t}\n\t\t\tpreviousByThread.set(threadKey, {\n\t\t\t\tinputTokens,\n\t\t\t\tcachedInputTokens,\n\t\t\t\toutputTokens,\n\t\t\t\ttotalTokens,\n\t\t\t\testimatedUsd\n\t\t\t});\n\t\t}\n\t\tconst resolvedTotalTokens = normalizedTotalTokens || (normalizedInputTokens + normalizedOutputTokens);\n\t\tconst resolvedEstimatedUsd = Number(normalizedEstimatedUsd.toFixed(6));\n\t\treturn {\n\t\t\t...row,\n\t\t\tinput_tokens: normalizedInputTokens,\n\t\t\tinputTokens: normalizedInputTokens,\n\t\t\tcached_input_tokens: normalizedCachedInputTokens,\n\t\t\tcachedInputTokens: normalizedCachedInputTokens,\n\t\t\toutput_tokens: normalizedOutputTokens,\n\t\t\toutputTokens: normalizedOutputTokens,\n\t\t\ttotal_tokens: resolvedTotalTokens,\n\t\t\ttotalTokens: resolvedTotalTokens,\n\t\t\tcost_estimate: resolvedEstimatedUsd,\n\t\t\testimatedUsd: resolvedEstimatedUsd\n\t\t} as T;\n\t});\n}\n\nfunction cleanList(values: any, limit = 20, max = 500): string[] {\n\tif (!Array.isArray(values)) {\n\t\treturn [];\n\t}\n\tconst result: string[] = [];\n\tfor (const value of values) {\n\t\tconst normalized = cleanText(value, max);\n\t\tif (normalized && !result.includes(normalized)) {\n\t\t\tresult.push(normalized);\n\t\t}\n\t\tif (result.length >= limit) {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction normalizeCheckStatus(value: any): AIQaCheckStatus {\n\tconst normalized = cleanText(value, 40).toLowerCase().replace(/[_\\s-]+/g, '_');\n\tif (normalized === 'passed' || normalized === 'ok' || normalized === 'ready') {\n\t\treturn 'pass';\n\t}\n\tif (normalized === 'failed' || normalized === 'error' || normalized === 'fail') {\n\t\treturn 'fail';\n\t}\n\tif (normalized === 'blocked' || normalized === 'dependency_blocked') {\n\t\treturn 'blocked';\n\t}\n\tif (normalized === 'warning') {\n\t\treturn 'warn';\n\t}\n\tif (normalized === 'skipped' || normalized === 'not_applicable') {\n\t\treturn 'skipped';\n\t}\n\treturn normalized === 'pass' || normalized === 'warn' ? normalized : 'unknown';\n}\n\nfunction normalizeCompileStatus(value: any): AIQaCompileStatus {\n\tconst normalized = cleanText(value, 40).toLowerCase().replace(/[_\\s-]+/g, '_');\n\tif (normalized === 'passed' || normalized === 'ok') {\n\t\treturn 'pass';\n\t}\n\tif (normalized === 'failed' || normalized === 'error') {\n\t\treturn 'fail';\n\t}\n\tif (normalized === 'blocked') {\n\t\treturn 'blocked';\n\t}\n\tif (normalized === 'stale' || normalized === 'stale_evidence') {\n\t\treturn 'stale';\n\t}\n\tif (normalized === 'skipped' || normalized === 'not_applicable') {\n\t\treturn 'skipped';\n\t}\n\treturn normalized === 'pass' || normalized === 'fail' ? normalized : 'unknown';\n}\n\nfunction makeGate(\n\tkey: string,\n\tlabel: string,\n\tstatus: AIRunGateStatus,\n\treason: string,\n\tevidenceRefs: string[] = [],\n\tnow?: Date | string,\n\tmetadata?: Record<string, any>\n): AIRunGateResult {\n\treturn {\n\t\tkey,\n\t\tlabel,\n\t\tstatus,\n\t\treason: cleanText(reason, 1400),\n\t\tevidenceRefs: cleanList(evidenceRefs, 20, 500),\n\t\trecordedAt: isoNow(now),\n\t\t...(metadata ? { metadata } : {})\n\t};\n}\n\nfunction failedOrBlocked(status: AIQaCheckStatus | AIQaCompileStatus): boolean {\n\treturn status === 'fail' || status === 'blocked';\n}\n\nfunction passed(status: AIQaCheckStatus | AIQaCompileStatus): boolean {\n\treturn status === 'pass';\n}\n\nfunction normalizeInfraChecks(values: AIQaInfraCheck[] | undefined): AIQaInfraCheck[] {\n\treturn (Array.isArray(values) ? values : []).map((entry) => ({\n\t\t...entry,\n\t\tname: cleanText(entry?.name, 120) || 'infra_check',\n\t\tstatus: normalizeCheckStatus(entry?.status),\n\t\tmessage: cleanText(entry?.message, 1000),\n\t\tpath: cleanText(entry?.path, 500)\n\t}));\n}\n\nfunction normalizeRouteProbes(values: AIQaRouteProbe[] | undefined): AIQaRouteProbe[] {\n\treturn (Array.isArray(values) ? values : []).map((entry) => ({\n\t\t...entry,\n\t\troute: cleanText(entry?.route, 500) || '/',\n\t\tstatus: normalizeCheckStatus(entry?.status),\n\t\tscreenshot: cleanText(entry?.screenshot, 500),\n\t\tcaption: cleanText(entry?.caption, 1000),\n\t\tmessage: cleanText(entry?.message, 1000),\n\t\tconsoleErrors: cleanList(entry?.consoleErrors, 30, 500),\n\t\tnetworkErrors: cleanList(entry?.networkErrors, 30, 500)\n\t}));\n}\n\nfunction normalizeBusinessAssertions(values: AIQaBusinessAssertion[] | undefined): AIQaBusinessAssertion[] {\n\treturn (Array.isArray(values) ? values : []).map((entry) => ({\n\t\t...entry,\n\t\tassertion: cleanText(entry?.assertion, 1000) || 'business assertion',\n\t\tstatus: normalizeCheckStatus(entry?.status),\n\t\tworkflow: cleanText(entry?.workflow, 400),\n\t\troute: cleanText(entry?.route, 500),\n\t\taction: cleanText(entry?.action, 500),\n\t\texpected: cleanText(entry?.expected, 1000),\n\t\tobserved: cleanText(entry?.observed, 1000),\n\t\tdataProof: cleanText(entry?.dataProof, 1400),\n\t\tartifactPaths: cleanList(entry?.artifactPaths, 30, 500),\n\t\tmessage: cleanText(entry?.message, 1000)\n\t}));\n}\n\nfunction collectBusinessAssertionArtifactPaths(assertions: AIQaBusinessAssertion[]): string[] {\n\tconst paths: string[] = [];\n\tfor (const assertion of assertions) {\n\t\tfor (const artifactPath of assertion.artifactPaths || []) {\n\t\t\tif (artifactPath && !paths.includes(artifactPath)) {\n\t\t\t\tpaths.push(artifactPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn paths;\n}\n\nexport function buildAIQaRun(input: AIQaEvaluationInput = {}): AIQaRun {\n\tconst now = isoNow(input.now);\n\tconst infraChecks = normalizeInfraChecks(input.infraChecks);\n\tconst compile = input.compile\n\t\t? {\n\t\t\t...input.compile,\n\t\t\tstatus: normalizeCompileStatus(input.compile.status),\n\t\t\tcommand: cleanText(input.compile.command, 500),\n\t\t\tartifactPath: cleanText(input.compile.artifactPath, 500),\n\t\t\tmessage: cleanText(input.compile.message, 1000)\n\t\t}\n\t\t: undefined;\n\tconst routeProbes = normalizeRouteProbes(input.routeProbes);\n\tconst businessAssertions = normalizeBusinessAssertions(input.businessAssertions);\n\tconst artifacts = Array.isArray(input.artifacts) ? input.artifacts : [];\n\tconst gateResults: AIRunGateResult[] = [];\n\n\tconst failedInfra = infraChecks.filter((check) => failedOrBlocked(check.status));\n\tif (failedInfra.length) {\n\t\tgateResults.push(makeGate(\n\t\t\t'qa_infra',\n\t\t\t'QA infrastructure',\n\t\t\t'blocked',\n\t\t\t`QA infrastructure failed before model/business validation: ${failedInfra.map((check) => `${check.name}: ${check.message || check.status}`).join('; ')}`,\n\t\t\tfailedInfra.map((check) => check.path || '').filter(Boolean),\n\t\t\tnow,\n\t\t\t{ failed_checks: failedInfra.map((check) => check.name) }\n\t\t));\n\t\treturn { outcome: 'infra_failed', infraChecks, compile, routeProbes, businessAssertions, artifacts, gateResults, updatedAt: now };\n\t}\n\tif (infraChecks.length) {\n\t\tgateResults.push(makeGate('qa_infra', 'QA infrastructure', 'pass', 'QA infrastructure preflight checks passed.', [], now));\n\t}\n\n\tif (compile && (failedOrBlocked(compile.status) || compile.status === 'stale' || compile.staleEvidence === true)) {\n\t\tgateResults.push(makeGate(\n\t\t\t'qa_compile',\n\t\t\t'Compile/build',\n\t\t\t'fail',\n\t\t\tcompile.status === 'stale' || compile.staleEvidence === true\n\t\t\t\t? 'Compile/build evidence is stale and cannot be used for acceptance.'\n\t\t\t\t: (compile.message || 'Compile/build failed before browser QA.'),\n\t\t\tcompile.artifactPath ? [compile.artifactPath] : [],\n\t\t\tnow,\n\t\t\t{ command: compile.command || '' }\n\t\t));\n\t\treturn { outcome: 'compile_failed', infraChecks, compile, routeProbes, businessAssertions, artifacts, gateResults, updatedAt: now };\n\t}\n\tif (compile && passed(compile.status)) {\n\t\tgateResults.push(makeGate('qa_compile', 'Compile/build', 'pass', 'Compile/build evidence passed.', compile.artifactPath ? [compile.artifactPath] : [], now));\n\t}\n\n\tconst failedRouteProbes = routeProbes.filter((probe) => failedOrBlocked(probe.status) || probe.shellOnly === true);\n\tif (failedRouteProbes.length) {\n\t\tgateResults.push(makeGate(\n\t\t\t'qa_route_probe',\n\t\t\t'Browser route probe',\n\t\t\t'fail',\n\t\t\t`Browser route probe failed or showed shell-only UI: ${failedRouteProbes.map((probe) => `${probe.route}: ${probe.message || probe.caption || probe.status}`).join('; ')}`,\n\t\t\tfailedRouteProbes.map((probe) => probe.screenshot || '').filter(Boolean),\n\t\t\tnow\n\t\t));\n\t\treturn { outcome: 'route_failed', infraChecks, compile, routeProbes, businessAssertions, artifacts, gateResults, updatedAt: now };\n\t}\n\tif (routeProbes.some((probe) => passed(probe.status))) {\n\t\tgateResults.push(makeGate(\n\t\t\t'qa_route_probe',\n\t\t\t'Browser route probe',\n\t\t\t'pass',\n\t\t\t'Browser route reached authenticated application content. This is not business acceptance by itself.',\n\t\t\trouteProbes.map((probe) => probe.screenshot || '').filter(Boolean),\n\t\t\tnow\n\t\t));\n\t}\n\n\tconst failedBusinessAssertions = businessAssertions.filter((assertion) => failedOrBlocked(assertion.status));\n\tif (failedBusinessAssertions.length) {\n\t\tgateResults.push(makeGate(\n\t\t\t'qa_business_assertion',\n\t\t\t'Business assertion',\n\t\t\t'fail',\n\t\t\t`Issue-specific workflow assertion failed: ${failedBusinessAssertions.map((assertion) => assertion.message || assertion.observed || assertion.assertion).join('; ')}`,\n\t\t\tcollectBusinessAssertionArtifactPaths(failedBusinessAssertions),\n\t\t\tnow\n\t\t));\n\t\treturn { outcome: 'business_assertion_failed', infraChecks, compile, routeProbes, businessAssertions, artifacts, gateResults, updatedAt: now };\n\t}\n\n\tconst passedBusinessAssertions = businessAssertions.filter((assertion) => passed(assertion.status));\n\tif (passedBusinessAssertions.length) {\n\t\tgateResults.push(makeGate(\n\t\t\t'qa_business_assertion',\n\t\t\t'Business assertion',\n\t\t\t'pass',\n\t\t\t'At least one issue-specific workflow/data assertion passed.',\n\t\t\tcollectBusinessAssertionArtifactPaths(passedBusinessAssertions),\n\t\t\tnow,\n\t\t\t{ passed_assertions: passedBusinessAssertions.map((assertion) => assertion.assertion) }\n\t\t));\n\t\treturn { outcome: 'business_assertion_passed', infraChecks, compile, routeProbes, businessAssertions, artifacts, gateResults, updatedAt: now };\n\t}\n\n\tif (routeProbes.some((probe) => passed(probe.status))) {\n\t\tgateResults.push(makeGate(\n\t\t\t'qa_business_assertion',\n\t\t\t'Business assertion',\n\t\t\t'blocked',\n\t\t\t'Browser route loaded, but no issue-specific business assertion passed. Route-only proof cannot accept the run.',\n\t\t\t[],\n\t\t\tnow\n\t\t));\n\t\treturn { outcome: 'route_only_pass', infraChecks, compile, routeProbes, businessAssertions, artifacts, gateResults, updatedAt: now };\n\t}\n\n\tgateResults.push(makeGate(\n\t\t'qa_business_assertion',\n\t\t'Business assertion',\n\t\t'blocked',\n\t\t'No issue-specific QA assertion was recorded.',\n\t\t[],\n\t\tnow\n\t));\n\treturn { outcome: 'incomplete', infraChecks, compile, routeProbes, businessAssertions, artifacts, gateResults, updatedAt: now };\n}\n\nfunction normalizeQaRun(input?: AIQaRun | AIQaEvaluationInput): AIQaRun | undefined {\n\tif (!input) {\n\t\treturn undefined;\n\t}\n\tif ((input as AIQaRun).outcome && Array.isArray((input as AIQaRun).gateResults)) {\n\t\treturn input as AIQaRun;\n\t}\n\treturn buildAIQaRun(input as AIQaEvaluationInput);\n}\n\nfunction statusLooksFailed(value: any): boolean {\n\tconst normalized = cleanText(value, 120).toLowerCase();\n\treturn !!normalized && /(fail|failed|error|blocked|missing|empty|stale|skipped|not ready|not_ready|could not|cannot)/i.test(normalized);\n}\n\nfunction statusLooksPassed(value: any): boolean {\n\tconst normalized = cleanText(value, 120).toLowerCase();\n\treturn !!normalized && /(pass|passed|success|complete|completed|ready|published|deployed|live|merged)/i.test(normalized);\n}\n\nfunction addGateOnce(gates: AIRunGateResult[], gate: AIRunGateResult): void {\n\tif (gates.some((entry) => entry.key === gate.key && entry.status === gate.status && entry.reason === gate.reason)) {\n\t\treturn;\n\t}\n\tgates.push(gate);\n}\n\nexport function classifyAIRunOutcome(input: AIRunOutcomeInput = {}): AIRunOutcomeDecision {\n\tconst now = isoNow(input.now);\n\tconst gates = Array.isArray(input.gates) ? [...input.gates] : [];\n\tconst warnings: string[] = [];\n\tconst qa = normalizeQaRun(input.qa);\n\tif (qa) {\n\t\tfor (const gate of qa.gateResults) {\n\t\t\taddGateOnce(gates, gate);\n\t\t}\n\t}\n\n\tif (input.manualHandoff === true) {\n\t\treturn {\n\t\t\toutcome: 'manual_handoff',\n\t\t\treason: 'Run requires manual handoff.',\n\t\t\tnextAction: 'Ask a human operator to resolve the blocked run.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\tif (input.stopped === true || /stop|stopped|cancel|cancelled|paused/i.test(`${input.status || ''} ${input.phase || ''}`)) {\n\t\treturn {\n\t\t\toutcome: 'stopped',\n\t\t\treason: 'Run was stopped before accepted evidence was recorded.',\n\t\t\tnextAction: 'Resume or restart only if the request is still active.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\tif (input.rejected === true) {\n\t\treturn {\n\t\t\toutcome: 'rejected',\n\t\t\treason: 'Run was explicitly rejected.',\n\t\t\tnextAction: 'Start a repair run from the failing evidence.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\n\tif (qa?.outcome === 'infra_failed') {\n\t\treturn {\n\t\t\toutcome: 'qa_infra_failed',\n\t\t\treason: 'QA infrastructure failed before product validation.',\n\t\t\tnextAction: 'Repair QA harness dependencies, ports, browser, Mongo, or startup before another model repair loop.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\tif (qa?.outcome === 'compile_failed') {\n\t\treturn {\n\t\t\toutcome: 'build_failed',\n\t\t\treason: 'Compile/build evidence failed or was stale.',\n\t\t\tnextAction: 'Repair compile/build first, then rerun QA from the same failed step.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\tif (qa?.outcome === 'route_failed') {\n\t\treturn {\n\t\t\toutcome: 'qa_incomplete',\n\t\t\treason: 'Browser route probe failed before business proof.',\n\t\t\tnextAction: 'Repair route/auth/startup issue and rerun the same browser route probe.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\tif (qa?.outcome === 'route_only_pass' || qa?.outcome === 'incomplete') {\n\t\treturn {\n\t\t\toutcome: input.scorecardPassed === true ? 'false_pass' : 'qa_incomplete',\n\t\t\treason: input.scorecardPassed === true\n\t\t\t\t? 'Scorecard or workflow status passed without issue-specific business assertion proof.'\n\t\t\t\t: 'QA has not recorded issue-specific business assertion proof.',\n\t\t\tnextAction: 'Add before/action/after workflow proof with screenshot/data assertions before acceptance.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\tif (qa?.outcome === 'business_assertion_failed') {\n\t\treturn {\n\t\t\toutcome: input.terminal === true ? 'rejected' : 'qa_incomplete',\n\t\t\treason: 'Issue-specific business assertion failed.',\n\t\t\tnextAction: 'Repair the product/data defect and rerun the failing assertion.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\n\tconst hasBusinessPass = qa?.outcome === 'business_assertion_passed';\n\tconst scorecardPassed = input.scorecardPassed === true || statusLooksPassed(input.scorecardStatus);\n\tconst releaseBlockers: string[] = [];\n\tif (statusLooksFailed(input.deployStatus)) {\n\t\treleaseBlockers.push(`deploy=${cleanText(input.deployStatus, 120)}`);\n\t}\n\tif (statusLooksFailed(input.publishStatus)) {\n\t\treleaseBlockers.push(`publish=${cleanText(input.publishStatus, 120)}`);\n\t}\n\tif (statusLooksFailed(input.sampleDataStatus)) {\n\t\treleaseBlockers.push(`sample_data=${cleanText(input.sampleDataStatus, 120)}`);\n\t}\n\tif (releaseBlockers.length && (scorecardPassed || hasBusinessPass)) {\n\t\taddGateOnce(gates, makeGate(\n\t\t\t'release',\n\t\t\t'Release/deploy',\n\t\t\t'fail',\n\t\t\t`Final acceptance is blocked after QA/scorecard because release gates failed: ${releaseBlockers.join(', ')}.`,\n\t\t\t[],\n\t\t\tnow\n\t\t));\n\t\treturn {\n\t\t\toutcome: 'release_blocked',\n\t\t\treason: `Release gates failed after QA/scorecard: ${releaseBlockers.join(', ')}.`,\n\t\t\tnextAction: 'Repair deploy/publish/sample-data coverage before marking the run accepted.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\n\tif (scorecardPassed && !hasBusinessPass) {\n\t\twarnings.push('scorecard_pass_without_business_assertion');\n\t\taddGateOnce(gates, makeGate(\n\t\t\t'business_assertion_required',\n\t\t\t'Business assertion',\n\t\t\t'blocked',\n\t\t\t'Scorecard passed, but no issue-specific business assertion proof was recorded.',\n\t\t\t[],\n\t\t\tnow\n\t\t));\n\t\treturn {\n\t\t\toutcome: 'false_pass',\n\t\t\treason: 'Scorecard-only proof is not acceptance.',\n\t\t\tnextAction: 'Record issue-specific workflow/data proof, then reclassify the run.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\n\tconst statusPhase = `${input.status || ''} ${input.phase || ''}`;\n\tif ((input.explicitAccepted === true || statusLooksPassed(statusPhase) || scorecardPassed) && hasBusinessPass) {\n\t\treturn {\n\t\t\toutcome: 'accepted',\n\t\t\treason: 'Run has terminal success signal and issue-specific business assertion proof.',\n\t\t\tnextAction: 'No repair action required.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\n\tif (statusLooksFailed(statusPhase)) {\n\t\treturn {\n\t\t\toutcome: 'rejected',\n\t\t\treason: 'Run ended with a failure status and no accepted proof.',\n\t\t\tnextAction: 'Classify the failing gate and rerun the smallest repair step.',\n\t\t\tgates,\n\t\t\twarnings,\n\t\t\trecordedAt: now\n\t\t};\n\t}\n\n\treturn {\n\t\toutcome: 'unknown',\n\t\treason: 'Run does not have enough normalized evidence for a terminal label.',\n\t\tnextAction: 'Ingest QA, deploy, assistant, usage, and commit evidence before using this run for training.',\n\t\tgates,\n\t\twarnings,\n\t\trecordedAt: now\n\t};\n}\n\nexport function buildAIRun(input: Omit<AIRun, 'outcome' | 'gates'> & {\n\toutcome?: AIRunOutcomeLabel;\n\tgates?: AIRunGateResult[];\n\tscorecardPassed?: boolean;\n\tdeployStatus?: string;\n\tpublishStatus?: string;\n\tsampleDataStatus?: string;\n\tmanualHandoff?: boolean;\n\tstopped?: boolean;\n\trejected?: boolean;\n\texplicitAccepted?: boolean;\n\tterminal?: boolean;\n\tnow?: Date | string;\n}): AIRun {\n\tconst decision = input.outcome\n\t\t? {\n\t\t\toutcome: input.outcome,\n\t\t\tgates: input.gates || [],\n\t\t\twarnings: input.warnings || [],\n\t\t\tnextAction: input.nextAction || '',\n\t\t\treason: '',\n\t\t\trecordedAt: isoNow(input.now)\n\t\t}\n\t\t: classifyAIRunOutcome({\n\t\t\tsource: input.source,\n\t\t\tstatus: input.status,\n\t\t\tphase: input.phase,\n\t\t\tqa: input.qa,\n\t\t\tgates: input.gates,\n\t\t\tscorecardPassed: input.scorecardPassed,\n\t\t\tdeployStatus: input.deployStatus,\n\t\t\tpublishStatus: input.publishStatus,\n\t\t\tsampleDataStatus: input.sampleDataStatus,\n\t\t\tmanualHandoff: input.manualHandoff,\n\t\t\tstopped: input.stopped,\n\t\t\trejected: input.rejected,\n\t\t\texplicitAccepted: input.explicitAccepted,\n\t\t\tterminal: input.terminal,\n\t\t\tnow: input.now\n\t\t});\n\treturn {\n\t\tid: input.id,\n\t\tsource: input.source || 'unknown',\n\t\tsourceIds: input.sourceIds || {},\n\t\ttitle: input.title,\n\t\tstatus: input.status,\n\t\tphase: input.phase,\n\t\tstartedAt: input.startedAt,\n\t\tcompletedAt: input.completedAt,\n\t\toutcome: decision.outcome,\n\t\tevents: Array.isArray(input.events) ? input.events : [],\n\t\tgates: decision.gates,\n\t\tqa: normalizeQaRun(input.qa),\n\t\tcost: input.cost,\n\t\tnextAction: decision.nextAction,\n\t\twarnings: decision.warnings,\n\t\tmetadata: input.metadata\n\t};\n}\n\nexport function buildAIRunCost(entries: OpenAIUsageCostEntry[] = []): AIRunCost {\n\tconst cost: AIRunCost = {\n\t\tinputTokens: 0,\n\t\tcachedInputTokens: 0,\n\t\toutputTokens: 0,\n\t\ttotalTokens: 0,\n\t\testimatedUsd: 0,\n\t\tmodels: [],\n\t\tcategories: {}\n\t};\n\tfor (const entry of normalizeOpenAIUsageRowsForCosting(entries)) {\n\t\tconst category = cleanText(entry.category, 120) || 'unknown';\n\t\tconst model = cleanText(entry.model, 120);\n\t\tconst inputTokens = Number(entry.input_tokens ?? entry.inputTokens ?? 0) || 0;\n\t\tconst cachedInputTokens = Number(entry.cached_input_tokens ?? entry.cachedInputTokens ?? 0) || 0;\n\t\tconst outputTokens = Number(entry.output_tokens ?? entry.outputTokens ?? 0) || 0;\n\t\tconst totalTokens = Number(entry.total_tokens ?? entry.totalTokens ?? (inputTokens + outputTokens)) || 0;\n\t\tconst estimatedUsd = Number(entry.cost_estimate ?? entry.estimatedUsd ?? 0) || 0;\n\t\tcost.inputTokens += inputTokens;\n\t\tcost.cachedInputTokens += cachedInputTokens;\n\t\tcost.outputTokens += outputTokens;\n\t\tcost.totalTokens += totalTokens;\n\t\tcost.estimatedUsd += estimatedUsd;\n\t\tif (model && !cost.models.includes(model)) {\n\t\t\tcost.models.push(model);\n\t\t}\n\t\tif (!cost.categories[category]) {\n\t\t\tcost.categories[category] = {\n\t\t\t\tinputTokens: 0,\n\t\t\t\tcachedInputTokens: 0,\n\t\t\t\toutputTokens: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\testimatedUsd: 0,\n\t\t\t\tcount: 0\n\t\t\t};\n\t\t}\n\t\tcost.categories[category].inputTokens += inputTokens;\n\t\tcost.categories[category].cachedInputTokens += cachedInputTokens;\n\t\tcost.categories[category].outputTokens += outputTokens;\n\t\tcost.categories[category].totalTokens += totalTokens;\n\t\tcost.categories[category].estimatedUsd += estimatedUsd;\n\t\tcost.categories[category].count += 1;\n\t}\n\tcost.estimatedUsd = Number(cost.estimatedUsd.toFixed(6));\n\tfor (const category of Object.keys(cost.categories)) {\n\t\tcost.categories[category].estimatedUsd = Number(cost.categories[category].estimatedUsd.toFixed(6));\n\t}\n\treturn cost;\n}\n\nexport function redactAIRunTrainingExample(example: AIRunTrainingExample): AIRunTrainingExample {\n\tconst redact = (value: string): string => cleanText(value, 5000)\n\t\t.replace(/mongodb(?:\\+srv)?:\\/\\/[^\\s\"'<>]+/ig, '[redacted-mongo-url]')\n\t\t.replace(/\\b(?:sk|ghp|xoxb|AKIA)[A-Za-z0-9_\\-]{12,}\\b/g, '[redacted-secret]')\n\t\t.replace(/\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z]{2,}\\b/ig, '[redacted-email]');\n\treturn {\n\t\t...example,\n\t\tinputSummary: redact(example.inputSummary),\n\t\tactionSummary: redact(example.actionSummary),\n\t\tevidence: cleanList(example.evidence, 80, 5000).map(redact)\n\t};\n}\n"]}
|
|
@@ -17,6 +17,7 @@ export interface ResolveIORunnerQaToolBundleOptions {
|
|
|
17
17
|
homeRoot?: string;
|
|
18
18
|
}
|
|
19
19
|
export declare function buildResolveIORunnerQaEnvScript(options?: ResolveIORunnerQaToolBundleOptions): string;
|
|
20
|
+
export declare function buildResolveIORunnerQaPreflightScript(): string;
|
|
20
21
|
export declare function buildResolveIORunnerLocalQaScript(): string;
|
|
21
22
|
export declare function buildResolveIORunnerLocalQaStopperScript(): string;
|
|
22
23
|
export declare function buildResolveIORunnerQaLiveDataSeederScript(): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildResolveIORunnerQaEnvScript = buildResolveIORunnerQaEnvScript;
|
|
4
|
+
exports.buildResolveIORunnerQaPreflightScript = buildResolveIORunnerQaPreflightScript;
|
|
4
5
|
exports.buildResolveIORunnerLocalQaScript = buildResolveIORunnerLocalQaScript;
|
|
5
6
|
exports.buildResolveIORunnerLocalQaStopperScript = buildResolveIORunnerLocalQaStopperScript;
|
|
6
7
|
exports.buildResolveIORunnerQaLiveDataSeederScript = buildResolveIORunnerQaLiveDataSeederScript;
|
|
@@ -374,6 +375,119 @@ function buildResolveIORunnerQaEnvScript(options) {
|
|
|
374
375
|
''
|
|
375
376
|
].filter(function (line) { return line !== ''; }).join('\n');
|
|
376
377
|
}
|
|
378
|
+
function buildResolveIORunnerQaPreflightScript() {
|
|
379
|
+
return [
|
|
380
|
+
'#!/usr/bin/env node',
|
|
381
|
+
'const fs = require("fs");',
|
|
382
|
+
'const path = require("path");',
|
|
383
|
+
'const { spawnSync } = require("child_process");',
|
|
384
|
+
'const projectRoot = path.resolve(process.argv[2] || process.cwd());',
|
|
385
|
+
'const artifactDir = path.join(projectRoot, "qa-artifacts");',
|
|
386
|
+
'const resultPath = path.join(artifactDir, "qa-preflight-result.json");',
|
|
387
|
+
'fs.mkdirSync(artifactDir, { recursive: true });',
|
|
388
|
+
'const checks = [];',
|
|
389
|
+
'function now() { return new Date().toISOString(); }',
|
|
390
|
+
'function redact(value) { return String(value || "").replace(/mongodb(?:\\+srv)?:\\/\\/[^\\s"\\\']+/ig, "[redacted-mongo-url]").replace(/\\b(?:sk|ghp|AKIA)[A-Za-z0-9_\\-]{12,}\\b/g, "[redacted-secret]"); }',
|
|
391
|
+
'function check(name, status, message, extra = {}) { checks.push({ name, status, message: redact(message), checkedAt: now(), ...extra }); }',
|
|
392
|
+
'function fileExecutable(filePath) { try { fs.accessSync(filePath, fs.constants.X_OK); return true; } catch (error) { return false; } }',
|
|
393
|
+
'function readJson(filePath) { try { return JSON.parse(fs.readFileSync(filePath, "utf8")); } catch (error) { return null; } }',
|
|
394
|
+
'function packageScripts(root) { const pkg = readJson(path.join(root, "package.json")); return pkg && pkg.scripts && typeof pkg.scripts === "object" ? pkg.scripts : {}; }',
|
|
395
|
+
'function requireFromCandidates(candidates, label) {',
|
|
396
|
+
' for (const candidate of candidates) {',
|
|
397
|
+
' try { return { module: require(candidate), candidate }; } catch (error) {}',
|
|
398
|
+
' }',
|
|
399
|
+
' throw new Error(`Unable to require ${label} from ${candidates.join(", ")}`);',
|
|
400
|
+
'}',
|
|
401
|
+
'function shellWhich(command) {',
|
|
402
|
+
' const result = spawnSync("bash", ["-lc", `command -v ${command}`], { encoding: "utf8", timeout: 3000 });',
|
|
403
|
+
' return result.status === 0 ? String(result.stdout || "").trim().split(/\\r?\\n/)[0] : "";',
|
|
404
|
+
'}',
|
|
405
|
+
'try {',
|
|
406
|
+
' const nodeMajor = Number(String(process.versions.node || "").split(".")[0] || 0);',
|
|
407
|
+
' check("node_version", nodeMajor >= 22 && nodeMajor < 23 ? "pass" : "fail", `Node ${process.version}`, { version: process.version });',
|
|
408
|
+
'} catch (error) { check("node_version", "fail", error && error.message || error); }',
|
|
409
|
+
'try {',
|
|
410
|
+
' const npmPath = shellWhich("npm");',
|
|
411
|
+
' check("npm_available", npmPath ? "pass" : "fail", npmPath ? `npm found at ${npmPath}` : "npm was not found on PATH", { path: npmPath });',
|
|
412
|
+
'} catch (error) { check("npm_available", "fail", error && error.message || error); }',
|
|
413
|
+
'try {',
|
|
414
|
+
' const scripts = packageScripts(projectRoot);',
|
|
415
|
+
' const serverScripts = fs.existsSync(path.join(projectRoot, "server")) ? packageScripts(path.join(projectRoot, "server")) : {};',
|
|
416
|
+
' check("client_start_script", scripts.client || scripts.start || scripts.server ? "pass" : "blocked", "Project package scripts checked.", { scripts: Object.keys(scripts).filter((key) => /^(client|start|server|dev|build|build-dev|build-prod)$/.test(key)) });',
|
|
417
|
+
' check("server_start_script", !fs.existsSync(path.join(projectRoot, "server")) || serverScripts.server || serverScripts.start || serverScripts["build-prod"] ? "pass" : "blocked", "Server package scripts checked.", { scripts: Object.keys(serverScripts).filter((key) => /^(server|start|dev|build|build-dev|build-prod)$/.test(key)) });',
|
|
418
|
+
'} catch (error) { check("package_scripts", "blocked", error && error.message || error); }',
|
|
419
|
+
'try {',
|
|
420
|
+
' const settingsCandidates = [',
|
|
421
|
+
' path.join(projectRoot, "server", "settings.json"),',
|
|
422
|
+
' path.join(projectRoot, "server", "settings.local.json"),',
|
|
423
|
+
' path.join(projectRoot, "settings.json"),',
|
|
424
|
+
' path.join(projectRoot, "settings.local.json"),',
|
|
425
|
+
' path.join(projectRoot, "server", ".env"),',
|
|
426
|
+
' path.join(projectRoot, "server", ".env.codex"),',
|
|
427
|
+
' path.join(projectRoot, ".env"),',
|
|
428
|
+
' path.join(projectRoot, ".env.codex")',
|
|
429
|
+
' ];',
|
|
430
|
+
' const found = settingsCandidates.find((candidate) => fs.existsSync(candidate));',
|
|
431
|
+
' check("settings_available", found || !fs.existsSync(path.join(projectRoot, "server")) ? "pass" : "blocked", found ? `Runtime settings/env file exists at ${path.relative(projectRoot, found)}` : "No server directory or settings file required.", { path: found ? path.relative(projectRoot, found) : "" });',
|
|
432
|
+
'} catch (error) { check("settings_available", "blocked", error && error.message || error); }',
|
|
433
|
+
'let puppeteer = null;',
|
|
434
|
+
'try {',
|
|
435
|
+
' const candidates = [',
|
|
436
|
+
' path.join(projectRoot, "node_modules", "puppeteer"),',
|
|
437
|
+
' path.join(projectRoot, "server", "node_modules", "puppeteer"),',
|
|
438
|
+
' path.join(projectRoot, "node_modules", "puppeteer-core"),',
|
|
439
|
+
' path.join(projectRoot, "server", "node_modules", "puppeteer-core"),',
|
|
440
|
+
' "puppeteer",',
|
|
441
|
+
' "puppeteer-core"',
|
|
442
|
+
' ];',
|
|
443
|
+
' const found = requireFromCandidates(candidates, "puppeteer/puppeteer-core");',
|
|
444
|
+
' puppeteer = found.module;',
|
|
445
|
+
' check("puppeteer_require", "pass", `Loaded ${found.candidate}`);',
|
|
446
|
+
'} catch (error) { check("puppeteer_require", "blocked", error && error.message || error); }',
|
|
447
|
+
'let chromePath = String(process.env.PUPPETEER_EXECUTABLE_PATH || process.env.CHROME_BIN || "").trim();',
|
|
448
|
+
'if (!chromePath) {',
|
|
449
|
+
' const candidates = [',
|
|
450
|
+
' "/var/lib/resolveio/puppeteer/chrome-headless-shell/linux-*/chrome-headless-shell-linux64/chrome-headless-shell",',
|
|
451
|
+
' "/var/lib/resolveio/puppeteer/chrome/linux-*/chrome-linux64/chrome",',
|
|
452
|
+
' "/usr/bin/google-chrome-stable",',
|
|
453
|
+
' "/usr/bin/google-chrome",',
|
|
454
|
+
' "/usr/bin/chromium",',
|
|
455
|
+
' "/usr/bin/chromium-browser"',
|
|
456
|
+
' ];',
|
|
457
|
+
' for (const pattern of candidates) {',
|
|
458
|
+
' const result = spawnSync("bash", ["-lc", `for f in ${pattern}; do [ -x "$f" ] && echo "$f" && exit 0; done; exit 1`], { encoding: "utf8", timeout: 3000 });',
|
|
459
|
+
' if (result.status === 0 && String(result.stdout || "").trim()) { chromePath = String(result.stdout || "").trim().split(/\\r?\\n/)[0]; break; }',
|
|
460
|
+
' }',
|
|
461
|
+
'}',
|
|
462
|
+
'check("chrome_executable", chromePath && fileExecutable(chromePath) ? "pass" : "blocked", chromePath ? `Chrome executable ${chromePath}` : "No executable Chrome/Chromium path found.", { path: chromePath });',
|
|
463
|
+
'if (puppeteer && chromePath && fileExecutable(chromePath) && String(process.env.RESOLVEIO_QA_PREFLIGHT_SKIP_BROWSER_LAUNCH || "").toLowerCase() !== "true") {',
|
|
464
|
+
' (async () => {',
|
|
465
|
+
' let browser = null;',
|
|
466
|
+
' try {',
|
|
467
|
+
' browser = await puppeteer.launch({ executablePath: chromePath, headless: "new", args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"] });',
|
|
468
|
+
' check("chrome_launch", "pass", "Puppeteer launched the staged browser.");',
|
|
469
|
+
' } catch (error) {',
|
|
470
|
+
' check("chrome_launch", "blocked", error && error.message || error);',
|
|
471
|
+
' } finally {',
|
|
472
|
+
' if (browser) await browser.close().catch(() => undefined);',
|
|
473
|
+
' finish();',
|
|
474
|
+
' }',
|
|
475
|
+
' })().catch((error) => { check("chrome_launch", "blocked", error && error.message || error); finish(); });',
|
|
476
|
+
'}',
|
|
477
|
+
'else {',
|
|
478
|
+
' if (!puppeteer || !chromePath) check("chrome_launch", "skipped", "Browser launch skipped because Puppeteer or Chrome executable is unavailable.");',
|
|
479
|
+
' finish();',
|
|
480
|
+
'}',
|
|
481
|
+
'function finish() {',
|
|
482
|
+
' const failed = checks.filter((entry) => ["fail", "blocked"].includes(entry.status));',
|
|
483
|
+
' const result = { status: failed.length ? "blocked" : "pass", outcome: failed.length ? "infra_failed" : "infra_passed", projectRoot, checks, updatedAt: now() };',
|
|
484
|
+
' fs.writeFileSync(resultPath, JSON.stringify(result, null, 2));',
|
|
485
|
+
' console.log(JSON.stringify(result, null, 2));',
|
|
486
|
+
' process.exit(failed.length ? 2 : 0);',
|
|
487
|
+
'}',
|
|
488
|
+
''
|
|
489
|
+
].join('\n');
|
|
490
|
+
}
|
|
377
491
|
function buildResolveIORunnerLocalQaScript() {
|
|
378
492
|
return [
|
|
379
493
|
'#!/usr/bin/env bash',
|
|
@@ -2776,15 +2890,18 @@ function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
|
2776
2890
|
'}',
|
|
2777
2891
|
'function updateMatrix(status, screenshotPath, caption, assertion) {',
|
|
2778
2892
|
' const matrix = readJson(matrixPath) || { status: "started", rows: [] };',
|
|
2779
|
-
'
|
|
2893
|
+
' const routeProbePassed = status === "route_probe_pass" || status === "pass";',
|
|
2894
|
+
' const matrixStatus = status === "route_probe_pass" ? "in_progress" : status;',
|
|
2895
|
+
' matrix.workflow_probe = { status, outcome: status === "route_probe_pass" ? "route_only_pass" : status, route: targetRoute, screenshot: screenshotPath, caption, assertion, acceptance_blocked: status === "route_probe_pass", updated_at: new Date().toISOString() };',
|
|
2780
2896
|
' matrix.updated_at = new Date().toISOString();',
|
|
2781
2897
|
' const rows = Array.isArray(matrix.rows) ? matrix.rows : [];',
|
|
2782
2898
|
' if (rows[0]) {',
|
|
2783
|
-
' rows[0].route_probe = { status, route: targetRoute, screenshot: screenshotPath, caption, assertion, updated_at: matrix.updated_at };',
|
|
2784
|
-
' if (
|
|
2785
|
-
' else if (!rows[0].status || rows[0].status === "pending") { rows[0].status = "in_progress"; }',
|
|
2899
|
+
' rows[0].route_probe = { status: routeProbePassed ? "pass" : status, outcome: status === "route_probe_pass" ? "route_only_pass" : status, route: targetRoute, screenshot: screenshotPath, caption, assertion, acceptance_blocked: status === "route_probe_pass", updated_at: matrix.updated_at };',
|
|
2900
|
+
' if (!routeProbePassed) { rows[0].status = "blocked"; rows[0].screenshot = screenshotPath; rows[0].caption = caption; }',
|
|
2901
|
+
' else if (!rows[0].status || rows[0].status === "pending") { rows[0].status = "in_progress"; rows[0].result = "in_progress"; rows[0].acceptance_blocked = true; rows[0].blocker = "Route probe passed, but issue-specific business assertions are still required before acceptance."; }',
|
|
2786
2902
|
' }',
|
|
2787
2903
|
' matrix.rows = rows;',
|
|
2904
|
+
' if (!matrix.status || matrix.status === "started" || matrix.status === "pending") matrix.status = matrixStatus;',
|
|
2788
2905
|
' writeJson(matrixPath, matrix);',
|
|
2789
2906
|
'}',
|
|
2790
2907
|
'',
|
|
@@ -2808,7 +2925,7 @@ function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
|
2808
2925
|
' summary = await waitForBillingDashboardWork(page) || summary;',
|
|
2809
2926
|
' const caption = `Workflow route ready: ${targetRoute} loaded in authenticated local QA with live seeded data available.`;',
|
|
2810
2927
|
' await page.screenshot({ path: passScreenshotPath, type: "jpeg", quality: 82, fullPage: false });',
|
|
2811
|
-
' updateMatrix("
|
|
2928
|
+
' updateMatrix("route_probe_pass", passScreenshotPath, caption, "Authenticated customer workflow route loaded; deeper row-specific UI/data proof still required.");',
|
|
2812
2929
|
' const specializedProof = await runAssetLocationRowProof(page, summary);',
|
|
2813
2930
|
' if (specializedProof && specializedProof.status !== "pass") {',
|
|
2814
2931
|
' const result = { status: "failed", clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption: "Asset location row proof failed; see qa-asset-location-proof.json.", page: summary, matrix: matrixPath, specializedProof: path.join(artifactDir, "qa-asset-location-proof.json") };',
|
|
@@ -2817,7 +2934,7 @@ function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
|
2817
2934
|
' process.exitCode = 1;',
|
|
2818
2935
|
' return;',
|
|
2819
2936
|
' }',
|
|
2820
|
-
' const result = { status: "pass", clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption: specializedProof ? "Asset location list/detail/edit QA passed with exact seeded assets and captions." : caption, page: summary, matrix: matrixPath, specializedProof: specializedProof ? path.join(artifactDir, "qa-asset-location-proof.json") : "" };',
|
|
2937
|
+
' const result = { status: specializedProof ? "pass" : "route_probe_pass", outcome: specializedProof ? "business_assertion_passed" : "route_only_pass", acceptance_blocked: !specializedProof, clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption: specializedProof ? "Asset location list/detail/edit QA passed with exact seeded assets and captions." : caption, page: summary, matrix: matrixPath, specializedProof: specializedProof ? path.join(artifactDir, "qa-asset-location-proof.json") : "" };',
|
|
2821
2938
|
' writeJson(resultPath, result);',
|
|
2822
2939
|
' console.log(JSON.stringify(result, null, 2));',
|
|
2823
2940
|
' } catch (error) {',
|
|
@@ -2826,8 +2943,8 @@ function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
|
2826
2943
|
' if (summary && pathMatchesRoute(summary.url, targetRoute) && !summary.hasLoginText && !summary.hasOfflineModeText && !isShellOnlySummary(summary)) {',
|
|
2827
2944
|
' const caption = `Workflow route ready after late hydration: ${targetRoute} loaded in authenticated local QA with live seeded data available.`;',
|
|
2828
2945
|
' try { if (page) await page.screenshot({ path: passScreenshotPath, type: "jpeg", quality: 82, fullPage: false }); } catch (screenshotError) {}',
|
|
2829
|
-
' updateMatrix("
|
|
2830
|
-
' const result = { status: "
|
|
2946
|
+
' updateMatrix("route_probe_pass", passScreenshotPath, caption, "Authenticated customer workflow route loaded after transient offline/shell state; deeper row-specific UI/data proof still required.");',
|
|
2947
|
+
' const result = { status: "route_probe_pass", outcome: "route_only_pass", acceptance_blocked: true, clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption, recoveredFromTransientError: error && (error.message || String(error)) || "late hydration", page: summary, matrix: matrixPath };',
|
|
2831
2948
|
' writeJson(resultPath, result);',
|
|
2832
2949
|
' console.log(JSON.stringify(result, null, 2));',
|
|
2833
2950
|
' process.exitCode = 0;',
|
|
@@ -2836,8 +2953,8 @@ function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
|
2836
2953
|
' const bootstrapProof = freshAuthBootstrapProof();',
|
|
2837
2954
|
' if (bootstrapProof) {',
|
|
2838
2955
|
' const caption = `Workflow route ready from authenticated bootstrap proof: ${targetRoute} loaded for the seeded QA user with live data before a transient probe shell state.`;',
|
|
2839
|
-
' updateMatrix("
|
|
2840
|
-
' const result = { status: "
|
|
2956
|
+
' updateMatrix("route_probe_pass", bootstrapProof.screenshot || passScreenshotPath, caption, "Authenticated bootstrap proof loaded the exact target route with live seeded data; deeper row-specific UI/data proof still required.");',
|
|
2957
|
+
' const result = { status: "route_probe_pass", outcome: "route_only_pass", acceptance_blocked: true, clientUrl, serverUrl, targetRoute, screenshot: bootstrapProof.screenshot || passScreenshotPath, caption, recoveredFromTransientError: error && (error.message || String(error)) || "bootstrap proof recovery", page: bootstrapProof.page, authBootstrapProof: authBootstrapResultPath, matrix: matrixPath };',
|
|
2841
2958
|
' writeJson(resultPath, result);',
|
|
2842
2959
|
' console.log(JSON.stringify(result, null, 2));',
|
|
2843
2960
|
' process.exitCode = 0;',
|
|
@@ -2873,6 +2990,7 @@ function buildResolveIORunnerQaToolsReadme(options) {
|
|
|
2873
2990
|
'',
|
|
2874
2991
|
'```bash',
|
|
2875
2992
|
"source ".concat(toolsDir, "/env.sh"),
|
|
2993
|
+
"node ".concat(toolsDir, "/qa-preflight.js <project-root>"),
|
|
2876
2994
|
"".concat(toolsDir, "/run-local-qa.sh <project-root>"),
|
|
2877
2995
|
"node ".concat(toolsDir, "/qa-live-data-seed.js <project-root>"),
|
|
2878
2996
|
"node ".concat(toolsDir, "/qa-auth-bootstrap.js <project-root> /target-route"),
|
|
@@ -2882,6 +3000,7 @@ function buildResolveIORunnerQaToolsReadme(options) {
|
|
|
2882
3000
|
'',
|
|
2883
3001
|
"This workspace reserves Angular QA client port ".concat(port, "; use `$").concat(clientUrlVar, "` instead of assuming 4200 is free."),
|
|
2884
3002
|
'The local QA runner starts server/client, polls the reserved client URL, writes `qa-artifacts/server.log` and `qa-artifacts/client.log`, and fails fast on fatal startup/runtime errors.',
|
|
3003
|
+
'Run `qa-preflight.js` before spending another model repair cycle when QA is failing. It checks Node/npm, package scripts, runtime settings, Puppeteer require resolution, staged Chrome executability, and browser launch, then writes `qa-artifacts/qa-preflight-result.json` with `infra_passed` or `infra_failed`.',
|
|
2885
3004
|
'The shared auth bootstrap first opens the exact localhost client origin, logs out any visible stale session, clears service workers/cache/IndexedDB/local/session storage, then calls `/login` and `/accessToken`, seeds `refreshToken`, `accessToken`, `user`, and `lastURL`, and writes `qa-artifacts/auth-bootstrap-result.json` plus a ready/failure screenshot.',
|
|
2886
3005
|
'The shared workflow probe logs in with the same local QA account, opens the target customer route, captures an email-safe desktop JPEG, and updates `qa-artifacts/qa-coverage-matrix.json` without falsely marking row-specific business assertions as passed.',
|
|
2887
3006
|
"For browser clickthrough work, start the runner once with `".concat(keepaliveVar, "=true ").concat(toolsDir, "/run-local-qa.sh <project-root>`; it detaches after the app is ready, and later calls should reuse `$").concat(clientUrlVar, "` for all login/upload/screenshot retries. Do not restart Angular for auth failures."),
|