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
@@ -8,10 +8,12 @@ export class CodexAppServerV2Client {
8
8
  cwd;
9
9
  timeoutMs;
10
10
  currentTimeProvider;
11
+ approvalPolicy;
11
12
  child = null;
12
13
  nextId = 1;
13
14
  pending = new Map();
14
15
  notifications = [];
16
+ listeners = new Set();
15
17
  stdoutBuffer = '';
16
18
  stderr = '';
17
19
  constructor(options) {
@@ -21,6 +23,7 @@ export class CodexAppServerV2Client {
21
23
  this.cwd = options.cwd || process.cwd();
22
24
  this.timeoutMs = Number(options.timeoutMs || 20_000);
23
25
  this.currentTimeProvider = options.currentTimeProvider || (() => new Date());
26
+ this.approvalPolicy = options.approvalPolicy || {};
24
27
  }
25
28
  async initialize() {
26
29
  this.start();
@@ -36,18 +39,58 @@ export class CodexAppServerV2Client {
36
39
  optOutNotificationMethods: []
37
40
  }
38
41
  });
39
- this.notify('notifications/initialized', {});
42
+ this.notify('initialized', {});
40
43
  return result;
41
44
  }
42
45
  async listThreads(params = {}) {
43
46
  return await this.request('thread/list', normalizeThreadListParams(params));
44
47
  }
48
+ async startThread(params = {}) {
49
+ return await this.request('thread/start', params);
50
+ }
51
+ async resumeThread(params = {}) {
52
+ return await this.request('thread/resume', params);
53
+ }
45
54
  async searchThreads(searchTerm, params = {}) {
46
55
  return await this.listThreads({ ...params, searchTerm });
47
56
  }
48
57
  async readThread(threadId, includeTurns = false) {
49
58
  return await this.request('thread/read', { threadId, includeTurns });
50
59
  }
60
+ async startTurn(params = {}) {
61
+ return await this.request('turn/start', params);
62
+ }
63
+ async steerTurn(params = {}) {
64
+ return await this.request('turn/steer', params);
65
+ }
66
+ async interruptTurn(params = {}) {
67
+ return await this.request('turn/interrupt', params);
68
+ }
69
+ onEvent(listener) {
70
+ this.listeners.add(listener);
71
+ return () => this.listeners.delete(listener);
72
+ }
73
+ waitForNotification(methods, timeoutMs = this.timeoutMs) {
74
+ const expected = new Set(Array.isArray(methods) ? methods.map(String) : [String(methods)]);
75
+ return new Promise((resolve, reject) => {
76
+ const timer = setTimeout(() => {
77
+ dispose();
78
+ reject(new Error(`Timed out waiting for app-server notification: ${Array.from(expected).join(', ')}`));
79
+ }, timeoutMs);
80
+ timer.unref?.();
81
+ const dispose = this.onEvent((event) => {
82
+ if (event && expected.has(String(event.method || ''))) {
83
+ clearTimeout(timer);
84
+ dispose();
85
+ resolve(event);
86
+ }
87
+ });
88
+ });
89
+ }
90
+ async waitForTurnCompletion(threadId, turnId, timeoutMs = this.timeoutMs) {
91
+ const expected = turnId ? ['turn/completed', 'thread/closed', 'thread/status/changed'] : ['turn/completed', 'thread/closed'];
92
+ return await this.waitForNotification(expected, timeoutMs);
93
+ }
51
94
  start() {
52
95
  if (this.child)
53
96
  return;
@@ -107,7 +150,14 @@ export class CodexAppServerV2Client {
107
150
  void this.respondToServerRequest(message);
108
151
  }
109
152
  else {
110
- this.notifications.push({ ...message, received_at: nowIso() });
153
+ const event = { ...message, received_at: nowIso() };
154
+ this.notifications.push(event);
155
+ for (const listener of this.listeners) {
156
+ try {
157
+ listener(event);
158
+ }
159
+ catch { }
160
+ }
111
161
  }
112
162
  }
113
163
  }
@@ -119,6 +169,38 @@ export class CodexAppServerV2Client {
119
169
  this.write({ jsonrpc: '2.0', id, result: currentTimeResponse(this.currentTimeProvider()) });
120
170
  return;
121
171
  }
172
+ if (method === 'item/commandExecution/requestApproval' || method === 'commandExecution/requestApproval') {
173
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.commandExecution?.(message.params) || { decision: 'cancel' } });
174
+ return;
175
+ }
176
+ if (method === 'item/fileChange/requestApproval' || method === 'fileChange/requestApproval') {
177
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.fileChange?.(message.params) || { decision: 'cancel' } });
178
+ return;
179
+ }
180
+ if (method === 'item/permissions/requestApproval' || method === 'permissions/requestApproval') {
181
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.permissions?.(message.params) || { permissions: { network: { enabled: false }, fileSystem: { read: [], write: [], entries: [] } }, scope: 'turn', strictAutoReview: true } });
182
+ return;
183
+ }
184
+ if (method === 'item/tool/requestUserInput') {
185
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.toolRequestUserInput?.(message.params) || { answers: {} } });
186
+ return;
187
+ }
188
+ if (method === 'item/tool/call') {
189
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.dynamicToolCall?.(message.params) || { contentItems: [], success: false } });
190
+ return;
191
+ }
192
+ if (method === 'mcpServer/elicitation/request') {
193
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.mcpElicitation?.(message.params) || { contentItems: [], success: false } });
194
+ return;
195
+ }
196
+ if (method === 'attestation/generate') {
197
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.attestation?.(message.params) || { decision: 'cancel' } });
198
+ return;
199
+ }
200
+ if (method === 'account/chatgptAuthTokens/refresh') {
201
+ this.write({ jsonrpc: '2.0', id, result: this.approvalPolicy.chatgptAuthTokensRefresh?.(message.params) || { ok: false } });
202
+ return;
203
+ }
122
204
  this.write({
123
205
  jsonrpc: '2.0',
124
206
  id,
@@ -182,6 +264,8 @@ export async function createCodexAppServerV2Client(options = {}) {
182
264
  clientOptions.timeoutMs = options.timeoutMs;
183
265
  if (options.currentTimeProvider !== undefined)
184
266
  clientOptions.currentTimeProvider = options.currentTimeProvider;
267
+ if (options.approvalPolicy !== undefined)
268
+ clientOptions.approvalPolicy = options.approvalPolicy;
185
269
  return {
186
270
  client: new CodexAppServerV2Client(clientOptions),
187
271
  runtimeIdentity: runtime.identity
@@ -27,22 +27,44 @@ export async function runFakeCodexSdkTask(input) {
27
27
  }
28
28
  function fakeStructuredOutput(input) {
29
29
  if (input.outputSchemaId === GPT_FINAL_ARBITER_RESULT_SCHEMA_ID) {
30
- const unsafe = /\b(truncate|delete all|drop table|credential)\b/i.test(input.prompt || '');
30
+ const prompt = String(input.prompt || '');
31
+ const leanEnabled = /\b(Lean review|Lean Engineering Policy|sks\.lean-engineering-policy)\b/i.test(prompt);
32
+ const unsafe = /\b(truncate|delete all|drop table|credential|delete validation|validation removed|path traversal|sql injection|secret leak)\b/i.test(prompt);
33
+ const overbuild = leanEnabled ? classifyLeanOverbuild(prompt) : null;
34
+ const status = unsafe ? 'rejected' : overbuild ? 'needs_more_work' : 'approved';
35
+ const leanStatus = unsafe ? 'rejected' : overbuild ? 'needs_more_work' : 'pass';
36
+ const blockers = unsafe ? ['unsafe_candidate_patch'] : overbuild?.blockers || [];
37
+ const findings = unsafe
38
+ ? [{ id: 'unsafe-candidate', severity: 'high', summary: 'unsafe candidate rejected' }]
39
+ : overbuild ? overbuild.findings : [];
31
40
  return {
32
41
  schema: GPT_FINAL_ARBITER_RESULT_SCHEMA_ID,
33
- status: unsafe ? 'rejected' : 'approved',
42
+ status,
34
43
  summary: unsafe
35
44
  ? 'Fake Codex SDK GPT final arbiter rejected an unsafe candidate for hermetic verification.'
36
- : 'Fake Codex SDK GPT final arbiter approved the candidate for hermetic verification.',
37
- gpt_review_findings: unsafe ? [{ id: 'unsafe-candidate', severity: 'high', summary: 'unsafe candidate rejected' }] : [],
38
- accepted_patch_envelopes: unsafe ? [] : [],
45
+ : overbuild
46
+ ? 'Fake Codex SDK GPT final arbiter requested a leaner candidate for hermetic verification.'
47
+ : 'Fake Codex SDK GPT final arbiter approved the candidate for hermetic verification.',
48
+ gpt_review_findings: findings,
49
+ accepted_patch_envelopes: status === 'approved' ? [] : [],
39
50
  modified_patch_envelopes: [],
40
- rejected_patch_envelopes: unsafe ? [{ id: 'unsafe-candidate', summary: 'unsafe candidate', patch_envelope_json: '{}' }] : [],
41
- required_followup_work: unsafe ? [{ id: 'unsafe_candidate_patch', severity: 'high', summary: 'unsafe_candidate_patch' }] : [],
51
+ rejected_patch_envelopes: status === 'rejected' ? [{ id: blockers[0] || 'rejected-candidate', summary: blockers[0] || 'rejected candidate', patch_envelope_json: '{}' }] : [],
52
+ required_followup_work: blockers.map((blocker) => ({ id: blocker, severity: unsafe ? 'high' : 'medium', summary: blocker })),
42
53
  verification_plan: ['schema validation', 'local collaboration final gate'],
43
54
  rollback_notes: [],
44
- blockers: unsafe ? ['unsafe_candidate_patch'] : [],
45
- confidence: unsafe ? 'medium' : 'high'
55
+ blockers,
56
+ lean_review: {
57
+ status: leanStatus,
58
+ selected_rung: unsafe ? 'unknown' : overbuild?.selected_rung || 'minimal-custom',
59
+ unnecessary_files: [],
60
+ unnecessary_dependencies: overbuild?.unnecessary_dependencies || [],
61
+ unnecessary_abstractions: overbuild?.unnecessary_abstractions || [],
62
+ fallback_findings: unsafe ? ['unsafe_candidate_patch'] : overbuild?.fallback_findings || [],
63
+ root_cause_review: overbuild?.root_cause_review || [],
64
+ verification_minimum_present: !unsafe && !/\b(missing runnable check|no runnable check)\b/i.test(prompt),
65
+ net_lines: null
66
+ },
67
+ confidence: unsafe || overbuild ? 'medium' : 'high'
46
68
  };
47
69
  }
48
70
  return {
@@ -56,4 +78,40 @@ function fakeStructuredOutput(input) {
56
78
  blockers: []
57
79
  };
58
80
  }
81
+ function classifyLeanOverbuild(prompt) {
82
+ if (/\b(existing helper reimplementation|same helper reimplementation|reimplement existing helper)\b/i.test(prompt)) {
83
+ return leanFinding('reuse_existing_helper', 'reuse-existing', 'Candidate reimplements an existing helper instead of reusing the repository authority.', {
84
+ root_cause_review: ['reuse existing helper or fix the common helper once']
85
+ });
86
+ }
87
+ if (/\b(new dependency|dependency bloat|native platform instead of dependency)\b/i.test(prompt)) {
88
+ return leanFinding('unnecessary_dependency', 'stdlib', 'Candidate adds a dependency where stdlib or platform support is sufficient.', {
89
+ unnecessary_dependencies: ['unjustified dependency']
90
+ });
91
+ }
92
+ if (/\b(one implementation factory|single implementation factory|one implementation interface)\b/i.test(prompt)) {
93
+ return leanFinding('single_impl_abstraction', 'minimal-custom', 'Candidate adds an abstraction without a second implementation or real variation axis.', {
94
+ unnecessary_abstractions: ['single implementation factory/interface']
95
+ });
96
+ }
97
+ if (/\b(hidden mock fallback|silent mock fallback|fixture fallback)\b/i.test(prompt)) {
98
+ return leanFinding('hidden_fallback', 'minimal-custom', 'Candidate hides a production failure behind a mock or fixture fallback.', {
99
+ fallback_findings: ['hidden mock fallback']
100
+ });
101
+ }
102
+ if (/\b(caller duplicate guard|duplicate caller guard|symptom patch)\b/i.test(prompt)) {
103
+ return leanFinding('root_cause_missing', 'minimal-custom', 'Candidate patches a caller symptom instead of the shared root cause.', {
104
+ root_cause_review: ['move duplicated guard to the shared root-cause helper']
105
+ });
106
+ }
107
+ return null;
108
+ }
109
+ function leanFinding(id, selectedRung, summary, extra = {}) {
110
+ return {
111
+ selected_rung: selectedRung,
112
+ blockers: [id],
113
+ findings: [{ id, severity: 'medium', summary }],
114
+ ...extra
115
+ };
116
+ }
59
117
  //# sourceMappingURL=codex-fake-sdk-adapter.js.map
@@ -37,6 +37,7 @@ export async function runWithCodexReliabilityShield(input, runAttempt) {
37
37
  break;
38
38
  }
39
39
  const blockers = attempts.flatMap((attempt) => attempt.blockers);
40
+ const modelCapacityRetryCount = attempts.filter((attempt) => attempt.model_capacity_error && attempt.retryable).length;
40
41
  const report = {
41
42
  schema: CODEX_RELIABILITY_SHIELD_SCHEMA,
42
43
  generated_at: nowIso(),
@@ -52,6 +53,8 @@ export async function runWithCodexReliabilityShield(input, runAttempt) {
52
53
  heartbeat_count: attempts.reduce((sum, attempt) => sum + attempt.heartbeat_count, 0),
53
54
  repaired_tool_result_count: attempts.reduce((sum, attempt) => sum + attempt.repaired_tool_result_count, 0),
54
55
  no_duplicate_streamed_output: attempts.slice(0, -1).every((attempt) => attempt.meaningful_event_count === 0),
56
+ model_capacity_retry_count: modelCapacityRetryCount,
57
+ selected_model_capacity_fallback: selectedAttempt > 1 && modelCapacityRetryCount > 0,
55
58
  blockers
56
59
  };
57
60
  return {
@@ -61,24 +64,27 @@ export async function runWithCodexReliabilityShield(input, runAttempt) {
61
64
  }
62
65
  export function evaluateCodexReliabilityAttempt(result, events, policy, attempt) {
63
66
  const meaningful = events.filter(isMeaningfulEvent);
64
- const fatal = hasFatalError(result, events);
67
+ const modelCapacity = isCodexModelCapacityError(result, events);
68
+ const fatal = !modelCapacity && hasFatalError(result, events);
65
69
  const idle = hasIdleTimeout(events, policy.idleTimeoutMs);
66
70
  const empty = events.length === 0 || (!String(result.finalResponse || '').trim() && meaningful.length === 0);
67
71
  const partial = meaningful.length > 0 && !result.structuredOutput;
68
72
  const blockers = [];
69
73
  let retryable = false;
70
74
  let retryReason = null;
71
- if (idle && partial)
75
+ if (modelCapacity)
76
+ blockers.push('codex_model_capacity_unavailable');
77
+ if (!modelCapacity && idle && partial)
72
78
  blockers.push('codex_reliability_idle_after_partial_output');
73
- if (partial && !idle)
79
+ if (!modelCapacity && partial && !idle)
74
80
  blockers.push('codex_reliability_partial_output_without_structured_result');
75
81
  if (fatal)
76
82
  blockers.push('codex_reliability_fatal_error_no_retry');
77
- if (!fatal && idle && meaningful.length === 0) {
83
+ if (!modelCapacity && !fatal && idle && meaningful.length === 0) {
78
84
  retryable = true;
79
85
  retryReason = 'stream_idle_before_meaningful_event';
80
86
  }
81
- else if (!fatal && empty) {
87
+ else if (!modelCapacity && !fatal && empty) {
82
88
  retryable = true;
83
89
  retryReason = 'empty_sdk_result_before_meaningful_event';
84
90
  }
@@ -92,11 +98,26 @@ export function evaluateCodexReliabilityAttempt(result, events, policy, attempt)
92
98
  retry_reason: retryReason,
93
99
  idle_timeout: idle,
94
100
  fatal_error: fatal,
101
+ model_capacity_error: modelCapacity,
102
+ capacity_fallback_hint: null,
95
103
  repaired_tool_result_count: 0,
96
104
  heartbeat_count: 0,
97
105
  blockers
98
106
  };
99
107
  }
108
+ export function isCodexModelCapacityError(result, events) {
109
+ const text = [
110
+ String(result.finalResponse || ''),
111
+ ...(Array.isArray(result.blockers) ? result.blockers : []),
112
+ ...events.map((event) => [
113
+ event?.error?.message,
114
+ event?.message,
115
+ event?.item?.text,
116
+ event?.raw?.failed_event?.error?.message
117
+ ].filter(Boolean).join('\n'))
118
+ ].join('\n');
119
+ return /selected model is at capacity|model(?:\s+[\w.-]+)?\s+is\s+at\s+capacity|try a different model|capacity(?:\s+is)?\s+exhausted|temporarily at capacity/i.test(text);
120
+ }
100
121
  export function repairToolCallSequence(events) {
101
122
  const repaired = [...events];
102
123
  const openToolCalls = new Set();
@@ -118,6 +118,8 @@ export async function runCodexTask(input) {
118
118
  patchEnvelopePath,
119
119
  blockers: finalBlockers,
120
120
  reliabilityShield: adapterResult?.reliabilityShield || null,
121
+ capacityFallback: adapterResult?.reliabilityShield?.selected_model_capacity_fallback === true,
122
+ modelCapacityRetryCount: Number(adapterResult?.reliabilityShield?.model_capacity_retry_count || 0),
121
123
  ultraRouterDecision: routerDecision,
122
124
  outputSchemaId: task.outputSchemaId,
123
125
  finalResponse: adapterResult?.finalResponse || '',
@@ -146,7 +148,11 @@ export async function runCodexTask(input) {
146
148
  result,
147
149
  capability: capability,
148
150
  sandbox,
149
- envProof: runtime.env.proof,
151
+ envProof: {
152
+ ...runtime.env.proof,
153
+ capacity_fallback_selected: result.capacityFallback === true,
154
+ model_capacity_retry_count: result.modelCapacityRetryCount
155
+ },
150
156
  config: runtime.config,
151
157
  reliabilityShield: adapterResult?.reliabilityShield || null,
152
158
  routerDecision: routerDecision,
@@ -5,6 +5,7 @@ import { evaluateLocalCollaborationFinalGate, resolveLocalCollaborationPolicy }
5
5
  import { runCodexTask } from './codex-control-plane.js';
6
6
  import { GPT_FINAL_ARBITER_INPUT_SCHEMA, GPT_FINAL_ARBITER_RESULT_SCHEMA_ID, gptFinalArbiterResultSchema, normalizeGptFinalArbiterResult } from './gpt-final-review-schema.js';
7
7
  import { compressGptFinalContext } from './gpt-final-context-compressor.js';
8
+ import { leanEngineeringCompactText } from '../lean-engineering-policy.js';
8
9
  export const GPT_FINAL_ARBITER_RUN_SCHEMA = 'sks.gpt-final-arbiter-run.v1';
9
10
  export async function runGptFinalArbiter(input, opts = {}) {
10
11
  const started = Date.now();
@@ -145,7 +146,9 @@ function buildArbiterPrompt(input, compressed) {
145
146
  return [
146
147
  'You are the GPT Final Arbiter for an SKS local collaboration run.',
147
148
  'Local model outputs are drafts only. Review the proof pack, candidate diff, patch envelopes, verification results, side effects, mutation ledger, and rollback plan.',
148
- 'Approve or modify only when the candidate is safe and supported. Reject unsafe local patches. Return only the requested structured JSON schema.',
149
+ leanEngineeringCompactText(),
150
+ 'Lean review: check for reused helpers before reimplementation, unjustified dependencies, one-implementation factories/interfaces, hidden mock or provider fallbacks, duplicated caller guards instead of root-cause fixes, forwarding-only files, missing runnable checks for non-trivial logic, and safety/validation removal disguised as simplification.',
151
+ 'Approve or modify only when the candidate is safe, supported, and no more complex than the request requires. Reject unsafe local patches. Return only the requested structured JSON schema.',
149
152
  JSON.stringify({
150
153
  route: input.route,
151
154
  mission_id: input.mission_id,
@@ -1,3 +1,4 @@
1
+ import { LEAN_SOLUTION_RUNGS } from '../lean-engineering-policy.js';
1
2
  export const GPT_FINAL_ARBITER_RESULT_SCHEMA_ID = 'sks.gpt-final-arbiter-result.v1';
2
3
  export const GPT_FINAL_ARBITER_INPUT_SCHEMA = 'sks.gpt-final-arbiter-input.v1';
3
4
  const reviewItemSchema = {
@@ -20,6 +21,32 @@ const patchDecisionSchema = {
20
21
  },
21
22
  additionalProperties: false
22
23
  };
24
+ const leanReviewSchema = {
25
+ type: 'object',
26
+ required: [
27
+ 'status',
28
+ 'selected_rung',
29
+ 'unnecessary_files',
30
+ 'unnecessary_dependencies',
31
+ 'unnecessary_abstractions',
32
+ 'fallback_findings',
33
+ 'root_cause_review',
34
+ 'verification_minimum_present',
35
+ 'net_lines'
36
+ ],
37
+ properties: {
38
+ status: { enum: ['pass', 'modified', 'rejected', 'needs_more_work'] },
39
+ selected_rung: { enum: [...LEAN_SOLUTION_RUNGS, 'unknown'] },
40
+ unnecessary_files: { type: 'array', items: { type: 'string' } },
41
+ unnecessary_dependencies: { type: 'array', items: { type: 'string' } },
42
+ unnecessary_abstractions: { type: 'array', items: { type: 'string' } },
43
+ fallback_findings: { type: 'array', items: { type: 'string' } },
44
+ root_cause_review: { type: 'array', items: { type: 'string' } },
45
+ verification_minimum_present: { type: 'boolean' },
46
+ net_lines: { type: ['number', 'null'] }
47
+ },
48
+ additionalProperties: false
49
+ };
23
50
  export const gptFinalArbiterResultSchema = {
24
51
  type: 'object',
25
52
  required: [
@@ -34,6 +61,7 @@ export const gptFinalArbiterResultSchema = {
34
61
  'verification_plan',
35
62
  'rollback_notes',
36
63
  'blockers',
64
+ 'lean_review',
37
65
  'confidence'
38
66
  ],
39
67
  properties: {
@@ -48,6 +76,7 @@ export const gptFinalArbiterResultSchema = {
48
76
  verification_plan: { type: 'array', items: { type: 'string' } },
49
77
  rollback_notes: { type: 'array', items: { type: 'string' } },
50
78
  blockers: { type: 'array', items: { type: 'string' } },
79
+ lean_review: leanReviewSchema,
51
80
  confidence: { enum: ['low', 'medium', 'high'] }
52
81
  },
53
82
  additionalProperties: false
@@ -66,6 +95,7 @@ export function normalizeGptFinalArbiterResult(value) {
66
95
  verification_plan: stringArray(value?.verification_plan),
67
96
  rollback_notes: stringArray(value?.rollback_notes),
68
97
  blockers: stringArray(value?.blockers),
98
+ lean_review: normalizeLeanReview(value?.lean_review, status),
69
99
  confidence: normalizeConfidence(value?.confidence)
70
100
  };
71
101
  }
@@ -107,6 +137,34 @@ function patchDecisionItems(value) {
107
137
  function stringArray(value) {
108
138
  return Array.isArray(value) ? value.map((entry) => String(entry || '').trim()).filter(Boolean) : [];
109
139
  }
140
+ function normalizeLeanReview(value, arbiterStatus) {
141
+ const raw = typeof value === 'object' && value !== null ? value : {};
142
+ return {
143
+ status: normalizeLeanReviewStatus(raw.status, arbiterStatus),
144
+ selected_rung: normalizeLeanRung(raw.selected_rung),
145
+ unnecessary_files: stringArray(raw.unnecessary_files),
146
+ unnecessary_dependencies: stringArray(raw.unnecessary_dependencies),
147
+ unnecessary_abstractions: stringArray(raw.unnecessary_abstractions),
148
+ fallback_findings: stringArray(raw.fallback_findings),
149
+ root_cause_review: stringArray(raw.root_cause_review),
150
+ verification_minimum_present: typeof raw.verification_minimum_present === 'boolean' ? raw.verification_minimum_present : arbiterStatus === 'approved' || arbiterStatus === 'modified',
151
+ net_lines: Number.isFinite(Number(raw.net_lines)) ? Number(raw.net_lines) : null
152
+ };
153
+ }
154
+ function normalizeLeanReviewStatus(value, arbiterStatus) {
155
+ if (value === 'pass' || value === 'modified' || value === 'rejected' || value === 'needs_more_work')
156
+ return value;
157
+ if (arbiterStatus === 'approved')
158
+ return 'pass';
159
+ if (arbiterStatus === 'modified')
160
+ return 'modified';
161
+ if (arbiterStatus === 'rejected')
162
+ return 'rejected';
163
+ return 'needs_more_work';
164
+ }
165
+ function normalizeLeanRung(value) {
166
+ return typeof value === 'string' && [...LEAN_SOLUTION_RUNGS, 'unknown'].includes(value) ? value : 'unknown';
167
+ }
110
168
  function normalizeSeverity(value) {
111
169
  return value === 'low' || value === 'medium' || value === 'high' ? value : 'medium';
112
170
  }
@@ -56,7 +56,7 @@ export function defaultModelCallBudget(provider) {
56
56
  const text = String(provider || '');
57
57
  if (text === 'local-llm' || text === 'ollama')
58
58
  return envInt('SKS_LOCAL_LLM_MAX_PARALLEL_REQUESTS', 4);
59
- return envInt('SKS_REMOTE_API_PARALLEL_BUDGET', 12);
59
+ return envInt('SKS_REMOTE_API_PARALLEL_BUDGET', 3);
60
60
  }
61
61
  class ModelCallSemaphoreImpl {
62
62
  provider;
@@ -1,4 +1,5 @@
1
1
  import { PACKAGE_VERSION, nowIso, sha256 } from '../fsx.js';
2
+ import { leanPolicyReference } from '../lean-engineering-policy.js';
2
3
  import { canonicalSkillName } from './skill-name-canonicalizer.js';
3
4
  export const CORE_SKILL_TEMPLATE_VERSION = 'sks-core-skill-template.v1';
4
5
  export const CORE_SKILL_MANAGED_BEGIN = '<!-- BEGIN SKS IMMUTABLE CORE SKILL -->';
@@ -83,6 +84,26 @@ const CORE_SKILL_DEFINITIONS = [
83
84
  when: 'Use when deeper local context or directory-specific recall is required.',
84
85
  evidence: '.sneakoscope/context/AGENTS.generated.md and managed memory artifacts.',
85
86
  fallback: 'Preserve user content and skip directories that cannot be safely updated.'
87
+ },
88
+ {
89
+ id: 'sks-core-search-visibility-core',
90
+ canonical_name: 'search-visibility-core',
91
+ display_name: 'search-visibility-core',
92
+ route: '$SEO-GEO-OPTIMIZER',
93
+ purpose: 'provide the shared search-visibility kernel for SEO and GEO audit, plan, explicit apply, verify, rollback, and Completion Proof without ranking, traffic, or citation guarantees.',
94
+ when: 'Use when $SEO-GEO-OPTIMIZER or sks seo-geo-optimizer needs typed mode-specific evidence, gates, artifacts, or safe mutation planning.',
95
+ evidence: 'search-visibility artifacts, seo-gate.json or geo-gate.json, mutation-plan.json, rollback-manifest.json, verification-report.json, and completion-proof.json.',
96
+ fallback: 'Keep unsupported frameworks plan-only, record unverified production/browser/Search Console/AI citation outcomes, and never invent guarantee evidence.'
97
+ },
98
+ {
99
+ id: 'sks-core-seo-geo-optimizer',
100
+ canonical_name: 'seo-geo-optimizer',
101
+ display_name: 'seo-geo-optimizer',
102
+ route: '$SEO-GEO-OPTIMIZER',
103
+ purpose: 'run the unified SEO/GEO optimizer route for Search Engine Optimization and Generative Engine Optimization, not geolocation or GeoIP, with no ranking, traffic, indexing, rich-result, answer inclusion, or AI citation guarantee.',
104
+ when: 'Use the CLI entrypoint: sks seo-geo-optimizer doctor|audit|plan|apply|verify|status|rollback|fixture --mode seo|geo for SEO and GEO visibility work.',
105
+ evidence: 'site inventory, route graph, seo-findings.json or geo-findings.json, claim-evidence-ledger.json, ai-crawler-policy.json, llms-txt-plan.json, verification report, route gate, and Completion Proof.',
106
+ fallback: 'Do not auto-allow training crawlers or fabricate AI answer visibility; mark missing live outcomes unverified and keep recovery on the unified optimizer route.'
86
107
  }
87
108
  ];
88
109
  export function coreSkillDefinitions() {
@@ -97,6 +118,7 @@ export function renderCoreSkillTemplate(name) {
97
118
  const skill = CORE_SKILL_DEFINITIONS.find((entry) => entry.canonical_name === canonical);
98
119
  if (!skill)
99
120
  throw new Error(`Unknown SKS core skill: ${name}`);
121
+ const lean = leanPolicyReference();
100
122
  return [
101
123
  '---',
102
124
  `name: ${skill.display_name}`,
@@ -117,6 +139,7 @@ export function renderCoreSkillTemplate(name) {
117
139
  `Command: ${skill.route}`,
118
140
  `Purpose: ${skill.purpose}`,
119
141
  `Use when: ${skill.when}`,
142
+ `Lean policy: ${lean.policy_id}/${lean.policy_hash}`,
120
143
  `Proof paths: ${skill.evidence}`,
121
144
  'Safety rules: preserve user-authored skills, keep route state bounded, and stop on hard blockers instead of fabricating fallback behavior.',
122
145
  `Failure recovery: ${skill.fallback}`,
@@ -1,4 +1,4 @@
1
- import { TRUST_VALIDATE_BENCH_COMMAND, benchRoot, runCoreBench } from '../bench.js';
1
+ import { TRUST_VALIDATE_BENCH_COMMAND, benchRoot, runCoreBench, runLeanPolicyBench } from '../bench.js';
2
2
  import { runProcess } from '../fsx.js';
3
3
  import { flag, readFlagValue } from './command-utils.js';
4
4
  export async function benchCommand(args = []) {
@@ -18,9 +18,18 @@ export async function benchCommand(args = []) {
18
18
  }
19
19
  if (action === 'route-fixtures')
20
20
  return commandBench('sks.route-fixture-bench.v1', ['all-features', 'selftest', '--mock', '--execute-fixtures', '--strict-artifacts', '--json'], args);
21
+ if (action === 'lean-policy') {
22
+ const report = await runLeanPolicyBench(root);
23
+ if (!report.ok)
24
+ process.exitCode = 1;
25
+ if (flag(args, '--json'))
26
+ return console.log(JSON.stringify(report, null, 2));
27
+ console.log(`lean-policy: ${report.ok ? 'pass' : 'blocked'}`);
28
+ return report;
29
+ }
21
30
  if (action === 'blackbox')
22
31
  return commandBench('sks.blackbox-bench.v1', ['blackbox-matrix-placeholder'], args);
23
- console.error('Usage: sks bench core|route-fixtures|blackbox|trust-kernel [--json] [--iterations N]');
32
+ console.error('Usage: sks bench core|route-fixtures|lean-policy|blackbox|trust-kernel [--json] [--iterations N]');
24
33
  process.exitCode = 2;
25
34
  }
26
35
  async function commandBench(schema, commandArgs, args = []) {
@@ -4,18 +4,50 @@ import { flag } from './command-utils.js';
4
4
  export async function codeStructureCommand(sub, args = []) {
5
5
  const action = sub || 'scan';
6
6
  if (action !== 'scan') {
7
- console.error('Usage: sks code-structure scan [--json]');
7
+ console.error('Usage: sks code-structure scan [--json] [--all] [--changed [ref|file[,file]]] [--changed-since <ref>]');
8
8
  process.exitCode = 1;
9
9
  return;
10
10
  }
11
11
  const root = await sksRoot();
12
- const report = await scanCodeStructure(root, { includeOk: flag(args, '--all') });
12
+ const changedArg = valueAfter(args, '--changed');
13
+ const changedSince = valueAfter(args, '--changed-since');
14
+ const changedArgLooksLikeFiles = Boolean(changedArg && (changedArg.includes(',')
15
+ || changedArg.includes('/')
16
+ || changedArg.includes('\\')
17
+ || /\.(js|ts|tsx|jsx|mjs|cjs|json|md|rs|toml)$/i.test(changedArg)));
18
+ const changedFiles = changedArg && changedArgLooksLikeFiles
19
+ ? changedArg.split(',').map((file) => file.trim()).filter(Boolean)
20
+ : [];
21
+ const report = await scanCodeStructure(root, {
22
+ includeOk: flag(args, '--all'),
23
+ changed: flag(args, '--changed') ? (changedFiles.length ? true : changedArg || true) : false,
24
+ changedSince,
25
+ changedFiles
26
+ });
13
27
  if (flag(args, '--json'))
14
28
  return console.log(JSON.stringify(report, null, 2));
15
29
  console.log('SKS Code Structure');
30
+ if (report.changed_scope?.mode !== 'full') {
31
+ console.log(`Changed scope: ${report.changed_scope.changed_files.length} files, ${report.changed_scope.net_lines} net lines`);
32
+ console.log(`Lean semantic review: ${report.semantic_review?.status || 'unknown'}`);
33
+ }
16
34
  for (const file of report.files.slice(0, 20))
17
35
  console.log(`${file.status} ${file.line_count} ${file.path}`);
18
36
  if (report.remaining_risks.length)
19
37
  console.log(`Risks: ${report.remaining_risks.join(', ')}`);
38
+ if (report.semantic_review?.findings?.length) {
39
+ for (const finding of report.semantic_review.findings.slice(0, 8)) {
40
+ console.log(`Lean ${finding.severity}: ${finding.file ? `${finding.file}: ` : ''}${finding.summary}`);
41
+ }
42
+ }
43
+ }
44
+ function valueAfter(args, name) {
45
+ const index = args.indexOf(name);
46
+ if (index === -1)
47
+ return null;
48
+ const value = args[index + 1];
49
+ if (!value || String(value).startsWith('--'))
50
+ return null;
51
+ return String(value);
20
52
  }
21
53
  //# sourceMappingURL=code-structure-command.js.map