sneakoscope 4.2.0 → 4.3.0
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/README.md +35 -8
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/sks.js +1 -1
- package/dist/cli/command-registry.js +3 -1
- package/dist/cli/ultra-search-command.js +163 -0
- package/dist/cli/xai-command.js +28 -168
- package/dist/core/agents/agent-codex-cockpit.js +3 -3
- package/dist/core/agents/agent-runner-ollama.js +2 -0
- package/dist/core/agents/agent-wrongness.js +1 -1
- package/dist/core/agents/native-worker-backend-router.js +3 -0
- package/dist/core/bench.js +115 -0
- package/dist/core/code-structure.js +399 -11
- package/dist/core/codex-control/codex-app-server-v2-client.js +86 -2
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +67 -9
- package/dist/core/codex-control/codex-reliability-shield.js +26 -5
- package/dist/core/codex-control/codex-task-runner.js +7 -1
- package/dist/core/codex-control/gpt-final-arbiter.js +4 -1
- package/dist/core/codex-control/gpt-final-review-schema.js +58 -0
- package/dist/core/codex-control/model-call-concurrency.js +1 -1
- package/dist/core/codex-native/core-skill-manifest.js +23 -0
- package/dist/core/commands/bench-command.js +11 -2
- package/dist/core/commands/code-structure-command.js +34 -2
- package/dist/core/commands/qa-loop-command.js +23 -7
- package/dist/core/commands/run-command.js +92 -2
- package/dist/core/commands/seo-command.js +130 -0
- package/dist/core/feature-fixtures.js +6 -0
- package/dist/core/feature-registry.js +3 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/hooks-runtime.js +9 -1
- package/dist/core/init.js +8 -6
- package/dist/core/lean-engineering-policy.js +159 -0
- package/dist/core/pipeline-internals/runtime-core.js +15 -5
- package/dist/core/proof/auto-finalize.js +3 -2
- package/dist/core/proof/proof-schema.js +2 -1
- package/dist/core/proof/proof-writer.js +1 -0
- package/dist/core/proof/route-adapter.js +4 -2
- package/dist/core/proof/route-finalizer.js +35 -3
- package/dist/core/qa-loop/qa-app-server-driver.js +134 -0
- package/dist/core/qa-loop/qa-contract-v2.js +231 -0
- package/dist/core/qa-loop/qa-gate-v2.js +132 -0
- package/dist/core/qa-loop/qa-runtime-artifacts.js +53 -0
- package/dist/core/qa-loop/qa-surface-router.js +114 -0
- package/dist/core/qa-loop/qa-types.js +18 -0
- package/dist/core/qa-loop.js +83 -26
- package/dist/core/release/gate-manifest.js +1 -0
- package/dist/core/release/sla-scheduler.js +1 -1
- package/dist/core/release-parallel-full-coverage.js +1 -1
- package/dist/core/routes.js +96 -14
- package/dist/core/search-visibility/adapter-registry.js +26 -0
- package/dist/core/search-visibility/adapters/next-app.js +6 -0
- package/dist/core/search-visibility/adapters/next-pages.js +6 -0
- package/dist/core/search-visibility/adapters/static-site.js +6 -0
- package/dist/core/search-visibility/analyzers.js +377 -0
- package/dist/core/search-visibility/artifacts.js +183 -0
- package/dist/core/search-visibility/discovery.js +347 -0
- package/dist/core/search-visibility/index.js +199 -0
- package/dist/core/search-visibility/mission.js +67 -0
- package/dist/core/search-visibility/mutation.js +314 -0
- package/dist/core/search-visibility/types.js +2 -0
- package/dist/core/search-visibility/verifier.js +60 -0
- package/dist/core/source-intelligence/source-intelligence-policy.js +45 -26
- package/dist/core/source-intelligence/source-intelligence-proof.js +10 -16
- package/dist/core/source-intelligence/source-intelligence-runner.js +56 -42
- package/dist/core/triwiki/triwiki-affected-graph.js +3 -2
- package/dist/core/trust-kernel/trust-report.js +3 -5
- package/dist/core/ultra-search/index.js +3 -0
- package/dist/core/ultra-search/runtime.js +502 -0
- package/dist/core/ultra-search/types.js +3 -0
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-visual-consistency-check.js +1 -1
- package/dist/scripts/check-architecture.js +40 -7
- package/dist/scripts/check-command-module-budget.js +43 -5
- package/dist/scripts/check-pipeline-budget.js +17 -30
- package/dist/scripts/check-publish-tag.js +33 -6
- package/dist/scripts/check-route-modularity.js +25 -33
- package/dist/scripts/check-runtime-schemas.js +22 -0
- package/dist/scripts/codex-control-all-pipelines-check.js +1 -0
- package/dist/scripts/codex-control-model-capacity-fallback-check.js +53 -0
- package/dist/scripts/config-managed-merge-callsite-coverage-check.js +7 -1
- package/dist/scripts/core-skill-immutable-sync-check.js +3 -2
- package/dist/scripts/core-skill-integrity-blackbox.js +3 -2
- package/dist/scripts/core-skill-manifest-check.js +7 -2
- package/dist/scripts/geo-claim-evidence-check.js +18 -0
- package/dist/scripts/geo-cli-blackbox-check.js +18 -0
- package/dist/scripts/geo-crawler-policy-check.js +16 -0
- package/dist/scripts/geo-llms-txt-optional-check.js +19 -0
- package/dist/scripts/gpt-final-arbiter-check.js +4 -1
- package/dist/scripts/loop-directive-check-lib.js +78 -1
- package/dist/scripts/qa-loop-app-server-driver-check.js +74 -0
- package/dist/scripts/qa-loop-surface-router-check.js +49 -0
- package/dist/scripts/release-check-dynamic-execute.js +1 -1
- package/dist/scripts/release-metadata-1-19-check.js +2 -2
- package/dist/scripts/release-parallel-check.js +17 -2
- package/dist/scripts/release-parallel-full-coverage-check.js +1 -1
- package/dist/scripts/release-readiness-report.js +6 -6
- package/dist/scripts/release-registry-check.js +33 -14
- package/dist/scripts/runtime-ts-rust-boundary-check.js +1 -1
- package/dist/scripts/search-visibility-gate-lib.js +124 -0
- package/dist/scripts/seo-audit-fixture-check.js +16 -0
- package/dist/scripts/seo-canonical-locale-check.js +19 -0
- package/dist/scripts/seo-cli-blackbox-check.js +18 -0
- package/dist/scripts/seo-geo-feature-fixture-quality-check.js +18 -0
- package/dist/scripts/seo-geo-geo-disambiguation-check.js +12 -0
- package/dist/scripts/seo-geo-no-unsupported-ranking-claims-check.js +18 -0
- package/dist/scripts/seo-geo-route-identity-check.js +12 -0
- package/dist/scripts/seo-geo-skill-rich-content-check.js +22 -0
- package/dist/scripts/seo-mutation-rollback-check.js +23 -0
- package/dist/scripts/seo-no-mutation-by-default-check.js +17 -0
- package/dist/scripts/seo-structured-data-visible-content-check.js +19 -0
- package/dist/scripts/sks-1-18-gate-lib.js +2 -2
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +10 -1
- package/dist/scripts/source-intelligence-all-modes-check.js +9 -19
- package/dist/scripts/source-intelligence-policy-check.js +6 -6
- package/dist/scripts/triwiki-affected-graph-check.js +2 -2
- package/dist/scripts/ultra-search-provider-interface-check.js +27 -0
- package/package.json +26 -5
- package/schemas/search-visibility/finding-ledger.schema.json +36 -0
- package/schemas/search-visibility/gate.schema.json +22 -0
- package/schemas/search-visibility/mutation-plan.schema.json +27 -0
- package/schemas/search-visibility/site-inventory.schema.json +21 -0
- package/schemas/search-visibility/verification-report.schema.json +23 -0
- package/dist/core/mcp/xai-mcp-detector.js +0 -157
- package/dist/core/mcp/xai-search-adapter.js +0 -100
- package/dist/scripts/xai-mcp-capability-check.js +0 -14
package/dist/core/qa-loop.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { exists, nowIso, readJson, readText, writeJsonAtomic, writeTextAtomic, PACKAGE_VERSION } from './fsx.js';
|
|
3
|
-
import { CODEX_APP_IMAGE_GENERATION_DOC_URL, CODEX_IMAGEGEN_REQUIRED_POLICY, CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE, CODEX_WEB_VERIFICATION_POLICY, evidenceMentionsForbiddenBrowserAutomation, evidenceMentionsForbiddenWebComputerUseEvidence } from './routes.js';
|
|
3
|
+
import { CODEX_APP_IMAGE_GENERATION_DOC_URL, CODEX_CHROME_EXTENSION_EVIDENCE_SOURCE, CODEX_COMPUTER_USE_EVIDENCE_SOURCE, CODEX_IMAGEGEN_REQUIRED_POLICY, CODEX_IN_APP_BROWSER_EVIDENCE_SOURCE, CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE, CODEX_WEB_VERIFICATION_POLICY, evidenceMentionsForbiddenBrowserAutomation, evidenceMentionsForbiddenWebComputerUseEvidence } from './routes.js';
|
|
4
4
|
import { appendAgentLedgerEvent, initializeAgentCentralLedger } from './agents/agent-central-ledger.js';
|
|
5
5
|
import { resolveCodexAppExecutionProfile } from './codex-app/codex-app-execution-profile.js';
|
|
6
6
|
import { resolveCodexNativeInvocationPlan } from './codex-native/codex-native-invocation-router.js';
|
|
7
7
|
import { imageDimensions, sha256File } from './wiki-image/image-hash.js';
|
|
8
|
+
import { initializeQaRuntimeArtifacts } from './qa-loop/qa-runtime-artifacts.js';
|
|
9
|
+
import { evaluateQaGateV2 } from './qa-loop/qa-gate-v2.js';
|
|
10
|
+
import { DEFAULT_QA_MAX_CYCLES, QA_GATE_V2_ARTIFACT, QA_SURFACE_SELECTION_ARTIFACT } from './qa-loop/qa-types.js';
|
|
8
11
|
export const QA_LOOP_ROUTE = 'QALoop';
|
|
9
12
|
export const QA_LOOP_VISUAL_EVIDENCE_ARTIFACT = 'qa-loop/visual-evidence.json';
|
|
10
13
|
const QA_REPORT_SUFFIX = 'qa-report.md';
|
|
11
|
-
const
|
|
14
|
+
const UI_SURFACE_ROUTER_ACK = 'use_codex_surface_router_browser_chrome_computer_no_synthetic_evidence';
|
|
15
|
+
const LEGACY_UI_CHROME_EXTENSION_FIRST_ACK = 'use_codex_chrome_extension_first_no_computer_use_for_web_ui_or_mark_unverified';
|
|
12
16
|
const GPT_IMAGE_2_ANNOTATED_REVIEW_REQUIRED_ACK = 'yes_gpt_image_2_annotated_review';
|
|
13
17
|
const IMAGE_FILE_RE = /\.(png|jpe?g|webp|gif)$/i;
|
|
14
18
|
export const QA_NATIVE_AGENT_PERSONAS = Object.freeze([
|
|
@@ -166,7 +170,7 @@ export function inferQaLoopAnswers(prompt = '') {
|
|
|
166
170
|
'검증하지 못한 UI/API 범위는 통과로 주장하지 않고 QA 리포트에 남긴다.'
|
|
167
171
|
];
|
|
168
172
|
if (isUiScope(scope))
|
|
169
|
-
acceptance.push('UI E2E 통과 증거는
|
|
173
|
+
acceptance.push('UI E2E 통과 증거는 surface router가 고른 @Browser/@Chrome/@Computer 실제 action·observation ledger와 필요한 screenshot/hash를 기록해야 한다.');
|
|
170
174
|
if (wantsGptImage2Review)
|
|
171
175
|
acceptance.push('gpt-image-2 annotated review image가 필요한 경우 실제 Codex App $imagegen/gpt-image-2 출력 파일 path, sha256, model, provider를 기록해야 한다.');
|
|
172
176
|
return {
|
|
@@ -181,17 +185,17 @@ export function inferQaLoopAnswers(prompt = '') {
|
|
|
181
185
|
EXTERNAL_SIDE_EFFECT_POLICY: 'block_all_external_side_effects',
|
|
182
186
|
...login,
|
|
183
187
|
CREDENTIAL_STORAGE_ACK: 'never_store_credentials_in_artifacts_or_wiki',
|
|
184
|
-
UI_CHROME_EXTENSION_ACK:
|
|
188
|
+
UI_CHROME_EXTENSION_ACK: UI_SURFACE_ROUTER_ACK,
|
|
185
189
|
QA_VISUAL_REVIEW_IMAGEGEN_REQUIRED: wantsGptImage2Review ? GPT_IMAGE_2_ANNOTATED_REVIEW_REQUIRED_ACK : 'not_required',
|
|
186
190
|
TEAM_MODE_ALLOWED: 'no_parent_only',
|
|
187
|
-
MAX_QA_CYCLES:
|
|
191
|
+
MAX_QA_CYCLES: String(DEFAULT_QA_MAX_CYCLES),
|
|
188
192
|
ACCEPTANCE_CRITERIA: acceptance,
|
|
189
193
|
NON_GOALS: [
|
|
190
194
|
'결제, 실제 이메일/SMS 발송, 관리자 권한 변경, 데이터 삭제, 프로덕션 데이터 변경은 테스트하지 않는다.'
|
|
191
195
|
],
|
|
192
196
|
RISK_BOUNDARY: [
|
|
193
197
|
'실제 사용자 데이터, 인증 권한, 결제, 메시지 발송, 웹훅, 외부 서비스 상태를 생성/수정/삭제하지 않는다.',
|
|
194
|
-
'Codex
|
|
198
|
+
'선택된 Codex App visual surface의 실제 action·observation evidence가 없으면 UI 검증 완료로 주장하지 않는다.',
|
|
195
199
|
'로그인이 필요하지만 임시 테스트 자격증명이 없으면 인증 구간은 차단/미검증으로 기록한다.'
|
|
196
200
|
],
|
|
197
201
|
MID_RUN_UNKNOWN_POLICY: ['preserve_existing_behavior', 'defer_optional_scope', 'block_only_if_no_safe_path']
|
|
@@ -245,7 +249,7 @@ export function qaLoopQuestionSlots() {
|
|
|
245
249
|
{ id: 'TEMP_TEST_CREDENTIALS_READY', question: 'If login is required, are test-only credentials ready to provide ephemerally during the run?', required: true, type: 'enum', options: ['not_required', 'yes_temp_only', 'no_block_authenticated_tests'] },
|
|
246
250
|
{ id: 'TEST_CREDENTIALS_RUNTIME_SOURCE', question: 'If login is required, how will test-only credentials be provided without saving the values?', required: true, type: 'enum', options: ['not_required', 'ephemeral_chat_only', 'environment_variables', 'secret_manager'] },
|
|
247
251
|
{ id: 'CREDENTIAL_STORAGE_ACK', question: 'Acknowledge credential handling policy.', required: true, type: 'enum', options: ['never_store_credentials_in_artifacts_or_wiki'] },
|
|
248
|
-
{ id: 'UI_CHROME_EXTENSION_ACK', question: 'Acknowledge UI E2E evidence policy:
|
|
252
|
+
{ id: 'UI_CHROME_EXTENSION_ACK', question: 'Acknowledge UI E2E evidence policy: QA-LOOP routes local/public web to @Browser, signed-in web to @Chrome, native/cross-app GUI to @Computer, and never treats synthetic artifacts as real proof.', required: true, type: 'enum', options: [UI_SURFACE_ROUTER_ACK, LEGACY_UI_CHROME_EXTENSION_FIRST_ACK] },
|
|
249
253
|
{ id: 'TEAM_MODE_ALLOWED', question: 'May QA-LOOP use Team/subagents where useful?', required: true, type: 'enum', options: ['yes_parallel_where_safe', 'no_parent_only'] },
|
|
250
254
|
{ id: 'MAX_QA_CYCLES', question: 'How many no-question QA cycles are allowed before pausing?', required: true, type: 'string' },
|
|
251
255
|
{ id: 'ACCEPTANCE_CRITERIA', question: 'List the QA completion criteria.', required: true, type: 'array_or_string' },
|
|
@@ -269,8 +273,8 @@ export function validateQaLoopAnswers(schema, answers = {}) {
|
|
|
269
273
|
errors.push({ slot: 'QA_MUTATION_POLICY', error: 'production_deployed_qa_is_read_only_smoke_only' });
|
|
270
274
|
if (answers.DESTRUCTIVE_DEPLOYED_TESTS_ALLOWED !== 'never')
|
|
271
275
|
errors.push({ slot: 'DESTRUCTIVE_DEPLOYED_TESTS_ALLOWED', error: 'destructive_deployed_tests_never_allowed' });
|
|
272
|
-
if (isUiScope(answers.QA_SCOPE) && answers.UI_CHROME_EXTENSION_ACK
|
|
273
|
-
errors.push({ slot: 'UI_CHROME_EXTENSION_ACK', error: '
|
|
276
|
+
if (isUiScope(answers.QA_SCOPE) && ![UI_SURFACE_ROUTER_ACK, LEGACY_UI_CHROME_EXTENSION_FIRST_ACK].includes(answers.UI_CHROME_EXTENSION_ACK))
|
|
277
|
+
errors.push({ slot: 'UI_CHROME_EXTENSION_ACK', error: 'ui_e2e_requires_codex_surface_router_ack' });
|
|
274
278
|
if (answers.LOGIN_REQUIRED === 'yes' && !['yes_temp_only', 'no_block_authenticated_tests'].includes(answers.TEMP_TEST_CREDENTIALS_READY))
|
|
275
279
|
errors.push({ slot: 'TEMP_TEST_CREDENTIALS_READY', error: 'authenticated_tests_require_ephemeral_test_credentials_or_must_be_blocked' });
|
|
276
280
|
if (answers.LOGIN_REQUIRED === 'yes' && answers.TEMP_TEST_CREDENTIALS_READY === 'yes_temp_only' && answers.TEST_CREDENTIALS_RUNTIME_SOURCE === 'not_required')
|
|
@@ -322,6 +326,7 @@ export function defaultQaGate(contract = {}, opts = {}) {
|
|
|
322
326
|
const gptImage2ReviewRequired = qaGptImage2AnnotatedReviewRequired(contract, contract.prompt);
|
|
323
327
|
const reportFile = opts.reportFile || qaReportFilename();
|
|
324
328
|
const corrective = a.QA_CORRECTIVE_POLICY !== 'report_only_no_code_changes';
|
|
329
|
+
const selectedSurface = opts.qaRuntime?.surface?.selected_surface || null;
|
|
325
330
|
return {
|
|
326
331
|
passed: false,
|
|
327
332
|
clarification_contract_sealed: Boolean(contract.sealed_hash),
|
|
@@ -333,6 +338,15 @@ export function defaultQaGate(contract = {}, opts = {}) {
|
|
|
333
338
|
deployed_destructive_tests_blocked: a.TARGET_ENVIRONMENT === 'local_dev_server' || a.DESTRUCTIVE_DEPLOYED_TESTS_ALLOWED === 'never',
|
|
334
339
|
credentials_not_persisted: false,
|
|
335
340
|
ui_e2e_required: uiRequired,
|
|
341
|
+
qa_contract_v2_required: opts.qaRuntime ? true : false,
|
|
342
|
+
qa_surface_selection_artifact: opts.qaRuntime ? QA_SURFACE_SELECTION_ARTIFACT : null,
|
|
343
|
+
qa_gate_v2_artifact: opts.qaRuntime ? QA_GATE_V2_ARTIFACT : null,
|
|
344
|
+
qa_surface_selected: selectedSurface,
|
|
345
|
+
ui_selected_surface: selectedSurface,
|
|
346
|
+
ui_live_surface_preflight_passed: !uiRequired,
|
|
347
|
+
ui_real_action_count: 0,
|
|
348
|
+
ui_observation_count: 0,
|
|
349
|
+
same_flow_replay_complete: false,
|
|
336
350
|
chrome_extension_preflight_passed: !uiRequired,
|
|
337
351
|
ui_chrome_extension_evidence: !uiRequired,
|
|
338
352
|
ui_computer_use_evidence: false,
|
|
@@ -385,6 +399,13 @@ export async function writeQaLoopArtifacts(dir, mission, contract) {
|
|
|
385
399
|
const root = missionRootFromDir(dir);
|
|
386
400
|
const executionProfile = root ? await resolveCodexAppExecutionProfile({ root }).catch(() => null) : null;
|
|
387
401
|
const codexNativeInvocation = root ? await resolveQaCodexNativeInvocation(root, mission.id).catch(() => null) : null;
|
|
402
|
+
const qaRuntime = await initializeQaRuntimeArtifacts(dir, {
|
|
403
|
+
...contract,
|
|
404
|
+
prompt: mission.prompt || contract.prompt,
|
|
405
|
+
mission_id: mission.id || contract.mission_id
|
|
406
|
+
}, {
|
|
407
|
+
missionId: mission.id || contract.mission_id || null
|
|
408
|
+
}).catch(() => null);
|
|
388
409
|
if (executionProfile)
|
|
389
410
|
await writeJsonAtomic(path.join(dir, 'qa-loop', 'execution-profile.json'), executionProfile).catch(() => undefined);
|
|
390
411
|
if (codexNativeInvocation)
|
|
@@ -397,11 +418,20 @@ export async function writeQaLoopArtifacts(dir, mission, contract) {
|
|
|
397
418
|
codex_app_execution_profile: executionProfile ? compactExecutionProfile(executionProfile) : null,
|
|
398
419
|
codex_native_invocation: codexNativeInvocation,
|
|
399
420
|
target: { scope: a.QA_SCOPE, environment: a.TARGET_ENVIRONMENT, base_url: a.TARGET_BASE_URL, api_base_url: a.API_BASE_URL },
|
|
400
|
-
|
|
421
|
+
qa_runtime_v2: qaRuntime ? {
|
|
422
|
+
contract_artifact: 'qa-loop/qa-contract-v2.json',
|
|
423
|
+
surface_selection_artifact: QA_SURFACE_SELECTION_ARTIFACT,
|
|
424
|
+
selected_surface: qaRuntime.surface.selected_surface,
|
|
425
|
+
journey_graph_artifact: 'qa-loop/qa-journey-graph.json',
|
|
426
|
+
gate_artifact: QA_GATE_V2_ARTIFACT
|
|
427
|
+
} : null,
|
|
428
|
+
safety: { mutation_policy: a.QA_MUTATION_POLICY, deployed_destructive_tests_allowed: 'never', credentials: 'temp_only_never_saved', ui_evidence: 'codex_surface_router_live_action_required_for_ui_e2e', visual_review: 'gpt_image_2_annotated_review_required_when_contract_requests_it' },
|
|
401
429
|
checklist
|
|
402
430
|
});
|
|
403
431
|
await writeJsonAtomic(path.join(dir, QA_LOOP_VISUAL_EVIDENCE_ARTIFACT), buildQaLoopVisualEvidenceArtifact(mission, contract));
|
|
404
|
-
await writeJsonAtomic(path.join(dir, 'qa-gate.json'), defaultQaGate(contract, { reportFile, executionProfile, codexNativeInvocation }));
|
|
432
|
+
await writeJsonAtomic(path.join(dir, 'qa-gate.json'), defaultQaGate(contract, { reportFile, executionProfile, codexNativeInvocation, qaRuntime }));
|
|
433
|
+
if (qaRuntime)
|
|
434
|
+
await evaluateQaGateV2(dir).catch(() => undefined);
|
|
405
435
|
await writeTextAtomic(path.join(dir, reportFile), qaReportTemplate(mission, contract, checklist));
|
|
406
436
|
return { checklist_count: checklist.length, report_file: reportFile };
|
|
407
437
|
}
|
|
@@ -441,8 +471,18 @@ export async function ensureQaLoopVisualEvidenceContract(dir, mission = {}, cont
|
|
|
441
471
|
}
|
|
442
472
|
export async function evaluateQaGate(dir) {
|
|
443
473
|
const gate = await readJson(path.join(dir, 'qa-gate.json'), {});
|
|
474
|
+
const surfaceSelection = await readJson(path.join(dir, QA_SURFACE_SELECTION_ARTIFACT), null);
|
|
475
|
+
const selectedSurface = gate.ui_selected_surface || gate.qa_surface_selected || surfaceSelection?.selected_surface || null;
|
|
476
|
+
const expectedEvidenceSource = evidenceSourceForSurface(selectedSurface);
|
|
477
|
+
const gateV2 = gate.qa_contract_v2_required === true ? await evaluateQaGateV2(dir).catch((err) => ({
|
|
478
|
+
passed: false,
|
|
479
|
+
blockers: [`qa_gate_v2_evaluation_failed:${err?.message || String(err)}`],
|
|
480
|
+
unverified: []
|
|
481
|
+
})) : null;
|
|
444
482
|
const reportFile = qaReportFileFromGate(gate);
|
|
445
483
|
const reasons = [];
|
|
484
|
+
if (gateV2 && gateV2.passed !== true)
|
|
485
|
+
reasons.push(...(gateV2.blockers || []));
|
|
446
486
|
for (const key of ['clarification_contract_sealed', 'qa_report_written', 'qa_ledger_complete', 'checklist_completed', 'safety_reviewed', 'deployed_destructive_tests_blocked', 'credentials_not_persisted', 'honest_mode_complete']) {
|
|
447
487
|
if (gate[key] !== true)
|
|
448
488
|
reasons.push(`${key}_missing`);
|
|
@@ -460,17 +500,22 @@ export async function evaluateQaGate(dir) {
|
|
|
460
500
|
if (gate.unsafe_external_side_effects === true)
|
|
461
501
|
reasons.push('unsafe_external_side_effects');
|
|
462
502
|
if (gate.ui_e2e_required === true) {
|
|
463
|
-
if (
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
503
|
+
if (!selectedSurface || selectedSurface === 'codex_chrome_extension') {
|
|
504
|
+
if (gate.chrome_extension_preflight_passed !== true)
|
|
505
|
+
reasons.push('chrome_extension_preflight_missing');
|
|
506
|
+
if (gate.ui_chrome_extension_evidence !== true)
|
|
507
|
+
reasons.push('ui_chrome_extension_evidence_missing');
|
|
508
|
+
}
|
|
509
|
+
else if (gate.ui_live_surface_preflight_passed !== true) {
|
|
510
|
+
reasons.push('ui_live_surface_preflight_missing');
|
|
511
|
+
}
|
|
512
|
+
if (gate.ui_computer_use_evidence === true && selectedSurface !== 'codex_computer_use')
|
|
468
513
|
reasons.push('ui_computer_use_evidence_forbidden_for_web');
|
|
469
|
-
if (gate.ui_evidence_source !==
|
|
470
|
-
reasons.push(
|
|
514
|
+
if (expectedEvidenceSource && gate.ui_evidence_source !== expectedEvidenceSource)
|
|
515
|
+
reasons.push(`ui_evidence_source_not_${expectedEvidenceSource}`);
|
|
471
516
|
if (evidenceMentionsForbiddenBrowserAutomation({ evidence: gate.evidence, notes: gate.notes, ui_evidence_source: gate.ui_evidence_source }))
|
|
472
517
|
reasons.push('forbidden_browser_automation_evidence');
|
|
473
|
-
if (evidenceMentionsForbiddenWebComputerUseEvidence({ evidence: gate.evidence, ui_evidence_source: gate.ui_evidence_source }))
|
|
518
|
+
if (selectedSurface !== 'codex_computer_use' && evidenceMentionsForbiddenWebComputerUseEvidence({ evidence: gate.evidence, ui_evidence_source: gate.ui_evidence_source }))
|
|
474
519
|
reasons.push('computer_use_web_evidence_forbidden');
|
|
475
520
|
reasons.push(...await missingQaLoopVisualEvidence(dir, gate));
|
|
476
521
|
}
|
|
@@ -502,7 +547,7 @@ export async function evaluateQaGate(dir) {
|
|
|
502
547
|
reasons.push('qa_ledger_missing');
|
|
503
548
|
const uniqueReasons = [...new Set(reasons)];
|
|
504
549
|
const passed = gate.passed === true && uniqueReasons.length === 0;
|
|
505
|
-
const result = { checked_at: nowIso(), passed, reasons: uniqueReasons, gate };
|
|
550
|
+
const result = { checked_at: nowIso(), passed, reasons: uniqueReasons, gate, gate_v2: gateV2 };
|
|
506
551
|
await writeJsonAtomic(path.join(dir, 'qa-gate.evaluated.json'), result);
|
|
507
552
|
return result;
|
|
508
553
|
}
|
|
@@ -592,9 +637,9 @@ CONTRACT:
|
|
|
592
637
|
${JSON.stringify(contract, null, 2)}
|
|
593
638
|
${imageContractText}${appHandoffText}${executionProfileText}
|
|
594
639
|
VISUAL EVIDENCE CONTRACT:
|
|
595
|
-
- For
|
|
596
|
-
- If decision-contract.json answers set QA_VISUAL_REVIEW_IMAGEGEN_REQUIRED=${GPT_IMAGE_2_ANNOTATED_REVIEW_REQUIRED_ACK}, use Codex App $imagegen/gpt-image-2 (${CODEX_APP_IMAGE_GENERATION_DOC_URL}) to produce a real generated annotated review image from the
|
|
597
|
-
- Do not substitute prose-only critique, Playwright/Selenium/Puppeteer
|
|
640
|
+
- For UI QA, do not mark live UI evidence true unless qa-loop/qa-surface-selection.json selected the correct @Browser/@Chrome/@Computer surface and action/observation ledgers record real user-like actions.
|
|
641
|
+
- If decision-contract.json answers set QA_VISUAL_REVIEW_IMAGEGEN_REQUIRED=${GPT_IMAGE_2_ANNOTATED_REVIEW_REQUIRED_ACK}, use Codex App $imagegen/gpt-image-2 (${CODEX_APP_IMAGE_GENERATION_DOC_URL}) to produce a real generated annotated review image from the selected-surface source screenshot. Record its path, sha256, model=gpt-image-2, provider=Codex App $imagegen, and source_screenshot_artifact in ${QA_LOOP_VISUAL_EVIDENCE_ARTIFACT} and qa-gate.json.
|
|
642
|
+
- Do not substitute prose-only critique, Playwright/Selenium/Puppeteer screenshots, static screenshots, plugin cache, placeholder images, fake fixtures, or direct API fallback as full UI visual evidence.
|
|
598
643
|
Previous tail:
|
|
599
644
|
${String(previous || '').slice(-2500)}
|
|
600
645
|
`;
|
|
@@ -623,7 +668,7 @@ function qaChecklist(a) {
|
|
|
623
668
|
['preflight.roles', 'Map roles, permissions, protected areas.']
|
|
624
669
|
];
|
|
625
670
|
if (qaUiRequired(a))
|
|
626
|
-
cases.push(['ui.
|
|
671
|
+
cases.push(['ui.surface_router', CODEX_WEB_VERIFICATION_POLICY], ['ui.navigation', 'Check primary navigation, deep links, back/forward, refresh, and protected routes.'], ['ui.auth', 'Check login, logout, session expiry, unauthorized access, and role-specific visibility.'], ['ui.forms', 'Check required fields, validation, disabled states, success, and failure.'], ['ui.states', 'Check loading, empty, error, retry, offline/timeout, and slow network states.'], ['ui.crud', 'Check allowed create/change flows and block forbidden destructive flows by environment.'], ['ui.responsive', 'Check desktop, tablet, mobile, overflow, long text, and keyboard focus order.'], ['ui.a11y', 'Check labels, focus traps, modals, contrast-sensitive controls, and screen-reader names.'], ['ui.visual', 'Capture evidence for meaningful UI regressions without storing secrets.']);
|
|
627
672
|
if (qaApiRequired(a))
|
|
628
673
|
cases.push(['api.health', 'Check health/version/readiness endpoints when available.'], ['api.auth', 'Check anonymous, authenticated, expired, and wrong-role access.'], ['api.contract', 'Check status codes, response shape, headers, content type, and error format.'], ['api.validation', 'Check missing, malformed, boundary, duplicate, and over-limit payloads.'], ['api.listing', 'Check pagination, sorting, filters, search, and empty results.'], ['api.mutation', 'Check allowed seeded create/change and forbid deployed destructive flows.'], ['api.idempotency', 'Check retry/idempotency behavior for safe operations.'], ['api.concurrency', 'Check stale change, conflict, and double-submit behavior.'], ['api.failure', 'Check timeout, upstream error, rate-limit, and rollback-visible failure paths.'], ['api.security', 'Check CORS, auth headers, PII redaction, and permission boundaries.']);
|
|
629
674
|
cases.push(['report.evidence', 'Record pass/fail/blocked/skipped with evidence.'], ['report.corrective_loop', 'Record fixes, rechecks, unresolved findings, deferred blockers.'], ['report.honest', 'Run Honest Mode.']);
|
|
@@ -675,6 +720,8 @@ async function missingQaLoopVisualEvidence(dir, gate = {}) {
|
|
|
675
720
|
const visual = await readJson(path.join(dir, QA_LOOP_VISUAL_EVIDENCE_ARTIFACT), null);
|
|
676
721
|
const reasons = [];
|
|
677
722
|
const uiRequired = gate.ui_e2e_required === true;
|
|
723
|
+
const selectedSurface = gate.ui_selected_surface || gate.qa_surface_selected || (gate.ui_chrome_extension_evidence === true ? 'codex_chrome_extension' : null);
|
|
724
|
+
const expectedSource = evidenceSourceForSurface(selectedSurface) || CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE;
|
|
678
725
|
if (uiRequired) {
|
|
679
726
|
const screenshot = visual?.chrome_extension_screenshot || {};
|
|
680
727
|
if (gate.ui_chrome_extension_screenshot_captured !== true && !positiveVisualStatus(screenshot.status, ['captured', 'attached', 'verified']))
|
|
@@ -690,8 +737,8 @@ async function missingQaLoopVisualEvidence(dir, gate = {}) {
|
|
|
690
737
|
else
|
|
691
738
|
reasons.push(...await imageEvidenceFileReasons(dir, screenshotPath, screenshotSha, 'ui_chrome_extension_screenshot', screenshotDims));
|
|
692
739
|
const screenshotSource = firstNonEmpty(gate.ui_chrome_extension_screenshot_source, screenshot.evidence_source, gate.ui_evidence_source);
|
|
693
|
-
if (screenshotSource !==
|
|
694
|
-
reasons.push(
|
|
740
|
+
if (screenshotSource !== expectedSource)
|
|
741
|
+
reasons.push(`ui_chrome_extension_screenshot_source_not_${expectedSource}`);
|
|
695
742
|
}
|
|
696
743
|
const review = visual?.gpt_image_2_annotated_review || {};
|
|
697
744
|
const gptImage2ReviewRequired = gate.gpt_image_2_annotated_review_required === true || review.required === true;
|
|
@@ -786,4 +833,14 @@ function positiveCount(value) {
|
|
|
786
833
|
const n = Number(value || 0);
|
|
787
834
|
return Number.isFinite(n) && n > 0;
|
|
788
835
|
}
|
|
836
|
+
function evidenceSourceForSurface(surface) {
|
|
837
|
+
const value = String(surface || '').trim();
|
|
838
|
+
if (value === 'codex_in_app_browser')
|
|
839
|
+
return CODEX_IN_APP_BROWSER_EVIDENCE_SOURCE;
|
|
840
|
+
if (value === 'codex_chrome_extension')
|
|
841
|
+
return CODEX_CHROME_EXTENSION_EVIDENCE_SOURCE;
|
|
842
|
+
if (value === 'codex_computer_use')
|
|
843
|
+
return CODEX_COMPUTER_USE_EVIDENCE_SOURCE;
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
789
846
|
//# sourceMappingURL=qa-loop.js.map
|
|
@@ -2,7 +2,7 @@ import { computeTriWikiAffectedGraph } from '../triwiki/triwiki-affected-graph.j
|
|
|
2
2
|
import { buildTriWikiSlaCertificate } from '../triwiki/triwiki-sla-certificate.js';
|
|
3
3
|
import { planExtremeParallelSchedule } from './extreme-parallel-scheduler.js';
|
|
4
4
|
export const SLA_SCHEDULER_SCHEMA = 'sks.sla-scheduler.v1';
|
|
5
|
-
export function planFiveMinuteSla(root, graph = computeTriWikiAffectedGraph({ root, tier: 'affected' }), slaMs = 300_000) {
|
|
5
|
+
export function planFiveMinuteSla(root, graph = computeTriWikiAffectedGraph({ root, tier: 'affected', includeProofLookup: false }), slaMs = 300_000) {
|
|
6
6
|
const schedule = planExtremeParallelSchedule(root, graph);
|
|
7
7
|
const certificate = buildTriWikiSlaCertificate({
|
|
8
8
|
graph,
|
|
@@ -17,7 +17,7 @@ export const RELEASE_1_17_GATE_SNAPSHOT = Object.freeze([
|
|
|
17
17
|
'release:readiness'
|
|
18
18
|
]);
|
|
19
19
|
export const RELEASE_1_18_REQUIRED_GATES = Object.freeze([
|
|
20
|
-
'
|
|
20
|
+
'ultra-search:provider-interface',
|
|
21
21
|
'source-intelligence:policy',
|
|
22
22
|
'source-intelligence:all-modes',
|
|
23
23
|
'codex-web:adapter',
|
package/dist/core/routes.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { PRODUCT_DESIGN_LEGACY_DESIGN_FALLBACK_SKILLS, PRODUCT_DESIGN_PLUGIN, PRODUCT_DESIGN_REQUIRED_SKILLS, productDesignPluginPolicyText } from './product-design-plugin.js';
|
|
2
|
+
import { leanEngineeringCompactText, leanEngineeringLongText } from './lean-engineering-policy.js';
|
|
2
3
|
export { productDesignPluginPolicyText };
|
|
4
|
+
export { leanEngineeringCompactText, leanEngineeringLongText };
|
|
3
5
|
const REFLECTION_SKILL_NAME = 'reflection';
|
|
4
6
|
export const SOLUTION_SCOUT_SKILL_NAME = 'solution-scout';
|
|
5
7
|
export const SOLUTION_SCOUT_STAGE_ID = 'solution_scout';
|
|
@@ -30,17 +32,32 @@ export const FROM_CHAT_IMG_CHECKLIST_ARTIFACT = 'from-chat-img-checklist.md';
|
|
|
30
32
|
export const FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT = 'from-chat-img-temp-triwiki.json';
|
|
31
33
|
export const FROM_CHAT_IMG_QA_LOOP_ARTIFACT = 'from-chat-img-qa-loop.json';
|
|
32
34
|
export const FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS = 5;
|
|
33
|
-
export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|computer-use|goal|fast-mode|research|db|git|codex|codex-app|codex-native|hooks|features|all-features|dfix|commit|commit-and-push|design|imagegen|dollar|context7|xai|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust';
|
|
35
|
+
export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|computer-use|goal|fast-mode|research|seo-geo-optimizer|db|git|codex|codex-app|codex-native|hooks|features|all-features|dfix|commit|commit-and-push|design|imagegen|dollar|context7|ultra-search|xai|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust';
|
|
34
36
|
export const CODEX_COMPUTER_USE_EVIDENCE_SOURCE = 'codex_computer_use';
|
|
35
|
-
export const
|
|
37
|
+
export const CODEX_IN_APP_BROWSER_EVIDENCE_SOURCE = 'codex_in_app_browser';
|
|
38
|
+
export const CODEX_CHROME_EXTENSION_EVIDENCE_SOURCE = 'codex_chrome_extension';
|
|
39
|
+
export const CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE = CODEX_IN_APP_BROWSER_EVIDENCE_SOURCE;
|
|
36
40
|
export const CODEX_IMAGEGEN_EVIDENCE_SOURCE = 'codex_app_imagegen_gpt_image_2';
|
|
41
|
+
export const CODEX_IN_APP_BROWSER_DOC_URL = 'https://developers.openai.com/codex/app/browser';
|
|
37
42
|
export const CODEX_CHROME_EXTENSION_DOC_URL = 'https://developers.openai.com/codex/app/chrome-extension';
|
|
43
|
+
export const CODEX_COMPUTER_USE_DOC_URL = 'https://developers.openai.com/codex/app/computer-use';
|
|
44
|
+
export const CODEX_RECORD_REPLAY_DOC_URL = 'https://developers.openai.com/codex/record-and-replay';
|
|
45
|
+
export const CODEX_APP_SERVER_DOC_URL = 'https://developers.openai.com/codex/app-server';
|
|
38
46
|
export const CODEX_APP_IMAGE_GENERATION_DOC_URL = 'https://developers.openai.com/codex/app/features#image-generation';
|
|
39
47
|
export const OPENAI_IMAGE_GENERATION_DOC_URL = 'https://developers.openai.com/api/docs/guides/image-generation';
|
|
40
48
|
export const OPENAI_CHATGPT_IMAGES_2_DOC_URL = 'https://openai.com/index/introducing-chatgpt-images-2-0/';
|
|
41
49
|
export const OPENAI_GPT_IMAGE_2_MODEL_DOC_URL = 'https://developers.openai.com/api/docs/models/gpt-image-2';
|
|
42
|
-
export const
|
|
43
|
-
|
|
50
|
+
export const QA_INTERACTION_SURFACES = Object.freeze([
|
|
51
|
+
'codex_in_app_browser',
|
|
52
|
+
'codex_chrome_extension',
|
|
53
|
+
'codex_computer_use',
|
|
54
|
+
'codex_app_plugin',
|
|
55
|
+
'structured_mcp',
|
|
56
|
+
'shell_or_api_diagnostic'
|
|
57
|
+
]);
|
|
58
|
+
export const CODEX_QA_SURFACE_ROUTING_POLICY = `Codex QA surface routing follows the official Codex App split: use @Browser / in-app Browser (${CODEX_IN_APP_BROWSER_DOC_URL}) first for localhost, local development servers, file-backed previews, and public pages that do not require sign-in; use @Chrome / Codex Chrome Extension (${CODEX_CHROME_EXTENSION_DOC_URL}) for signed-in websites, cookies, browser profiles, extensions, existing tabs, or internal tools; use @Computer or @AppName (${CODEX_COMPUTER_USE_DOC_URL}) for native macOS/Windows apps, OS settings, cross-app workflows, and GUI-only bugs. Prefer structured Plugins/MCPs for repeatable data operations, then verify rendered user-visible results with Browser, Chrome, or Computer Use. Playwright, Selenium, Puppeteer, Chrome MCP, static screenshots, plugin cache, and final-agent prose are not Codex App live action proof. App Server evidence (${CODEX_APP_SERVER_DOC_URL}) must correlate thread, turn, item/tool events, approvals, diffs, actions, observations, findings, fixes, and same-flow replay before a real QA pass is claimed.`;
|
|
59
|
+
export const CODEX_WEB_VERIFICATION_POLICY = CODEX_QA_SURFACE_ROUTING_POLICY;
|
|
60
|
+
export const CODEX_COMPUTER_USE_ONLY_POLICY = `Codex Computer Use is a live GUI surface for supported macOS and Windows environments, invoked with @Computer or @AppName for native apps, OS settings, browser contexts that truly require GUI-level operation, and cross-app workflows. Do not replace @Browser localhost/public-page checks or @Chrome signed-in checks with Computer Use unless the surface router records a specific GUI-only/cross-app reason. If live Computer Use tools, permissions, or app access are unavailable, mark the affected native/GUI evidence blocked or unverified instead of fabricating screenshots or actions. Codex App readiness/config checks are capability evidence only, not target interaction proof.`;
|
|
44
61
|
export const IMAGEGEN_SOCIAL_SOURCE_POLICY = 'Use public X/social/community reports only as prompt-quality and workflow-sentiment hints after official OpenAI/Codex docs. Social posts are not capability specs, evidence of tool availability, or proof that a generated asset was created.';
|
|
45
62
|
export const CODEX_IMAGEGEN_REQUIRED_POLICY = 'Pipeline image generation, raster asset creation/editing, and generated image-review evidence must use real Codex App imagegen/$imagegen with gpt-image-2 when that evidence is required for full verification. For newest-model image requests, prompt explicitly for "ChatGPT Images 2.0 / GPT Image 2.0 with gpt-image-2" instead of relying on generic image-generation wording. Do not substitute placeholder SVG/HTML/CSS, prose-only critique, stock-like stand-ins, manually fabricated files, or missing-output ledgers for requested/generated raster assets or required generated review images. If imagegen/gpt-image-2 is unavailable or generated annotated images cannot be created/linked, record the blocker and cap any closeout at verified_partial/reference-only instead of claiming generated-image evidence or full route verification; that partial closeout requires source screenshots plus hashes, docs evidence, source Image Voxel anchors, and Honest Mode evidence. In Codex App prompts, invoke $imagegen when live image generation is needed; SKS hooks and skills can require the policy but cannot attach missing host image-generation tools to an already-started turn. Official OpenAI/Codex docs are authoritative for capabilities, surfaces, limits, and evidence rules; X/social/community reports may inform prompt style only.';
|
|
46
63
|
export const DEFAULT_CODEX_APP_PLUGINS = Object.freeze([
|
|
@@ -56,7 +73,7 @@ export const RESERVED_CODEX_PLUGIN_SKILL_NAMES = Object.freeze([
|
|
|
56
73
|
'browser-use',
|
|
57
74
|
...DEFAULT_CODEX_APP_PLUGINS.map(([name]) => name)
|
|
58
75
|
].sort());
|
|
59
|
-
export const FORBIDDEN_BROWSER_AUTOMATION_RE = /\b(playwright|chrome\s+mcp|
|
|
76
|
+
export const FORBIDDEN_BROWSER_AUTOMATION_RE = /\b(playwright|chrome\s+mcp|selenium|puppeteer)\b/i;
|
|
60
77
|
export function evidenceMentionsForbiddenBrowserAutomation(value, seen = new Set()) {
|
|
61
78
|
if (value == null)
|
|
62
79
|
return false;
|
|
@@ -166,6 +183,8 @@ export const RECOMMENDED_SKILLS = [
|
|
|
166
183
|
'pipeline-runner',
|
|
167
184
|
'solution-scout',
|
|
168
185
|
'context7-docs',
|
|
186
|
+
'ultra-search',
|
|
187
|
+
'search-visibility-core',
|
|
169
188
|
'seo-geo-optimizer',
|
|
170
189
|
'autoresearch-loop',
|
|
171
190
|
'performance-evaluator',
|
|
@@ -262,13 +281,13 @@ export function chatCaptureIntakeText() {
|
|
|
262
281
|
return `From-Chat-IMG intake: explicit signal only. Select forensic visual effort. Treat uploads as chat screenshot plus originals. For web/browser/webapp targets, use the Codex Chrome Extension path first; for native Mac/non-web app surfaces, use Codex Computer Use visual inspection when available. List requirements first in source order, match regions to attachments with confidence, and write ${FROM_CHAT_IMG_WORK_ORDER_ARTIFACT}, ${FROM_CHAT_IMG_SOURCE_INVENTORY_ARTIFACT}, ${FROM_CHAT_IMG_VISUAL_MAP_ARTIFACT}, ${FROM_CHAT_IMG_COVERAGE_ARTIFACT}, ${FROM_CHAT_IMG_CHECKLIST_ARTIFACT}, ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT}, and ${FROM_CHAT_IMG_QA_LOOP_ARTIFACT}. ${CODEX_WEB_VERIFICATION_POLICY} ${CODEX_COMPUTER_USE_ONLY_POLICY} Preserve each visible customer request as source-bound text, account for every screenshot image region and separate attachment, map each item to work-order actions, perform the customer-request work, then run a scoped QA-LOOP over that exact work-order range before Team completion. Update checklist checkboxes as work proceeds until all boxes are checked, unresolved_items is empty, scoped_qa_loop_completed=true, QA unresolved findings are zero, and schema validation passes. ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT} is temporary TriWiki-backed session context with expires_after_sessions=${FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS}, so it can be forgotten by retention after enough later sessions. Do not assume ordinary image prompts are chat captures.`;
|
|
263
282
|
}
|
|
264
283
|
export function noUnrequestedFallbackCodePolicyText() {
|
|
265
|
-
return
|
|
284
|
+
return leanEngineeringCompactText();
|
|
266
285
|
}
|
|
267
286
|
export function outcomeRubricPolicyText() {
|
|
268
|
-
return 'Outcome rubric policy:
|
|
287
|
+
return 'Outcome rubric policy: use the Lean Engineering Policy plus existing Proof Field, route gate, reflection, and Honest Mode evidence as the compact rubric: goal fit, minimum touched surface, bounded verification, and explicit escalation triggers.';
|
|
269
288
|
}
|
|
270
289
|
export function speedLanePolicyText() {
|
|
271
|
-
return 'Proof Field speed lane policy: after the intended write scope is known, run or mentally apply `sks proof-field scan --intent "<goal>" --changed <files>`.
|
|
290
|
+
return 'Proof Field speed lane policy: after the intended write scope is known, run or mentally apply `sks proof-field scan --intent "<goal>" --changed <files>`. Fast lanes keep the parent-owned minimal patch, listed verification, TriWiki validate, and Honest Mode; DB, security, visual-forensic, unknown surface, broad changes, failed verification, or unsupported claims fail closed to the normal Team/Honest path.';
|
|
272
291
|
}
|
|
273
292
|
export function hasFromChatImgSignal(prompt = '') {
|
|
274
293
|
return /(?:^|\s)\$?from-chat-img(?:\s|:|$)/i.test(String(prompt || ''));
|
|
@@ -521,13 +540,42 @@ export const ROUTES = [
|
|
|
521
540
|
cliEntrypoint: 'sks research prepare|run',
|
|
522
541
|
examples: ['$Research investigate this idea']
|
|
523
542
|
},
|
|
543
|
+
{
|
|
544
|
+
id: 'UltraSearch',
|
|
545
|
+
command: '$Ultra-Search',
|
|
546
|
+
mode: 'ULTRA_SEARCH',
|
|
547
|
+
route: 'provider-independent source intelligence',
|
|
548
|
+
description: 'Run UltraSearch source acquisition, source normalization, claim/proof ledgers, and provider-independent citation evidence without requiring xAI/Grok.',
|
|
549
|
+
requiredSkills: ['ultra-search', 'pipeline-runner', 'context7-docs', 'honest-mode'],
|
|
550
|
+
dollarAliases: ['$UltraSearch'],
|
|
551
|
+
lifecycle: ['source_intent', 'query_variants', 'provider_plan', 'source_ledgers', 'claim_ledgers', 'ultra_search_gate', 'honest_mode'],
|
|
552
|
+
context7Policy: 'if_external_docs',
|
|
553
|
+
reasoningPolicy: 'high',
|
|
554
|
+
stopGate: 'ultra-search/ultra-search-gate.json',
|
|
555
|
+
cliEntrypoint: 'sks ultra-search doctor|run|x|fetch|status|inspect|sources|claims|cache|bench|migrate-xai',
|
|
556
|
+
examples: ['$Ultra-Search run "current package release notes"', '$UltraSearch x "site:x.com product launch"']
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
id: 'SEOGEOOptimizer',
|
|
560
|
+
command: '$SEO-GEO-OPTIMIZER',
|
|
561
|
+
mode: 'SEO_GEO_OPTIMIZER',
|
|
562
|
+
route: 'search visibility optimization audit/apply/verify',
|
|
563
|
+
description: 'Unified SEO/GEO optimizer route for Search Engine Optimization and Generative Engine Optimization. Uses one shared kernel with mode-specific evidence, gates, safe apply, rollback, and Completion Proof. Not a ranking, traffic, or AI citation guarantee.',
|
|
564
|
+
requiredSkills: ['seo-geo-optimizer', 'search-visibility-core', 'pipeline-runner', REFLECTION_SKILL_NAME, 'honest-mode'],
|
|
565
|
+
lifecycle: ['doctor', 'read_only_audit', 'mode_specific_evidence', 'mutation_plan', 'explicit_apply_only', 'rollback_manifest', 'source_verify', 'seo_or_geo_gate', 'completion_proof', 'honest_mode'],
|
|
566
|
+
context7Policy: 'if_external_docs',
|
|
567
|
+
reasoningPolicy: 'high',
|
|
568
|
+
stopGate: 'seo-gate.json|geo-gate.json',
|
|
569
|
+
cliEntrypoint: 'sks seo-geo-optimizer doctor|audit|plan|apply|verify|status|rollback|fixture --mode seo|geo',
|
|
570
|
+
examples: ['$SEO-GEO-OPTIMIZER audit this site', 'sks seo-geo-optimizer audit --mode seo --target package --json', 'sks seo-geo-optimizer apply latest --mode geo --include-llms-txt --apply']
|
|
571
|
+
},
|
|
524
572
|
{
|
|
525
573
|
id: 'AutoResearch',
|
|
526
574
|
command: '$AutoResearch',
|
|
527
575
|
mode: 'AUTORESEARCH',
|
|
528
576
|
route: 'iterative experiment loop',
|
|
529
577
|
description: 'Program, hypothesize, test, measure, keep/discard, falsify, and report evidence.',
|
|
530
|
-
requiredSkills: ['autoresearch', 'autoresearch-loop', '
|
|
578
|
+
requiredSkills: ['autoresearch', 'autoresearch-loop', 'performance-evaluator', 'pipeline-runner', 'context7-docs', REFLECTION_SKILL_NAME, 'honest-mode'],
|
|
531
579
|
lifecycle: ['experiment_ledger', 'metric', 'keep_or_discard', 'falsification', 'post_route_reflection', 'honest_conclusion'],
|
|
532
580
|
context7Policy: 'required',
|
|
533
581
|
reasoningPolicy: 'xhigh',
|
|
@@ -659,7 +707,7 @@ export const COMMAND_CATALOG = [
|
|
|
659
707
|
{ name: 'hooks', usage: 'sks hooks explain|status|trust-report|replay|codex-validate|warning-check ... [--json]', description: 'Explain Codex hook events, validate vendored latest 10-event output schemas, replay fixtures, and enforce warning-zero SKS hook policies under the 0.134 compatibility matrix.' },
|
|
660
708
|
{ name: 'codex-lb', usage: 'sks codex-lb status|health|metrics|doctor|circuit|repair|setup ...', description: 'Configure, health-check, repair, and record circuit evidence for codex-lb provider auth without confusing ChatGPT OAuth and proxy keys.' },
|
|
661
709
|
{ name: 'zellij', usage: 'sks zellij status|repair [--json] | sks naruto dashboard latest | sks --mad', description: 'Inspect Zellij runtime status, explain repair (no auto-install), and open the SKS Zellij runtime used by MAD and Naruto lane UI.' },
|
|
662
|
-
{ name: 'tmux', usage: '
|
|
710
|
+
{ name: 'tmux', usage: 'removed-runtime migration notice (replacement: zellij)', description: 'Show the removed-runtime migration notice and point operators to Zellij.' },
|
|
663
711
|
{ name: 'mad-sks', usage: 'sks mad-sks plan|run|status|proof ... | sks --mad [--high]', description: 'Open or inspect MAD-SKS scoped permission workflows and the Zellij permission launcher.' },
|
|
664
712
|
{ name: 'auto-review', usage: 'sks auto-review status|enable|start [--high] | sks --Auto-review --high', description: 'Enable Codex automatic approval review and launch SKS Zellij with the auto-review profile.' },
|
|
665
713
|
{ name: 'dollar-commands', usage: 'sks dollar-commands [--json]', description: 'List Codex App $ commands such as $DFix and $Naruto.' },
|
|
@@ -673,7 +721,8 @@ export const COMMAND_CATALOG = [
|
|
|
673
721
|
{ name: 'image-ux-review', usage: 'sks ux-review run --image <path> --fix --json | sks image-ux-review status <mission-id|latest> [--json]', description: 'Run or inspect $Image-UX-Review gpt-image-2/imagegen annotated UI/UX review artifacts, issue ledgers, safe fix loops, recapture, and proof gates.' },
|
|
674
722
|
{ name: 'computer-use', usage: 'sks computer-use import|status|smoke|require ... [--json]', description: 'Record native Mac/non-web Computer Use visual evidence while keeping web verification on the Chrome Extension path.' },
|
|
675
723
|
{ name: 'context7', usage: 'sks context7 check|setup|tools|resolve|docs|evidence ...', description: 'Check, configure, and call the local Context7 MCP requirement.' },
|
|
676
|
-
{ name: '
|
|
724
|
+
{ name: 'ultra-search', usage: 'sks ultra-search doctor|run|x|fetch|status|inspect|sources|claims|cache|bench|migrate-xai', description: 'Run provider-independent UltraSearch source intelligence.' },
|
|
725
|
+
{ name: 'xai', usage: 'sks xai check|status|docs', description: 'Deprecated compatibility notice; use sks ultra-search.' },
|
|
677
726
|
{ name: 'recallpulse', usage: 'sks recallpulse run|status|eval|governance|checklist <mission-id|latest>', description: 'Run report-only RecallPulse active recall, durable status, proof capsule, evidence envelope, and governance checks.' },
|
|
678
727
|
{ name: 'pipeline', usage: 'sks pipeline status|resume|plan|answer ...', description: 'Inspect the active skill-first route, materialized execution plan, ambiguity gates, and completion gates.' },
|
|
679
728
|
{ name: 'guard', usage: 'sks guard check [--json]', description: 'Check SKS harness self-protection lock, fingerprints, and source-repo exception state.' },
|
|
@@ -691,6 +740,7 @@ export const COMMAND_CATALOG = [
|
|
|
691
740
|
{ name: 'init', usage: 'sks init [--force] [--local-only] [--install-scope global|project]', description: 'Initialize the local SKS control surface.' },
|
|
692
741
|
{ name: 'selftest', usage: 'sks selftest [--mock]', description: 'Run local smoke tests without calling a model.' },
|
|
693
742
|
{ name: 'goal', usage: 'sks goal create|pause|resume|clear|status ...', description: 'Prepare and control the fast SKS bridge overlay for Codex native persisted /goal workflows.' },
|
|
743
|
+
{ name: 'seo-geo-optimizer', usage: 'sks seo-geo-optimizer [seo|geo] doctor|audit|plan|apply|verify|status|rollback|fixture [mission|latest] [--mode seo|geo] [--target auto|website|docs|package] [--json]', description: 'Run the unified SEO/GEO optimizer on the shared search-visibility kernel with mode-specific gates and proof.' },
|
|
694
744
|
{ name: 'research', usage: 'sks research prepare|run|status ...', description: 'Run long-form real research missions with xhigh agent Eureka ideas, debate, layered sources, paper, novelty, and falsification gates.' },
|
|
695
745
|
{ name: 'db', usage: 'sks db policy|scan|mcp-config|classify|check ...', description: 'Inspect and enforce database/Supabase safety policy.' },
|
|
696
746
|
{ name: 'eval', usage: 'sks eval run|compare|thresholds ...', description: 'Run deterministic context-quality and performance evidence checks.' },
|
|
@@ -732,6 +782,7 @@ export function routeByDollarCommand(commandName) {
|
|
|
732
782
|
return ROUTES.find((route) => [
|
|
733
783
|
dollarSkillName(route.command),
|
|
734
784
|
...(route.dollarAliases || []).map((alias) => dollarSkillName(alias)),
|
|
785
|
+
...(route.hiddenDollarAliases || []).map((alias) => dollarSkillName(alias)),
|
|
735
786
|
...(route.appSkillAliases || [])
|
|
736
787
|
].includes(key)) || null;
|
|
737
788
|
}
|
|
@@ -833,6 +884,23 @@ export function looksLikeImageUxReviewRequest(prompt = '') {
|
|
|
833
884
|
const commandCue = /\$?(?:image-ux-review|ux-review|visual-review|ui-ux-review)\b/i.test(text);
|
|
834
885
|
return commandCue || (reviewCue && imagegenCue);
|
|
835
886
|
}
|
|
887
|
+
export function looksLikeGeoLocationRequest(prompt = '') {
|
|
888
|
+
return /\b(?:geolocation|geoip|geo\s*ip|map\s+coordinates?|coordinates?|latitude|longitude|location\s+permission|cdn\s+edge\s+geography|regional?\s+redirect|country\s+routing|지도\s*좌표|위치\s*권한|지역\s*리다이렉트|국가별\s*라우팅)\b/i.test(String(prompt || ''));
|
|
889
|
+
}
|
|
890
|
+
export function looksLikeSeoRequest(prompt = '') {
|
|
891
|
+
const text = String(prompt || '');
|
|
892
|
+
return /\b(?:SEO|search\s+engine\s+optimization|technical\s+seo|canonical|sitemap|robots\.txt|hreflang|structured\s+data|json-ld|indexability|crawlability|metadata|meta\s+description|npm\s+seo|package\s+seo|검색\s*엔진\s*최적화|검색\s*노출|사이트맵|캐노니컬|구조화\s*데이터)\b/i.test(text);
|
|
893
|
+
}
|
|
894
|
+
export function looksLikeGenerativeEngineOptimizationRequest(prompt = '') {
|
|
895
|
+
if (looksLikeGeoLocationRequest(prompt))
|
|
896
|
+
return false;
|
|
897
|
+
const text = String(prompt || '');
|
|
898
|
+
return /\b(?:GEO|generative\s+engine\s+optimization|AI\s+(?:answer|search)\s+(?:visibility|discoverability)|LLM\s+(?:citation|answer|visibility|discoverability)|answerability|entity\s+(?:facts?|clarity)|claim\s+evidence|crawler\s+policy|OAI-SearchBot|GPTBot|ChatGPT-User|Claude-SearchBot|ClaudeBot|Claude-User|llms\.txt|AI\s*검색\s*가시성|AI\s*답변\s*가시성|생성형\s*엔진\s*최적화)\b/i.test(text);
|
|
899
|
+
}
|
|
900
|
+
export function looksLikeUltraSearchRequest(prompt = '') {
|
|
901
|
+
const text = String(prompt || '');
|
|
902
|
+
return /\b(?:UltraSearch|Ultra-Search|ultra\s*search|source\s+intelligence|provider-independent\s+source|source\s+acquisition|citation\s+proof|x-search)\b|울트라\s*서치|소스\s*인텔리전스/i.test(text);
|
|
903
|
+
}
|
|
836
904
|
export function routePrompt(prompt) {
|
|
837
905
|
const text = stripVisibleDecisionAnswerBlocks(prompt);
|
|
838
906
|
const command = dollarCommand(text);
|
|
@@ -880,7 +948,13 @@ export function routePrompt(prompt) {
|
|
|
880
948
|
return routeById('Team');
|
|
881
949
|
if (/\b(qa[-\s]?loop|qaloop|e2e\s+qa|qa\s+e2e)\b/i.test(text))
|
|
882
950
|
return routeById('QALoop');
|
|
883
|
-
if (
|
|
951
|
+
if (looksLikeUltraSearchRequest(text) && !looksLikeCodeChangingWork(text) && !looksLikeAnswerOnlyRequest(text))
|
|
952
|
+
return routeById('UltraSearch');
|
|
953
|
+
if (looksLikeGenerativeEngineOptimizationRequest(text))
|
|
954
|
+
return routeById('SEOGEOOptimizer');
|
|
955
|
+
if (looksLikeSeoRequest(text))
|
|
956
|
+
return routeById('SEOGEOOptimizer');
|
|
957
|
+
if (/\b(autoresearch|experiment|benchmark|ranking|optimi[sz]e|improve metric|github stars?|npm downloads?|스타|다운로드)\b/i.test(text))
|
|
884
958
|
return routeById('AutoResearch');
|
|
885
959
|
if (/\b(research|hypothesis|falsify|novelty|frontier|조사|연구)\b/i.test(text))
|
|
886
960
|
return routeById('Research');
|
|
@@ -977,6 +1051,10 @@ export function routeRequiresSubagents(route, prompt = '') {
|
|
|
977
1051
|
return false;
|
|
978
1052
|
if (route.id === 'ImageUXReview')
|
|
979
1053
|
return false;
|
|
1054
|
+
if (route.id === 'UltraSearch')
|
|
1055
|
+
return false;
|
|
1056
|
+
if (route.id === 'SEOGEOOptimizer')
|
|
1057
|
+
return false;
|
|
980
1058
|
if (route.id === 'MadDB')
|
|
981
1059
|
return false;
|
|
982
1060
|
if (route.id === 'Research' || route.id === 'AutoResearch')
|
|
@@ -1011,7 +1089,7 @@ export function simpleGitOnlyRouteId(prompt = '') {
|
|
|
1011
1089
|
}
|
|
1012
1090
|
export function reflectionRequiredForRoute(route) {
|
|
1013
1091
|
const id = String(route?.id || route?.mode || route?.route || route || '').replace(/^\$/, '');
|
|
1014
|
-
return /^(team|naruto|shadowclone|shadow-clone|kagebunshin|kage-bunshin|qaloop|qa-loop|ppt|imageuxreview|image-ux-review|research|autoresearch|db|database|madsks|mad-sks|maddb|mad-db|gx)$/i.test(id);
|
|
1092
|
+
return /^(team|naruto|shadowclone|shadow-clone|kagebunshin|kage-bunshin|qaloop|qa-loop|ppt|imageuxreview|image-ux-review|research|autoresearch|seo|geo|db|database|madsks|mad-sks|maddb|mad-db|gx)$/i.test(id);
|
|
1015
1093
|
}
|
|
1016
1094
|
export function looksLikeCodeChangingWork(prompt = '') {
|
|
1017
1095
|
const text = String(prompt || '');
|
|
@@ -1059,9 +1137,13 @@ export function routeReasoning(route, prompt = '') {
|
|
|
1059
1137
|
return teamRouteReasoning(text);
|
|
1060
1138
|
if (route?.id === 'Research' || route?.id === 'AutoResearch')
|
|
1061
1139
|
return reasoning('xhigh', 'research_or_experiment_route');
|
|
1140
|
+
if (route?.id === 'UltraSearch')
|
|
1141
|
+
return reasoning('high', 'source_intelligence_route');
|
|
1142
|
+
if (route?.id === 'SEOGEOOptimizer')
|
|
1143
|
+
return reasoning('high', 'search_visibility_route');
|
|
1062
1144
|
if (route?.id === 'ImageUXReview')
|
|
1063
1145
|
return reasoning('high', 'image_generation_visual_review_route');
|
|
1064
|
-
if (/\b(research|autoresearch|hypothesis|falsify|novelty|frontier|benchmark|experiment|
|
|
1146
|
+
if (/\b(research|autoresearch|hypothesis|falsify|novelty|frontier|benchmark|experiment|ranking|연구|실험|가설|검증)\b/i.test(text))
|
|
1065
1147
|
return reasoning('xhigh', 'research_level_prompt');
|
|
1066
1148
|
if (base === 'xhigh')
|
|
1067
1149
|
return reasoning('xhigh', 'route_policy_xhigh');
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { auditSeo } from './analyzers.js';
|
|
2
|
+
import { detectProject, discoverSiteInventory } from './discovery.js';
|
|
3
|
+
import { verifySearchVisibility } from './verifier.js';
|
|
4
|
+
class GenericSearchVisibilityAdapter {
|
|
5
|
+
id = 'generic-search-visibility';
|
|
6
|
+
async detect(ctx) {
|
|
7
|
+
return detectProject(ctx);
|
|
8
|
+
}
|
|
9
|
+
async discover(ctx, detection) {
|
|
10
|
+
return discoverSiteInventory(ctx, detection);
|
|
11
|
+
}
|
|
12
|
+
async audit(ctx, inventory) {
|
|
13
|
+
return auditSeo(ctx.root, inventory);
|
|
14
|
+
}
|
|
15
|
+
async verify(ctx, inventory) {
|
|
16
|
+
return verifySearchVisibility(ctx, inventory, null);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const GENERIC_ADAPTER = new GenericSearchVisibilityAdapter();
|
|
20
|
+
export function adapterForDetection(_detection) {
|
|
21
|
+
return GENERIC_ADAPTER;
|
|
22
|
+
}
|
|
23
|
+
export function searchVisibilityAdapters() {
|
|
24
|
+
return [GENERIC_ADAPTER];
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=adapter-registry.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const NEXT_APP_SEARCH_VISIBILITY_ADAPTER_ID = 'next-app';
|
|
2
|
+
export const NEXT_APP_SEARCH_VISIBILITY_SUPPORT = {
|
|
3
|
+
sourceAudit: true,
|
|
4
|
+
mutation: 'guarded_metadata_robots_sitemap_jsonld_when_source_patterns_are_unambiguous',
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=next-app.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const NEXT_PAGES_SEARCH_VISIBILITY_ADAPTER_ID = 'next-pages';
|
|
2
|
+
export const NEXT_PAGES_SEARCH_VISIBILITY_SUPPORT = {
|
|
3
|
+
sourceAudit: true,
|
|
4
|
+
mutation: 'guarded_metadata_robots_sitemap_jsonld_when_source_patterns_are_unambiguous',
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=next-pages.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const STATIC_SITE_SEARCH_VISIBILITY_ADAPTER_ID = 'static-site';
|
|
2
|
+
export const STATIC_SITE_SEARCH_VISIBILITY_SUPPORT = {
|
|
3
|
+
sourceAudit: true,
|
|
4
|
+
mutation: 'create_only_policy_files_and_managed_head_blocks_when_ownership_is_clear',
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=static-site.js.map
|