@vibecheckai/cli 3.2.5 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/.generated +25 -25
- package/bin/dev/run-v2-torture.js +30 -30
- package/bin/registry.js +192 -5
- package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -295
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +280 -6
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +312 -4
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +113 -1
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +133 -6
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/analyzers.js +81 -18
- package/bin/runners/lib/api-client.js +269 -0
- package/bin/runners/lib/auth-truth.js +193 -193
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/backup.js +62 -62
- package/bin/runners/lib/billing.js +107 -107
- package/bin/runners/lib/claims.js +118 -118
- package/bin/runners/lib/cli-output.js +7 -1
- package/bin/runners/lib/cli-ui.js +540 -540
- package/bin/runners/lib/contracts/auth-contract.js +202 -202
- package/bin/runners/lib/contracts/env-contract.js +181 -181
- package/bin/runners/lib/contracts/external-contract.js +206 -206
- package/bin/runners/lib/contracts/guard.js +168 -168
- package/bin/runners/lib/contracts/index.js +89 -89
- package/bin/runners/lib/contracts/plan-validator.js +311 -311
- package/bin/runners/lib/contracts/route-contract.js +199 -199
- package/bin/runners/lib/contracts.js +804 -804
- package/bin/runners/lib/detect.js +89 -89
- package/bin/runners/lib/doctor/autofix.js +254 -254
- package/bin/runners/lib/doctor/index.js +37 -37
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -325
- package/bin/runners/lib/doctor/modules/index.js +46 -46
- package/bin/runners/lib/doctor/modules/network.js +250 -250
- package/bin/runners/lib/doctor/modules/project.js +312 -312
- package/bin/runners/lib/doctor/modules/runtime.js +224 -224
- package/bin/runners/lib/doctor/modules/security.js +348 -348
- package/bin/runners/lib/doctor/modules/system.js +213 -213
- package/bin/runners/lib/doctor/modules/vibecheck.js +394 -394
- package/bin/runners/lib/doctor/reporter.js +262 -262
- package/bin/runners/lib/doctor/service.js +262 -262
- package/bin/runners/lib/doctor/types.js +113 -113
- package/bin/runners/lib/doctor/ui.js +263 -263
- package/bin/runners/lib/doctor-v2.js +608 -608
- package/bin/runners/lib/drift.js +425 -425
- package/bin/runners/lib/enforcement.js +72 -72
- package/bin/runners/lib/enterprise-detect.js +603 -603
- package/bin/runners/lib/enterprise-init.js +942 -942
- package/bin/runners/lib/env-resolver.js +417 -417
- package/bin/runners/lib/env-template.js +66 -66
- package/bin/runners/lib/env.js +189 -189
- package/bin/runners/lib/error-handler.js +16 -9
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/extractors/client-calls.js +990 -990
- package/bin/runners/lib/extractors/fastify-route-dump.js +573 -573
- package/bin/runners/lib/extractors/fastify-routes.js +426 -426
- package/bin/runners/lib/extractors/index.js +363 -363
- package/bin/runners/lib/extractors/next-routes.js +524 -524
- package/bin/runners/lib/extractors/proof-graph.js +431 -431
- package/bin/runners/lib/extractors/route-matcher.js +451 -451
- package/bin/runners/lib/extractors/truthpack-v2.js +377 -377
- package/bin/runners/lib/extractors/ui-bindings.js +547 -547
- package/bin/runners/lib/findings-schema.js +281 -281
- package/bin/runners/lib/firewall-prompt.js +50 -50
- package/bin/runners/lib/global-flags.js +37 -0
- package/bin/runners/lib/graph/graph-builder.js +265 -265
- package/bin/runners/lib/graph/html-renderer.js +413 -413
- package/bin/runners/lib/graph/index.js +32 -32
- package/bin/runners/lib/graph/runtime-collector.js +215 -215
- package/bin/runners/lib/graph/static-extractor.js +518 -518
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/html-report.js +650 -650
- package/bin/runners/lib/llm.js +75 -75
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/meter.js +61 -61
- package/bin/runners/lib/missions/evidence.js +126 -126
- package/bin/runners/lib/patch.js +40 -40
- package/bin/runners/lib/permissions/auth-model.js +213 -213
- package/bin/runners/lib/permissions/idor-prover.js +205 -205
- package/bin/runners/lib/permissions/index.js +45 -45
- package/bin/runners/lib/permissions/matrix-builder.js +198 -198
- package/bin/runners/lib/pkgjson.js +28 -28
- package/bin/runners/lib/policy.js +295 -295
- package/bin/runners/lib/preflight.js +142 -142
- package/bin/runners/lib/reality/correlation-detectors.js +359 -359
- package/bin/runners/lib/reality/index.js +318 -318
- package/bin/runners/lib/reality/request-hashing.js +416 -416
- package/bin/runners/lib/reality/request-mapper.js +453 -453
- package/bin/runners/lib/reality/safety-rails.js +463 -463
- package/bin/runners/lib/reality/semantic-snapshot.js +408 -408
- package/bin/runners/lib/reality/toast-detector.js +393 -393
- package/bin/runners/lib/reality-findings.js +84 -84
- package/bin/runners/lib/receipts.js +179 -179
- package/bin/runners/lib/redact.js +29 -29
- package/bin/runners/lib/replay/capsule-manager.js +154 -154
- package/bin/runners/lib/replay/index.js +263 -263
- package/bin/runners/lib/replay/player.js +348 -348
- package/bin/runners/lib/replay/recorder.js +331 -331
- package/bin/runners/lib/report.js +135 -135
- package/bin/runners/lib/route-detection.js +1140 -1140
- package/bin/runners/lib/sandbox/index.js +59 -59
- package/bin/runners/lib/sandbox/proof-chain.js +399 -399
- package/bin/runners/lib/sandbox/sandbox-runner.js +205 -205
- package/bin/runners/lib/sandbox/worktree.js +174 -174
- package/bin/runners/lib/schema-validator.js +350 -350
- package/bin/runners/lib/schemas/contracts.schema.json +160 -160
- package/bin/runners/lib/schemas/finding.schema.json +100 -100
- package/bin/runners/lib/schemas/mission-pack.schema.json +206 -206
- package/bin/runners/lib/schemas/proof-graph.schema.json +176 -176
- package/bin/runners/lib/schemas/reality-report.schema.json +162 -162
- package/bin/runners/lib/schemas/share-pack.schema.json +180 -180
- package/bin/runners/lib/schemas/ship-report.schema.json +117 -117
- package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -303
- package/bin/runners/lib/schemas/validator.js +438 -438
- package/bin/runners/lib/score-history.js +282 -282
- package/bin/runners/lib/share-pack.js +239 -239
- package/bin/runners/lib/snippets.js +67 -67
- package/bin/runners/lib/unified-cli-output.js +604 -0
- package/bin/runners/lib/upsell.js +658 -510
- package/bin/runners/lib/usage.js +153 -153
- package/bin/runners/lib/validate-patch.js +156 -156
- package/bin/runners/lib/verdict-engine.js +628 -628
- package/bin/runners/reality/engine.js +917 -917
- package/bin/runners/reality/flows.js +122 -122
- package/bin/runners/reality/report.js +378 -378
- package/bin/runners/reality/session.js +193 -193
- package/bin/runners/runAgent.d.ts +5 -0
- package/bin/runners/runApprove.js +1200 -0
- package/bin/runners/runAuth.js +324 -95
- package/bin/runners/runCheckpoint.js +39 -21
- package/bin/runners/runClassify.js +859 -0
- package/bin/runners/runContext.js +136 -24
- package/bin/runners/runDoctor.js +108 -68
- package/bin/runners/runFirewall.d.ts +5 -0
- package/bin/runners/runFirewallHook.d.ts +5 -0
- package/bin/runners/runFix.js +6 -5
- package/bin/runners/runGuard.js +262 -168
- package/bin/runners/runInit.js +3 -2
- package/bin/runners/runMcp.js +130 -52
- package/bin/runners/runPolish.js +43 -20
- package/bin/runners/runProve.js +1 -2
- package/bin/runners/runReport.js +3 -2
- package/bin/runners/runScan.js +145 -44
- package/bin/runners/runShip.js +3 -4
- package/bin/runners/runTruth.d.ts +5 -0
- package/bin/runners/runValidate.js +19 -2
- package/bin/runners/runWatch.js +104 -53
- package/bin/vibecheck.js +106 -19
- package/mcp-server/HARDENING_SUMMARY.md +299 -0
- package/mcp-server/agent-firewall-interceptor.js +367 -31
- package/mcp-server/authority-tools.js +569 -0
- package/mcp-server/conductor/conflict-resolver.js +588 -0
- package/mcp-server/conductor/execution-planner.js +544 -0
- package/mcp-server/conductor/index.js +377 -0
- package/mcp-server/conductor/lock-manager.js +615 -0
- package/mcp-server/conductor/request-queue.js +550 -0
- package/mcp-server/conductor/session-manager.js +500 -0
- package/mcp-server/conductor/tools.js +510 -0
- package/mcp-server/index.js +1199 -208
- package/mcp-server/lib/api-client.cjs +305 -0
- package/mcp-server/lib/logger.cjs +30 -0
- package/mcp-server/logger.js +173 -0
- package/mcp-server/package.json +2 -2
- package/mcp-server/premium-tools.js +2 -2
- package/mcp-server/tier-auth.js +351 -136
- package/mcp-server/tools/index.js +72 -72
- package/mcp-server/truth-firewall-tools.js +145 -15
- package/mcp-server/vibecheck-tools.js +2 -2
- package/package.json +2 -3
- package/mcp-server/index.old.js +0 -4137
- package/mcp-server/package-lock.json +0 -165
package/mcp-server/tier-auth.js
CHANGED
|
@@ -1,157 +1,276 @@
|
|
|
1
|
+
/* vibecheck-disable */
|
|
1
2
|
/**
|
|
2
3
|
* MCP Server Tier Authentication & Authorization
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
+
* UNIFIED AUTHORITY SYSTEM for MCP tools.
|
|
6
|
+
*
|
|
7
|
+
* Authority Rules:
|
|
8
|
+
* - FREE: May see problems, never resolve certainty. Read-only context tools.
|
|
9
|
+
* - STARTER: May fix, but not prove. Read tools + advisory actions.
|
|
10
|
+
* - PRO: May enforce reality. Full MCP access with proof generation.
|
|
11
|
+
* - ENTERPRISE: All features + compliance tools.
|
|
12
|
+
*
|
|
13
|
+
* Verdict authority is paid. Evidence beats explanations.
|
|
5
14
|
*/
|
|
6
15
|
|
|
7
16
|
import fs from "fs/promises";
|
|
8
17
|
import path from "path";
|
|
9
18
|
import os from "os";
|
|
10
19
|
|
|
11
|
-
//
|
|
20
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
21
|
+
// TIER DEFINITIONS - UNIFIED AUTHORITY SYSTEM
|
|
22
|
+
// Synchronized with packages/core/src/tier-config.ts
|
|
23
|
+
//
|
|
24
|
+
// Authority Rules:
|
|
25
|
+
// - FREE: May see problems, never resolve certainty
|
|
26
|
+
// - STARTER: May fix, but not prove (Advisory verdicts only)
|
|
27
|
+
// - PRO: May enforce reality (Full verdict authority)
|
|
28
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
12
29
|
export const TIERS = {
|
|
13
30
|
free: {
|
|
14
31
|
name: 'FREE',
|
|
15
32
|
price: 0,
|
|
16
33
|
order: 0,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
'reality', 'reality.preview',
|
|
30
|
-
// MCP (help only)
|
|
31
|
-
'mcp.help_only',
|
|
32
|
-
// Report (html/md only)
|
|
33
|
-
'report', 'report.html_md',
|
|
34
|
-
],
|
|
34
|
+
// Verdict authority
|
|
35
|
+
verdictAuthority: 'NONE',
|
|
36
|
+
canIssueVerdicts: false,
|
|
37
|
+
canEnforceCI: false,
|
|
38
|
+
canGenerateProof: false,
|
|
39
|
+
// Agent Firewall configuration
|
|
40
|
+
firewall: {
|
|
41
|
+
mode: 'observe', // Log only, never block
|
|
42
|
+
canOverride: false, // Cannot override blocks
|
|
43
|
+
auditEnabled: false, // No audit trail
|
|
44
|
+
},
|
|
45
|
+
// Limits
|
|
35
46
|
limits: {
|
|
36
|
-
scans:
|
|
37
|
-
shipChecks: 20,
|
|
47
|
+
scans: -1, // Unlimited scans
|
|
38
48
|
realityMaxPages: 5,
|
|
39
49
|
realityMaxClicks: 20,
|
|
40
|
-
|
|
41
|
-
mcpRateLimit: 10, // requests per minute
|
|
50
|
+
mcpRateLimit: 10,
|
|
42
51
|
},
|
|
43
|
-
// MCP tools allowed on FREE
|
|
52
|
+
// MCP tools allowed on FREE (read-only context only)
|
|
44
53
|
mcpTools: [
|
|
45
54
|
'vibecheck.get_truthpack',
|
|
46
|
-
'vibecheck.validate_claim',
|
|
47
55
|
'vibecheck.compile_context',
|
|
48
56
|
'vibecheck.search_evidence',
|
|
57
|
+
'vibecheck_agent_firewall_intercept', // Observe mode
|
|
58
|
+
'vibecheck_conductor_status', // Read-only coordination status
|
|
59
|
+
// Authority System - FREE tier
|
|
60
|
+
'vibecheck.classify', // Inventory authority (read-only)
|
|
61
|
+
'vibecheck.authority_list', // List available authorities
|
|
49
62
|
],
|
|
63
|
+
// Authority System configuration
|
|
64
|
+
authority: {
|
|
65
|
+
canClassify: true, // Can run inventory analysis
|
|
66
|
+
canApprove: false, // Cannot get verdicts
|
|
67
|
+
canEnforce: false, // Cannot enforce in CI
|
|
68
|
+
canGenerateBadge: false, // Cannot generate badges
|
|
69
|
+
availableAuthorities: ['inventory'],
|
|
70
|
+
},
|
|
50
71
|
},
|
|
51
72
|
starter: {
|
|
52
73
|
name: 'STARTER',
|
|
53
|
-
price: 39,
|
|
74
|
+
price: 39,
|
|
54
75
|
order: 1,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Reality basic
|
|
68
|
-
'reality.basic',
|
|
69
|
-
// MCP read-only
|
|
70
|
-
'mcp', 'mcp.read_only',
|
|
71
|
-
// Ship full
|
|
72
|
-
'ship.full',
|
|
73
|
-
],
|
|
76
|
+
// Verdict authority - ADVISORY (verdicts not enforced)
|
|
77
|
+
verdictAuthority: 'ADVISORY',
|
|
78
|
+
canIssueVerdicts: true, // SHIP, WARN only
|
|
79
|
+
canEnforceCI: false, // Cannot block builds
|
|
80
|
+
canGenerateProof: false, // Cannot generate proof
|
|
81
|
+
// Agent Firewall configuration
|
|
82
|
+
firewall: {
|
|
83
|
+
mode: 'advisory', // Warn but allow
|
|
84
|
+
canOverride: true, // Can override with reason
|
|
85
|
+
auditEnabled: true, // Basic audit trail
|
|
86
|
+
},
|
|
87
|
+
// Limits
|
|
74
88
|
limits: {
|
|
75
|
-
scans: -1,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
fixApplyPatches: false,
|
|
80
|
-
mcpRateLimit: 60, // requests per minute
|
|
89
|
+
scans: -1, // Unlimited scans
|
|
90
|
+
realityMaxPages: -1, // Unlimited browser testing
|
|
91
|
+
realityMaxClicks: -1,
|
|
92
|
+
mcpRateLimit: 60,
|
|
81
93
|
},
|
|
82
|
-
// MCP tools allowed on STARTER (
|
|
94
|
+
// MCP tools allowed on STARTER (read + advisory actions)
|
|
83
95
|
mcpTools: [
|
|
84
96
|
'vibecheck.ctx',
|
|
85
97
|
'vibecheck.scan',
|
|
86
|
-
'vibecheck.ship',
|
|
98
|
+
'vibecheck.ship', // Advisory verdicts only
|
|
87
99
|
'vibecheck.get_truthpack',
|
|
88
100
|
'vibecheck.validate_claim',
|
|
89
101
|
'vibecheck.compile_context',
|
|
90
102
|
'vibecheck.search_evidence',
|
|
91
103
|
'vibecheck.find_counterexamples',
|
|
92
104
|
'vibecheck.check_invariants',
|
|
105
|
+
'vibecheck.fix', // Plan mode only
|
|
106
|
+
'vibecheck_agent_firewall_intercept', // Advisory mode
|
|
107
|
+
// Conductor - multi-agent coordination
|
|
108
|
+
'vibecheck_conductor_register',
|
|
109
|
+
'vibecheck_conductor_acquire_lock',
|
|
110
|
+
'vibecheck_conductor_release_lock',
|
|
111
|
+
'vibecheck_conductor_propose',
|
|
112
|
+
'vibecheck_conductor_status',
|
|
113
|
+
'vibecheck_conductor_terminate',
|
|
114
|
+
// Authority System - STARTER tier
|
|
115
|
+
'vibecheck.classify', // Inventory authority
|
|
116
|
+
'vibecheck.approve', // Advisory verdicts
|
|
117
|
+
'vibecheck.authority_list', // List authorities
|
|
118
|
+
'vibecheck.authority_approve', // Authority approval (advisory)
|
|
93
119
|
],
|
|
120
|
+
// Authority System configuration
|
|
121
|
+
authority: {
|
|
122
|
+
canClassify: true, // Can run inventory analysis
|
|
123
|
+
canApprove: true, // Can get advisory verdicts
|
|
124
|
+
canEnforce: false, // Cannot enforce in CI
|
|
125
|
+
canGenerateBadge: false, // Cannot generate badges
|
|
126
|
+
availableAuthorities: ['inventory', 'safe-consolidation'],
|
|
127
|
+
},
|
|
94
128
|
},
|
|
95
129
|
pro: {
|
|
96
130
|
name: 'PRO',
|
|
97
131
|
price: 99,
|
|
98
132
|
order: 2,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
'
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
'mcp.full',
|
|
113
|
-
],
|
|
133
|
+
// Verdict authority - ENFORCED (verdicts block CI/PRs)
|
|
134
|
+
verdictAuthority: 'ENFORCED',
|
|
135
|
+
canIssueVerdicts: true, // SHIP, WARN, BLOCK
|
|
136
|
+
canEnforceCI: true, // Can block builds
|
|
137
|
+
canGenerateProof: true, // Can generate cryptographic proof
|
|
138
|
+
// Agent Firewall configuration
|
|
139
|
+
firewall: {
|
|
140
|
+
mode: 'enforce', // Block violations
|
|
141
|
+
canOverride: true, // Can override with approval
|
|
142
|
+
auditEnabled: true, // Full audit trail
|
|
143
|
+
criticEnabled: true, // Enable Critic LLM
|
|
144
|
+
},
|
|
145
|
+
// Limits
|
|
114
146
|
limits: {
|
|
115
|
-
scans: -1,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
147
|
+
scans: -1,
|
|
148
|
+
realityMaxPages: -1,
|
|
149
|
+
realityMaxClicks: -1,
|
|
150
|
+
mcpRateLimit: -1, // Unlimited
|
|
151
|
+
},
|
|
152
|
+
// MCP tools - FULL ACCESS
|
|
153
|
+
mcpTools: ['*'], // All tools unlocked
|
|
154
|
+
// Authority System configuration
|
|
155
|
+
authority: {
|
|
156
|
+
canClassify: true, // Can run inventory analysis
|
|
157
|
+
canApprove: true, // Can get verdicts
|
|
158
|
+
canEnforce: true, // Can enforce in CI (STOP verdicts block)
|
|
159
|
+
canGenerateBadge: true, // Can generate authority badges
|
|
160
|
+
availableAuthorities: ['inventory', 'safe-consolidation', 'security-remediation'],
|
|
121
161
|
},
|
|
122
|
-
// MCP tools allowed on PRO (curated)
|
|
123
|
-
mcpTools: [
|
|
124
|
-
'vibecheck.ctx',
|
|
125
|
-
'vibecheck.scan',
|
|
126
|
-
'vibecheck.ship',
|
|
127
|
-
'vibecheck.get_truthpack',
|
|
128
|
-
'vibecheck.validate_claim',
|
|
129
|
-
'vibecheck.compile_context',
|
|
130
|
-
'vibecheck.search_evidence',
|
|
131
|
-
'vibecheck.find_counterexamples',
|
|
132
|
-
'vibecheck.check_invariants',
|
|
133
|
-
],
|
|
134
162
|
},
|
|
135
|
-
|
|
136
|
-
name: '
|
|
137
|
-
price: 0, //
|
|
163
|
+
enterprise: {
|
|
164
|
+
name: 'ENTERPRISE',
|
|
165
|
+
price: 0, // Custom pricing
|
|
138
166
|
order: 3,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
167
|
+
// Verdict authority - ENFORCED + Compliance
|
|
168
|
+
verdictAuthority: 'ENFORCED',
|
|
169
|
+
canIssueVerdicts: true,
|
|
170
|
+
canEnforceCI: true,
|
|
171
|
+
canGenerateProof: true,
|
|
172
|
+
// Agent Firewall configuration
|
|
173
|
+
firewall: {
|
|
174
|
+
mode: 'enforce', // Block violations
|
|
175
|
+
canOverride: true, // Can override with multi-approval
|
|
176
|
+
auditEnabled: true, // Full compliance audit trail
|
|
177
|
+
criticEnabled: true, // Enable Critic LLM
|
|
178
|
+
complianceMode: true, // Generate compliance artifacts
|
|
179
|
+
},
|
|
180
|
+
// Limits
|
|
143
181
|
limits: {
|
|
144
|
-
scans: -1,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
realityMaxClicks: -1,
|
|
148
|
-
fixApplyPatches: true,
|
|
182
|
+
scans: -1,
|
|
183
|
+
realityMaxPages: -1,
|
|
184
|
+
realityMaxClicks: -1,
|
|
149
185
|
mcpRateLimit: -1,
|
|
150
186
|
},
|
|
151
|
-
|
|
187
|
+
// MCP tools - FULL ACCESS + Compliance
|
|
188
|
+
mcpTools: ['*'],
|
|
189
|
+
// Authority System configuration
|
|
190
|
+
authority: {
|
|
191
|
+
canClassify: true, // Can run inventory analysis
|
|
192
|
+
canApprove: true, // Can get verdicts
|
|
193
|
+
canEnforce: true, // Can enforce in CI (STOP verdicts block)
|
|
194
|
+
canGenerateBadge: true, // Can generate authority badges
|
|
195
|
+
canCustomize: true, // Can create custom authorities
|
|
196
|
+
availableAuthorities: ['*'], // All authorities including custom
|
|
197
|
+
},
|
|
152
198
|
}
|
|
153
199
|
};
|
|
154
200
|
|
|
201
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
202
|
+
// CLI FEATURE → TIER MAPPING
|
|
203
|
+
// Maps CLI features (not MCP tools) to minimum required tier
|
|
204
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
205
|
+
export const CLI_FEATURE_TIERS = {
|
|
206
|
+
// FREE - Basic scanning (always available)
|
|
207
|
+
'scan': 'free',
|
|
208
|
+
'ctx': 'free',
|
|
209
|
+
'ship': 'free',
|
|
210
|
+
'classify': 'free', // Authority: inventory (read-only)
|
|
211
|
+
|
|
212
|
+
// STARTER - Enhanced features
|
|
213
|
+
'gate': 'starter',
|
|
214
|
+
'badge': 'starter',
|
|
215
|
+
'fix': 'starter', // Plan mode
|
|
216
|
+
'approve': 'starter', // Authority: advisory verdicts
|
|
217
|
+
'authority.starter': 'starter', // Authority System access
|
|
218
|
+
|
|
219
|
+
// PRO - Full enforcement
|
|
220
|
+
'prove': 'pro',
|
|
221
|
+
'fix.apply_patches': 'pro', // Apply mode
|
|
222
|
+
'reality': 'pro',
|
|
223
|
+
'autopilot': 'pro',
|
|
224
|
+
'verify': 'pro',
|
|
225
|
+
'authority.pro': 'pro', // Authority: enforced verdicts + badges
|
|
226
|
+
'authority.enforce': 'pro', // Authority: CI blocking
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
230
|
+
// MCP TOOL → TIER MAPPING (Unified Authority System)
|
|
231
|
+
// Aligned with packages/core/src/features.ts
|
|
232
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
233
|
+
export const MCP_TOOL_TIERS = {
|
|
234
|
+
// FREE - Read-only context tools ONLY
|
|
235
|
+
// Free users may see problems, never resolve certainty
|
|
236
|
+
'vibecheck.get_truthpack': 'free',
|
|
237
|
+
'vibecheck.compile_context': 'free',
|
|
238
|
+
'vibecheck.search_evidence': 'free',
|
|
239
|
+
'vibecheck_agent_firewall_intercept': 'free', // Observe mode only
|
|
240
|
+
'vibecheck.classify': 'free', // Authority: inventory (read-only)
|
|
241
|
+
'vibecheck.authority_list': 'free', // List available authorities
|
|
242
|
+
|
|
243
|
+
// STARTER - Advisory verdict authority
|
|
244
|
+
// Starter users may fix, but not prove
|
|
245
|
+
'vibecheck.ctx': 'starter',
|
|
246
|
+
'vibecheck.scan': 'starter',
|
|
247
|
+
'vibecheck.ship': 'starter', // SHIP/WARN (advisory, not enforced)
|
|
248
|
+
'vibecheck.fix': 'starter', // Plan mode only (no apply)
|
|
249
|
+
'vibecheck.validate_claim': 'starter',
|
|
250
|
+
'vibecheck.find_counterexamples': 'starter',
|
|
251
|
+
'vibecheck.check_invariants': 'starter',
|
|
252
|
+
'vibecheck.gate': 'starter', // Advisory gates
|
|
253
|
+
'vibecheck.badge': 'starter', // Unverified badges
|
|
254
|
+
'vibecheck.approve': 'starter', // Authority: advisory verdicts
|
|
255
|
+
'vibecheck.authority_approve': 'starter', // Authority approval (advisory)
|
|
256
|
+
|
|
257
|
+
// PRO - Full verdict authority & enforcement
|
|
258
|
+
// Pro users may enforce reality
|
|
259
|
+
'vibecheck.prove': 'pro', // Cryptographic proof generation
|
|
260
|
+
'vibecheck.fix.apply': 'pro', // Apply fixes
|
|
261
|
+
'vibecheck.fix.verify': 'pro', // Verify fixes with proof
|
|
262
|
+
'vibecheck.reality': 'pro', // Full browser testing
|
|
263
|
+
'vibecheck.reality.prove': 'pro', // Prove runtime behavior
|
|
264
|
+
'vibecheck.enforce': 'pro', // Enforce verdicts in CI
|
|
265
|
+
'vibecheck.ai_test': 'pro', // AI agent testing
|
|
266
|
+
'vibecheck.autopilot': 'pro', // Autonomous protection
|
|
267
|
+
'vibecheck.report': 'pro', // Advanced reporting
|
|
268
|
+
'vibecheck.allowlist': 'pro', // Manage allowlists
|
|
269
|
+
'vibecheck.status': 'pro', // Advanced status
|
|
270
|
+
'vibecheck.authority_enforce': 'pro', // Authority: enforced verdicts
|
|
271
|
+
'vibecheck.authority_badge': 'pro', // Authority: generate badges
|
|
272
|
+
};
|
|
273
|
+
|
|
155
274
|
/**
|
|
156
275
|
* Load user configuration from ~/.vibecheck/credentials.json
|
|
157
276
|
*/
|
|
@@ -165,50 +284,149 @@ async function loadUserConfig() {
|
|
|
165
284
|
}
|
|
166
285
|
}
|
|
167
286
|
|
|
287
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
288
|
+
// SECURE TIER VALIDATION - API-First with Caching
|
|
289
|
+
// SECURITY: Never trust API key prefix alone - always validate with API
|
|
290
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
291
|
+
|
|
168
292
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
293
|
+
* Tier cache to avoid hammering the API on every request
|
|
294
|
+
* Structure: Map<apiKeyHash, { tier, validatedAt, expiresAt }>
|
|
295
|
+
*/
|
|
296
|
+
const tierCache = new Map();
|
|
297
|
+
const TIER_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
298
|
+
const TIER_CACHE_MAX_SIZE = 1000; // Prevent unbounded growth
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Hash API key for cache key (don't store raw keys in memory)
|
|
302
|
+
*/
|
|
303
|
+
function hashApiKey(apiKey) {
|
|
304
|
+
const crypto = require('crypto');
|
|
305
|
+
return crypto.createHash('sha256').update(apiKey).digest('hex').slice(0, 32);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Evict expired entries and enforce max size
|
|
310
|
+
*/
|
|
311
|
+
function cleanupTierCache() {
|
|
312
|
+
const now = Date.now();
|
|
313
|
+
for (const [key, value] of tierCache) {
|
|
314
|
+
if (value.expiresAt < now) {
|
|
315
|
+
tierCache.delete(key);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
// If still too large, evict oldest entries
|
|
319
|
+
if (tierCache.size > TIER_CACHE_MAX_SIZE) {
|
|
320
|
+
const entries = Array.from(tierCache.entries())
|
|
321
|
+
.sort((a, b) => a[1].validatedAt - b[1].validatedAt);
|
|
322
|
+
const toDelete = entries.slice(0, tierCache.size - TIER_CACHE_MAX_SIZE);
|
|
323
|
+
for (const [key] of toDelete) {
|
|
324
|
+
tierCache.delete(key);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Determine tier from API key - ALWAYS validates with API first
|
|
331
|
+
*
|
|
332
|
+
* SECURITY FIX: Previous version checked prefix patterns BEFORE API validation,
|
|
333
|
+
* allowing attackers to spoof tier with fake keys like "gr_pro_anything".
|
|
334
|
+
* Now we ALWAYS validate with API first. Prefix is never authoritative.
|
|
335
|
+
*
|
|
336
|
+
* @param {string} apiKey - The API key to validate
|
|
337
|
+
* @returns {Promise<string|null>} - Tier name or null if invalid
|
|
171
338
|
*/
|
|
172
339
|
async function getTierFromApiKey(apiKey) {
|
|
173
|
-
if (!apiKey
|
|
340
|
+
if (!apiKey || typeof apiKey !== 'string') return null;
|
|
341
|
+
|
|
342
|
+
// Validate key format (basic sanity check)
|
|
343
|
+
if (apiKey.length < 10 || apiKey.length > 256) return null;
|
|
174
344
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
345
|
+
const keyHash = hashApiKey(apiKey);
|
|
346
|
+
const now = Date.now();
|
|
347
|
+
|
|
348
|
+
// Check cache first (only if not expired)
|
|
349
|
+
const cached = tierCache.get(keyHash);
|
|
350
|
+
if (cached && cached.expiresAt > now) {
|
|
351
|
+
return cached.tier;
|
|
352
|
+
}
|
|
180
353
|
|
|
181
|
-
//
|
|
354
|
+
// ALWAYS validate with API - this is the authoritative source
|
|
182
355
|
try {
|
|
356
|
+
const controller = new AbortController();
|
|
357
|
+
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10s timeout
|
|
358
|
+
|
|
183
359
|
const response = await fetch('https://api.vibecheckai.dev/whoami', {
|
|
184
360
|
headers: {
|
|
185
361
|
'Authorization': `Bearer ${apiKey}`,
|
|
186
362
|
'Content-Type': 'application/json',
|
|
187
363
|
},
|
|
364
|
+
signal: controller.signal,
|
|
188
365
|
});
|
|
189
366
|
|
|
367
|
+
clearTimeout(timeoutId);
|
|
368
|
+
|
|
190
369
|
if (!response.ok) {
|
|
191
|
-
|
|
370
|
+
// API explicitly rejected this key - it's invalid
|
|
371
|
+
// Cache the rejection briefly to avoid hammering on invalid keys
|
|
372
|
+
tierCache.set(keyHash, {
|
|
373
|
+
tier: null,
|
|
374
|
+
validatedAt: now,
|
|
375
|
+
expiresAt: now + 60000, // Cache rejections for 1 minute
|
|
376
|
+
});
|
|
377
|
+
return null;
|
|
192
378
|
}
|
|
193
379
|
|
|
194
380
|
const data = await response.json();
|
|
195
381
|
|
|
196
382
|
// Map API response to tier
|
|
383
|
+
let tier;
|
|
197
384
|
switch (data.plan?.toLowerCase()) {
|
|
198
385
|
case 'starter':
|
|
199
|
-
|
|
386
|
+
tier = 'starter';
|
|
387
|
+
break;
|
|
200
388
|
case 'pro':
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
389
|
+
tier = 'pro';
|
|
390
|
+
break;
|
|
391
|
+
case 'enterprise':
|
|
392
|
+
tier = 'enterprise';
|
|
393
|
+
break;
|
|
204
394
|
default:
|
|
205
|
-
|
|
395
|
+
tier = 'free';
|
|
206
396
|
}
|
|
397
|
+
|
|
398
|
+
// Cache the validated tier
|
|
399
|
+
tierCache.set(keyHash, {
|
|
400
|
+
tier,
|
|
401
|
+
validatedAt: now,
|
|
402
|
+
expiresAt: now + TIER_CACHE_TTL_MS,
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// Periodic cleanup
|
|
406
|
+
if (tierCache.size > TIER_CACHE_MAX_SIZE * 0.9) {
|
|
407
|
+
cleanupTierCache();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return tier;
|
|
411
|
+
|
|
207
412
|
} catch (error) {
|
|
208
|
-
|
|
209
|
-
|
|
413
|
+
// Network error - check if we have a recent valid cache entry
|
|
414
|
+
// (This allows graceful degradation during brief network issues)
|
|
415
|
+
if (cached && cached.tier !== null) {
|
|
416
|
+
// Only use stale cache if it was validated within last 15 minutes
|
|
417
|
+
// and the original validation was successful (tier !== null)
|
|
418
|
+
const staleTolerance = 15 * 60 * 1000; // 15 minutes
|
|
419
|
+
if (now - cached.validatedAt < staleTolerance) {
|
|
420
|
+
console.error(`[TIER-AUTH] API unreachable, using stale cache for ${keyHash.slice(0, 8)}...`);
|
|
421
|
+
return cached.tier;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// No valid cache - fail closed for security
|
|
426
|
+
console.error('[TIER-AUTH] API validation failed with no valid cache, denying access:', error.message);
|
|
427
|
+
return null;
|
|
210
428
|
}
|
|
211
|
-
}
|
|
429
|
+
}
|
|
212
430
|
|
|
213
431
|
/**
|
|
214
432
|
* Check if user has access to a specific feature
|
|
@@ -240,28 +458,20 @@ export async function getFeatureAccessStatus(featureName, providedApiKey = null)
|
|
|
240
458
|
}
|
|
241
459
|
const currentTierConfig = TIERS[currentTier];
|
|
242
460
|
|
|
243
|
-
// Find which tier
|
|
244
|
-
|
|
245
|
-
let requiredTierConfig = null;
|
|
246
|
-
|
|
247
|
-
for (const [tierName, tierConfig] of Object.entries(TIERS)) {
|
|
248
|
-
if (tierConfig.features.includes(featureName)) {
|
|
249
|
-
requiredTier = tierName;
|
|
250
|
-
requiredTierConfig = tierConfig;
|
|
251
|
-
break;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
461
|
+
// Find which tier requires this feature using CLI_FEATURE_TIERS mapping
|
|
462
|
+
const requiredTier = CLI_FEATURE_TIERS[featureName];
|
|
254
463
|
|
|
255
|
-
// If feature not found in
|
|
464
|
+
// If feature not found in mapping, allow it (default to free)
|
|
256
465
|
if (!requiredTier) {
|
|
257
466
|
return {
|
|
258
|
-
hasAccess:
|
|
467
|
+
hasAccess: true,
|
|
259
468
|
tier: currentTier,
|
|
260
|
-
reason:
|
|
261
|
-
upgradeUrl: 'https://vibecheckai.dev'
|
|
469
|
+
reason: `Feature '${featureName}' has no tier restriction`
|
|
262
470
|
};
|
|
263
471
|
}
|
|
264
472
|
|
|
473
|
+
const requiredTierConfig = TIERS[requiredTier];
|
|
474
|
+
|
|
265
475
|
// Check if current tier meets minimum requirement (using order)
|
|
266
476
|
const hasAccess = currentTierConfig.order >= requiredTierConfig.order;
|
|
267
477
|
|
|
@@ -287,7 +497,7 @@ export async function getFeatureAccessStatus(featureName, providedApiKey = null)
|
|
|
287
497
|
*/
|
|
288
498
|
export function withTierCheck(featureName, handler) {
|
|
289
499
|
return async (args) => {
|
|
290
|
-
const access = await
|
|
500
|
+
const access = await getFeatureAccessStatus(featureName, args?.apiKey);
|
|
291
501
|
|
|
292
502
|
if (!access.hasAccess) {
|
|
293
503
|
return {
|
|
@@ -393,7 +603,7 @@ export async function getMcpToolAccess(toolName, providedApiKey = null) {
|
|
|
393
603
|
*/
|
|
394
604
|
export function withMcpToolCheck(toolName, handler) {
|
|
395
605
|
return async (args) => {
|
|
396
|
-
const access = await
|
|
606
|
+
const access = await getMcpToolAccess(toolName, args?.apiKey);
|
|
397
607
|
|
|
398
608
|
if (!access.hasAccess) {
|
|
399
609
|
return {
|
|
@@ -427,12 +637,17 @@ export async function getUserInfo() {
|
|
|
427
637
|
const tier = getTierFromApiKey(config.apiKey);
|
|
428
638
|
const tierConfig = TIERS[tier];
|
|
429
639
|
|
|
640
|
+
// Get features available for this tier from CLI_FEATURE_TIERS
|
|
641
|
+
const availableFeatures = Object.entries(CLI_FEATURE_TIERS)
|
|
642
|
+
.filter(([, reqTier]) => TIERS[reqTier].order <= tierConfig.order)
|
|
643
|
+
.map(([feature]) => feature);
|
|
644
|
+
|
|
430
645
|
return {
|
|
431
646
|
authenticated: true,
|
|
432
647
|
tier,
|
|
433
648
|
email: config.email,
|
|
434
649
|
authenticatedAt: config.authenticatedAt,
|
|
435
|
-
features:
|
|
650
|
+
features: availableFeatures,
|
|
436
651
|
limits: tierConfig.limits,
|
|
437
652
|
mcpTools: tierConfig.mcpTools,
|
|
438
653
|
};
|