sneakoscope 6.5.1 → 6.7.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 (91) hide show
  1. package/README.md +9 -7
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/cli/command-manifest-lite.js +2 -2
  5. package/dist/cli/command-registry.js +2 -2
  6. package/dist/config/skills-manifest.json +62 -62
  7. package/dist/core/agents/agent-effort-policy.js +13 -7
  8. package/dist/core/agents/agent-orchestrator.js +0 -6
  9. package/dist/core/agents/agent-output-validator.js +2 -1
  10. package/dist/core/agents/agent-patch-queue-store.js +0 -8
  11. package/dist/core/agents/agent-worker-pipeline.js +12 -6
  12. package/dist/core/agents/native-worker-backend-router.js +1 -1
  13. package/dist/core/bench.js +1 -1
  14. package/dist/core/codex/official-goal-mode.js +4 -2
  15. package/dist/core/codex-control/codex-control-proof.js +1 -0
  16. package/dist/core/codex-control/codex-fake-sdk-adapter.js +1 -1
  17. package/dist/core/codex-control/codex-lb-launch-recovery.js +7 -3
  18. package/dist/core/codex-control/codex-sdk-adapter.js +8 -7
  19. package/dist/core/codex-control/codex-sdk-config-policy.js +4 -24
  20. package/dist/core/codex-control/codex-sdk-env-policy.js +396 -11
  21. package/dist/core/codex-control/codex-task-runner.js +112 -57
  22. package/dist/core/codex-control/gpt-final-arbiter.js +1 -2
  23. package/dist/core/codex-control/python-codex-sdk-adapter.js +38 -15
  24. package/dist/core/codex-native/core-skill-manifest.js +4 -7
  25. package/dist/core/codex-runtime/resolve-codex-runtime.js +199 -0
  26. package/dist/core/commands/command-utils.js +2 -2
  27. package/dist/core/commands/eval-command.js +19 -2
  28. package/dist/core/commands/goal-command.js +37 -86
  29. package/dist/core/commands/naruto-command.js +189 -135
  30. package/dist/core/evaluation.js +83 -21
  31. package/dist/core/feature-fixtures.js +4 -3
  32. package/dist/core/fsx.js +141 -12
  33. package/dist/core/goal-workflow.js +71 -140
  34. package/dist/core/hooks-runtime/hook-io.js +2 -2
  35. package/dist/core/hooks-runtime.js +228 -50
  36. package/dist/core/init/skills.js +7 -6
  37. package/dist/core/init.js +52 -33
  38. package/dist/core/lean-engineering-policy.js +25 -23
  39. package/dist/core/locks/file-lock.js +5 -4
  40. package/dist/core/managed-assets/managed-assets-manifest.js +1 -1
  41. package/dist/core/mission.js +99 -3
  42. package/dist/core/pipeline-internals/runtime-core.js +67 -95
  43. package/dist/core/pipeline-internals/runtime-gates.js +25 -6
  44. package/dist/core/proof/fake-real-proof-policy.js +32 -9
  45. package/dist/core/proof/route-proof-gate.js +49 -1
  46. package/dist/core/provider/model-router.js +2 -0
  47. package/dist/core/questions.js +31 -5
  48. package/dist/core/recallpulse.js +1 -1
  49. package/dist/core/release/canonical-test-proof.js +135 -0
  50. package/dist/core/release/release-closure-contract.js +1 -0
  51. package/dist/core/release/release-closure-validation.js +25 -12
  52. package/dist/core/release/release-closure.js +34 -5
  53. package/dist/core/release/release-gate-contract.js +0 -3
  54. package/dist/core/release/release-gate-dag.js +4 -2
  55. package/dist/core/release/release-real-contract.js +41 -2
  56. package/dist/core/retention.js +90 -1
  57. package/dist/core/routes/dollar-manifest-lite.js +1 -1
  58. package/dist/core/routes.js +17 -18
  59. package/dist/core/safety/ssot-guard.js +1 -54
  60. package/dist/core/stop-gate/stop-gate-check.js +0 -14
  61. package/dist/core/stop-gate/stop-gate-writer.js +0 -4
  62. package/dist/core/subagents/agent-catalog.js +28 -5
  63. package/dist/core/subagents/model-policy.js +52 -11
  64. package/dist/core/subagents/naruto-proof-projection.js +40 -9
  65. package/dist/core/subagents/official-subagent-preparation.js +340 -52
  66. package/dist/core/subagents/official-subagent-prompt.js +16 -6
  67. package/dist/core/subagents/official-subagent-runner.js +122 -11
  68. package/dist/core/subagents/subagent-evidence.js +44 -8
  69. package/dist/core/subagents/wave-lifecycle.js +238 -0
  70. package/dist/core/verification/machine-feedback.js +39 -19
  71. package/dist/core/version.js +1 -1
  72. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +194 -24
  73. package/dist/native/sks-menubar/Sources/ProcessClient.swift +47 -5
  74. package/dist/scripts/architecture-guard-check.js +1 -9
  75. package/dist/scripts/canonical-test-runner.js +51 -8
  76. package/dist/scripts/codex-0144-binary-identity-check.js +10 -4
  77. package/dist/scripts/codex-0144-policy-check.js +4 -0
  78. package/dist/scripts/codex-sdk-real-smoke-check.js +20 -2
  79. package/dist/scripts/current-command-surface-check.js +1 -1
  80. package/dist/scripts/docs-truthfulness-check.js +4 -2
  81. package/dist/scripts/gate-policy-audit-check.js +7 -1
  82. package/dist/scripts/loop-directive-check-lib.js +14 -13
  83. package/dist/scripts/product-design-plugin-routing-check.js +4 -9
  84. package/dist/scripts/release-affected-selector-check.js +7 -1
  85. package/dist/scripts/release-check-stamp.js +151 -18
  86. package/dist/scripts/release-dynamic-presets-check.js +5 -2
  87. package/dist/scripts/release-real-check.js +21 -3
  88. package/package.json +1 -1
  89. package/release-gates.v2.json +19 -20
  90. package/schemas/codex/agent-result.schema.json +4 -0
  91. package/dist/core/loops/goal-to-loop-compat.js +0 -22
@@ -1158,9 +1158,6 @@ function enforceWorkerQualityProtocolForSlice(result, slice) {
1158
1158
  const kind = String(slice?.work_item_kind || result?.work_item_kind || '').toLowerCase();
1159
1159
  const text = [kind, slice?.id, slice?.title].join(' ').toLowerCase();
1160
1160
  const blockers = [];
1161
- if ((kind === 'bugfix' || /\b(fix|bug|regression|broken|failure|crash|error)\b|버그|회귀/.test(text)) && !validRegressionProof(result.regression_proof || firstEnvelopeField(result, 'regression_proof'))) {
1162
- blockers.push('tdd_evidence_missing');
1163
- }
1164
1161
  if ((kind === 'conflict_resolution' || /\b(repair|conflict|rebase|rollback)\b|수리|충돌/.test(text)) && !(result.repair_hypothesis || firstEnvelopeField(result, 'repair_hypothesis'))) {
1165
1162
  blockers.push('repair_without_hypothesis');
1166
1163
  }
@@ -1176,9 +1173,6 @@ function enforceWorkerQualityProtocolForSlice(result, slice) {
1176
1173
  function firstEnvelopeField(result, field) {
1177
1174
  return (Array.isArray(result?.patch_envelopes) ? result.patch_envelopes : []).find((envelope) => envelope?.[field])?.[field] || null;
1178
1175
  }
1179
- function validRegressionProof(proof) {
1180
- return Boolean(proof && proof.failed_before === true && proof.passed_after === true && String(proof.test_file || '').trim());
1181
- }
1182
1176
  function normalizePathList(values) {
1183
1177
  return (Array.isArray(values) ? values : []).map((file) => String(file || '').replace(/\\/g, '/').replace(/^\.\/+/, '').replace(/\/+$/, '')).filter(Boolean);
1184
1178
  }
@@ -62,7 +62,8 @@ export const AGENT_RESULT_RUNTIME_SCHEMA = {
62
62
  required: ['status', 'checks'],
63
63
  properties: {
64
64
  status: { type: 'string' },
65
- checks: { type: 'array', items: { type: 'string' } }
65
+ checks: { type: 'array', items: { type: 'string' } },
66
+ reason: { type: 'string', minLength: 1 }
66
67
  },
67
68
  additionalProperties: false
68
69
  },
@@ -64,7 +64,6 @@ export class PersistentAgentPatchQueueStore {
64
64
  ...(impact.cochange_required?.length && !cochangeAck ? [`impact_scan_cochange_missing:${impact.cochange_required.slice(0, 5).join(',')}`] : []),
65
65
  ...((diffQuality.errors || []).map((issue) => `diff_quality:${issue}`)),
66
66
  ...(feedback.ok === false ? ['machine_feedback_failed'] : []),
67
- ...(isBugfixKind(context.work_item_kind, envelope.task_slice_id) && !validRegressionProof(envelope.regression_proof || context.regression_proof) ? ['tdd_evidence_missing'] : []),
68
67
  ...(isRepairKind(context.work_item_kind, envelope.task_slice_id) && !(envelope.repair_hypothesis || context.repair_hypothesis) ? ['repair_without_hypothesis'] : [])
69
68
  ];
70
69
  return {
@@ -145,17 +144,10 @@ export class PersistentAgentPatchQueueStore {
145
144
  await appendJsonlMany(path.join(this.artifactDir, AGENT_PATCH_QUEUE_EVENTS_ARTIFACT), events.filter(Boolean));
146
145
  }
147
146
  }
148
- function isBugfixKind(kind, id) {
149
- const text = `${String(kind || '')} ${String(id || '')}`.toLowerCase();
150
- return /\b(bugfix|fix|bug|regression|broken|failure|crash|error)\b|버그|회귀/.test(text);
151
- }
152
147
  function isRepairKind(kind, id) {
153
148
  const text = `${String(kind || '')} ${String(id || '')}`.toLowerCase();
154
149
  return /\b(conflict_resolution|repair|conflict|rebase|rollback)\b|수리|충돌/.test(text);
155
150
  }
156
- function validRegressionProof(proof) {
157
- return Boolean(proof && proof.failed_before === true && proof.passed_after === true && String(proof.test_file || '').trim());
158
- }
159
151
  function changedFilesForEnvelope(envelope) {
160
152
  const files = envelope.git_worktree?.changed_files?.length
161
153
  ? envelope.git_worktree.changed_files
@@ -100,17 +100,22 @@ function qualityProtocolBlockers(result) {
100
100
  return [];
101
101
  const kind = String(result.work_item_kind || result.naruto_runtime?.work_item_kind || '').toLowerCase();
102
102
  const text = [kind, result.task_slice_id].join(' ').toLowerCase();
103
- const proof = result.regression_proof || result.patch_envelopes?.find((envelope) => envelope.regression_proof)?.regression_proof || null;
104
103
  const repair = result.repair_hypothesis || result.patch_envelopes?.find((envelope) => envelope.repair_hypothesis)?.repair_hypothesis || null;
105
104
  const blockers = [];
106
- if ((kind === 'bugfix' || /\b(fix|bug|regression|broken|failure|crash|error)\b|버그|회귀/.test(text)) && !validRegressionProof(proof))
107
- blockers.push('tdd_evidence_missing');
105
+ if (!validWriteVerification(result.verification))
106
+ blockers.push('verification_evidence_missing');
108
107
  if ((kind === 'conflict_resolution' || /\b(repair|conflict|rebase|rollback)\b|수리|충돌/.test(text)) && !repair)
109
108
  blockers.push('repair_without_hypothesis');
110
109
  return blockers;
111
110
  }
112
- function validRegressionProof(proof) {
113
- return Boolean(proof && proof.failed_before === true && proof.passed_after === true && String(proof.test_file || '').trim());
111
+ function validWriteVerification(verification) {
112
+ const status = String(verification?.status || '').trim().toLowerCase();
113
+ const checks = Array.isArray(verification?.checks)
114
+ ? verification.checks.map((check) => String(check || '').trim()).filter(Boolean)
115
+ : [];
116
+ if (status === 'passed')
117
+ return checks.length > 0;
118
+ return status === 'not_applicable' && Boolean(String(verification?.reason || '').trim());
114
119
  }
115
120
  export function agentWorkerPipelineContract() {
116
121
  return {
@@ -169,7 +174,8 @@ function isRecord(value) {
169
174
  function normalizeVerification(value) {
170
175
  return {
171
176
  status: String(value?.status || 'not_run'),
172
- checks: Array.isArray(value?.checks) ? value.checks : []
177
+ checks: Array.isArray(value?.checks) ? value.checks : [],
178
+ ...(String(value?.reason || '').trim() ? { reason: String(value.reason).trim() } : {})
173
179
  };
174
180
  }
175
181
  function acceptsNoPatchReadOnlyOrNoop(value) {
@@ -418,7 +418,7 @@ function buildWorkerPrompt(slice) {
418
418
  ? 'Quality gates run before queue acceptance: impact-scan requires cochanged callers for exported signature changes, machine-feedback runs type/lint/related tests, diff-quality blocks dead exports, and compiled mistake rules block repeated mistakes.'
419
419
  : '',
420
420
  write.length
421
- ? 'If this is a bugfix, create a regression test first and include regression_proof with failed_before true and passed_after true. For repair work, include repair_hypothesis before patching.'
421
+ ? 'Every write result must report verification status passed with at least one concrete check, or status not_applicable with a specific reason. For a reproducible bug or changed observable behavior, add the smallest regression check that would catch it. Do not manufacture a dedicated test when a smaller real check is sufficient. For repair work, include repair_hypothesis before patching.'
422
422
  : '',
423
423
  leanEngineeringCompactText(),
424
424
  'Required JSON fields: status, summary, findings, changed_files, patch_envelopes, verification, rollback_notes, blockers.'
@@ -343,7 +343,7 @@ export async function runLeanPolicyBench(root = process.cwd()) {
343
343
  async function fakeGptFinalScenario(candidate, leanEnabled) {
344
344
  const prompt = [
345
345
  leanEnabled ? leanEngineeringCompactText() : 'Baseline implementation context without lean policy.',
346
- leanEnabled ? 'Lean review: evaluate over-build, dependency, fallback, root-cause, and validation safety.' : 'Review only catastrophic safety issues.',
346
+ leanEnabled ? 'Apply the Core Engineering Directive to the candidate and the available evidence.' : 'Review only catastrophic safety issues.',
347
347
  `Candidate: ${candidate}`
348
348
  ].join('\n');
349
349
  const result = await runFakeCodexSdkTask({
@@ -20,7 +20,7 @@ export async function detectOfficialGoalMode(opts = {}) {
20
20
  ok: true,
21
21
  official_goal_available: official,
22
22
  default_enabled: official,
23
- mode: official ? 'official_goal_default' : 'sks_goal_fallback',
23
+ mode: official ? 'official_goal_default' : 'official_goal_unavailable',
24
24
  codex_help_checked: Boolean(helpText),
25
25
  codex_goal_help_checked: Boolean(goalHelpText),
26
26
  codex_features_checked: Boolean(featuresText),
@@ -28,9 +28,11 @@ export async function detectOfficialGoalMode(opts = {}) {
28
28
  codex_goals_feature_enabled: goalsFeature,
29
29
  config_goal_defaults_detected: configDefault,
30
30
  blockers: [],
31
- warnings: official ? [] : ['official_goal_unavailable_using_sks_goal_fallback']
31
+ warnings: official ? [] : ['official_goal_unavailable_no_fallback']
32
32
  };
33
33
  }
34
+ // Capability evidence for non-Goal routes. This records whether the active
35
+ // Codex runtime exposes native Goal; it never creates or controls a goal.
34
36
  export async function writeOfficialGoalModeArtifact(dir, detection) {
35
37
  const artifact = path.join(dir, 'goal-mode-applied.json');
36
38
  await writeJsonAtomic(artifact, detection);
@@ -18,6 +18,7 @@ export async function writeCodexControlProof(root, input) {
18
18
  zellij_pane_id: input.task.zellijPaneId || null,
19
19
  sdk_thread_id: input.result.sdkThreadId,
20
20
  sdk_run_id: input.result.sdkRunId,
21
+ runtime_identity: input.result.runtimeIdentity || null,
21
22
  stream_event_count: input.result.streamEventCount,
22
23
  structured_output_valid: input.result.structuredOutputValid,
23
24
  output_schema_id: input.task.outputSchemaId,
@@ -31,7 +31,7 @@ export async function runFakeCodexSdkTask(input) {
31
31
  function fakeStructuredOutput(input) {
32
32
  if (input.outputSchemaId === GPT_FINAL_ARBITER_RESULT_SCHEMA_ID) {
33
33
  const prompt = String(input.prompt || '');
34
- const leanEnabled = /\b(Lean review|Lean Engineering Policy|sks\.lean-engineering-policy)\b/i.test(prompt);
34
+ const leanEnabled = /\b(Core Engineering Directive|sks\.lean-engineering-policy)\b/i.test(prompt);
35
35
  const unsafe = /\b(truncate|delete all|drop table|credential|delete validation|validation removed|path traversal|sql injection|secret leak)\b/i.test(prompt);
36
36
  const overbuild = leanEnabled ? classifyLeanOverbuild(prompt) : null;
37
37
  const status = unsafe ? 'rejected' : overbuild ? 'needs_more_work' : 'approved';
@@ -46,9 +46,8 @@ export async function inspectCodexLbCliLaunchRecovery(input) {
46
46
  : configLayer(await readText(projectConfigPath, '').catch(() => ''), 'project');
47
47
  const overrides = cliConfigOverrides(args);
48
48
  const environmentSelectsCodexLb = env.SKS_PROVIDER === 'codex-lb' || env.SKS_USE_CODEX_LB === '1';
49
- // Codex CLI options are the final operator intent. They override SKS's
50
- // environment-selected default just as `-c` overrides config.toml.
51
- if (cliSelectsLocalProvider(args) || (overrides.modelProvider && overrides.modelProvider !== 'codex-lb')) {
49
+ // Local-provider CLI options are the final operator intent.
50
+ if (cliSelectsLocalProvider(args)) {
52
51
  return codexLbToolOutputRecoveryNotSelected();
53
52
  }
54
53
  const loadedLayers = [userConfig, profileConfig, projectConfig];
@@ -60,6 +59,11 @@ export async function inspectCodexLbCliLaunchRecovery(input) {
60
59
  if (projectConfig.hasMachineLocalProviderConfig) {
61
60
  return projectProviderConfigBlocked();
62
61
  }
62
+ // Explicit model-provider overrides still win over user/profile defaults,
63
+ // but only after repository-local provider redirects have been rejected.
64
+ if (overrides.modelProvider && overrides.modelProvider !== 'codex-lb') {
65
+ return codexLbToolOutputRecoveryNotSelected();
66
+ }
63
67
  const selectedProvider = overrides.modelProvider
64
68
  ?? (environmentSelectsCodexLb ? 'codex-lb' : null)
65
69
  ?? profileConfig.modelProvider
@@ -5,7 +5,7 @@ import { buildCodexExecutionPolicy, buildCodexSdkConfig } from './codex-sdk-conf
5
5
  import { buildCodexSdkEnv } from './codex-sdk-env-policy.js';
6
6
  import { translateCodexSdkEvent } from './codex-event-translator.js';
7
7
  import { codexTimeoutClassForRoute } from './codex-reliability-shield.js';
8
- import { resolveCodexRuntime } from '../codex-runtime/resolve-codex-runtime.js';
8
+ import { resolveOfficialCodexPackageRuntime } from '../codex-runtime/resolve-codex-runtime.js';
9
9
  import { codexLbToolCatalogPath, ensureCodexLbToolCatalog, isCodexLbGpt56Model } from '../codex-lb/codex-lb-tool-catalog.js';
10
10
  export async function runRealCodexSdkTask(input, policy) {
11
11
  if (codexSdkTurnTimeoutMs(input) <= 0) {
@@ -23,16 +23,14 @@ export async function runRealCodexSdkTask(input, policy) {
23
23
  raw: { aborted: true, hard_deadline_exceeded: true }
24
24
  };
25
25
  }
26
+ const runtime = await resolveCodexSdkRuntime(input);
27
+ if (!runtime.ok || !runtime.identity) {
28
+ throw new Error(`Trusted Codex SDK runtime unavailable: ${runtime.blockers.join(',')}`);
29
+ }
26
30
  const mod = await import('@openai/codex-sdk');
27
31
  const Codex = mod.Codex || mod.default?.Codex || mod.default;
28
32
  if (typeof Codex !== 'function')
29
33
  throw new Error('Codex SDK export Codex not found');
30
- const runtime = await resolveCodexRuntime({
31
- explicitPath: typeof input.requestedScopeContract?.codex_bin === 'string' ? input.requestedScopeContract.codex_bin : null,
32
- requestedBy: 'codex-sdk-adapter'
33
- });
34
- if (!runtime.identity)
35
- throw new Error(`Codex runtime not found: ${runtime.blockers.join(',')}`);
36
34
  const toolCatalog = await prepareCodexLbToolCatalog(input, policy);
37
35
  if (toolCatalog.required && !toolCatalog.ok) {
38
36
  return {
@@ -160,6 +158,9 @@ export async function runRealCodexSdkTask(input, policy) {
160
158
  raw: { item_count: events.filter((event) => String(event?.type || '').startsWith('item.')).length, tool_catalog: toolCatalog }
161
159
  };
162
160
  }
161
+ export async function resolveCodexSdkRuntime(_input) {
162
+ return resolveOfficialCodexPackageRuntime({ requestedBy: 'codex-sdk-adapter' });
163
+ }
163
164
  export function codexSdkRuntimePolicies(input) {
164
165
  const env = buildCodexSdkEnv(input);
165
166
  const config = buildCodexSdkConfig(input);
@@ -3,6 +3,10 @@ export function buildCodexSdkConfig(input) {
3
3
  const model = String(input.model || process.env.SKS_CODEX_MODEL || process.env.CODEX_MODEL || '').trim();
4
4
  const serviceTier = String(input.serviceTier || process.env.SKS_SERVICE_TIER || 'fast');
5
5
  const config = {
6
+ // Internal control-plane work is always native Codex. Ambient proxy
7
+ // credentials are not provider-selection consent.
8
+ model_provider: 'openai',
9
+ forced_login_method: 'chatgpt',
6
10
  service_tier: serviceTier === 'standard' ? 'standard' : 'fast',
7
11
  model_reasoning_effort: String(input.modelReasoningEffort || input.reasoningEffort || process.env.SKS_CODEX_REASONING || process.env.CODEX_MODEL_REASONING_EFFORT || 'medium'),
8
12
  mcp_servers: {},
@@ -20,21 +24,6 @@ export function buildCodexSdkConfig(input) {
20
24
  config.mcp_servers = {};
21
25
  config.sks = { ...config.sks, no_mcp: true };
22
26
  }
23
- const codexLbApiKey = String(process.env.CODEX_LB_API_KEY || '').trim();
24
- const codexLbBaseUrl = normalizeCodexLbBaseUrl(process.env.CODEX_LB_BASE_URL);
25
- if (process.env.SKS_CODEX_LB_AUTOBYPASS !== '1' && codexLbApiKey && codexLbBaseUrl) {
26
- config.model_provider = 'codex-lb';
27
- config.model_providers = {
28
- 'codex-lb': {
29
- name: 'openai',
30
- base_url: codexLbBaseUrl,
31
- wire_api: 'responses',
32
- env_key: 'CODEX_LB_API_KEY',
33
- supports_websockets: true,
34
- requires_openai_auth: true
35
- }
36
- };
37
- }
38
27
  return config;
39
28
  }
40
29
  export function buildCodexExecutionPolicy(input) {
@@ -60,12 +49,3 @@ export function redactCodexSdkConfig(config) {
60
49
  return value;
61
50
  }));
62
51
  }
63
- function normalizeCodexLbBaseUrl(value) {
64
- let host = String(value || '').trim();
65
- if (!host)
66
- return '';
67
- if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(host))
68
- host = `https://${host}`;
69
- host = host.replace(/\/+$/, '');
70
- return /\/backend-api\/codex$/i.test(host) ? host : `${host}/backend-api/codex`;
71
- }