@guilz-dev/belay 0.9.4 → 0.10.1
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 +3 -2
- package/dist/adapters/claude/runtime-entry.js +5 -18
- package/dist/adapters/codex/runtime-entry.js +10 -11
- package/dist/adapters/cursor/hook-dispatch-entry.d.ts +3 -0
- package/dist/adapters/cursor/hook-dispatch-entry.js +11 -0
- package/dist/adapters/cursor/hook-router.d.ts +1 -0
- package/dist/adapters/cursor/hook-router.js +39 -9
- package/dist/adapters/cursor/hook-routing-health.d.ts +1 -0
- package/dist/adapters/cursor/hook-routing-health.js +53 -0
- package/dist/adapters/cursor/hooks.d.ts +1 -1
- package/dist/adapters/cursor/hooks.js +16 -5
- package/dist/adapters/cursor/routing-config-trust.d.ts +1 -0
- package/dist/adapters/cursor/routing-config-trust.js +67 -0
- package/dist/adapters/cursor/runtime-entry.d.ts +2 -2
- package/dist/adapters/cursor/runtime-entry.js +35 -10
- package/dist/adapters/shared/gate-runtime.d.ts +0 -2
- package/dist/adapters/shared/gate-runtime.js +12 -52
- package/dist/bundle/claude-runtime.mjs +1083 -669
- package/dist/bundle/codex-runtime.mjs +1092 -698
- package/dist/bundle/cursor-dispatcher.mjs +119 -28
- package/dist/bundle/cursor-runtime.mjs +1132 -677
- package/dist/cli.js +53 -4
- package/dist/commands/approval-token.d.ts +10 -0
- package/dist/commands/approval-token.js +26 -0
- package/dist/commands/audit.d.ts +2 -1
- package/dist/commands/audit.js +2 -2
- package/dist/commands/config.d.ts +1 -1
- package/dist/commands/config.js +28 -2
- package/dist/commands/doctor.js +14 -54
- package/dist/commands/dogfood-check.d.ts +3 -0
- package/dist/commands/dogfood-check.js +116 -0
- package/dist/commands/dogfood.d.ts +1 -0
- package/dist/commands/dogfood.js +4 -3
- package/dist/commands/judge.js +2 -2
- package/dist/commands/recovery-checkpoints.js +2 -11
- package/dist/config-io.d.ts +1 -0
- package/dist/config-io.js +8 -1
- package/dist/core/capability/index.d.ts +1 -1
- package/dist/core/capability/index.js +1 -1
- package/dist/core/capability/policy-engine.d.ts +19 -0
- package/dist/core/capability/policy-engine.js +31 -0
- package/dist/core/classify-tool.js +372 -148
- package/dist/core/config.js +2 -2
- package/dist/core/dogfood-environment.d.ts +8 -0
- package/dist/core/dogfood-environment.js +55 -0
- package/dist/core/effect-ir/shell-lower/decoders/belay.js +12 -0
- package/dist/core/egress-approval.js +0 -18
- package/dist/core/gate-engine.js +2 -9
- package/dist/core/notify.d.ts +8 -2
- package/dist/core/notify.js +63 -7
- package/dist/core/recovery/operator-guidance.js +4 -4
- package/dist/core/repo-config-trust.d.ts +31 -0
- package/dist/core/repo-config-trust.js +152 -0
- package/dist/corpus/benign-probe-cores.d.ts +1 -1
- package/dist/corpus/benign-probe-cores.js +0 -1
- package/dist/defaults.js +0 -25
- package/dist/installer/scope-config.js +2 -2
- package/dist/installer.js +4 -4
- package/dist/types.d.ts +19 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -1
|
@@ -5,7 +5,6 @@ import path from 'node:path';
|
|
|
5
5
|
import { compactApprovals, createApprovalRecordWithEnvelope } from '../../core/approval.js';
|
|
6
6
|
import { buildReplayHint, buildRetryInstructionForConfig, canAutoReplay, getExecutionLeaseMs, validateReplayEnvelope, } from '../../core/approval-replay.js';
|
|
7
7
|
import { claimApprovedForReplay, gateApprovalStoreFromDeps, recordApproval, } from '../../core/approval-service.js';
|
|
8
|
-
import { issueApprovalToken } from '../../core/approval-token.js';
|
|
9
8
|
import { buildAuditActionSnapshot, buildAuditReplayContext, } from '../../core/audit-replay-context.js';
|
|
10
9
|
import { approvalCorrelationId, serializeAuditRecordV3, toolInvocationCorrelationId, } from '../../core/audit-serialize.js';
|
|
11
10
|
import { boundedUtf8Tail } from '../../core/bounded-output.js';
|
|
@@ -31,12 +30,13 @@ import { effectPlanAuditFields, hashEffectPlan } from '../../core/effect-ir/audi
|
|
|
31
30
|
import { buildCapabilityEffectPlan } from '../../core/effect-ir/build.js';
|
|
32
31
|
import { classifyResultToGateVerdict, unnormalizedGateVerdict, } from '../../core/gate-contract.js';
|
|
33
32
|
import { classifyGatedActionAsync, extractAgentAssessment, GateNormalizationError, gateEnabledForAction, normalizeGatedAction, } from '../../core/gate-engine.js';
|
|
34
|
-
import { approvalCommandMatch, approvedApprovalsFile, belayStateDir, canonicalStringify, classifierOptionsFromConfig, configuredControlPlaneDir, hashValue, pendingApprovalsFile, resolveControlPlaneDir, scrubOptionsFromConfig, scrubString, scrubValue,
|
|
33
|
+
import { approvalCommandMatch, approvedApprovalsFile, belayStateDir, canonicalStringify, classifierOptionsFromConfig, configuredControlPlaneDir, hashValue, pendingApprovalsFile, resolveControlPlaneDir, scrubOptionsFromConfig, scrubString, scrubValue, } from '../../core/index.js';
|
|
35
34
|
import { extractJudgeFallbackReason, formatJudgeInfrastructureDenyMessage, inferProviderIdFromFallbackReason, isJudgeInfrastructureFailure, } from '../../core/judge-fallback-hints.js';
|
|
36
35
|
import { notifyDeny } from '../../core/notify.js';
|
|
37
36
|
import { canonicalPath } from '../../core/path-utils.js';
|
|
38
37
|
import { recoveryFailClosedResult, recoveryFailReasonFromSkip, } from '../../core/recovery/fail-closed.js';
|
|
39
38
|
import { fingerprintReplayPayload, redactToolInvocationId } from '../../core/replay-scrub.js';
|
|
39
|
+
import { assertRepoConfigTrusted } from '../../core/repo-config-trust.js';
|
|
40
40
|
import { FILE_CHECKPOINT_ISOLATION_UNAVAILABLE, isTransactionalEligible, runTransactionalExecution, TRANSACTIONAL_ALREADY_APPLIED, TRANSACTIONAL_APPROVAL_BYPASS_REASONS, } from '../../core/transactional/index.js';
|
|
41
41
|
import { buildAuditProvenanceFields } from '../../runtime-provenance.js';
|
|
42
42
|
import { egressStatus } from '../../services/egress-service.js';
|
|
@@ -91,7 +91,15 @@ async function loadJsonFile(filePath, fallback) {
|
|
|
91
91
|
export function createDefaultGateRuntimeDeps() {
|
|
92
92
|
return {
|
|
93
93
|
async readConfig(configPath) {
|
|
94
|
-
|
|
94
|
+
try {
|
|
95
|
+
return JSON.parse(await readFile(configPath, 'utf8'));
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (error.code === 'ENOENT') {
|
|
99
|
+
return {};
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
95
103
|
},
|
|
96
104
|
async appendAudit(ctx, event) {
|
|
97
105
|
const auditPath = path.join(ctx.repoRoot, ctx.config.audit.logPath);
|
|
@@ -149,6 +157,7 @@ export function createDefaultGateRuntimeDeps() {
|
|
|
149
157
|
}
|
|
150
158
|
export async function resolveGateConfig(ctx, deps) {
|
|
151
159
|
const loaded = await deps.readConfig(ctx.configPath);
|
|
160
|
+
await assertRepoConfigTrusted(ctx.repoRoot, ctx.layout.name, loaded);
|
|
152
161
|
let teamConfig = null;
|
|
153
162
|
const teamPath = teamConfigPath();
|
|
154
163
|
if (existsSync(teamPath)) {
|
|
@@ -817,41 +826,6 @@ export async function evaluateGatedAction(ctx, deps, params) {
|
|
|
817
826
|
scopeHintPayload: params.payload,
|
|
818
827
|
});
|
|
819
828
|
}
|
|
820
|
-
/** R39: unmapped Codex tools ask via pending approval — not hard deny without approval path. */
|
|
821
|
-
export async function gateUnmappedToolVerdict(ctx, deps, toolName, payload) {
|
|
822
|
-
const scrubOpts = scrubOptionsFromConfig(ctx.config);
|
|
823
|
-
const replayPayload = fingerprintReplayPayload('tool', payload, scrubOpts) ?? {};
|
|
824
|
-
const result = {
|
|
825
|
-
verdict: 'deny_pending_approval',
|
|
826
|
-
reason: 'unmapped_tool',
|
|
827
|
-
summary: toolName,
|
|
828
|
-
fingerprint: toolFingerprint(toolName, replayPayload, ctx.repoRoot),
|
|
829
|
-
assessment: {
|
|
830
|
-
reversibility: 'irreversible',
|
|
831
|
-
external: false,
|
|
832
|
-
blastRadius: 'unknown Codex tool action',
|
|
833
|
-
confidence: 0.5,
|
|
834
|
-
signals: ['unmapped_tool'],
|
|
835
|
-
},
|
|
836
|
-
};
|
|
837
|
-
return gateDecisionToVerdict(ctx, deps, 'tool', result, {
|
|
838
|
-
approvalInput: {
|
|
839
|
-
input: toolName,
|
|
840
|
-
inputKind: 'tool',
|
|
841
|
-
cwd: ctx.repoRoot,
|
|
842
|
-
toolName,
|
|
843
|
-
payload: replayPayload,
|
|
844
|
-
},
|
|
845
|
-
replayAction: {
|
|
846
|
-
kind: 'tool',
|
|
847
|
-
cwd: ctx.repoRoot,
|
|
848
|
-
toolName,
|
|
849
|
-
payload: replayPayload,
|
|
850
|
-
fingerprint: result.fingerprint,
|
|
851
|
-
repoRoot: ctx.repoRoot,
|
|
852
|
-
},
|
|
853
|
-
});
|
|
854
|
-
}
|
|
855
829
|
async function consumeCapabilityGrantIfUsed(ctx, deps, result) {
|
|
856
830
|
if (result.reason !== 'capability_grant' &&
|
|
857
831
|
result.authorizationDecision?.matchedRule !== 'grant.exact') {
|
|
@@ -937,19 +911,6 @@ async function gateDecisionToVerdict(ctx, deps, kind, result, auditExtras = {})
|
|
|
937
911
|
if (created) {
|
|
938
912
|
await recordGateApprovalAsk(stateDir, result.reason, false);
|
|
939
913
|
}
|
|
940
|
-
let approvalToken;
|
|
941
|
-
try {
|
|
942
|
-
approvalToken = await issueApprovalToken({
|
|
943
|
-
approvalId: approval.approvalId,
|
|
944
|
-
fingerprint: approval.fingerprint,
|
|
945
|
-
repoRoot: approval.repoRoot,
|
|
946
|
-
issuedAt: approval.createdAt,
|
|
947
|
-
expiresAt: approval.expiresAt,
|
|
948
|
-
}, configuredControlPlaneDir(ctx.config));
|
|
949
|
-
}
|
|
950
|
-
catch {
|
|
951
|
-
approvalToken = undefined;
|
|
952
|
-
}
|
|
953
914
|
const denialReason = failure?.reason ?? result.reason;
|
|
954
915
|
if (ctx.config.notifications.webhookUrl || ctx.config.notifications.commandHook) {
|
|
955
916
|
await notifyDeny(ctx.config.notifications, {
|
|
@@ -958,7 +919,6 @@ async function gateDecisionToVerdict(ctx, deps, kind, result, auditExtras = {})
|
|
|
958
919
|
summary: result.normalizedCommand ?? result.summary ?? '',
|
|
959
920
|
repoRoot: ctx.repoRoot,
|
|
960
921
|
fingerprint: result.fingerprint,
|
|
961
|
-
approvalToken,
|
|
962
922
|
});
|
|
963
923
|
}
|
|
964
924
|
const failureAuditFields = typeof failure?.auditFields === 'function'
|