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.
Files changed (126) hide show
  1. package/README.md +35 -8
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/crates/sks-core/src/main.rs +1 -1
  5. package/dist/bin/sks.js +1 -1
  6. package/dist/cli/command-registry.js +3 -1
  7. package/dist/cli/ultra-search-command.js +163 -0
  8. package/dist/cli/xai-command.js +28 -168
  9. package/dist/core/agents/agent-codex-cockpit.js +3 -3
  10. package/dist/core/agents/agent-runner-ollama.js +2 -0
  11. package/dist/core/agents/agent-wrongness.js +1 -1
  12. package/dist/core/agents/native-worker-backend-router.js +3 -0
  13. package/dist/core/bench.js +115 -0
  14. package/dist/core/code-structure.js +399 -11
  15. package/dist/core/codex-control/codex-app-server-v2-client.js +86 -2
  16. package/dist/core/codex-control/codex-fake-sdk-adapter.js +67 -9
  17. package/dist/core/codex-control/codex-reliability-shield.js +26 -5
  18. package/dist/core/codex-control/codex-task-runner.js +7 -1
  19. package/dist/core/codex-control/gpt-final-arbiter.js +4 -1
  20. package/dist/core/codex-control/gpt-final-review-schema.js +58 -0
  21. package/dist/core/codex-control/model-call-concurrency.js +1 -1
  22. package/dist/core/codex-native/core-skill-manifest.js +23 -0
  23. package/dist/core/commands/bench-command.js +11 -2
  24. package/dist/core/commands/code-structure-command.js +34 -2
  25. package/dist/core/commands/qa-loop-command.js +23 -7
  26. package/dist/core/commands/run-command.js +92 -2
  27. package/dist/core/commands/seo-command.js +130 -0
  28. package/dist/core/feature-fixtures.js +6 -0
  29. package/dist/core/feature-registry.js +3 -1
  30. package/dist/core/fsx.js +1 -1
  31. package/dist/core/hooks-runtime.js +9 -1
  32. package/dist/core/init.js +8 -6
  33. package/dist/core/lean-engineering-policy.js +159 -0
  34. package/dist/core/pipeline-internals/runtime-core.js +15 -5
  35. package/dist/core/proof/auto-finalize.js +3 -2
  36. package/dist/core/proof/proof-schema.js +2 -1
  37. package/dist/core/proof/proof-writer.js +1 -0
  38. package/dist/core/proof/route-adapter.js +4 -2
  39. package/dist/core/proof/route-finalizer.js +35 -3
  40. package/dist/core/qa-loop/qa-app-server-driver.js +134 -0
  41. package/dist/core/qa-loop/qa-contract-v2.js +231 -0
  42. package/dist/core/qa-loop/qa-gate-v2.js +132 -0
  43. package/dist/core/qa-loop/qa-runtime-artifacts.js +53 -0
  44. package/dist/core/qa-loop/qa-surface-router.js +114 -0
  45. package/dist/core/qa-loop/qa-types.js +18 -0
  46. package/dist/core/qa-loop.js +83 -26
  47. package/dist/core/release/gate-manifest.js +1 -0
  48. package/dist/core/release/sla-scheduler.js +1 -1
  49. package/dist/core/release-parallel-full-coverage.js +1 -1
  50. package/dist/core/routes.js +96 -14
  51. package/dist/core/search-visibility/adapter-registry.js +26 -0
  52. package/dist/core/search-visibility/adapters/next-app.js +6 -0
  53. package/dist/core/search-visibility/adapters/next-pages.js +6 -0
  54. package/dist/core/search-visibility/adapters/static-site.js +6 -0
  55. package/dist/core/search-visibility/analyzers.js +377 -0
  56. package/dist/core/search-visibility/artifacts.js +183 -0
  57. package/dist/core/search-visibility/discovery.js +347 -0
  58. package/dist/core/search-visibility/index.js +199 -0
  59. package/dist/core/search-visibility/mission.js +67 -0
  60. package/dist/core/search-visibility/mutation.js +314 -0
  61. package/dist/core/search-visibility/types.js +2 -0
  62. package/dist/core/search-visibility/verifier.js +60 -0
  63. package/dist/core/source-intelligence/source-intelligence-policy.js +45 -26
  64. package/dist/core/source-intelligence/source-intelligence-proof.js +10 -16
  65. package/dist/core/source-intelligence/source-intelligence-runner.js +56 -42
  66. package/dist/core/triwiki/triwiki-affected-graph.js +3 -2
  67. package/dist/core/trust-kernel/trust-report.js +3 -5
  68. package/dist/core/ultra-search/index.js +3 -0
  69. package/dist/core/ultra-search/runtime.js +502 -0
  70. package/dist/core/ultra-search/types.js +3 -0
  71. package/dist/core/version.js +1 -1
  72. package/dist/scripts/agent-visual-consistency-check.js +1 -1
  73. package/dist/scripts/check-architecture.js +40 -7
  74. package/dist/scripts/check-command-module-budget.js +43 -5
  75. package/dist/scripts/check-pipeline-budget.js +17 -30
  76. package/dist/scripts/check-publish-tag.js +33 -6
  77. package/dist/scripts/check-route-modularity.js +25 -33
  78. package/dist/scripts/check-runtime-schemas.js +22 -0
  79. package/dist/scripts/codex-control-all-pipelines-check.js +1 -0
  80. package/dist/scripts/codex-control-model-capacity-fallback-check.js +53 -0
  81. package/dist/scripts/config-managed-merge-callsite-coverage-check.js +7 -1
  82. package/dist/scripts/core-skill-immutable-sync-check.js +3 -2
  83. package/dist/scripts/core-skill-integrity-blackbox.js +3 -2
  84. package/dist/scripts/core-skill-manifest-check.js +7 -2
  85. package/dist/scripts/geo-claim-evidence-check.js +18 -0
  86. package/dist/scripts/geo-cli-blackbox-check.js +18 -0
  87. package/dist/scripts/geo-crawler-policy-check.js +16 -0
  88. package/dist/scripts/geo-llms-txt-optional-check.js +19 -0
  89. package/dist/scripts/gpt-final-arbiter-check.js +4 -1
  90. package/dist/scripts/loop-directive-check-lib.js +78 -1
  91. package/dist/scripts/qa-loop-app-server-driver-check.js +74 -0
  92. package/dist/scripts/qa-loop-surface-router-check.js +49 -0
  93. package/dist/scripts/release-check-dynamic-execute.js +1 -1
  94. package/dist/scripts/release-metadata-1-19-check.js +2 -2
  95. package/dist/scripts/release-parallel-check.js +17 -2
  96. package/dist/scripts/release-parallel-full-coverage-check.js +1 -1
  97. package/dist/scripts/release-readiness-report.js +6 -6
  98. package/dist/scripts/release-registry-check.js +33 -14
  99. package/dist/scripts/runtime-ts-rust-boundary-check.js +1 -1
  100. package/dist/scripts/search-visibility-gate-lib.js +124 -0
  101. package/dist/scripts/seo-audit-fixture-check.js +16 -0
  102. package/dist/scripts/seo-canonical-locale-check.js +19 -0
  103. package/dist/scripts/seo-cli-blackbox-check.js +18 -0
  104. package/dist/scripts/seo-geo-feature-fixture-quality-check.js +18 -0
  105. package/dist/scripts/seo-geo-geo-disambiguation-check.js +12 -0
  106. package/dist/scripts/seo-geo-no-unsupported-ranking-claims-check.js +18 -0
  107. package/dist/scripts/seo-geo-route-identity-check.js +12 -0
  108. package/dist/scripts/seo-geo-skill-rich-content-check.js +22 -0
  109. package/dist/scripts/seo-mutation-rollback-check.js +23 -0
  110. package/dist/scripts/seo-no-mutation-by-default-check.js +17 -0
  111. package/dist/scripts/seo-structured-data-visible-content-check.js +19 -0
  112. package/dist/scripts/sks-1-18-gate-lib.js +2 -2
  113. package/dist/scripts/sks-3-1-5-directive-check-lib.js +10 -1
  114. package/dist/scripts/source-intelligence-all-modes-check.js +9 -19
  115. package/dist/scripts/source-intelligence-policy-check.js +6 -6
  116. package/dist/scripts/triwiki-affected-graph-check.js +2 -2
  117. package/dist/scripts/ultra-search-provider-interface-check.js +27 -0
  118. package/package.json +26 -5
  119. package/schemas/search-visibility/finding-ledger.schema.json +36 -0
  120. package/schemas/search-visibility/gate.schema.json +22 -0
  121. package/schemas/search-visibility/mutation-plan.schema.json +27 -0
  122. package/schemas/search-visibility/site-inventory.schema.json +21 -0
  123. package/schemas/search-visibility/verification-report.schema.json +23 -0
  124. package/dist/core/mcp/xai-mcp-detector.js +0 -157
  125. package/dist/core/mcp/xai-search-adapter.js +0 -100
  126. package/dist/scripts/xai-mcp-capability-check.js +0 -14
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
7
+ import { runQaAppServerDriver } from '../core/qa-loop/qa-app-server-driver.js';
8
+ import { selectQaSurface } from '../core/qa-loop/qa-surface-router.js';
9
+ const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-qa-app-server-driver-'));
10
+ const calls = [];
11
+ const fakeClient = {
12
+ listeners: [],
13
+ async initialize() {
14
+ calls.push('initialize');
15
+ },
16
+ onEvent(listener) {
17
+ this.listeners.push(listener);
18
+ return () => {
19
+ this.listeners = this.listeners.filter((item) => item !== listener);
20
+ };
21
+ },
22
+ async startThread(params) {
23
+ calls.push(['thread/start', params]);
24
+ const event = { method: 'thread/started', params: { threadId: 'thread-qa-driver', thread: { id: 'thread-qa-driver' } } };
25
+ this.listeners.forEach((listener) => listener(event));
26
+ return { thread: { id: 'thread-qa-driver' }, cwd: params.cwd };
27
+ },
28
+ async startTurn(params) {
29
+ calls.push(['turn/start', params]);
30
+ this.listeners.forEach((listener) => listener({ method: 'turn/started', params: { threadId: params.threadId, turn: { id: 'turn-qa-driver' } } }));
31
+ this.listeners.forEach((listener) => listener({
32
+ method: 'item/tool/call',
33
+ params: {
34
+ threadId: params.threadId,
35
+ turnId: 'turn-qa-driver',
36
+ itemId: 'item-click-1',
37
+ tool: '@Browser',
38
+ action: 'click',
39
+ cookie: 'secret-cookie-value'
40
+ }
41
+ }));
42
+ return { turn: { id: 'turn-qa-driver' } };
43
+ },
44
+ async waitForTurnCompletion(threadId, turnId) {
45
+ calls.push(['wait', { threadId, turnId }]);
46
+ return { threadId, turnId, status: 'completed' };
47
+ }
48
+ };
49
+ const surface = selectQaSurface({ missionId: 'M-qa-driver', targetUrl: 'http://localhost:3000', prompt: 'local Browser QA' });
50
+ const session = await runQaAppServerDriver({
51
+ missionDir: tmp,
52
+ missionId: 'M-qa-driver',
53
+ client: fakeClient,
54
+ cwd: process.cwd(),
55
+ prompt: '@Browser open http://localhost:3000 and click Save',
56
+ surfaceSelection: surface,
57
+ timeoutMs: 500
58
+ });
59
+ assertGate(session.status === 'completed', 'QA App Server driver fake session must complete', session);
60
+ assertGate(session.thread_id === 'thread-qa-driver', 'thread id must be correlated', session);
61
+ assertGate(session.turn_id === 'turn-qa-driver', 'turn id must be correlated', session);
62
+ assertGate(session.action_event_count >= 1, 'action-like tool event must be counted', session);
63
+ const runtimeEvents = await fs.readFile(path.join(tmp, 'qa-loop', 'runtime-events.jsonl'), 'utf8');
64
+ const actionLedger = await fs.readFile(path.join(tmp, 'qa-loop', 'action-ledger.jsonl'), 'utf8');
65
+ assertGate(runtimeEvents.includes('thread-qa-driver') && runtimeEvents.includes('turn-qa-driver'), 'runtime events must include thread/turn IDs', runtimeEvents);
66
+ assertGate(actionLedger.includes('item-click-1'), 'action ledger must include item id', actionLedger);
67
+ assertGate(!runtimeEvents.includes('secret-cookie-value') && !actionLedger.includes('secret-cookie-value'), 'driver must redact cookie/token-like fields from artifacts');
68
+ emitGate('qa-loop:app-server-driver', {
69
+ calls: calls.map((call) => Array.isArray(call) ? call[0] : call),
70
+ action_event_count: session.action_event_count,
71
+ event_count: session.event_count,
72
+ redaction: true
73
+ });
74
+ //# sourceMappingURL=qa-loop-app-server-driver-check.js.map
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
7
+ import { buildQaContractV2 } from '../core/qa-loop/qa-contract-v2.js';
8
+ import { evaluateQaGateV2 } from '../core/qa-loop/qa-gate-v2.js';
9
+ import { initializeQaRuntimeArtifacts } from '../core/qa-loop/qa-runtime-artifacts.js';
10
+ import { selectQaSurface } from '../core/qa-loop/qa-surface-router.js';
11
+ const cases = [
12
+ ['localhost no auth chooses Browser', selectQaSurface({ targetUrl: 'http://localhost:3000/settings', prompt: 'test local web settings' }).selected_surface, 'codex_in_app_browser'],
13
+ ['public no auth chooses Browser', selectQaSurface({ targetUrl: 'https://example.com', prompt: 'public marketing page QA' }).selected_surface, 'codex_in_app_browser'],
14
+ ['signed-in browser state chooses Chrome', selectQaSurface({ targetUrl: 'https://example.com/app', prompt: 'verify logged-in cookie profile flow' }).selected_surface, 'codex_chrome_extension'],
15
+ ['extension-dependent site chooses Chrome', selectQaSurface({ targetUrl: 'https://example.com', prompt: 'browser extension dependent QA' }).selected_surface, 'codex_chrome_extension'],
16
+ ['native macOS GUI chooses Computer Use', selectQaSurface({ prompt: 'native macOS Settings GUI bug' }).selected_surface, 'codex_computer_use'],
17
+ ['native Windows GUI chooses Computer Use', selectQaSurface({ prompt: 'Windows desktop app dialog bug' }).selected_surface, 'codex_computer_use'],
18
+ ['structured data without UI chooses MCP', selectQaSurface({ prompt: 'Gmail data sync check', uiRequired: false, targetKind: 'structured_data' }).selected_surface, 'structured_mcp']
19
+ ];
20
+ for (const [label, actual, expected] of cases) {
21
+ assertGate(actual === expected, `${label}: expected ${expected}, got ${actual}`, { actual, expected });
22
+ }
23
+ const contract = buildQaContractV2({
24
+ prompt: 'QA local settings form at http://localhost:3000',
25
+ answers: {
26
+ QA_SCOPE: 'ui_e2e_only',
27
+ TARGET_BASE_URL: 'http://localhost:3000',
28
+ LOGIN_REQUIRED: 'no',
29
+ MAX_QA_CYCLES: ''
30
+ }
31
+ }, { missionId: 'M-router-check' });
32
+ assertGate(contract.runtime.max_cycles === 5, 'QA contract v2 default max cycles must be 5', contract.runtime);
33
+ assertGate(contract.mutation.source_code_patch_policy === 'enabled', 'safe local source fixes must default on unless report-only', contract.mutation);
34
+ const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-qa-router-'));
35
+ await initializeQaRuntimeArtifacts(tmp, contract, { missionId: 'M-router-check' });
36
+ let gate = await evaluateQaGateV2(tmp);
37
+ assertGate(gate.passed === false, 'UI-required QA cannot pass with zero real actions', gate);
38
+ assertGate(gate.blockers.includes('ui_required_but_real_action_count_zero'), 'zero-action blocker missing', gate);
39
+ await fs.appendFile(path.join(tmp, 'qa-loop', 'action-ledger.jsonl'), `${JSON.stringify({ schema: 'sks.qa-loop-action.v2', status: 'completed', real: true, journey_fingerprint: 'J', kind: 'click' })}\n`);
40
+ await fs.appendFile(path.join(tmp, 'qa-loop', 'observation-ledger.jsonl'), `${JSON.stringify({ schema: 'sks.qa-loop-observation.v2', status: 'observed', real: true, journey_fingerprint: 'J', kind: 'visual_delta' })}\n`);
41
+ gate = await evaluateQaGateV2(tmp);
42
+ assertGate(gate.real_action_count === 1 && gate.observation_count === 1, 'real action and observation ledgers must be counted', gate);
43
+ emitGate('qa-loop:surface-router', {
44
+ matrix_cases: cases.length,
45
+ default_max_cycles: contract.runtime.max_cycles,
46
+ zero_action_blocked: true,
47
+ selected_surface: contract.target.kind
48
+ });
49
+ //# sourceMappingURL=qa-loop-surface-router-check.js.map
@@ -60,7 +60,7 @@ for (const gate of plan.selected) {
60
60
  continue;
61
61
  }
62
62
  const command = `npm run ${gate.id}`;
63
- if (FORBIDDEN_RECURSIVE_GATES.has(gate.id) || /npm\s+run\s+(release:check|release:real-check|release:publish|publish:npm|publish:dry|prepublishOnly)\b/.test(command)) {
63
+ if (FORBIDDEN_RECURSIVE_GATES.has(gate.id) || /npm\s+run\s+(release:check|release:real-check|release:publish|publish:ignore-scripts|publish:npm|publish:dry|prepublishOnly)\b/.test(command)) {
64
64
  failures.push({ id: gate.id, exit_code: null, stdout_tail: '', stderr_tail: 'forbidden_recursive_gate_spawn' });
65
65
  continue;
66
66
  }
@@ -21,7 +21,7 @@ const requiredDocs = [
21
21
  'README.md',
22
22
  'CHANGELOG.md',
23
23
  'docs/source-intelligence-layer.md',
24
- 'docs/xai-context7-codex-web-policy.md',
24
+ 'docs/ultra-search-source-intelligence-policy.md',
25
25
  'docs/main-no-scout-worker-scout-policy.md',
26
26
  'docs/agent-terminal-lanes.md',
27
27
  'docs/migration/tmux-to-zellij.md',
@@ -97,7 +97,7 @@ const requiredScripts = [
97
97
  'agent:janitor',
98
98
  'agent:multi-project-isolation',
99
99
  'verification:parallel-engine',
100
- 'xai-mcp:capability',
100
+ 'ultra-search:provider-interface',
101
101
  'source-intelligence:policy',
102
102
  'source-intelligence:all-modes',
103
103
  'codex-web:adapter',
@@ -34,10 +34,25 @@ const tasks = [
34
34
  task('agent:janitor', 'npm run agent:janitor --silent', { dependencies: ['build'] }),
35
35
  task('agent:multi-project-isolation', 'npm run agent:multi-project-isolation --silent', { dependencies: ['build'] }),
36
36
  task('verification:parallel-engine', 'npm run verification:parallel-engine --silent', { dependencies: ['build'] }),
37
- task('xai-mcp:capability', 'npm run xai-mcp:capability --silent', { dependencies: ['build'] }),
37
+ task('ultra-search:provider-interface', 'npm run ultra-search:provider-interface --silent', { dependencies: ['build'] }),
38
38
  task('source-intelligence:policy', 'npm run source-intelligence:policy --silent', { dependencies: ['build'] }),
39
- task('source-intelligence:all-modes', 'npm run source-intelligence:all-modes --silent', { dependencies: ['build', 'source-intelligence:policy', 'xai-mcp:capability', 'codex-web:adapter'] }),
39
+ task('source-intelligence:all-modes', 'npm run source-intelligence:all-modes --silent', { dependencies: ['build', 'source-intelligence:policy', 'ultra-search:provider-interface', 'codex-web:adapter'] }),
40
40
  task('codex-web:adapter', 'npm run codex-web:adapter --silent', { dependencies: ['build'] }),
41
+ task('seo:cli-blackbox', 'npm run seo:cli-blackbox --silent', { dependencies: ['build'] }),
42
+ task('seo:audit-fixture', 'npm run seo:audit-fixture --silent', { dependencies: ['build'] }),
43
+ task('seo:no-mutation-by-default', 'npm run seo:no-mutation-by-default --silent', { dependencies: ['build'] }),
44
+ task('seo:mutation-rollback', 'npm run seo:mutation-rollback --silent', { dependencies: ['build'] }),
45
+ task('seo:canonical-sitemap-locale', 'npm run seo:canonical-sitemap-locale --silent', { dependencies: ['build'] }),
46
+ task('seo:structured-data-visible-content', 'npm run seo:structured-data-visible-content --silent', { dependencies: ['build'] }),
47
+ task('geo:cli-blackbox', 'npm run geo:cli-blackbox --silent', { dependencies: ['build'] }),
48
+ task('geo:claim-evidence', 'npm run geo:claim-evidence --silent', { dependencies: ['build'] }),
49
+ task('geo:crawler-purpose-policy', 'npm run geo:crawler-purpose-policy --silent', { dependencies: ['build'] }),
50
+ task('geo:llms-txt-optional', 'npm run geo:llms-txt-optional --silent', { dependencies: ['build'] }),
51
+ task('seo-geo:route-identity', 'npm run seo-geo:route-identity --silent', { dependencies: ['build'] }),
52
+ task('seo-geo:geo-disambiguation', 'npm run seo-geo:geo-disambiguation --silent', { dependencies: ['build'] }),
53
+ task('seo-geo:skill-rich-content', 'npm run seo-geo:skill-rich-content --silent', { dependencies: ['build'] }),
54
+ task('seo-geo:no-unsupported-ranking-claims', 'npm run seo-geo:no-unsupported-ranking-claims --silent', { dependencies: ['build'] }),
55
+ task('seo-geo:feature-fixture-quality', 'npm run seo-geo:feature-fixture-quality --silent', { dependencies: ['build'] }),
41
56
  task('doctor:codex-doctor-parity', 'npm run doctor:codex-doctor-parity --silent', { dependencies: ['build'] }),
42
57
  task('codex:permission-profiles', 'npm run codex:permission-profiles --silent', { dependencies: ['build'] }),
43
58
  task('codex:legacy-profile-consumers-removed', 'npm run codex:legacy-profile-consumers-removed --silent', { dependencies: ['build'] }),
@@ -6,7 +6,7 @@ import { assertGate, emitGate, importDist, packageScripts, root } from './sks-1-
6
6
  const mod = await importDist('core/release-parallel-full-coverage.js');
7
7
  const pkgScripts = packageScripts();
8
8
  const parallelSource = fs.readFileSync(path.join(root, 'src/scripts/release-parallel-check.ts'), 'utf8');
9
- const current = [...new Set(Object.keys(pkgScripts).filter((name) => parallelSource.includes(name)).concat(Object.keys(pkgScripts).filter((name) => /^xai-mcp|^source-intelligence|^codex-web|^goal-mode|^agent:main-no-scout|^agent:worker-scout-limited|^agent:background-terminals|^agent:zellij-runtime|^agent:visual-consistency|^release:parallel-full-coverage|^priority:full-closure/.test(name))))];
9
+ const current = [...new Set(Object.keys(pkgScripts).filter((name) => parallelSource.includes(name)).concat(Object.keys(pkgScripts).filter((name) => /^ultra-search|^source-intelligence|^codex-web|^goal-mode|^agent:main-no-scout|^agent:worker-scout-limited|^agent:background-terminals|^agent:zellij-runtime|^agent:visual-consistency|^release:parallel-full-coverage|^priority:full-closure/.test(name))))];
10
10
  const report = mod.evaluateReleaseParallelFullCoverage(current);
11
11
  assertGate(report.ok === true, 'release parallel DAG must preserve previous gates and include 1.18 gates', report);
12
12
  emitGate('release:parallel-full-coverage', { previous_gate_count: report.previous_gate_count, current_gate_count: report.current_gate_count });
@@ -103,7 +103,7 @@ const checks = {
103
103
  computer_use_live_evidence: scriptContains('release:check', 'computer-use:live-evidence'),
104
104
  docs_truthfulness: scriptContains('release:check', 'docs:truthfulness'),
105
105
  release_readiness: scriptContains('release:check:parallel', 'release:readiness'),
106
- xai_mcp_capability: scriptContains('release:check:parallel', 'xai-mcp:capability'),
106
+ ultra_search_provider_interface: scriptContains('release:check:parallel', 'ultra-search:provider-interface'),
107
107
  source_intelligence_policy: scriptContains('release:check:parallel', 'source-intelligence:policy'),
108
108
  source_intelligence_all_modes: scriptContains('release:check:parallel', 'source-intelligence:all-modes'),
109
109
  codex_web_adapter: scriptContains('release:check:parallel', 'codex-web:adapter'),
@@ -318,7 +318,7 @@ for (const [name, ok] of Object.entries({
318
318
  verification_parallel_engine: checks.verification_parallel_engine,
319
319
  release_metadata: checks.release_metadata,
320
320
  release_readiness: checks.release_readiness,
321
- xai_mcp_capability: checks.xai_mcp_capability,
321
+ ultra_search_provider_interface: checks.ultra_search_provider_interface,
322
322
  source_intelligence_policy: checks.source_intelligence_policy,
323
323
  source_intelligence_all_modes: checks.source_intelligence_all_modes,
324
324
  codex_web_adapter: checks.codex_web_adapter,
@@ -809,13 +809,13 @@ const report = {
809
809
  flagship_proof_graph_v4_report_ok: runtimeChecks.flagship_proof_graph_v4
810
810
  },
811
811
  source_intelligence_1_18: {
812
- status: checks.xai_mcp_capability
812
+ status: checks.ultra_search_provider_interface
813
813
  && checks.source_intelligence_policy
814
814
  && checks.source_intelligence_all_modes
815
815
  && checks.codex_web_adapter ? 'present' : 'missing',
816
- mode_default: 'context7_codex_web',
817
- xai_when_available: checks.xai_mcp_capability,
818
- xai_missing_fallback: checks.source_intelligence_all_modes,
816
+ mode_default: 'ultra_balanced',
817
+ x_search_public_discovery: checks.ultra_search_provider_interface,
818
+ no_xai_runtime_dependency: checks.source_intelligence_all_modes,
819
819
  codex_web_adapter: checks.codex_web_adapter
820
820
  },
821
821
  agent_terminal_zellij_1_18: {
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- // @ts-nocheck
3
2
  import { spawnSync } from 'node:child_process';
4
3
  import fs from 'node:fs';
5
4
  import os from 'node:os';
@@ -27,7 +26,7 @@ function readJson(file) {
27
26
  return JSON.parse(fs.readFileSync(path.join(root, file), 'utf8'));
28
27
  }
29
28
  catch (err) {
30
- fail(`unable to read ${file}`, err.message);
29
+ fail(`unable to read ${file}`, err instanceof Error ? err.message : String(err));
31
30
  }
32
31
  }
33
32
  function run(cmd, args, options = {}) {
@@ -58,17 +57,23 @@ function checkPackagePublishConfig(pkg) {
58
57
  if (isPrerelease && pkg.publishConfig?.tag !== 'rc') {
59
58
  fail('package.json publishConfig.tag must be rc for prerelease versions', `found: ${pkg.publishConfig?.tag || 'missing'}\nversion: ${pkg.version}`);
60
59
  }
61
- if (!isPrerelease && pkg.publishConfig?.tag && pkg.publishConfig.tag !== 'latest') {
62
- fail('package.json publishConfig.tag must be latest or omitted for stable versions', `found: ${pkg.publishConfig.tag}\nversion: ${pkg.version}`);
60
+ if (!isPrerelease && pkg.publishConfig?.tag && pkg.publishConfig.tag !== 'latest' && !isBackfillTag(pkg.publishConfig.tag)) {
61
+ fail('package.json publishConfig.tag must be latest, omitted, or explicit backfill-* for stable backfill versions', `found: ${pkg.publishConfig.tag}\nversion: ${pkg.version}`);
63
62
  }
64
63
  }
65
64
  function checkRootNpmrc(pkg) {
66
65
  const npmrcPath = path.join(root, '.npmrc');
67
- if (!fs.existsSync(npmrcPath))
66
+ const publishConfigTag = String(pkg.publishConfig?.tag || '');
67
+ if (!fs.existsSync(npmrcPath)) {
68
+ if (isBackfillTag(publishConfigTag)) {
69
+ fail('root .npmrc must pin the backfill publish tag for npm publish --ignore-scripts', `expected: tag=${publishConfigTag}`);
70
+ }
68
71
  return;
72
+ }
69
73
  const text = fs.readFileSync(npmrcPath, 'utf8');
70
74
  const unsafe = [];
71
75
  const isPrerelease = /-/.test(String(pkg.version || ''));
76
+ let npmrcTag = '';
72
77
  for (const [index, line] of text.split(/\r?\n/).entries()) {
73
78
  const trimmed = line.trim();
74
79
  if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith(';'))
@@ -78,16 +83,23 @@ function checkRootNpmrc(pkg) {
78
83
  unsafe.push(`${index + 1}: ${trimmed}`);
79
84
  const tagMatch = trimmed.match(/^tag\s*=\s*(.+)$/);
80
85
  if (tagMatch) {
81
- const tag = tagMatch[1].trim();
86
+ const tag = String(tagMatch[1] || '').trim();
87
+ npmrcTag = tag;
82
88
  if (isPrerelease && tag !== 'rc')
83
89
  unsafe.push(`${index + 1}: ${trimmed}`);
84
- if (!isPrerelease && tag !== 'latest')
90
+ if (!isPrerelease && tag !== 'latest' && !isBackfillTag(tag))
85
91
  unsafe.push(`${index + 1}: ${trimmed}`);
86
92
  }
87
93
  }
88
94
  if (unsafe.length) {
89
95
  fail('root .npmrc contains publish config incompatible with this release', unsafe.join('\n'));
90
96
  }
97
+ if (publishConfigTag && npmrcTag && publishConfigTag !== npmrcTag) {
98
+ fail('root .npmrc tag disagrees with package.json publishConfig.tag', `.npmrc tag: ${npmrcTag}\npublishConfig.tag: ${publishConfigTag}`);
99
+ }
100
+ if (isBackfillTag(publishConfigTag) && npmrcTag !== publishConfigTag) {
101
+ fail('root .npmrc must pin the backfill publish tag for npm publish --ignore-scripts', `.npmrc tag: ${npmrcTag || 'missing'}\nexpected: ${publishConfigTag}`);
102
+ }
91
103
  }
92
104
  function checkLockfile(pkg) {
93
105
  const lock = readJson('package-lock.json');
@@ -147,8 +159,10 @@ function compareVersions(a, b) {
147
159
  const pb = String(b || '').split(/[.-]/).map((part) => Number.parseInt(part, 10));
148
160
  const len = Math.max(pa.length, pb.length);
149
161
  for (let i = 0; i < len; i += 1) {
150
- const da = Number.isFinite(pa[i]) ? pa[i] : 0;
151
- const db = Number.isFinite(pb[i]) ? pb[i] : 0;
162
+ const paValue = pa[i];
163
+ const pbValue = pb[i];
164
+ const da = Number.isFinite(paValue) ? paValue || 0 : 0;
165
+ const db = Number.isFinite(pbValue) ? pbValue || 0 : 0;
152
166
  if (da !== db)
153
167
  return da > db ? 1 : -1;
154
168
  }
@@ -193,14 +207,17 @@ function checkPublishedVersion(pkg) {
193
207
  fail('package version is already published on npm', `${pkg.name}@${pkg.version}`);
194
208
  }
195
209
  const cmp = compareVersions(pkg.version, latest);
196
- if (requireUnpublished && cmp <= 0) {
210
+ if (requireUnpublished && cmp <= 0 && !isBackfillTag(pkg.publishConfig?.tag || '')) {
197
211
  fail('package version is not newer than the npm latest dist-tag', `package.json: ${pkg.version}\nnpm latest: ${latest}`);
198
212
  }
199
213
  const note = exactPublished
200
214
  ? `exact version already exists; current npm latest is ${latest}`
201
- : (cmp > 0 ? `ready for new publish over npm latest ${latest}` : `current npm latest is ${latest}`);
215
+ : (cmp > 0 ? `ready for new publish over npm latest ${latest}` : `ready as backfill over current npm latest ${latest} with tag ${pkg.publishConfig?.tag || 'missing'}`);
202
216
  console.log(`Registry metadata check passed: ${pkg.name}@${pkg.version}; ${note}.`);
203
217
  }
218
+ function isBackfillTag(value) {
219
+ return /^backfill(?:[-_][a-z0-9.-]+)?$/i.test(String(value || ''));
220
+ }
204
221
  function checkPublishAuth(pkg) {
205
222
  if (skipNetwork) {
206
223
  fail('publish auth check cannot run when SKS_SKIP_REGISTRY_NETWORK_CHECK=1 is set');
@@ -324,8 +341,10 @@ function packageMaintainers(pkg, env) {
324
341
  function normalizeNpmUser(value) {
325
342
  if (!value)
326
343
  return '';
327
- if (typeof value === 'object')
328
- return normalizeNpmUser(value.name || value.username || '');
344
+ if (typeof value === 'object') {
345
+ const record = value;
346
+ return normalizeNpmUser(record.name || record.username || '');
347
+ }
329
348
  const text = String(value).trim();
330
349
  if (/^["[{]/.test(text)) {
331
350
  try {
@@ -335,7 +354,7 @@ function normalizeNpmUser(value) {
335
354
  // Fall through for legacy plain-text npm output.
336
355
  }
337
356
  }
338
- return text.replace(/^@/, '').split(/\s+/)[0].toLowerCase();
357
+ return String(text.replace(/^@/, '').split(/\s+/)[0] || '').toLowerCase();
339
358
  }
340
359
  function tail(value, limit = 1200) {
341
360
  const text = String(value || '').trim();
@@ -13,7 +13,7 @@ import { root, assertGate, emitGate, importDist, readText, readJson } from './sk
13
13
  assertGate(!/cargo|rustc/.test(readText('src/scripts/build-dist.ts')), 'build-dist must not invoke cargo/rustc');
14
14
  assertGate(!/cargo|rustc/.test(readText('src/scripts/clean-dist.ts')), 'clean-dist must not invoke cargo/rustc');
15
15
  const pkg = readJson('package.json');
16
- for (const s of ['prepack', 'prepublishOnly', 'publish:dry', 'publish:npm']) {
16
+ for (const s of ['prepack', 'prepublishOnly', 'publish:dry', 'publish:ignore-scripts', 'publish:npm']) {
17
17
  assertGate(!String(pkg.scripts?.[s] || '').includes('cargo'), `publish_script_compiles_rust:${s}`);
18
18
  }
19
19
  // 2) The published binary is JS; no prebuilt native artifact is shipped or required.
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { spawnSync } from 'node:child_process';
7
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
8
+ export { assertGate, emitGate, root };
9
+ export function makeSearchVisibilityFixture(name = 'search-visibility', options = {}) {
10
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), `sks-${name}-`));
11
+ fs.mkdirSync(path.join(dir, 'public'), { recursive: true });
12
+ fs.mkdirSync(path.join(dir, 'bin'), { recursive: true });
13
+ const packageJson = {
14
+ name: `sks-${name}-fixture`,
15
+ version: '0.0.0',
16
+ description: options.description || 'Source-backed search visibility fixture for Sneakoscope gates.',
17
+ keywords: ['sneakoscope', 'search-visibility'],
18
+ repository: { type: 'git', url: 'https://example.test/repo.git' },
19
+ homepage: 'https://example.test/',
20
+ bugs: { url: 'https://example.test/issues' },
21
+ bin: { [`${name}-fixture`]: 'bin/fixture.js' },
22
+ scripts: { build: 'node -e "console.log(1)"' },
23
+ };
24
+ fs.writeFileSync(path.join(dir, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\n`);
25
+ fs.writeFileSync(path.join(dir, 'bin', 'fixture.js'), '#!/usr/bin/env node\nconsole.log("fixture")\n');
26
+ fs.writeFileSync(path.join(dir, 'README.md'), `# ${options.title || 'Search Visibility Fixture'}\n\nInstall with \`npm i\` and run \`${name}-fixture\`.\n`);
27
+ fs.writeFileSync(path.join(dir, 'public', 'index.html'), options.html || [
28
+ '<!doctype html>',
29
+ '<html lang="en">',
30
+ '<head><meta charset="utf-8"><title>Search Visibility Fixture</title><meta name="description" content="A source-backed fixture."></head>',
31
+ '<body><main><h1>Search Visibility Fixture</h1><p>Official source-backed content.</p><a href="/docs">Docs</a></main></body>',
32
+ '</html>',
33
+ '',
34
+ ].join('\n'));
35
+ return dir;
36
+ }
37
+ export function runSks(args, options = {}) {
38
+ const result = spawnSync(process.execPath, [path.join(root, 'dist', 'bin', 'sks.js'), ...args], {
39
+ cwd: root,
40
+ encoding: 'utf8',
41
+ stdio: 'pipe',
42
+ env: {
43
+ ...process.env,
44
+ SKS_REQUIRE_ZELLIJ: '0',
45
+ SKS_TEST_REAL_IMAGEGEN: '0',
46
+ SKS_REAL_IMAGEGEN: '0',
47
+ SKS_REQUIRE_REAL_COMPUTER_USE: '0',
48
+ ...(options.env || {}),
49
+ },
50
+ timeout: options.timeoutMs || 120000,
51
+ });
52
+ if (!options.allowFailure) {
53
+ assertGate(result.status === 0, `sks command failed: ${args.join(' ')}`, {
54
+ status: result.status,
55
+ stdout: result.stdout,
56
+ stderr: result.stderr,
57
+ });
58
+ }
59
+ return result;
60
+ }
61
+ export function runSksJson(args, options = {}) {
62
+ const result = runSks(args, options);
63
+ const parsed = parseJsonOutput(result.stdout);
64
+ assertGate(parsed && typeof parsed === 'object', `sks command did not emit JSON: ${args.join(' ')}`, {
65
+ status: result.status,
66
+ stdout: result.stdout,
67
+ stderr: result.stderr,
68
+ });
69
+ return { result, json: parsed };
70
+ }
71
+ export function parseJsonOutput(stdout) {
72
+ const text = String(stdout || '').trim();
73
+ if (!text)
74
+ return null;
75
+ try {
76
+ return JSON.parse(text);
77
+ }
78
+ catch { }
79
+ const start = text.indexOf('{');
80
+ const end = text.lastIndexOf('}');
81
+ if (start >= 0 && end > start) {
82
+ try {
83
+ return JSON.parse(text.slice(start, end + 1));
84
+ }
85
+ catch { }
86
+ }
87
+ return null;
88
+ }
89
+ export function missionDir(missionId, baseRoot = root) {
90
+ return path.join(baseRoot, '.sneakoscope', 'missions', missionId);
91
+ }
92
+ export function artifactPath(missionId, rel, baseRoot = root) {
93
+ return path.join(missionDir(missionId, baseRoot), rel.startsWith('search-visibility/') ? rel : path.join('search-visibility', rel));
94
+ }
95
+ export function readJsonFile(file) {
96
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
97
+ }
98
+ export function assertMissionArtifact(missionId, rel, baseRoot = root) {
99
+ const file = rel === 'completion-proof.json' || rel.endsWith('-gate.json')
100
+ ? path.join(missionDir(missionId, baseRoot), rel)
101
+ : artifactPath(missionId, rel, baseRoot);
102
+ assertGate(fs.existsSync(file), `missing mission artifact: ${rel}`, { missionId, file });
103
+ return readJsonFile(file);
104
+ }
105
+ export function listSourceFiles(dir) {
106
+ const out = [];
107
+ walk(dir, out);
108
+ return out
109
+ .map((file) => path.relative(dir, file).split(path.sep).join('/'))
110
+ .filter((rel) => !rel.startsWith('.sneakoscope/'))
111
+ .sort();
112
+ }
113
+ function walk(dir, out) {
114
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
115
+ if (entry.name === '.sneakoscope' || entry.name === 'node_modules' || entry.name === '.git')
116
+ continue;
117
+ const full = path.join(dir, entry.name);
118
+ if (entry.isDirectory())
119
+ walk(full, out);
120
+ else if (entry.isFile())
121
+ out.push(full);
122
+ }
123
+ }
124
+ //# sourceMappingURL=search-visibility-gate-lib.js.map
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, assertMissionArtifact, emitGate, makeSearchVisibilityFixture, runSksJson } from './search-visibility-gate-lib.js';
4
+ const fixture = makeSearchVisibilityFixture('seo-audit');
5
+ const { json } = runSksJson(['seo-geo-optimizer', 'audit', '--mode', 'seo', '--root', fixture, '--target', 'website', '--framework', 'static', '--url', 'https://example.test', '--offline', '--json']);
6
+ assertGate(json.route === '$SEO-GEO-OPTIMIZER' && json.mission_id, 'seo audit must create a unified optimizer mission', json);
7
+ const inventory = assertMissionArtifact(json.mission_id, 'site-inventory.json', fixture);
8
+ const findings = assertMissionArtifact(json.mission_id, 'seo-findings.json', fixture);
9
+ const gate = assertMissionArtifact(json.mission_id, 'seo-gate.json', fixture);
10
+ const proof = assertMissionArtifact(json.mission_id, 'completion-proof.json', fixture);
11
+ assertGate(inventory.detected_adapter.adapterId === 'static-site', 'fixture should detect static-site adapter', inventory.detected_adapter);
12
+ assertGate(Array.isArray(findings.findings) && findings.findings.every((finding) => finding.evidence?.length > 0), 'SEO findings must be atomic and evidence-backed', findings);
13
+ assertGate(gate.route === '$SEO-GEO-OPTIMIZER' && gate.completion_proof.endsWith('/completion-proof.json'), 'seo gate must link completion proof', gate);
14
+ assertGate(proof.schema === 'sks.completion-proof.v1' && proof.route === '$SEO-GEO-OPTIMIZER', 'completion proof must retain unified route identity', proof);
15
+ emitGate('seo:audit-fixture', { mission_id: json.mission_id, findings: findings.findings.length });
16
+ //# sourceMappingURL=seo-audit-fixture-check.js.map
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, assertMissionArtifact, emitGate, makeSearchVisibilityFixture, runSksJson } from './search-visibility-gate-lib.js';
6
+ const fixture = makeSearchVisibilityFixture('seo-locale');
7
+ fs.mkdirSync(path.join(fixture, 'public', 'fr'), { recursive: true });
8
+ fs.writeFileSync(path.join(fixture, 'public', 'fr', 'index.html'), '<!doctype html><html lang="fr"><head><title>FR</title><link rel="canonical" href="/fr"></head><body><h1>FR</h1></body></html>\n');
9
+ const audit = runSksJson(['seo-geo-optimizer', 'audit', '--mode', 'seo', '--root', fixture, '--target', 'website', '--framework', 'static', '--url', 'https://example.test', '--offline', '--json']).json;
10
+ const canonical = assertMissionArtifact(audit.mission_id, 'canonical-map.json', fixture);
11
+ const locale = assertMissionArtifact(audit.mission_id, 'locale-graph.json', fixture);
12
+ const sitemap = assertMissionArtifact(audit.mission_id, 'sitemap-audit.json', fixture);
13
+ const findings = assertMissionArtifact(audit.mission_id, 'seo-findings.json', fixture);
14
+ assertGate(/not guaranteed/i.test(canonical.warning), 'canonical report must avoid search-engine selection guarantees', canonical);
15
+ assertGate(locale.checks.self_hreflang_verified === false && Array.isArray(locale.unverified), 'locale report must separate unverified hreflang checks', locale);
16
+ assertGate(sitemap.indexing_guarantee === false, 'sitemap report must not claim indexing guarantee', sitemap);
17
+ assertGate(findings.findings.some((finding) => finding.ruleId.includes('canonical') || finding.category === 'locale'), 'fixture should produce canonical or locale findings', findings);
18
+ emitGate('seo:canonical-sitemap-locale', { mission_id: audit.mission_id });
19
+ //# sourceMappingURL=seo-canonical-locale-check.js.map
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate, runSks, runSksJson } from './search-visibility-gate-lib.js';
4
+ const commands = runSksJson(['commands', '--json']).json;
5
+ assertGate(commands.commands.some((row) => row.name === 'seo-geo-optimizer' && /unified SEO\/GEO optimizer/i.test(row.description)), 'commands --json must expose seo-geo-optimizer');
6
+ assertGate(!commands.commands.some((row) => row.name === 'seo' || row.name === 'geo'), 'commands --json must not expose split seo/geo command surfaces');
7
+ const optimizerUsage = runSks(['usage', 'seo-geo-optimizer']);
8
+ assertGate(/sks seo-geo-optimizer \[seo\|geo\] doctor\|audit\|plan\|apply\|verify\|status\|rollback\|fixture/.test(optimizerUsage.stdout), 'usage seo-geo-optimizer must expose unified lifecycle');
9
+ const doctor = runSksJson(['seo-geo-optimizer', 'doctor', '--mode', 'seo', '--json']).json;
10
+ assertGate(doctor.route === '$SEO-GEO-OPTIMIZER' && doctor.schema === 'sks.search-visibility.doctor-command.v1', 'optimizer seo doctor must preserve unified route identity', doctor);
11
+ const invalid = runSks(['seo-geo-optimizer', 'nonsense-subcommand'], { allowFailure: true });
12
+ assertGate(invalid.status === 2 && /Usage: sks seo-geo-optimizer/.test(invalid.stderr), 'invalid optimizer subcommand must exit 2 with usage', {
13
+ status: invalid.status,
14
+ stdout: invalid.stdout,
15
+ stderr: invalid.stderr,
16
+ });
17
+ emitGate('seo:cli-blackbox', { adapter: doctor.adapter, confidence: doctor.confidence });
18
+ //# sourceMappingURL=seo-cli-blackbox-check.js.map
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate, importDist, root } from './sks-1-18-gate-lib.js';
4
+ const registryMod = await importDist('core/feature-registry.js');
5
+ const registry = await registryMod.buildFeatureRegistry({ root });
6
+ const byId = new Map(registry.features.map((feature) => [feature.id, feature]));
7
+ for (const id of ['cli-seo-geo-optimizer', 'route-seo-geo-optimizer']) {
8
+ const feature = byId.get(id);
9
+ assertGate(feature, `feature missing: ${id}`);
10
+ assertGate(feature.fixture?.status === 'pass', `feature fixture must pass: ${id}`, feature);
11
+ assertGate(feature.fixture?.quality !== 'static_contract', `SEO/GEO feature must not rely on static contract: ${id}`, feature.fixture);
12
+ assertGate(['runtime_verified', 'runtime_mock_verified'].includes(feature.fixture?.quality), `SEO/GEO fixture quality must be runtime-backed: ${id}`, feature.fixture);
13
+ }
14
+ const selftest = registryMod.buildAllFeaturesSelftest(registry, {});
15
+ const runtimeCheck = selftest.checks.find((check) => check.id === 'runtime_routes_not_static_contract');
16
+ assertGate(runtimeCheck?.ok === true, 'runtime route static-contract guard must pass', runtimeCheck);
17
+ emitGate('seo-geo:feature-fixture-quality', { features: 2 });
18
+ //# sourceMappingURL=seo-geo-feature-fixture-quality-check.js.map
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate, importDist } from './sks-1-18-gate-lib.js';
4
+ const routes = await importDist('core/routes.js');
5
+ const commandFor = (prompt) => routes.routePrompt(prompt)?.command;
6
+ assertGate(commandFor('$SEO-GEO-OPTIMIZER improve AI answer visibility') === '$SEO-GEO-OPTIMIZER', 'explicit optimizer should route to unified route');
7
+ assertGate(commandFor('Generative Engine Optimization crawler policy audit') === '$SEO-GEO-OPTIMIZER', 'generative engine optimization should route to unified optimizer');
8
+ assertGate(commandFor('SEO audit canonical sitemap metadata') === '$SEO-GEO-OPTIMIZER', 'SEO intent should route to unified optimizer');
9
+ assertGate(commandFor('fix GeoIP regional redirect bug') !== '$SEO-GEO-OPTIMIZER', 'GeoIP/geolocation request must not route to optimizer');
10
+ assertGate(commandFor('map coordinates and location permission issue') !== '$SEO-GEO-OPTIMIZER', 'location permission request must not route to optimizer');
11
+ emitGate('seo-geo:geo-disambiguation');
12
+ //# sourceMappingURL=seo-geo-geo-disambiguation-check.js.map
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, assertMissionArtifact, emitGate, makeSearchVisibilityFixture, runSksJson } from './search-visibility-gate-lib.js';
6
+ const fixture = makeSearchVisibilityFixture('unsupported-claims', {
7
+ description: 'Guarantees top rank and AI citation for every site.',
8
+ });
9
+ fs.appendFileSync(path.join(fixture, 'README.md'), '\nWe guarantee rank #1, traffic lift, and AI answer citation.\n');
10
+ const seo = runSksJson(['seo-geo-optimizer', 'audit', '--mode', 'seo', '--root', fixture, '--target', 'package', '--offline', '--json'], { allowFailure: true }).json;
11
+ const geo = runSksJson(['seo-geo-optimizer', 'audit', '--mode', 'geo', '--root', fixture, '--target', 'package', '--offline', '--json'], { allowFailure: true }).json;
12
+ const seoGate = assertMissionArtifact(seo.mission_id, 'seo-gate.json', fixture);
13
+ const geoGate = assertMissionArtifact(geo.mission_id, 'geo-gate.json', fixture);
14
+ const claims = assertMissionArtifact(geo.mission_id, 'claim-evidence-ledger.json', fixture);
15
+ assertGate(seoGate.ok === false && seoGate.unsupported_claims.length > 0, 'SEO gate must reject unsupported ranking/traffic/citation guarantees', seoGate);
16
+ assertGate(geoGate.ok === false && claims.claims.some((claim) => claim.safe_to_publish === false), 'GEO gate must reject unsupported AI citation claims', { geoGate, claims });
17
+ emitGate('seo-geo:no-unsupported-ranking-claims', { seo_mission: seo.mission_id, geo_mission: geo.mission_id });
18
+ //# sourceMappingURL=seo-geo-no-unsupported-ranking-claims-check.js.map
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate, runSksJson } from './search-visibility-gate-lib.js';
4
+ const seo = runSksJson(['run', '$SEO-GEO-OPTIMIZER SEO audit this fixture', '--execute', '--json']).json;
5
+ const geo = runSksJson(['run', '$SEO-GEO-OPTIMIZER Generative Engine Optimization audit AI search visibility', '--execute', '--json']).json;
6
+ const seoText = JSON.stringify(seo);
7
+ const geoText = JSON.stringify(geo);
8
+ assertGate(/\$SEO-GEO-OPTIMIZER/.test(seoText) && /sks seo-geo-optimizer/.test(seoText) && /--mode seo/.test(seoText), 'sks run --execute must preserve unified optimizer route and execute seo mode path', seo);
9
+ assertGate(/\$SEO-GEO-OPTIMIZER/.test(geoText) && /sks seo-geo-optimizer/.test(geoText) && /--mode geo/.test(geoText), 'sks run --execute must preserve unified optimizer route and execute geo mode path', geo);
10
+ assertGate(!/\$AutoResearch/.test(seoText) && !/\$AutoResearch/.test(geoText), 'SEO/GEO route identity must not collapse into AutoResearch', { seo, geo });
11
+ emitGate('seo-geo:route-identity', { seo_status: seo.status, geo_status: geo.status });
12
+ //# sourceMappingURL=seo-geo-route-identity-check.js.map