@guilz-dev/belay 0.4.0 → 0.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.
- package/README.md +27 -2
- package/dist/adapters/claude/runtime-entry.js +54 -25
- package/dist/adapters/layouts/scope.js +3 -2
- package/dist/adapters/shared/gate-runtime.d.ts +8 -2
- package/dist/adapters/shared/gate-runtime.js +579 -181
- package/dist/bundle/claude-runtime.mjs +13574 -6334
- package/dist/bundle/codex-runtime.mjs +13108 -5903
- package/dist/bundle/cursor-runtime.mjs +12676 -5476
- package/dist/cli.js +80 -2
- package/dist/commands/approve.js +34 -10
- package/dist/commands/classify-for-report.js +1 -1
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.js +134 -11
- package/dist/commands/doctor.js +87 -1
- package/dist/commands/explain.js +11 -1
- package/dist/commands/judge.js +3 -2
- package/dist/commands/recovery-checkpoints.d.ts +164 -0
- package/dist/commands/recovery-checkpoints.js +347 -0
- package/dist/commands/revoke.js +19 -7
- package/dist/commands/session.d.ts +20 -0
- package/dist/commands/session.js +51 -0
- package/dist/commands/status.js +7 -0
- package/dist/config-io.js +91 -23
- package/dist/conformance/guarantee-posture.d.ts +21 -0
- package/dist/conformance/guarantee-posture.js +46 -0
- package/dist/conformance/guarantee-table.d.ts +1 -0
- package/dist/conformance/guarantee-table.js +20 -9
- package/dist/conformance/types.d.ts +1 -0
- package/dist/core/approval-replay.d.ts +1 -1
- package/dist/core/approval-replay.js +4 -1
- package/dist/core/approval-service.d.ts +6 -1
- package/dist/core/approval-service.js +87 -24
- package/dist/core/approval.d.ts +4 -0
- package/dist/core/approval.js +19 -5
- package/dist/core/audit-types.d.ts +13 -0
- package/dist/core/capability/approval-state-mutation.d.ts +32 -0
- package/dist/core/capability/approval-state-mutation.js +165 -0
- package/dist/core/capability/approval-v3.d.ts +32 -0
- package/dist/core/capability/approval-v3.js +114 -0
- package/dist/core/capability/attestation.d.ts +16 -0
- package/dist/core/capability/attestation.js +62 -0
- package/dist/core/capability/boundary-attestation-sign.d.ts +21 -0
- package/dist/core/capability/boundary-attestation-sign.js +84 -0
- package/dist/core/capability/boundary-driver-container.d.ts +19 -0
- package/dist/core/capability/boundary-driver-container.js +189 -0
- package/dist/core/capability/boundary-driver.d.ts +29 -0
- package/dist/core/capability/boundary-driver.js +44 -0
- package/dist/core/capability/boundary-egress.d.ts +21 -0
- package/dist/core/capability/boundary-egress.js +109 -0
- package/dist/core/capability/boundary-grant-materialize.d.ts +14 -0
- package/dist/core/capability/boundary-grant-materialize.js +93 -0
- package/dist/core/capability/boundary-profile.d.ts +15 -0
- package/dist/core/capability/boundary-profile.js +25 -0
- package/dist/core/capability/boundary-run.d.ts +48 -0
- package/dist/core/capability/boundary-run.js +51 -0
- package/dist/core/capability/boundary-session.d.ts +61 -0
- package/dist/core/capability/boundary-session.js +138 -0
- package/dist/core/capability/boundary-workspace-mount.d.ts +5 -0
- package/dist/core/capability/boundary-workspace-mount.js +68 -0
- package/dist/core/capability/capability-request-hash.d.ts +2 -0
- package/dist/core/capability/capability-request-hash.js +8 -0
- package/dist/core/capability/gate-latency-ratchet.d.ts +7 -0
- package/dist/core/capability/gate-latency-ratchet.js +18 -0
- package/dist/core/capability/gate-policy-shadow.d.ts +25 -0
- package/dist/core/capability/gate-policy-shadow.js +130 -0
- package/dist/core/capability/gate-shadow-audit.d.ts +1 -0
- package/dist/core/capability/gate-shadow-audit.js +1 -0
- package/dist/core/capability/gate-shadow-ratchet.d.ts +14 -0
- package/dist/core/capability/gate-shadow-ratchet.js +81 -0
- package/dist/core/capability/grant-consumption.d.ts +4 -0
- package/dist/core/capability/grant-consumption.js +11 -0
- package/dist/core/capability/grant-lease.d.ts +44 -0
- package/dist/core/capability/grant-lease.js +243 -0
- package/dist/core/capability/grant-loader.d.ts +12 -0
- package/dist/core/capability/grant-loader.js +23 -0
- package/dist/core/capability/grant-match.d.ts +6 -0
- package/dist/core/capability/grant-match.js +96 -0
- package/dist/core/capability/grant.d.ts +16 -0
- package/dist/core/capability/grant.js +16 -0
- package/dist/core/capability/index.d.ts +8 -0
- package/dist/core/capability/index.js +7 -0
- package/dist/core/capability/limits.d.ts +7 -0
- package/dist/core/capability/limits.js +55 -0
- package/dist/core/capability/policy-bridge.d.ts +18 -0
- package/dist/core/capability/policy-bridge.js +51 -0
- package/dist/core/capability/policy-engine.d.ts +77 -0
- package/dist/core/capability/policy-engine.js +663 -0
- package/dist/core/capability/policy-types.d.ts +20 -0
- package/dist/core/capability/policy-types.js +1 -0
- package/dist/core/capability/request.d.ts +48 -0
- package/dist/core/capability/request.js +1 -0
- package/dist/core/capability/resolver.d.ts +4 -0
- package/dist/core/capability/resolver.js +4 -0
- package/dist/core/classify-subagent.d.ts +2 -1
- package/dist/core/classify-subagent.js +38 -2
- package/dist/core/classify-tool.js +126 -62
- package/dist/core/config.d.ts +34 -3
- package/dist/core/config.js +118 -3
- package/dist/core/effect-ir/audit.d.ts +9 -0
- package/dist/core/effect-ir/audit.js +86 -0
- package/dist/core/effect-ir/build.d.ts +31 -0
- package/dist/core/effect-ir/build.js +277 -0
- package/dist/core/effect-ir/index.d.ts +8 -0
- package/dist/core/effect-ir/index.js +7 -0
- package/dist/core/effect-ir/normalize.d.ts +4 -0
- package/dist/core/effect-ir/normalize.js +104 -0
- package/dist/core/effect-ir/package-exec-eval.d.ts +8 -0
- package/dist/core/effect-ir/package-exec-eval.js +152 -0
- package/dist/core/effect-ir/package-exec.d.ts +29 -0
- package/dist/core/effect-ir/package-exec.js +292 -0
- package/dist/core/effect-ir/policy.d.ts +13 -0
- package/dist/core/effect-ir/policy.js +77 -0
- package/dist/core/effect-ir/types.d.ts +55 -0
- package/dist/core/effect-ir/types.js +1 -0
- package/dist/core/egress/allowlist.d.ts +1 -0
- package/dist/core/egress/allowlist.js +8 -0
- package/dist/core/egress-approval.js +45 -51
- package/dist/core/gate-contract.d.ts +5 -0
- package/dist/core/gate-contract.js +5 -0
- package/dist/core/gate-engine.js +30 -8
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.js +2 -1
- package/dist/core/judge-cloud-consent.js +29 -15
- package/dist/core/judge-doctor.js +39 -14
- package/dist/core/judge-fallback-hints.d.ts +13 -0
- package/dist/core/judge-fallback-hints.js +108 -0
- package/dist/core/network-endpoint.d.ts +10 -0
- package/dist/core/network-endpoint.js +51 -0
- package/dist/core/path-utils.d.ts +1 -0
- package/dist/core/path-utils.js +5 -2
- package/dist/core/process-runner.d.ts +10 -0
- package/dist/core/process-runner.js +124 -0
- package/dist/core/recover-advice.js +2 -1
- package/dist/core/recovery/artifact-store.d.ts +29 -0
- package/dist/core/recovery/artifact-store.js +336 -0
- package/dist/core/recovery/capability.d.ts +3 -0
- package/dist/core/recovery/capability.js +22 -0
- package/dist/core/recovery/checkpoint.d.ts +25 -0
- package/dist/core/recovery/checkpoint.js +260 -0
- package/dist/core/recovery/fail-closed.d.ts +6 -0
- package/dist/core/recovery/fail-closed.js +25 -0
- package/dist/core/recovery/index.d.ts +5 -0
- package/dist/core/recovery/index.js +4 -0
- package/dist/core/recovery/operator-guidance.d.ts +7 -0
- package/dist/core/recovery/operator-guidance.js +39 -0
- package/dist/core/recovery/reconcile.d.ts +3 -0
- package/dist/core/recovery/reconcile.js +48 -0
- package/dist/core/recovery/resource-identity.d.ts +4 -0
- package/dist/core/recovery/resource-identity.js +34 -0
- package/dist/core/recovery/restore.d.ts +13 -0
- package/dist/core/recovery/restore.js +114 -0
- package/dist/core/recovery/snapshot-node.d.ts +27 -0
- package/dist/core/recovery/snapshot-node.js +261 -0
- package/dist/core/recovery/types.d.ts +104 -0
- package/dist/core/recovery/types.js +1 -0
- package/dist/core/standing-allow.js +3 -0
- package/dist/core/transactional/apply-observed-changes.d.ts +13 -0
- package/dist/core/transactional/apply-observed-changes.js +275 -0
- package/dist/core/transactional/backend-selector.d.ts +8 -0
- package/dist/core/transactional/backend-selector.js +118 -0
- package/dist/core/transactional/backend.d.ts +55 -0
- package/dist/core/transactional/backend.js +1 -0
- package/dist/core/transactional/diff-evaluator.js +4 -1
- package/dist/core/transactional/eligibility.js +4 -0
- package/dist/core/transactional/file-checkpoint-backend.d.ts +3 -0
- package/dist/core/transactional/file-checkpoint-backend.js +278 -0
- package/dist/core/transactional/file-checkpoint-git.d.ts +11 -0
- package/dist/core/transactional/file-checkpoint-git.js +217 -0
- package/dist/core/transactional/file-checkpoint-staging.d.ts +13 -0
- package/dist/core/transactional/file-checkpoint-staging.js +54 -0
- package/dist/core/transactional/file-clone.d.ts +15 -0
- package/dist/core/transactional/file-clone.js +139 -0
- package/dist/core/transactional/file-tree-path.d.ts +7 -0
- package/dist/core/transactional/file-tree-path.js +50 -0
- package/dist/core/transactional/file-tree.d.ts +41 -0
- package/dist/core/transactional/file-tree.js +186 -0
- package/dist/core/transactional/git-worktree-backend.d.ts +2 -0
- package/dist/core/transactional/git-worktree-backend.js +50 -0
- package/dist/core/transactional/git-worktree.d.ts +14 -9
- package/dist/core/transactional/git-worktree.js +62 -87
- package/dist/core/transactional/index.d.ts +11 -0
- package/dist/core/transactional/index.js +10 -0
- package/dist/core/transactional/reasons.d.ts +1 -0
- package/dist/core/transactional/reasons.js +5 -0
- package/dist/core/transactional/runner.js +171 -23
- package/dist/core/transactional/snapshot-node.d.ts +26 -0
- package/dist/core/transactional/snapshot-node.js +87 -0
- package/dist/core/transactional/types.d.ts +21 -1
- package/dist/core/types.d.ts +30 -3
- package/dist/core/verdict/adapter.d.ts +3 -4
- package/dist/core/verdict/adapter.js +24 -12
- package/dist/core/verdict/cursor-acp-client.d.ts +67 -0
- package/dist/core/verdict/cursor-acp-client.js +345 -0
- package/dist/core/verdict/egress-classify.d.ts +2 -2
- package/dist/core/verdict/egress-classify.js +2 -2
- package/dist/core/verdict/git-classifier.d.ts +26 -0
- package/dist/core/verdict/git-classifier.js +533 -0
- package/dist/core/verdict/judge-audit.js +1 -0
- package/dist/core/verdict/judge-baseline.d.ts +1 -1
- package/dist/core/verdict/judge-baseline.js +1 -0
- package/dist/core/verdict/judge-broker-service.js +12 -0
- package/dist/core/verdict/judge-catalog.js +1 -0
- package/dist/core/verdict/judge-cli-fingerprint.d.ts +1 -0
- package/dist/core/verdict/judge-cli-fingerprint.js +6 -0
- package/dist/core/verdict/judge-cli.js +5 -3
- package/dist/core/verdict/judge-provider-matrix.js +1 -1
- package/dist/core/verdict/judge-runtime-config.d.ts +2 -0
- package/dist/core/verdict/judge-runtime-config.js +10 -6
- package/dist/core/verdict/judge-session-broker.d.ts +1 -1
- package/dist/core/verdict/judge-session-broker.js +10 -5
- package/dist/core/verdict/judge-transport.d.ts +5 -1
- package/dist/core/verdict/judge-transport.js +24 -14
- package/dist/core/verdict/judge.d.ts +2 -15
- package/dist/core/verdict/judge.js +5 -68
- package/dist/core/verdict/launcher-resolve.d.ts +2 -0
- package/dist/core/verdict/launcher-resolve.js +14 -16
- package/dist/core/verdict/prescan.d.ts +15 -0
- package/dist/core/verdict/prescan.js +68 -0
- package/dist/core/verdict/shell-policy.d.ts +26 -0
- package/dist/core/verdict/shell-policy.js +40 -0
- package/dist/core/verdict/shell-semantics.d.ts +24 -0
- package/dist/core/verdict/shell-semantics.js +225 -0
- package/dist/core/verdict/types.d.ts +18 -1
- package/dist/core/verdict/verdict.js +313 -178
- package/dist/corpus/evaluate.js +3 -7
- package/dist/corpus/gate-latency-budget.d.ts +39 -0
- package/dist/corpus/gate-latency-budget.js +33 -0
- package/dist/corpus/mutators.d.ts +1 -1
- package/dist/corpus/mutators.js +11 -0
- package/dist/corpus/runtime-match.js +1 -3
- package/dist/corpus/standing-allow-catalog.generated.js +29 -9
- package/dist/judge-broker-daemon.js +15 -1
- package/dist/services/sandbox-service.d.ts +4 -0
- package/dist/services/sandbox-service.js +28 -2
- package/dist/types.d.ts +13 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/belay/SKILL.md +8 -3
- package/skills/belay/belay-approve.md +10 -7
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { extractRedirectTargets } from '../shell-tokenizer.js';
|
|
3
|
+
const GIT_BRANCH_MUTATION_FLAGS = new Set([
|
|
4
|
+
'--copy',
|
|
5
|
+
'--create-reflog',
|
|
6
|
+
'--delete',
|
|
7
|
+
'--edit-description',
|
|
8
|
+
'--force',
|
|
9
|
+
'--move',
|
|
10
|
+
'--no-create-reflog',
|
|
11
|
+
'--no-track',
|
|
12
|
+
'--recurse-submodules',
|
|
13
|
+
'--set-upstream-to',
|
|
14
|
+
'--track',
|
|
15
|
+
'--unset-upstream',
|
|
16
|
+
]);
|
|
17
|
+
const GIT_BRANCH_LIST_FLAGS = new Set([
|
|
18
|
+
'--abbrev',
|
|
19
|
+
'--all',
|
|
20
|
+
'--column',
|
|
21
|
+
'--color',
|
|
22
|
+
'--contains',
|
|
23
|
+
'--format',
|
|
24
|
+
'--ignore-case',
|
|
25
|
+
'--list',
|
|
26
|
+
'--merged',
|
|
27
|
+
'--no-abbrev',
|
|
28
|
+
'--no-column',
|
|
29
|
+
'--no-color',
|
|
30
|
+
'--no-contains',
|
|
31
|
+
'--no-merged',
|
|
32
|
+
'--points-at',
|
|
33
|
+
'--remotes',
|
|
34
|
+
'--show-current',
|
|
35
|
+
'--sort',
|
|
36
|
+
'--verbose',
|
|
37
|
+
]);
|
|
38
|
+
const GIT_BRANCH_MUTATION_SHORT_FLAGS = new Set(['c', 'C', 'd', 'D', 'f', 'm', 'M', 't', 'u']);
|
|
39
|
+
const GIT_BRANCH_LIST_SHORT_FLAGS = new Set(['a', 'i', 'l', 'r', 'v']);
|
|
40
|
+
const READ_ONLY_SUBCOMMANDS = new Set([
|
|
41
|
+
'status',
|
|
42
|
+
'diff',
|
|
43
|
+
'log',
|
|
44
|
+
'show',
|
|
45
|
+
'rev-parse',
|
|
46
|
+
'describe',
|
|
47
|
+
'show-ref',
|
|
48
|
+
'reflog',
|
|
49
|
+
'ls-files',
|
|
50
|
+
'ls-tree',
|
|
51
|
+
'cat-file',
|
|
52
|
+
'verify-commit',
|
|
53
|
+
'whatchanged',
|
|
54
|
+
'shortlog',
|
|
55
|
+
'help',
|
|
56
|
+
'version',
|
|
57
|
+
]);
|
|
58
|
+
const READ_ONLY_COMPOUND_SUBCOMMANDS = new Set(['worktree list', 'stash list', 'stash show']);
|
|
59
|
+
const LOCAL_MUTATION_SUBCOMMANDS = new Set([
|
|
60
|
+
'add',
|
|
61
|
+
'commit',
|
|
62
|
+
'mv',
|
|
63
|
+
'revert',
|
|
64
|
+
'merge',
|
|
65
|
+
'cherry-pick',
|
|
66
|
+
'am',
|
|
67
|
+
'apply',
|
|
68
|
+
'format-patch',
|
|
69
|
+
]);
|
|
70
|
+
const REMOTE_SUBCOMMANDS = new Set(['fetch', 'pull']);
|
|
71
|
+
const LOCAL_MUTATION_COMPOUND_SUBCOMMANDS = new Set([
|
|
72
|
+
'worktree add',
|
|
73
|
+
'stash push',
|
|
74
|
+
'stash apply',
|
|
75
|
+
'stash pop',
|
|
76
|
+
'stash drop',
|
|
77
|
+
'stash branch',
|
|
78
|
+
]);
|
|
79
|
+
const FILE_OPERAND_SUBCOMMANDS = new Set([
|
|
80
|
+
'add',
|
|
81
|
+
'rm',
|
|
82
|
+
'mv',
|
|
83
|
+
'checkout',
|
|
84
|
+
'restore',
|
|
85
|
+
'clean',
|
|
86
|
+
'apply',
|
|
87
|
+
'cherry-pick',
|
|
88
|
+
'merge',
|
|
89
|
+
'show',
|
|
90
|
+
'diff',
|
|
91
|
+
'grep',
|
|
92
|
+
'ls-files',
|
|
93
|
+
]);
|
|
94
|
+
const COMPOUND_SUBCOMMAND_HEADS = new Set(['worktree', 'stash', 'tag']);
|
|
95
|
+
/** Positional args before `--` are refs/revisions, not worktree paths. */
|
|
96
|
+
const REF_ONLY_WITHOUT_TERMINATOR = new Set(['checkout', 'show', 'log']);
|
|
97
|
+
function isGitExecutable(token) {
|
|
98
|
+
return path.basename(token) === 'git';
|
|
99
|
+
}
|
|
100
|
+
function takesValue(flag) {
|
|
101
|
+
return (flag === '-C' ||
|
|
102
|
+
flag === '-c' ||
|
|
103
|
+
flag === '--git-dir' ||
|
|
104
|
+
flag === '--work-tree' ||
|
|
105
|
+
flag === '--exec-path' ||
|
|
106
|
+
flag === '--paginate' ||
|
|
107
|
+
flag === '--config-env' ||
|
|
108
|
+
flag.startsWith('-C') ||
|
|
109
|
+
flag.startsWith('-c') ||
|
|
110
|
+
flag.startsWith('--git-dir=') ||
|
|
111
|
+
flag.startsWith('--work-tree='));
|
|
112
|
+
}
|
|
113
|
+
function peelGlobalOptions(tokens, baseCwd) {
|
|
114
|
+
let effectiveCwd = baseCwd;
|
|
115
|
+
let gitDir;
|
|
116
|
+
let workTree;
|
|
117
|
+
const rest = [];
|
|
118
|
+
let index = 1;
|
|
119
|
+
while (index < tokens.length) {
|
|
120
|
+
const token = tokens[index];
|
|
121
|
+
if (!token) {
|
|
122
|
+
index += 1;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (token === '--') {
|
|
126
|
+
rest.push(...tokens.slice(index));
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
if (token === '--no-pager' || token === '--no-replace-objects') {
|
|
130
|
+
index += 1;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (token === '-C' || token === '--work-tree' || token === '--git-dir' || token === '-c') {
|
|
134
|
+
const value = tokens[index + 1];
|
|
135
|
+
if (token === '-C' && value) {
|
|
136
|
+
effectiveCwd = path.resolve(baseCwd, value);
|
|
137
|
+
}
|
|
138
|
+
else if (token === '--work-tree' && value) {
|
|
139
|
+
workTree = value;
|
|
140
|
+
}
|
|
141
|
+
else if (token === '--git-dir' && value) {
|
|
142
|
+
gitDir = value;
|
|
143
|
+
}
|
|
144
|
+
index += value ? 2 : 1;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (token.startsWith('-C') && token.length > 2) {
|
|
148
|
+
effectiveCwd = path.resolve(baseCwd, token.slice(2));
|
|
149
|
+
index += 1;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (token.startsWith('--work-tree=')) {
|
|
153
|
+
workTree = token.slice('--work-tree='.length);
|
|
154
|
+
index += 1;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (token.startsWith('--git-dir=')) {
|
|
158
|
+
gitDir = token.slice('--git-dir='.length);
|
|
159
|
+
index += 1;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (token.startsWith('-c') || token.startsWith('--config')) {
|
|
163
|
+
index += token.includes('=') ? 1 : tokens[index + 1] ? 2 : 1;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (token.startsWith('-')) {
|
|
167
|
+
if (takesValue(token) && !token.includes('=')) {
|
|
168
|
+
index += 2;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
index += 1;
|
|
172
|
+
}
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
rest.push(...tokens.slice(index));
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
return { rest, effectiveCwd, gitDir, workTree };
|
|
179
|
+
}
|
|
180
|
+
function resolveSubcommand(rest) {
|
|
181
|
+
const head = rest[0] ?? '';
|
|
182
|
+
const second = rest[1] ?? '';
|
|
183
|
+
if (COMPOUND_SUBCOMMAND_HEADS.has(head) && second && !second.startsWith('-')) {
|
|
184
|
+
return { subcommand: `${head} ${second}`, args: rest.slice(2) };
|
|
185
|
+
}
|
|
186
|
+
return { subcommand: head, args: rest.slice(1) };
|
|
187
|
+
}
|
|
188
|
+
export function normalizeGitInvocation(tokens, baseCwd) {
|
|
189
|
+
if (!isGitExecutable(tokens[0] ?? '')) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
const peeled = peelGlobalOptions(tokens, baseCwd);
|
|
193
|
+
const { subcommand, args } = resolveSubcommand(peeled.rest);
|
|
194
|
+
if (!subcommand) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
subcommand,
|
|
199
|
+
args,
|
|
200
|
+
effectiveCwd: peeled.effectiveCwd !== baseCwd ? peeled.effectiveCwd : undefined,
|
|
201
|
+
gitDir: peeled.gitDir,
|
|
202
|
+
workTree: peeled.workTree,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function hasGitBranchLongFlag(tokens, flags) {
|
|
206
|
+
return tokens.some((token) => {
|
|
207
|
+
const [name] = token.split('=', 1);
|
|
208
|
+
return name ? flags.has(name) : false;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
function hasGitBranchShortFlag(tokens, flags) {
|
|
212
|
+
return tokens.some((token) => {
|
|
213
|
+
if (!/^-[^-]+$/.test(token)) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
return [...token.slice(1)].some((flag) => flags.has(flag));
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
function gitBranchEffect(args) {
|
|
220
|
+
const optionTerminator = args.indexOf('--');
|
|
221
|
+
const optionArgs = optionTerminator >= 0 ? args.slice(0, optionTerminator) : args;
|
|
222
|
+
if (hasGitBranchLongFlag(optionArgs, GIT_BRANCH_MUTATION_FLAGS) ||
|
|
223
|
+
hasGitBranchShortFlag(optionArgs, GIT_BRANCH_MUTATION_SHORT_FLAGS)) {
|
|
224
|
+
return 'local_mutation';
|
|
225
|
+
}
|
|
226
|
+
if (hasGitBranchLongFlag(optionArgs, GIT_BRANCH_LIST_FLAGS) ||
|
|
227
|
+
hasGitBranchShortFlag(optionArgs, GIT_BRANCH_LIST_SHORT_FLAGS)) {
|
|
228
|
+
return 'read_only';
|
|
229
|
+
}
|
|
230
|
+
const positionalArgs = args.filter((token, index) => (optionTerminator >= 0 && index > optionTerminator) ||
|
|
231
|
+
(token !== '--' && !token.startsWith('-')));
|
|
232
|
+
return positionalArgs.length === 0 ? 'read_only' : 'local_mutation';
|
|
233
|
+
}
|
|
234
|
+
function hasFlag(args, ...flags) {
|
|
235
|
+
return args.some((token) => flags.includes(token) || flags.some((flag) => token.startsWith(`${flag}=`)));
|
|
236
|
+
}
|
|
237
|
+
function isDryRunClean(args) {
|
|
238
|
+
return hasFlag(args, '-n', '--dry-run', '--dry-run=');
|
|
239
|
+
}
|
|
240
|
+
function isHardReset(args) {
|
|
241
|
+
return hasFlag(args, '--hard');
|
|
242
|
+
}
|
|
243
|
+
function extractMessageSkippedIndices(args) {
|
|
244
|
+
const skipped = new Set();
|
|
245
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
246
|
+
const token = args[index];
|
|
247
|
+
if (!token) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (token === '-m' || token === '--message' || token === '-F' || token === '--file') {
|
|
251
|
+
skipped.add(index);
|
|
252
|
+
if (args[index + 1]) {
|
|
253
|
+
skipped.add(index + 1);
|
|
254
|
+
index += 1;
|
|
255
|
+
}
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (token.startsWith('-m') && token.length > 2) {
|
|
259
|
+
skipped.add(index);
|
|
260
|
+
}
|
|
261
|
+
if (token.startsWith('--message=')) {
|
|
262
|
+
skipped.add(index);
|
|
263
|
+
}
|
|
264
|
+
if (token.startsWith('--set-upstream-to=')) {
|
|
265
|
+
skipped.add(index);
|
|
266
|
+
}
|
|
267
|
+
if (token === '--set-upstream-to' && args[index + 1]) {
|
|
268
|
+
skipped.add(index);
|
|
269
|
+
skipped.add(index + 1);
|
|
270
|
+
index += 1;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return skipped;
|
|
274
|
+
}
|
|
275
|
+
function looksLikeFileOperand(token) {
|
|
276
|
+
if (!token || token === '--' || token.startsWith('-')) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
if (token.includes('/') || token.includes('\\')) {
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
if (token.startsWith('.')) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
return token.includes('.');
|
|
286
|
+
}
|
|
287
|
+
function looksLikeDiffPathOperand(token) {
|
|
288
|
+
if (!looksLikeFileOperand(token)) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
if (token.startsWith('.') || path.isAbsolute(token)) {
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
return token.includes('.');
|
|
295
|
+
}
|
|
296
|
+
function resolveGitWorkTree(baseCwd, effectiveCwd, workTree, gitDir) {
|
|
297
|
+
const resolveBase = effectiveCwd ?? baseCwd;
|
|
298
|
+
if (workTree) {
|
|
299
|
+
return path.resolve(resolveBase, workTree);
|
|
300
|
+
}
|
|
301
|
+
if (gitDir) {
|
|
302
|
+
const resolvedGitDir = path.resolve(resolveBase, gitDir);
|
|
303
|
+
if (path.basename(resolvedGitDir) === '.git') {
|
|
304
|
+
return path.dirname(resolvedGitDir);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
function extractGitFileOperands(subcommand, args) {
|
|
310
|
+
const baseSubcommand = subcommand.split(' ')[0] ?? subcommand;
|
|
311
|
+
if (!FILE_OPERAND_SUBCOMMANDS.has(baseSubcommand) &&
|
|
312
|
+
subcommand !== 'checkout' &&
|
|
313
|
+
subcommand !== 'restore') {
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
const redirects = extractRedirectTargets(['git', baseSubcommand, ...args]);
|
|
317
|
+
const skipped = extractMessageSkippedIndices(args);
|
|
318
|
+
const optionTerminator = args.indexOf('--');
|
|
319
|
+
const operands = [...redirects];
|
|
320
|
+
if (REF_ONLY_WITHOUT_TERMINATOR.has(subcommand) && optionTerminator < 0) {
|
|
321
|
+
return operands;
|
|
322
|
+
}
|
|
323
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
324
|
+
if (skipped.has(index)) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const token = args[index];
|
|
328
|
+
if (!token || token.startsWith('-') || token === '--') {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (optionTerminator >= 0 && index < optionTerminator) {
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (subcommand === 'branch' ||
|
|
335
|
+
subcommand === 'push' ||
|
|
336
|
+
subcommand === 'fetch' ||
|
|
337
|
+
subcommand === 'pull') {
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (baseSubcommand === 'diff' && optionTerminator < 0) {
|
|
341
|
+
if (looksLikeDiffPathOperand(token)) {
|
|
342
|
+
operands.push(token);
|
|
343
|
+
}
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
if (looksLikeFileOperand(token) || baseSubcommand === 'add' || baseSubcommand === 'rm') {
|
|
347
|
+
operands.push(token);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return operands;
|
|
351
|
+
}
|
|
352
|
+
function classifyDestructiveGit(subcommand, args) {
|
|
353
|
+
if (subcommand === 'reset' && isHardReset(args)) {
|
|
354
|
+
return {
|
|
355
|
+
reason: 'git_history_destructive',
|
|
356
|
+
signals: ['git_history_destructive', 'git.reset.hard'],
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
if (subcommand === 'clean' && !isDryRunClean(args)) {
|
|
360
|
+
return { reason: 'git_history_destructive', signals: ['git_history_destructive', 'git.clean'] };
|
|
361
|
+
}
|
|
362
|
+
if (subcommand === 'stash clear') {
|
|
363
|
+
return {
|
|
364
|
+
reason: 'git_history_destructive',
|
|
365
|
+
signals: ['git_history_destructive', 'git.stash.clear'],
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (subcommand === 'worktree remove' && hasFlag(args, '--force')) {
|
|
369
|
+
return {
|
|
370
|
+
reason: 'git_history_destructive',
|
|
371
|
+
signals: ['git_history_destructive', 'git.worktree.remove.force'],
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
if (subcommand === 'restore' && hasFlag(args, '--worktree', '-W')) {
|
|
375
|
+
return {
|
|
376
|
+
reason: 'git_history_destructive',
|
|
377
|
+
signals: ['git_history_destructive', 'git.restore.worktree'],
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
export function isGitReadOnlyInvocation(tokens, baseCwd) {
|
|
383
|
+
const semantics = classifyGitCommand(tokens, baseCwd);
|
|
384
|
+
return semantics?.isReadOnly === true;
|
|
385
|
+
}
|
|
386
|
+
export function classifyGitCommand(tokens, baseCwd) {
|
|
387
|
+
const normalized = normalizeGitInvocation(tokens, baseCwd);
|
|
388
|
+
if (!normalized) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
const { subcommand, args, effectiveCwd, gitDir, workTree } = normalized;
|
|
392
|
+
const normalizedKey = `git ${subcommand}`;
|
|
393
|
+
const gitWorkTree = resolveGitWorkTree(baseCwd, effectiveCwd, workTree, gitDir);
|
|
394
|
+
const effectiveGitDir = gitDir ? path.resolve(effectiveCwd ?? baseCwd, gitDir) : undefined;
|
|
395
|
+
const scopeTargets = [effectiveCwd, gitWorkTree, effectiveGitDir].filter((target, index, targets) => Boolean(target) && targets.indexOf(target) === index);
|
|
396
|
+
const pathTargets = extractGitFileOperands(subcommand, args);
|
|
397
|
+
const signals = [`git.${subcommand.replaceAll(' ', '.')}`];
|
|
398
|
+
const destructive = classifyDestructiveGit(subcommand, args);
|
|
399
|
+
if (destructive) {
|
|
400
|
+
return {
|
|
401
|
+
effect: 'local_mutation',
|
|
402
|
+
pathTargets,
|
|
403
|
+
scopeTargets,
|
|
404
|
+
signals: [...signals, ...destructive.signals],
|
|
405
|
+
requiresAsk: destructive,
|
|
406
|
+
effectiveCwd,
|
|
407
|
+
gitWorkTree,
|
|
408
|
+
normalizedKey,
|
|
409
|
+
isReadOnly: false,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
if (subcommand === 'push') {
|
|
413
|
+
return {
|
|
414
|
+
effect: 'remote_mutation',
|
|
415
|
+
pathTargets,
|
|
416
|
+
scopeTargets,
|
|
417
|
+
signals: [...signals, 'git.push'],
|
|
418
|
+
effectiveCwd,
|
|
419
|
+
gitWorkTree,
|
|
420
|
+
normalizedKey,
|
|
421
|
+
isReadOnly: false,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
if (REMOTE_SUBCOMMANDS.has(subcommand)) {
|
|
425
|
+
return {
|
|
426
|
+
effect: 'remote_mutation',
|
|
427
|
+
pathTargets: [],
|
|
428
|
+
scopeTargets,
|
|
429
|
+
signals: [...signals, 'git.remote'],
|
|
430
|
+
egressClass: 'ambiguous',
|
|
431
|
+
effectiveCwd,
|
|
432
|
+
gitWorkTree,
|
|
433
|
+
normalizedKey,
|
|
434
|
+
isReadOnly: false,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
if (subcommand === 'branch') {
|
|
438
|
+
const effect = gitBranchEffect(args);
|
|
439
|
+
return {
|
|
440
|
+
effect,
|
|
441
|
+
pathTargets: [],
|
|
442
|
+
scopeTargets,
|
|
443
|
+
signals,
|
|
444
|
+
effectiveCwd,
|
|
445
|
+
gitWorkTree,
|
|
446
|
+
normalizedKey,
|
|
447
|
+
isReadOnly: effect === 'read_only',
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
if (subcommand === 'checkout') {
|
|
451
|
+
return {
|
|
452
|
+
effect: 'local_mutation',
|
|
453
|
+
pathTargets,
|
|
454
|
+
scopeTargets,
|
|
455
|
+
signals,
|
|
456
|
+
effectiveCwd,
|
|
457
|
+
gitWorkTree,
|
|
458
|
+
normalizedKey,
|
|
459
|
+
isReadOnly: false,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
if (subcommand === 'clean' && isDryRunClean(args)) {
|
|
463
|
+
return {
|
|
464
|
+
effect: 'read_only',
|
|
465
|
+
pathTargets: [],
|
|
466
|
+
scopeTargets,
|
|
467
|
+
signals,
|
|
468
|
+
effectiveCwd,
|
|
469
|
+
gitWorkTree,
|
|
470
|
+
normalizedKey,
|
|
471
|
+
isReadOnly: true,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
if (subcommand === 'reset' && !isHardReset(args)) {
|
|
475
|
+
return {
|
|
476
|
+
effect: 'local_mutation',
|
|
477
|
+
pathTargets: [],
|
|
478
|
+
scopeTargets,
|
|
479
|
+
signals,
|
|
480
|
+
effectiveCwd,
|
|
481
|
+
gitWorkTree,
|
|
482
|
+
normalizedKey,
|
|
483
|
+
isReadOnly: false,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
if (subcommand === 'tag' && hasFlag(args, '--list', '-l')) {
|
|
487
|
+
return {
|
|
488
|
+
effect: 'read_only',
|
|
489
|
+
pathTargets: [],
|
|
490
|
+
scopeTargets,
|
|
491
|
+
signals,
|
|
492
|
+
effectiveCwd,
|
|
493
|
+
gitWorkTree,
|
|
494
|
+
normalizedKey,
|
|
495
|
+
isReadOnly: true,
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
if (READ_ONLY_SUBCOMMANDS.has(subcommand) || READ_ONLY_COMPOUND_SUBCOMMANDS.has(subcommand)) {
|
|
499
|
+
return {
|
|
500
|
+
effect: 'read_only',
|
|
501
|
+
pathTargets: subcommand === 'show' || subcommand === 'diff' ? pathTargets : [],
|
|
502
|
+
scopeTargets,
|
|
503
|
+
signals,
|
|
504
|
+
effectiveCwd,
|
|
505
|
+
gitWorkTree,
|
|
506
|
+
normalizedKey,
|
|
507
|
+
isReadOnly: true,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
if (LOCAL_MUTATION_SUBCOMMANDS.has(subcommand) ||
|
|
511
|
+
LOCAL_MUTATION_COMPOUND_SUBCOMMANDS.has(subcommand)) {
|
|
512
|
+
return {
|
|
513
|
+
effect: 'local_mutation',
|
|
514
|
+
pathTargets: subcommand === 'commit' ? [] : pathTargets,
|
|
515
|
+
scopeTargets,
|
|
516
|
+
signals,
|
|
517
|
+
effectiveCwd,
|
|
518
|
+
gitWorkTree,
|
|
519
|
+
normalizedKey,
|
|
520
|
+
isReadOnly: false,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
return {
|
|
524
|
+
effect: 'unknown',
|
|
525
|
+
pathTargets,
|
|
526
|
+
scopeTargets,
|
|
527
|
+
signals,
|
|
528
|
+
effectiveCwd,
|
|
529
|
+
gitWorkTree,
|
|
530
|
+
normalizedKey,
|
|
531
|
+
isReadOnly: false,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
@@ -11,6 +11,7 @@ export function judgeTraceAuditFields(trace) {
|
|
|
11
11
|
judgeModelRequested: trace.modelRequested,
|
|
12
12
|
judgeModelResolved: trace.modelResolved,
|
|
13
13
|
judgeLatencyMs: trace.latencyMs,
|
|
14
|
+
...(trace.transport ? { judgeTransport: trace.transport } : {}),
|
|
14
15
|
...(trace.outboundRedacted !== undefined
|
|
15
16
|
? { judgeOutboundRedacted: trace.outboundRedacted }
|
|
16
17
|
: {}),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JUDGE_LATENCY_SLO } from './judge-runtime-config.js';
|
|
2
|
-
export type JudgeLatencyPhase = 'tier0' | 'tier1_spawn' | 'tier1_session' | 'tier1_connect' | 'tier1_eval' | 'tier1_parse';
|
|
2
|
+
export type JudgeLatencyPhase = 'tier0' | 'gate' | 'tier1_spawn' | 'tier1_session' | 'tier1_connect' | 'tier1_eval' | 'tier1_parse';
|
|
3
3
|
export interface JudgeLatencySample {
|
|
4
4
|
phase: JudgeLatencyPhase;
|
|
5
5
|
latencyMs: number;
|
|
@@ -34,6 +34,7 @@ export function judgeLatencyPercentiles(phase) {
|
|
|
34
34
|
export function judgeLatencySloReport() {
|
|
35
35
|
const measured = {
|
|
36
36
|
tier0: judgeLatencyPercentiles('tier0'),
|
|
37
|
+
gate: judgeLatencyPercentiles('gate'),
|
|
37
38
|
tier1_spawn: judgeLatencyPercentiles('tier1_spawn'),
|
|
38
39
|
tier1_session: judgeLatencyPercentiles('tier1_session'),
|
|
39
40
|
tier1_connect: judgeLatencyPercentiles('tier1_connect'),
|
|
@@ -204,6 +204,18 @@ export async function stopJudgeBrokerDaemon(stateDir) {
|
|
|
204
204
|
catch {
|
|
205
205
|
// already stopped
|
|
206
206
|
}
|
|
207
|
+
const deadline = Date.now() + 1_000;
|
|
208
|
+
while (isProcessAlive(status.pid) && Date.now() < deadline) {
|
|
209
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
210
|
+
}
|
|
211
|
+
if (isProcessAlive(status.pid)) {
|
|
212
|
+
try {
|
|
213
|
+
process.kill(status.pid, 'SIGKILL');
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// already stopped
|
|
217
|
+
}
|
|
218
|
+
}
|
|
207
219
|
}
|
|
208
220
|
await cleanupJudgeBrokerArtifacts(paths);
|
|
209
221
|
return status?.pid ? 1 : 0;
|
|
@@ -102,6 +102,7 @@ export function resolveJudgeFromCatalog(input) {
|
|
|
102
102
|
const model = input.model?.trim() || spec.defaultModel;
|
|
103
103
|
const endpoint = input.endpoint !== undefined ? input.endpoint?.trim() || null : spec.defaultEndpoint;
|
|
104
104
|
return {
|
|
105
|
+
mode: 'shadow',
|
|
105
106
|
provider: spec.driver,
|
|
106
107
|
providerId: spec.id,
|
|
107
108
|
model,
|
|
@@ -2,4 +2,5 @@ import type { JudgeProviderId } from './judge-catalog.js';
|
|
|
2
2
|
export type CliFingerprintResolver = (providerId: Exclude<JudgeProviderId, 'ollama'>) => Promise<string>;
|
|
3
3
|
export declare function setCliFingerprintResolverForTests(resolver: CliFingerprintResolver | null): void;
|
|
4
4
|
export declare function resolveCliVersionFingerprint(providerId: Exclude<JudgeProviderId, 'ollama'>, timeoutMs?: number): Promise<string>;
|
|
5
|
+
export declare function resolveJudgeSessionFingerprint(providerId: Exclude<JudgeProviderId, 'ollama'>, timeoutMs?: number): Promise<string>;
|
|
5
6
|
export declare function resetCliFingerprintCache(): void;
|
|
@@ -56,6 +56,12 @@ export async function resolveCliVersionFingerprint(providerId, timeoutMs = 3_000
|
|
|
56
56
|
fingerprintCache.set(cacheKey, version);
|
|
57
57
|
return version;
|
|
58
58
|
}
|
|
59
|
+
export async function resolveJudgeSessionFingerprint(providerId, timeoutMs = 3_000) {
|
|
60
|
+
if (providerId === 'cursor' && !fingerprintResolver) {
|
|
61
|
+
return 'cursor-acp-v1';
|
|
62
|
+
}
|
|
63
|
+
return resolveCliVersionFingerprint(providerId, timeoutMs);
|
|
64
|
+
}
|
|
59
65
|
export function resetCliFingerprintCache() {
|
|
60
66
|
fingerprintCache.clear();
|
|
61
67
|
}
|
|
@@ -326,9 +326,11 @@ function createCliJudge(options) {
|
|
|
326
326
|
judgeTimeoutMs: timeoutMs,
|
|
327
327
|
},
|
|
328
328
|
}, { runCommand });
|
|
329
|
-
const traceTransport = transportResult.transport === '
|
|
330
|
-
?
|
|
331
|
-
: transport
|
|
329
|
+
const traceTransport = transportResult.transport === 'acp'
|
|
330
|
+
? 'cursor-acp'
|
|
331
|
+
: transportResult.transport === 'session'
|
|
332
|
+
? `${providerId}-cli-session`
|
|
333
|
+
: transport;
|
|
332
334
|
if (!transportResult.verdict) {
|
|
333
335
|
const fallbackReason = transportResult.fallbackReason ??
|
|
334
336
|
`${providerId}_cli_parse_error`;
|
|
@@ -14,7 +14,7 @@ export const JUDGE_PROVIDER_SESSION_MATRIX = {
|
|
|
14
14
|
'io_error',
|
|
15
15
|
'version_mismatch',
|
|
16
16
|
],
|
|
17
|
-
notes: 'Pilot provider:
|
|
17
|
+
notes: 'Pilot provider: persistent ACP in ask mode; bounded conversation reuse is broker-controlled.',
|
|
18
18
|
},
|
|
19
19
|
codex: {
|
|
20
20
|
providerId: 'codex',
|
|
@@ -40,3 +40,5 @@ export declare const DEFAULT_JUDGE_RUNTIME_CONFIG: BelayJudgeRuntimeConfig;
|
|
|
40
40
|
export declare function normalizeJudgeRuntimeConfig(runtime: Partial<BelayJudgeRuntimeConfig> | undefined): BelayJudgeRuntimeConfig;
|
|
41
41
|
export declare function normalizeJudgeSessionConfig(session: Partial<BelayJudgeSessionConfig> | undefined): BelayJudgeSessionConfig;
|
|
42
42
|
export declare function resolveSessionEvalTimeoutMs(sessionConfig: BelayJudgeSessionConfig, judgeTimeoutMs: number): number;
|
|
43
|
+
/** Live CLI smoke probes use the configured judge timeout without an artificial cap. */
|
|
44
|
+
export declare function resolveJudgeSmokeProbeTimeoutMs(judgeTimeoutMs: number): number;
|
|
@@ -9,11 +9,11 @@ export const JUDGE_LATENCY_SLO = {
|
|
|
9
9
|
sessionMaxP95Ms: 15_000,
|
|
10
10
|
};
|
|
11
11
|
export const DEFAULT_JUDGE_SESSION_CONFIG = {
|
|
12
|
-
enabled:
|
|
13
|
-
maxTurns:
|
|
14
|
-
maxAgeMs:
|
|
15
|
-
maxIdleMs:
|
|
16
|
-
maxPromptBytes:
|
|
12
|
+
enabled: true,
|
|
13
|
+
maxTurns: 8,
|
|
14
|
+
maxAgeMs: 10 * 60 * 1000,
|
|
15
|
+
maxIdleMs: 2 * 60 * 1000,
|
|
16
|
+
maxPromptBytes: 32 * 1024,
|
|
17
17
|
providerAllowlist: ['cursor'],
|
|
18
18
|
connectTimeoutMs: 5_000,
|
|
19
19
|
evalTimeoutMs: null,
|
|
@@ -73,7 +73,7 @@ export function normalizeJudgeRuntimeConfig(runtime) {
|
|
|
73
73
|
export function normalizeJudgeSessionConfig(session) {
|
|
74
74
|
const input = session ?? {};
|
|
75
75
|
return {
|
|
76
|
-
enabled: input.enabled ===
|
|
76
|
+
enabled: typeof input.enabled === 'boolean' ? input.enabled : DEFAULT_JUDGE_SESSION_CONFIG.enabled,
|
|
77
77
|
maxTurns: normalizePositiveInt(input.maxTurns, DEFAULT_JUDGE_SESSION_CONFIG.maxTurns),
|
|
78
78
|
maxAgeMs: normalizePositiveInt(input.maxAgeMs, DEFAULT_JUDGE_SESSION_CONFIG.maxAgeMs),
|
|
79
79
|
maxIdleMs: normalizePositiveInt(input.maxIdleMs, DEFAULT_JUDGE_SESSION_CONFIG.maxIdleMs),
|
|
@@ -90,3 +90,7 @@ export function normalizeJudgeSessionConfig(session) {
|
|
|
90
90
|
export function resolveSessionEvalTimeoutMs(sessionConfig, judgeTimeoutMs) {
|
|
91
91
|
return sessionConfig.evalTimeoutMs ?? judgeTimeoutMs;
|
|
92
92
|
}
|
|
93
|
+
/** Live CLI smoke probes use the configured judge timeout without an artificial cap. */
|
|
94
|
+
export function resolveJudgeSmokeProbeTimeoutMs(judgeTimeoutMs) {
|
|
95
|
+
return judgeTimeoutMs;
|
|
96
|
+
}
|
|
@@ -29,7 +29,7 @@ export interface JudgeSessionBrokerOptions {
|
|
|
29
29
|
}
|
|
30
30
|
export declare class JudgeSessionBroker {
|
|
31
31
|
private readonly sessions;
|
|
32
|
-
private readonly
|
|
32
|
+
private readonly providerMutexes;
|
|
33
33
|
private readonly options;
|
|
34
34
|
constructor(options: JudgeSessionBrokerOptions);
|
|
35
35
|
listSessions(): BrokerSessionRecord[];
|