@jinn-network/client 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -1
- package/dist/adapters/mech/adapter.d.ts +19 -1
- package/dist/adapters/mech/adapter.js +130 -14
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +22 -1
- package/dist/adapters/mech/contracts.js +34 -24
- package/dist/adapters/mech/contracts.js.map +1 -1
- package/dist/adapters/mech/safe.d.ts +1 -1
- package/dist/adapters/mech/safe.js +5 -3
- package/dist/adapters/mech/safe.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +6 -1
- package/dist/adapters/mech/types.js.map +1 -1
- package/dist/agent/operator-claude.js +8 -0
- package/dist/agent/operator-claude.js.map +1 -1
- package/dist/api/activity-events-endpoint.d.ts +14 -0
- package/dist/api/activity-events-endpoint.js +59 -0
- package/dist/api/activity-events-endpoint.js.map +1 -0
- package/dist/api/bootstrap-endpoint.d.ts +1 -2
- package/dist/api/bootstrap-endpoint.js +42 -24
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/codex-doctor-endpoint.d.ts +22 -5
- package/dist/api/codex-doctor-endpoint.js +136 -17
- package/dist/api/codex-doctor-endpoint.js.map +1 -1
- package/dist/api/debug-report-endpoint.d.ts +27 -0
- package/dist/api/debug-report-endpoint.js +157 -0
- package/dist/api/debug-report-endpoint.js.map +1 -0
- package/dist/api/gather-status.d.ts +33 -0
- package/dist/api/gather-status.js +211 -26
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/hermes-doctor-endpoint.d.ts +15 -7
- package/dist/api/hermes-doctor-endpoint.js +56 -19
- package/dist/api/hermes-doctor-endpoint.js.map +1 -1
- package/dist/api/launcher-status.d.ts +4 -2
- package/dist/api/launcher-status.js +11 -10
- package/dist/api/launcher-status.js.map +1 -1
- package/dist/api/launcher-tasks.d.ts +1 -1
- package/dist/api/launcher-tasks.js +12 -8
- package/dist/api/launcher-tasks.js.map +1 -1
- package/dist/api/operator-artifacts-endpoint.js +73 -6
- package/dist/api/operator-artifacts-endpoint.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +7 -1
- package/dist/api/portfolio-v0-build.js +6 -2
- package/dist/api/portfolio-v0-build.js.map +1 -1
- package/dist/api/prediction-v1-build.d.ts +6 -0
- package/dist/api/prediction-v1-build.js +3 -1
- package/dist/api/prediction-v1-build.js.map +1 -1
- package/dist/api/server.d.ts +17 -0
- package/dist/api/server.js +40 -1
- package/dist/api/server.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +0 -9
- package/dist/api/setup-endpoints.js +11 -153
- package/dist/api/setup-endpoints.js.map +1 -1
- package/dist/api/solvernets-endpoints.js +30 -63
- package/dist/api/solvernets-endpoints.js.map +1 -1
- package/dist/api/status-build.d.ts +115 -2
- package/dist/api/status-build.js +47 -11
- package/dist/api/status-build.js.map +1 -1
- package/dist/api/status-harness-rollup.d.ts +35 -0
- package/dist/api/status-harness-rollup.js +45 -0
- package/dist/api/status-harness-rollup.js.map +1 -0
- package/dist/api/task-runs-build.d.ts +8 -0
- package/dist/api/task-runs-build.js +5 -1
- package/dist/api/task-runs-build.js.map +1 -1
- package/dist/build-info.json +4 -4
- package/dist/build-meta.json +1 -1
- package/dist/captures/live-publisher.js +24 -4
- package/dist/captures/live-publisher.js.map +1 -1
- package/dist/captures/publish.d.ts +1 -1
- package/dist/chain-read-errors.d.ts +12 -0
- package/dist/chain-read-errors.js +26 -1
- package/dist/chain-read-errors.js.map +1 -1
- package/dist/cli/commands/codedigest-revert-check.d.ts +33 -0
- package/dist/cli/commands/codedigest-revert-check.js +249 -0
- package/dist/cli/commands/codedigest-revert-check.js.map +1 -0
- package/dist/cli/commands/solver-nets.d.ts +1 -0
- package/dist/cli/commands/solver-nets.js +177 -22
- package/dist/cli/commands/solver-nets.js.map +1 -1
- package/dist/cli/commands/solver-plugins-block.d.ts +33 -0
- package/dist/cli/commands/solver-plugins-block.js +118 -0
- package/dist/cli/commands/solver-plugins-block.js.map +1 -0
- package/dist/cli/commands/solver-plugins-feedback.d.ts +72 -0
- package/dist/cli/commands/solver-plugins-feedback.js +262 -0
- package/dist/cli/commands/solver-plugins-feedback.js.map +1 -0
- package/dist/cli/commands/solver-plugins-read.d.ts +54 -0
- package/dist/cli/commands/solver-plugins-read.js +259 -0
- package/dist/cli/commands/solver-plugins-read.js.map +1 -0
- package/dist/cli/commands/solver-plugins.d.ts +35 -0
- package/dist/cli/commands/solver-plugins.js +399 -2
- package/dist/cli/commands/solver-plugins.js.map +1 -1
- package/dist/cli/commands/tasks.js +15 -2
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/task-native-readiness.d.ts +7 -0
- package/dist/cli/task-native-readiness.js +7 -5
- package/dist/cli/task-native-readiness.js.map +1 -1
- package/dist/config.d.ts +183 -232
- package/dist/config.js +232 -107
- package/dist/config.js.map +1 -1
- package/dist/daemon/ai-units-gate.d.ts +54 -0
- package/dist/daemon/ai-units-gate.js +82 -0
- package/dist/daemon/ai-units-gate.js.map +1 -0
- package/dist/daemon/creator.js +13 -0
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +10 -0
- package/dist/daemon/daemon.js +203 -30
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/gate-logger.d.ts +9 -0
- package/dist/daemon/gate-logger.js +2 -0
- package/dist/daemon/gate-logger.js.map +1 -0
- package/dist/daemon/jinn-claim-loop.js +22 -4
- package/dist/daemon/jinn-claim-loop.js.map +1 -1
- package/dist/daemon/readiness-gate.d.ts +1 -4
- package/dist/daemon/readiness-gate.js.map +1 -1
- package/dist/daemon/spend-cap-gate.d.ts +40 -0
- package/dist/daemon/spend-cap-gate.js +46 -0
- package/dist/daemon/spend-cap-gate.js.map +1 -0
- package/dist/dashboard/assets/index-CzKxvMcU.css +32 -0
- package/dist/dashboard/assets/index-yVemxHot.js +351 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/discovery/http.js +328 -1
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.js +42 -4
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +129 -0
- package/dist/discovery/types.js.map +1 -1
- package/dist/discovery/with-fallback.js +27 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +8 -3
- package/dist/earning/bootstrap.js +36 -13
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/safe-adapter.js +23 -11
- package/dist/earning/safe-adapter.js.map +1 -1
- package/dist/earning/types.d.ts +6 -6
- package/dist/earning/viem-clients.d.ts +11 -4
- package/dist/earning/viem-clients.js +14 -5
- package/dist/earning/viem-clients.js.map +1 -1
- package/dist/erc8004/identity.d.ts +19 -3
- package/dist/erc8004/identity.js +38 -11
- package/dist/erc8004/identity.js.map +1 -1
- package/dist/erc8004/index.d.ts +1 -1
- package/dist/erc8004/index.js.map +1 -1
- package/dist/events/types.d.ts +2 -2
- package/dist/harnesses/cost-estimates.d.ts +10 -31
- package/dist/harnesses/cost-estimates.js +11 -43
- package/dist/harnesses/cost-estimates.js.map +1 -1
- package/dist/harnesses/engine/engine.d.ts +28 -4
- package/dist/harnesses/engine/engine.js +103 -17
- package/dist/harnesses/engine/engine.js.map +1 -1
- package/dist/harnesses/engine/persistence.d.ts +21 -4
- package/dist/harnesses/engine/persistence.js +43 -6
- package/dist/harnesses/engine/persistence.js.map +1 -1
- package/dist/harnesses/engine/state.d.ts +9 -0
- package/dist/harnesses/engine/state.js +23 -10
- package/dist/harnesses/engine/state.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/bootstrap.js +4 -2
- package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +1 -1
- package/dist/harnesses/impls/hermes-agent/config-builder.js +4 -2
- package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/harness.d.ts +14 -0
- package/dist/harnesses/impls/hermes-agent/harness.js +16 -2
- package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/prompt.d.ts +6 -6
- package/dist/harnesses/impls/hermes-agent/prompt.js +6 -6
- package/dist/harnesses/impls/learner/adapters/claude-code.d.ts +17 -0
- package/dist/harnesses/impls/learner/adapters/claude-code.js +113 -14
- package/dist/harnesses/impls/learner/adapters/claude-code.js.map +1 -1
- package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +9 -0
- package/dist/harnesses/impls/learner/adapters/codex-code.js +30 -8
- package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
- package/dist/harnesses/impls/learner/harness.d.ts +24 -0
- package/dist/harnesses/impls/learner/harness.js +27 -3
- package/dist/harnesses/impls/learner/harness.js.map +1 -1
- package/dist/harnesses/impls/learner/harvest.d.ts +1 -1
- package/dist/harnesses/impls/learner/harvest.js +23 -5
- package/dist/harnesses/impls/learner/harvest.js.map +1 -1
- package/dist/harnesses/impls/learner/restoration-patch.d.ts +2 -2
- package/dist/harnesses/impls/learner/restoration-patch.js +25 -6
- package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +21 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +74 -5
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +103 -32
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
- package/dist/harnesses/readiness-registry.d.ts +7 -0
- package/dist/harnesses/readiness-registry.js +9 -0
- package/dist/harnesses/readiness-registry.js.map +1 -1
- package/dist/learner/revert-decision.d.ts +59 -0
- package/dist/learner/revert-decision.js +53 -0
- package/dist/learner/revert-decision.js.map +1 -0
- package/dist/learner/revert-stats.d.ts +24 -0
- package/dist/learner/revert-stats.js +44 -0
- package/dist/learner/revert-stats.js.map +1 -0
- package/dist/main.js +177 -104
- package/dist/main.js.map +1 -1
- package/dist/mcp/get-codedigest-reward.d.ts +13 -0
- package/dist/mcp/get-codedigest-reward.js +23 -0
- package/dist/mcp/get-codedigest-reward.js.map +1 -0
- package/dist/mcp/server.js +23 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/observability/debug-report-assemble.d.ts +43 -0
- package/dist/observability/debug-report-assemble.js +80 -0
- package/dist/observability/debug-report-assemble.js.map +1 -0
- package/dist/observability/emit-event.d.ts +9 -2
- package/dist/observability/emit-event.js +36 -2
- package/dist/observability/emit-event.js.map +1 -1
- package/dist/observability/file-logger.d.ts +69 -0
- package/dist/observability/file-logger.js +177 -0
- package/dist/observability/file-logger.js.map +1 -0
- package/dist/observability/redact-secrets.d.ts +65 -0
- package/dist/observability/redact-secrets.js +300 -0
- package/dist/observability/redact-secrets.js.map +1 -0
- package/dist/observability/tar.d.ts +30 -0
- package/dist/observability/tar.js +102 -0
- package/dist/observability/tar.js.map +1 -0
- package/dist/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
- package/dist/plugins/learner/skills/learn/promoter-prompt.md +72 -1
- package/dist/preflight/pidfile-liveness.d.ts +44 -0
- package/dist/preflight/pidfile-liveness.js +103 -0
- package/dist/preflight/pidfile-liveness.js.map +1 -0
- package/dist/preflight/rpc-network.d.ts +40 -0
- package/dist/preflight/rpc-network.js +67 -1
- package/dist/preflight/rpc-network.js.map +1 -1
- package/dist/rpc/transport.d.ts +109 -0
- package/dist/rpc/transport.js +220 -0
- package/dist/rpc/transport.js.map +1 -0
- package/dist/scripts/donation-consumption-acceptance.js +7 -28
- package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
- package/dist/scripts/swe-rebench-v2-pytest-missing.json +16 -0
- package/dist/solver-nets/prediction-operator-ux.d.ts +1 -2
- package/dist/solver-nets/prediction-operator-ux.js +56 -53
- package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
- package/dist/solver-nets/registry.d.ts +19 -1
- package/dist/solver-nets/registry.js +37 -24
- package/dist/solver-nets/registry.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-pool.d.ts +9 -2
- package/dist/solver-types/_swe-rebench-v2-pool.js +15 -20
- package/dist/solver-types/_swe-rebench-v2-pool.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-state.d.ts +15 -0
- package/dist/solver-types/_swe-rebench-v2-state.js +19 -0
- package/dist/solver-types/_swe-rebench-v2-state.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +116 -2
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +296 -21
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2-auto.d.ts +20 -11
- package/dist/solver-types/swe-rebench-v2-auto.js +64 -19
- package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2.d.ts +8 -2
- package/dist/solver-types/swe-rebench-v2.js +127 -11
- package/dist/solver-types/swe-rebench-v2.js.map +1 -1
- package/dist/solvernets/daemon-init.d.ts +1 -1
- package/dist/solvernets/daemon-init.js +19 -4
- package/dist/solvernets/daemon-init.js.map +1 -1
- package/dist/solvernets/launched-record-dispatcher.d.ts +4 -0
- package/dist/solvernets/launched-record-dispatcher.js +10 -4
- package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
- package/dist/solvernets/registry-client-erc8004.js +11 -0
- package/dist/solvernets/registry-client-erc8004.js.map +1 -1
- package/dist/solvernets/store.d.ts +2 -2
- package/dist/spend/ai-units-config.d.ts +39 -0
- package/dist/spend/ai-units-config.js +28 -0
- package/dist/spend/ai-units-config.js.map +1 -0
- package/dist/spend/ai-units.d.ts +89 -0
- package/dist/spend/ai-units.js +156 -0
- package/dist/spend/ai-units.js.map +1 -0
- package/dist/spend/cost-surface-status.d.ts +12 -0
- package/dist/spend/cost-surface-status.js +24 -0
- package/dist/spend/cost-surface-status.js.map +1 -0
- package/dist/spend/credential.d.ts +39 -0
- package/dist/spend/credential.js +71 -0
- package/dist/spend/credential.js.map +1 -0
- package/dist/spend/daemon-config.d.ts +13 -0
- package/dist/spend/daemon-config.js +24 -0
- package/dist/spend/daemon-config.js.map +1 -0
- package/dist/spend/pricing.d.ts +16 -0
- package/dist/spend/pricing.js +26 -0
- package/dist/spend/pricing.js.map +1 -0
- package/dist/spend/record.d.ts +13 -0
- package/dist/spend/record.js +36 -0
- package/dist/spend/record.js.map +1 -0
- package/dist/spend/usage.d.ts +27 -0
- package/dist/spend/usage.js +113 -0
- package/dist/spend/usage.js.map +1 -0
- package/dist/store/store.d.ts +101 -0
- package/dist/store/store.js +304 -4
- package/dist/store/store.js.map +1 -1
- package/dist/trajectory/transcript-parsers/codex-session.d.ts +12 -6
- package/dist/trajectory/transcript-parsers/codex-session.js +114 -13
- package/dist/trajectory/transcript-parsers/codex-session.js.map +1 -1
- package/dist/trajectory/transcript-parsers/types.d.ts +8 -8
- package/dist/trajectory/transcript-session-dirs.d.ts +18 -0
- package/dist/trajectory/transcript-session-dirs.js +85 -0
- package/dist/trajectory/transcript-session-dirs.js.map +1 -0
- package/dist/trajectory/transcript-watcher.d.ts +20 -1
- package/dist/trajectory/transcript-watcher.js +108 -32
- package/dist/trajectory/transcript-watcher.js.map +1 -1
- package/dist/tx-retry.d.ts +25 -0
- package/dist/tx-retry.js +95 -7
- package/dist/tx-retry.js.map +1 -1
- package/dist/types/payloads/portfolio-v0.d.ts +3 -3
- package/dist/types/payloads/prediction-apy-v0.d.ts +3 -3
- package/dist/types/payloads/prediction-v0.d.ts +12 -12
- package/package.json +11 -3
- package/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
- package/plugins/learner/skills/learn/promoter-prompt.md +72 -1
- package/plugins/swe-rebench-v2-diffmin/README.md +10 -9
- package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +1 -1
- package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +15 -10
- package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +10 -12
- package/plugins/swe-rebench-v2-runtime/.claude-plugin/plugin.json +1 -1
- package/plugins/swe-rebench-v2-runtime/.codex-plugin/plugin.json +3 -3
- package/plugins/swe-rebench-v2-runtime/README.md +6 -6
- package/plugins/swe-rebench-v2-runtime/jinn.plugin.json +2 -3
- package/plugins/swe-rebench-v2-runtime/skills/task/SKILL.md +81 -0
- package/dist/dashboard/assets/index-BUlE8F3Y.js +0 -330
- package/dist/dashboard/assets/index-blqc7eqq.css +0 -32
- package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +0 -29
- package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +0 -53
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { emitEnvelope } from '../../errors/envelope.js';
|
|
7
|
+
import { loadConfig } from '../../config.js';
|
|
8
|
+
import { createDiscoveryAPI } from '../../discovery/factory.js';
|
|
9
|
+
import { DiscoveryUnavailableError } from '../../discovery/types.js';
|
|
10
|
+
import { hashImplStateDir } from '../../harnesses/freeze.js';
|
|
11
|
+
import { decideRevert, resolveRevertPolicy, } from '../../learner/revert-decision.js';
|
|
12
|
+
const PRODUCTION_DEPS = {
|
|
13
|
+
buildDiscovery: (configPath) => {
|
|
14
|
+
const config = loadConfig(configPath);
|
|
15
|
+
const chainId = config.network === 'testnet' ? 84532 : 8453;
|
|
16
|
+
// Mirror the daemon's floor wiring (solver-plugins.ts discoveryApiFactory):
|
|
17
|
+
// only rpcUrl + chainId are needed for the http primary; the floor is never
|
|
18
|
+
// routed for getCodeDigestRewards (withFallback propagates the error).
|
|
19
|
+
return createDiscoveryAPI(config.discovery ?? { mode: 'onchain' }, {
|
|
20
|
+
rpcUrl: config.rpcUrl,
|
|
21
|
+
chainId,
|
|
22
|
+
});
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* A commit sha as it appears in the operator's local `improvePromotionsDir`
|
|
27
|
+
* records: 7-64 hex chars (abbreviated through full git object ids). Rejecting
|
|
28
|
+
* anything else BEFORE handing the value to `git archive` closes the
|
|
29
|
+
* argument-injection class where a leading-dash value (`--output=...`,
|
|
30
|
+
* `--remote=...`) is parsed as a git option instead of a tree-ish (#764 M1).
|
|
31
|
+
*/
|
|
32
|
+
const COMMIT_SHA_RE = /^[0-9a-fA-F]{7,64}$/;
|
|
33
|
+
export function isValidCommitSha(sha) {
|
|
34
|
+
return COMMIT_SHA_RE.test(sha);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Hash a commit's tree the way production stamps codeDigest: export the tree
|
|
38
|
+
* with `git archive` (no `.git`) and re-hash with the same deterministic hasher
|
|
39
|
+
* `hashImplStateDir` uses, ignoring `.git`. Returns the `sha256:`-prefixed
|
|
40
|
+
* digest the indexer stores. Keeping this in TS means the Consolidator prompt
|
|
41
|
+
* never reimplements the hasher (the single largest correctness risk, #764).
|
|
42
|
+
*/
|
|
43
|
+
export async function codeDigestForCommit(implStateDir, sha) {
|
|
44
|
+
if (!isValidCommitSha(sha)) {
|
|
45
|
+
throw new Error(`commit sha must be 7-64 hex chars (got "${sha}")`);
|
|
46
|
+
}
|
|
47
|
+
const exportDir = mkdtempSync(join(tmpdir(), 'cd-export-'));
|
|
48
|
+
try {
|
|
49
|
+
// `--` is an end-of-options separator: even though `sha` is shape-validated
|
|
50
|
+
// above, this is defense-in-depth so `git archive` can never parse a
|
|
51
|
+
// leading-dash value as an option (#764 M1, git argument-injection class).
|
|
52
|
+
const tar = execFileSync('git', ['archive', '--', sha], { cwd: implStateDir, maxBuffer: 1 << 28 });
|
|
53
|
+
execFileSync('tar', ['-x', '-C', exportDir], { input: tar });
|
|
54
|
+
const hex = await hashImplStateDir(exportDir, { ignoreRelPaths: ['.git'] });
|
|
55
|
+
return `sha256:${hex}`;
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
rmSync(exportDir, { recursive: true, force: true });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Validate the optional numeric CLI flags (#764 M1). Each is only checked when
|
|
63
|
+
* the operator actually provided it (omitted → policy default applies). Returns
|
|
64
|
+
* the first failure, or `undefined` when all provided flags are in range.
|
|
65
|
+
* - min-samples: finite integer >= 1
|
|
66
|
+
* - window: finite integer >= 1
|
|
67
|
+
* - alpha: finite number in the open interval (0, 1)
|
|
68
|
+
*/
|
|
69
|
+
export function validateNumericFlags(flags) {
|
|
70
|
+
const isPositiveInt = (n) => Number.isFinite(n) && Number.isInteger(n) && n >= 1;
|
|
71
|
+
if (flags.minSamples !== undefined) {
|
|
72
|
+
const n = Number(flags.minSamples);
|
|
73
|
+
if (!isPositiveInt(n)) {
|
|
74
|
+
return { field: 'min-samples', message: `--min-samples must be a finite integer >= 1 (got "${flags.minSamples}")` };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (flags.window !== undefined) {
|
|
78
|
+
const n = Number(flags.window);
|
|
79
|
+
if (!isPositiveInt(n)) {
|
|
80
|
+
return { field: 'window', message: `--window must be a finite integer >= 1 (got "${flags.window}")` };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (flags.alpha !== undefined) {
|
|
84
|
+
const n = Number(flags.alpha);
|
|
85
|
+
if (!Number.isFinite(n) || n <= 0 || n >= 1) {
|
|
86
|
+
return { field: 'alpha', message: `--alpha must be a finite number in (0, 1) (got "${flags.alpha}")` };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
function toAggregate(codeDigest, rows) {
|
|
92
|
+
const found = rows.find((r) => r.codeDigest === codeDigest);
|
|
93
|
+
if (!found)
|
|
94
|
+
return { codeDigest, attempts: 0, passes: 0, passRate: 0 };
|
|
95
|
+
return { codeDigest, attempts: found.attempts, passes: found.passes, passRate: found.passRate };
|
|
96
|
+
}
|
|
97
|
+
export function createCodedigestRevertCheckCommand(deps = PRODUCTION_DEPS) {
|
|
98
|
+
return {
|
|
99
|
+
name: 'codedigest-revert-check',
|
|
100
|
+
summary: 'Decide whether an Improve commit regressed the pass rate (per-codeDigest, #764)',
|
|
101
|
+
helpText: `Usage:
|
|
102
|
+
jinn codedigest-revert-check --code-digest <sha256:...> --parent-code-digest <sha256:...> [options]
|
|
103
|
+
jinn codedigest-revert-check --impl-state-dir <path> --commit <sha> --parent <sha> [options]
|
|
104
|
+
|
|
105
|
+
Options:
|
|
106
|
+
--operator 0x.. Restrict aggregates to attempts this operator Safe claimed
|
|
107
|
+
--solvernet <cid> Restrict to a SolverNet manifest CID
|
|
108
|
+
--min-samples N Minimum indexed attempts per arm (default 30)
|
|
109
|
+
--alpha A Two-sided significance threshold (default 0.05)
|
|
110
|
+
--window N Recent-attempts window per codeDigest (default 200)
|
|
111
|
+
--json Emit JSON (default)
|
|
112
|
+
|
|
113
|
+
Either pass two codeDigests directly, OR pass --impl-state-dir + --commit + --parent
|
|
114
|
+
to have the command export each commit's tree (git archive, no .git) and hash it
|
|
115
|
+
the way production stamps codeDigest — so the caller never reimplements the hasher.
|
|
116
|
+
|
|
117
|
+
Emits a JSON decision: { withCommit, atParent, delta, pValue, significant, recommendRevert, reason }.
|
|
118
|
+
On indexer outage emits recommendRevert=false reason=discovery_unavailable (the Consolidator then skips reverts).`,
|
|
119
|
+
async run(ctx) {
|
|
120
|
+
let parsed;
|
|
121
|
+
try {
|
|
122
|
+
parsed = parseArgs({
|
|
123
|
+
args: ctx.argv,
|
|
124
|
+
options: {
|
|
125
|
+
'code-digest': { type: 'string' },
|
|
126
|
+
'parent-code-digest': { type: 'string' },
|
|
127
|
+
'impl-state-dir': { type: 'string' },
|
|
128
|
+
commit: { type: 'string' },
|
|
129
|
+
parent: { type: 'string' },
|
|
130
|
+
operator: { type: 'string' },
|
|
131
|
+
solvernet: { type: 'string' },
|
|
132
|
+
'min-samples': { type: 'string' },
|
|
133
|
+
alpha: { type: 'string' },
|
|
134
|
+
window: { type: 'string' },
|
|
135
|
+
config: { type: 'string' },
|
|
136
|
+
json: { type: 'boolean', default: true },
|
|
137
|
+
},
|
|
138
|
+
allowPositionals: false,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
emitEnvelope({
|
|
143
|
+
code: 'invalid_invocation',
|
|
144
|
+
message: err instanceof Error ? err.message : String(err),
|
|
145
|
+
exampleCli: 'jinn codedigest-revert-check --code-digest sha256:.. --parent-code-digest sha256:..',
|
|
146
|
+
details: { field: 'flags' },
|
|
147
|
+
}, { writer: ctx.writer, exit: ctx.exit });
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
// Resolve the two codeDigests — either supplied directly or hashed from
|
|
151
|
+
// an impl-state-dir git history.
|
|
152
|
+
let child = parsed.values['code-digest'];
|
|
153
|
+
let parent = parsed.values['parent-code-digest'];
|
|
154
|
+
const implStateDir = parsed.values['impl-state-dir'];
|
|
155
|
+
const commitSha = parsed.values.commit;
|
|
156
|
+
const parentSha = parsed.values.parent;
|
|
157
|
+
if ((!child || !parent) && implStateDir && commitSha && parentSha) {
|
|
158
|
+
// Validate sha shape before any git invocation. A leading-dash value
|
|
159
|
+
// would be parsed by `git archive` as an option, not a tree-ish
|
|
160
|
+
// (#764 M1 argument-injection). Reject with the command's existing
|
|
161
|
+
// invalid_invocation envelope (exit 11) rather than letting it flow
|
|
162
|
+
// into git.
|
|
163
|
+
const badSha = !isValidCommitSha(commitSha)
|
|
164
|
+
? { field: 'commit', value: commitSha }
|
|
165
|
+
: !isValidCommitSha(parentSha)
|
|
166
|
+
? { field: 'parent', value: parentSha }
|
|
167
|
+
: undefined;
|
|
168
|
+
if (badSha) {
|
|
169
|
+
emitEnvelope({
|
|
170
|
+
code: 'invalid_invocation',
|
|
171
|
+
message: `--${badSha.field} sha must be 7-64 hex chars (got "${badSha.value}")`,
|
|
172
|
+
exampleCli: 'jinn codedigest-revert-check --impl-state-dir <path> --commit <sha> --parent <sha>',
|
|
173
|
+
details: { field: badSha.field },
|
|
174
|
+
}, { writer: ctx.writer, exit: ctx.exit });
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
[child, parent] = await Promise.all([
|
|
179
|
+
codeDigestForCommit(implStateDir, commitSha),
|
|
180
|
+
codeDigestForCommit(implStateDir, parentSha),
|
|
181
|
+
]);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
emitEnvelope({
|
|
185
|
+
code: 'invalid_invocation',
|
|
186
|
+
message: `failed to hash commit trees: ${err instanceof Error ? err.message : String(err)}`,
|
|
187
|
+
exampleCli: 'jinn codedigest-revert-check --impl-state-dir <path> --commit <sha> --parent <sha>',
|
|
188
|
+
details: { field: 'impl-state-dir' },
|
|
189
|
+
}, { writer: ctx.writer, exit: ctx.exit });
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (!child || !parent) {
|
|
194
|
+
emitEnvelope({
|
|
195
|
+
code: 'invalid_invocation',
|
|
196
|
+
message: 'provide either --code-digest + --parent-code-digest, or --impl-state-dir + --commit + --parent',
|
|
197
|
+
exampleCli: 'jinn codedigest-revert-check --code-digest sha256:.. --parent-code-digest sha256:..',
|
|
198
|
+
details: { field: 'flags' },
|
|
199
|
+
}, { writer: ctx.writer, exit: ctx.exit });
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// Validate provided numeric flags. `Number('abc')` is NaN, `--alpha 0`
|
|
203
|
+
// silently disables every revert, `--window 0` is nonsensical — reject
|
|
204
|
+
// out-of-range input with the command's existing invalid_invocation
|
|
205
|
+
// envelope (exit 11) rather than letting a bad value flow into the policy.
|
|
206
|
+
const numErr = validateNumericFlags({
|
|
207
|
+
minSamples: parsed.values['min-samples'],
|
|
208
|
+
window: parsed.values.window,
|
|
209
|
+
alpha: parsed.values.alpha,
|
|
210
|
+
});
|
|
211
|
+
if (numErr) {
|
|
212
|
+
emitEnvelope({
|
|
213
|
+
code: 'invalid_invocation',
|
|
214
|
+
message: numErr.message,
|
|
215
|
+
exampleCli: 'jinn codedigest-revert-check --code-digest sha256:.. --parent-code-digest sha256:.. --alpha 0.05 --window 200 --min-samples 30',
|
|
216
|
+
details: { field: numErr.field },
|
|
217
|
+
}, { writer: ctx.writer, exit: ctx.exit });
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const policy = resolveRevertPolicy({
|
|
221
|
+
...(parsed.values['min-samples'] ? { minSamplesPerArm: Number(parsed.values['min-samples']) } : {}),
|
|
222
|
+
...(parsed.values.alpha ? { alpha: Number(parsed.values.alpha) } : {}),
|
|
223
|
+
...(parsed.values.window ? { recentAttemptsWindow: Number(parsed.values.window) } : {}),
|
|
224
|
+
});
|
|
225
|
+
const discovery = deps.buildDiscovery(parsed.values.config);
|
|
226
|
+
let rows;
|
|
227
|
+
try {
|
|
228
|
+
rows = await discovery.getCodeDigestRewards({
|
|
229
|
+
codeDigests: [child, parent],
|
|
230
|
+
window: policy.recentAttemptsWindow,
|
|
231
|
+
...(parsed.values.operator ? { operator: parsed.values.operator } : {}),
|
|
232
|
+
...(parsed.values.solvernet ? { solverNetManifestCid: parsed.values.solvernet } : {}),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
if (err instanceof DiscoveryUnavailableError) {
|
|
237
|
+
ctx.writer.write(JSON.stringify({ recommendRevert: false, reason: 'discovery_unavailable', message: err.message }) + '\n');
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
throw err;
|
|
241
|
+
}
|
|
242
|
+
const decision = decideRevert({ withCommit: toAggregate(child, rows), atParent: toAggregate(parent, rows) }, policy);
|
|
243
|
+
ctx.writer.write(JSON.stringify(decision) + '\n');
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
const command = createCodedigestRevertCheckCommand();
|
|
248
|
+
export default command;
|
|
249
|
+
//# sourceMappingURL=codedigest-revert-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codedigest-revert-check.js","sourceRoot":"","sources":["../../../src/cli/commands/codedigest-revert-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ export declare function resolveValidatePoolInstanceIds(flags: {
|
|
|
4
4
|
instancesFile?: string;
|
|
5
5
|
seedPositive?: boolean;
|
|
6
6
|
knownBad?: boolean;
|
|
7
|
+
knownPytestMissing?: boolean;
|
|
7
8
|
}): string[];
|
|
8
9
|
export declare function describeSweRebenchV2PoolFreshness(opts: {
|
|
9
10
|
stateDir: string;
|
|
@@ -8,9 +8,9 @@ import { emitResult } from '../output.js';
|
|
|
8
8
|
import { loadConfig } from '../../config.js';
|
|
9
9
|
import { buildHarnesses } from '../../harnesses/impls/index.js';
|
|
10
10
|
import { canonicalHarnessName, CLAUDE_CODE_HARNESS, harnessNameMatches } from '../../harnesses/names.js';
|
|
11
|
-
import { loadSolverNets } from '../../solver-nets/registry.js';
|
|
11
|
+
import { findJoinedByName, loadSolverNets, solverTypeFromJoinedContract, } from '../../solver-nets/registry.js';
|
|
12
12
|
import { buildPredictionOperatorStatus, runPredictionSample, } from '../../solver-nets/prediction-operator-ux.js';
|
|
13
|
-
import { EVAL_SEMANTICS_VERSION } from '../../solver-types/_swe-rebench-v2-validated-pool.js';
|
|
13
|
+
import { EVAL_SEMANTICS_VERSION, summarizeValidatedPool, } from '../../solver-types/_swe-rebench-v2-validated-pool.js';
|
|
14
14
|
import { defaultStateDir as sweRebenchV2DefaultStateDir } from '../../solver-types/swe-rebench-v2.js';
|
|
15
15
|
const DEFAULT_CONFIG_PATH = join(homedir(), '.jinn-client', 'config.json');
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
@@ -60,6 +60,9 @@ export function resolveValidatePoolInstanceIds(flags) {
|
|
|
60
60
|
if (flags.knownBad) {
|
|
61
61
|
collected.push(...readInstanceIdFile('swe-rebench-v2-known-bad.json'));
|
|
62
62
|
}
|
|
63
|
+
if (flags.knownPytestMissing) {
|
|
64
|
+
collected.push(...readInstanceIdFile('swe-rebench-v2-pytest-missing.json'));
|
|
65
|
+
}
|
|
63
66
|
return Array.from(new Set(collected));
|
|
64
67
|
}
|
|
65
68
|
// ---------------------------------------------------------------------------
|
|
@@ -135,6 +138,61 @@ function predictionDefault() {
|
|
|
135
138
|
taskGenerator: { enabled: true },
|
|
136
139
|
};
|
|
137
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Project a joined-config entry into the legacy `SolverNetConfig` display
|
|
143
|
+
* shape used by the show/doctor/sample renderers. Mid-migration entries may
|
|
144
|
+
* lack `contract`, in which case `solverType` is reported as `'(unknown)'`.
|
|
145
|
+
*/
|
|
146
|
+
function solverNetFromJoined(net) {
|
|
147
|
+
return {
|
|
148
|
+
enabled: true,
|
|
149
|
+
solverType: solverTypeFromJoinedContract(net) ?? '(unknown)',
|
|
150
|
+
...(net.harness ? { harness: net.harness } : {}),
|
|
151
|
+
plugins: Array.isArray(net.plugins) ? net.plugins : [],
|
|
152
|
+
// Generator ownership is launched-record-driven (issue #421); a joined
|
|
153
|
+
// entry never carries a taskGenerator block of its own.
|
|
154
|
+
taskGenerator: { enabled: false },
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Resolve the SolverNet a read-only subverb (show/doctor/sample) should
|
|
159
|
+
* operate against. Per issue #421 F4:
|
|
160
|
+
*
|
|
161
|
+
* 1. Prefer the still-on-disk legacy file shape (`cfg.solverNets[name]`)
|
|
162
|
+
* when present, so display-time sanitization (e.g. promoting
|
|
163
|
+
* `canonicalPlugin.source` into `plugins[]`) keeps working on configs
|
|
164
|
+
* the operator hasn't rewritten yet. The on-disk file is untouched by
|
|
165
|
+
* the in-memory migration; this branch surfaces what's literally on
|
|
166
|
+
* disk.
|
|
167
|
+
* 2. Otherwise consult `loadConfig().joinedSolverNets` — the canonical
|
|
168
|
+
* view for an operator who has rejoined via the SPA (where there is
|
|
169
|
+
* no legacy on-disk block to fall back to).
|
|
170
|
+
* 3. Otherwise surface `undefined` so the caller can emit
|
|
171
|
+
* `Unknown SolverNet: <name>`. The synthetic `predictionDefault()`
|
|
172
|
+
* shim is gone — it was masking the rejoined-via-SPA case.
|
|
173
|
+
*/
|
|
174
|
+
function resolveReadOnlySolverNet(configPath, cfg, name) {
|
|
175
|
+
// 1. Legacy on-disk file shape (untouched by in-memory migration). Keeps
|
|
176
|
+
// canonicalPlugin promotion working for operators who haven't re-saved
|
|
177
|
+
// their config yet.
|
|
178
|
+
const legacy = cfg.solverNets?.[name];
|
|
179
|
+
if (legacy)
|
|
180
|
+
return legacy;
|
|
181
|
+
// 2. Joined view — the post-SPA-join authoritative shape.
|
|
182
|
+
try {
|
|
183
|
+
const loaded = loadConfig(configPath);
|
|
184
|
+
const joined = findJoinedByName(loaded.joinedSolverNets, name);
|
|
185
|
+
if (joined)
|
|
186
|
+
return solverNetFromJoined(joined);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// If loadConfig fails (malformed schema, missing file when configPath
|
|
190
|
+
// was explicit, etc.), surface `undefined` so the caller reports the
|
|
191
|
+
// unresolved name rather than throwing through to the operator.
|
|
192
|
+
}
|
|
193
|
+
// 3. Nothing matched.
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
138
196
|
function sourceOf(entry) {
|
|
139
197
|
return typeof entry === 'string' ? entry : entry.source;
|
|
140
198
|
}
|
|
@@ -286,6 +344,7 @@ const command = {
|
|
|
286
344
|
jinn solver-nets validate-pool swe-rebench-v2 [--limit <n>] [--force]
|
|
287
345
|
[--instance-id <id>]... [--instances-file <path>]
|
|
288
346
|
[--seed-positive] [--known-bad]
|
|
347
|
+
[--known-pytest-missing]
|
|
289
348
|
Run the gold patch of each pool instance through the eval harness
|
|
290
349
|
and cache which instances are scorable; the generator then posts
|
|
291
350
|
only those. Requires Docker + \`jinn harnesses enable
|
|
@@ -296,8 +355,17 @@ const command = {
|
|
|
296
355
|
--known-bad scopes the run to instances in
|
|
297
356
|
client/scripts/swe-rebench-v2-known-bad.json (gold eval runs;
|
|
298
357
|
expected to record scorable:false).
|
|
358
|
+
--known-pytest-missing scopes the run to instances in
|
|
359
|
+
client/scripts/swe-rebench-v2-pytest-missing.json (Stage-1 #493
|
|
360
|
+
sample of ungradeable:pytest_missing instances; under v4
|
|
361
|
+
EVAL_SEMANTICS_VERSION + the pytest-install guard these should
|
|
362
|
+
re-validate as scorable:true).
|
|
299
363
|
Repeatable --instance-id and --instances-file scope the run to
|
|
300
364
|
a specific subset.
|
|
365
|
+
jinn solver-nets validate-pool-report swe-rebench-v2 [--human|--json]
|
|
366
|
+
Read-only report of the local validated-pool.json: total entries,
|
|
367
|
+
scorable/unscorable counts, histogram by normalised reason, and
|
|
368
|
+
the highest-yield unscorable blocker. Does not run any eval.
|
|
301
369
|
|
|
302
370
|
Output flags:
|
|
303
371
|
--human Render readable terminal output instead of JSON (supported by
|
|
@@ -324,28 +392,24 @@ Output flags:
|
|
|
324
392
|
'instances-file': { type: 'string' },
|
|
325
393
|
'seed-positive': { type: 'boolean' },
|
|
326
394
|
'known-bad': { type: 'boolean' },
|
|
395
|
+
'known-pytest-missing': { type: 'boolean' },
|
|
327
396
|
},
|
|
328
397
|
});
|
|
329
398
|
const human = Boolean(parsed.values['human']);
|
|
330
399
|
const json = Boolean(parsed.values['json']);
|
|
331
400
|
const [name, arg2] = parsed.positionals;
|
|
332
401
|
if (!subverb || subverb === 'list') {
|
|
402
|
+
// Issue #421: the legacy `solverNets` block has been retired. `loadConfig`
|
|
403
|
+
// migrates any on-disk legacy entries into joinedSolverNets with
|
|
404
|
+
// synthetic `legacy:<short-name>` keys, so the joined-only iteration
|
|
405
|
+
// here surfaces both modern and migrated entries.
|
|
333
406
|
const loaded = loadConfig(configPath);
|
|
334
|
-
const legacy = Object.entries(loaded.solverNets).map(([netName, net]) => ({
|
|
335
|
-
name: netName,
|
|
336
|
-
source: 'legacy',
|
|
337
|
-
enabled: net.enabled,
|
|
338
|
-
solverType: net.solverType,
|
|
339
|
-
harness: net.harness,
|
|
340
|
-
pluginCount: net.plugins.length,
|
|
341
|
-
taskGeneratorEnabled: net.taskGenerator.enabled,
|
|
342
|
-
}));
|
|
343
407
|
const joined = Object.entries(loaded.joinedSolverNets ?? {}).map(([cid, net]) => ({
|
|
344
408
|
name: net.name ?? cid,
|
|
345
409
|
source: 'joined',
|
|
346
410
|
manifestCid: cid,
|
|
347
411
|
enabled: true,
|
|
348
|
-
solverType:
|
|
412
|
+
solverType: net.contract ? `${net.contract.id}.${net.contract.version}` : '(unknown)',
|
|
349
413
|
harness: net.harness,
|
|
350
414
|
pluginCount: (net.plugins ?? []).length,
|
|
351
415
|
taskGeneratorEnabled: false,
|
|
@@ -353,21 +417,89 @@ Output flags:
|
|
|
353
417
|
const value = {
|
|
354
418
|
verb: 'solver-nets list',
|
|
355
419
|
configPath,
|
|
356
|
-
solverNets:
|
|
420
|
+
solverNets: joined,
|
|
357
421
|
};
|
|
358
422
|
emit(ctx, value, human, json, (v) => {
|
|
359
423
|
const list = v;
|
|
360
424
|
if (list.solverNets.length === 0)
|
|
361
425
|
return 'No SolverNets configured.';
|
|
362
426
|
return list.solverNets
|
|
363
|
-
.map((n) => {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
})
|
|
427
|
+
.map((n) => `${n.name} ${n.enabled ? 'enabled' : 'disabled'} ${n.solverType} ` +
|
|
428
|
+
`harness=${n.harness ?? '(default)'} plugins=${n.pluginCount} ` +
|
|
429
|
+
`generator=${n.taskGeneratorEnabled ? 'on' : 'off'} source=${n.source} cid=${n.manifestCid}`)
|
|
367
430
|
.join('\n');
|
|
368
431
|
});
|
|
369
432
|
return;
|
|
370
433
|
}
|
|
434
|
+
if (subverb === 'validate-pool-report') {
|
|
435
|
+
if (name !== 'swe-rebench-v2') {
|
|
436
|
+
fail(ctx, 'solver-nets validate-pool-report currently supports only `swe-rebench-v2`');
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
const stateDir = ctx.env['JINN_SWE_REBENCH_V2_STATE_DIR'] ?? sweRebenchV2DefaultStateDir();
|
|
440
|
+
const path = join(stateDir, 'validated-pool.json');
|
|
441
|
+
let raw;
|
|
442
|
+
try {
|
|
443
|
+
raw = JSON.parse(readFileSync(path, 'utf8'));
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
fail(ctx, `validated-pool.json is absent or unreadable at ${path}`);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
let summary;
|
|
450
|
+
try {
|
|
451
|
+
summary = summarizeValidatedPool(raw);
|
|
452
|
+
}
|
|
453
|
+
catch (err) {
|
|
454
|
+
fail(ctx, `validated-pool.json is malformed: ${err.message}`);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
const evalSemanticsVersion = raw.evalSemanticsVersion ?? 'unknown';
|
|
458
|
+
const freshness = await describeSweRebenchV2PoolFreshness({ stateDir });
|
|
459
|
+
const highestYieldBlocker = summary.byReason.find((b) => b.reason !== 'gold-patch-resolves')?.reason ?? null;
|
|
460
|
+
const value = {
|
|
461
|
+
verb: 'solver-nets validate-pool-report',
|
|
462
|
+
solverNet: 'swe-rebench-v2',
|
|
463
|
+
evalSemanticsVersion,
|
|
464
|
+
currentEvalSemanticsVersion: EVAL_SEMANTICS_VERSION,
|
|
465
|
+
stateDir,
|
|
466
|
+
...summary,
|
|
467
|
+
highestYieldBlocker,
|
|
468
|
+
freshness,
|
|
469
|
+
};
|
|
470
|
+
emit(ctx, value, human, json, (v) => {
|
|
471
|
+
const s = v;
|
|
472
|
+
const lines = [
|
|
473
|
+
`SolverNet: swe-rebench-v2`,
|
|
474
|
+
` stateDir: ${s.stateDir}`,
|
|
475
|
+
` evalSemanticsVersion (file): ${s.evalSemanticsVersion}`,
|
|
476
|
+
` evalSemanticsVersion (current): ${s.currentEvalSemanticsVersion}`,
|
|
477
|
+
` total entries: ${s.totalEntries}`,
|
|
478
|
+
` scorable: ${s.scorable}`,
|
|
479
|
+
` unscorable: ${s.unscorable}`,
|
|
480
|
+
`Histogram (by normalised reason, descending):`,
|
|
481
|
+
];
|
|
482
|
+
for (const bucket of s.byReason) {
|
|
483
|
+
lines.push(` ${String(bucket.count).padStart(6)} ${bucket.reason}`);
|
|
484
|
+
}
|
|
485
|
+
if (s.highestYieldBlocker) {
|
|
486
|
+
lines.push(`Highest-yield unscorable blocker: ${s.highestYieldBlocker}`);
|
|
487
|
+
}
|
|
488
|
+
// #806: gold-patch-not-resolved entries whose PASS_TO_PASS tests broke
|
|
489
|
+
// (p2p_broke > 0) are usually an environment/setup problem, not a
|
|
490
|
+
// non-resolving gold patch — a chase-able, recoverable capacity blocker.
|
|
491
|
+
const p2pBroke = s.byReason.find((b) => b.reason === 'gold-patch-not-resolved:p2p-broke');
|
|
492
|
+
if (p2pBroke && p2pBroke.count > 0) {
|
|
493
|
+
lines.push(`Candidate capacity blocker: ${p2pBroke.count} gold-patch-not-resolved entr${p2pBroke.count === 1 ? 'y' : 'ies'} broke PASS_TO_PASS (environment/setup problem, likely recoverable — investigate before treating as non-resolving patches)`);
|
|
494
|
+
}
|
|
495
|
+
if (s.freshness.status === 'stale') {
|
|
496
|
+
lines.push(`Freshness: stale — ${s.freshness.reason}`);
|
|
497
|
+
lines.push(` run: ${s.freshness.cli}`);
|
|
498
|
+
}
|
|
499
|
+
return lines.join('\n');
|
|
500
|
+
});
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
371
503
|
if (subverb === 'validate-pool') {
|
|
372
504
|
if (name !== 'swe-rebench-v2') {
|
|
373
505
|
fail(ctx, 'solver-nets validate-pool currently supports only `swe-rebench-v2`');
|
|
@@ -401,6 +533,7 @@ Output flags:
|
|
|
401
533
|
instancesFile: parsed.values['instances-file'],
|
|
402
534
|
seedPositive: Boolean(parsed.values['seed-positive']),
|
|
403
535
|
knownBad: Boolean(parsed.values['known-bad']),
|
|
536
|
+
knownPytestMissing: Boolean(parsed.values['known-pytest-missing']),
|
|
404
537
|
});
|
|
405
538
|
process.stderr.write('[validate-pool] loading the SWE-rebench v2 pool…\n');
|
|
406
539
|
let poolTasks = await loadSweRebenchV2Pool();
|
|
@@ -428,11 +561,33 @@ Output flags:
|
|
|
428
561
|
fail(ctx, `solver-nets ${subverb} requires <name>`);
|
|
429
562
|
return;
|
|
430
563
|
}
|
|
431
|
-
const
|
|
432
|
-
if (
|
|
433
|
-
solverNets
|
|
564
|
+
const isReadOnlySubverb = subverb === 'show' || subverb === 'doctor' || subverb === 'sample';
|
|
565
|
+
if (!isReadOnlySubverb) {
|
|
566
|
+
// Issue #421: these subverbs still edit the legacy solverNets file shape
|
|
567
|
+
// for one upgrade cycle. The daemon's loadConfig migrates any on-disk
|
|
568
|
+
// legacy entries into joinedSolverNets on next start; the canonical join
|
|
569
|
+
// flow is the SPA (Operator > SolverNets).
|
|
570
|
+
process.stderr.write(`[solver-nets] WARNING: subverb '${subverb}' edits the legacy solverNets ` +
|
|
571
|
+
`file shape (issue #421). The daemon auto-migrates this on next load; ` +
|
|
572
|
+
`re-join via the SPA (Operator > SolverNets) to replace synthetic legacy:* ` +
|
|
573
|
+
`keys with real manifest CIDs.\n`);
|
|
574
|
+
}
|
|
575
|
+
// Resolve the SolverNet to operate on. Read-only subverbs prefer the
|
|
576
|
+
// joined view (issue #421 F4) so an operator who has rejoined via the
|
|
577
|
+
// SPA sees their real entry rather than a synthetic predictionDefault()
|
|
578
|
+
// stub. Mutation subverbs keep the legacy on-disk shape because they
|
|
579
|
+
// write through it for the one-cycle bridge.
|
|
580
|
+
let net;
|
|
581
|
+
if (isReadOnlySubverb) {
|
|
582
|
+
net = resolveReadOnlySolverNet(configPath, cfg, name);
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
const solverNets = ensureSolverNets(cfg);
|
|
586
|
+
if (name === 'prediction' && !solverNets[name]) {
|
|
587
|
+
solverNets[name] = predictionDefault();
|
|
588
|
+
}
|
|
589
|
+
net = solverNets[name];
|
|
434
590
|
}
|
|
435
|
-
const net = solverNets[name];
|
|
436
591
|
if (!net) {
|
|
437
592
|
fail(ctx, `Unknown SolverNet: ${name}`);
|
|
438
593
|
return;
|
|
@@ -445,7 +600,7 @@ Output flags:
|
|
|
445
600
|
if (subverb === 'doctor') {
|
|
446
601
|
if (net.solverType === 'prediction.v1') {
|
|
447
602
|
const loaded = loadConfig(configPath);
|
|
448
|
-
const status = await buildPredictionOperatorStatus({ config: loaded, configPath
|
|
603
|
+
const status = await buildPredictionOperatorStatus({ config: loaded, configPath });
|
|
449
604
|
emit(ctx, { verb: 'solver-nets doctor', ...status }, human, json, renderPredictionStatusHuman);
|
|
450
605
|
return;
|
|
451
606
|
}
|