@veil-runtime/core 0.1.0 → 0.1.2

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/NOTICE ADDED
@@ -0,0 +1,5 @@
1
+ Veil
2
+ Copyright 2026 Mustapha Keraan
3
+
4
+ This software is licensed under the Apache License, Version 2.0.
5
+ See LICENSE for the license terms.
package/README.md CHANGED
@@ -353,67 +353,101 @@ Optional:
353
353
 
354
354
  ---
355
355
 
356
- ## Installation
357
-
358
- Install the public runtime package in an application:
359
-
360
- ```bash
361
- npm install @veil-runtime/core
362
- ```
363
-
364
- Create and execute a capability through the public API:
365
-
366
- ```ts
367
- import {
368
- createCapability,
369
- OperatorRuntime,
370
- type CapabilityModule,
371
- type ExecutionPlan,
372
- } from '@veil-runtime/core';
373
-
374
- const echo = createCapability<{ value: string }, string>({
375
- name: 'example.echo',
376
- version: '1.0.0',
377
- description: 'Return the provided value',
378
- risk: 'read',
379
- async execute({ input }) {
380
- return input.value;
381
- },
382
- });
383
-
384
- const module: CapabilityModule = {
385
- manifest: {
386
- name: 'example',
387
- version: '1.0.0',
388
- capabilities: [echo.name],
389
- },
390
- capabilities: [echo],
391
- };
392
-
393
- const plan: ExecutionPlan = {
394
- version: '1.0',
395
- steps: [{
396
- id: 'echo',
397
- capability: echo.name,
398
- capabilityVersion: echo.version,
399
- input: { value: 'Hello from Veil' },
400
- }],
401
- };
402
-
403
- const runtime = new OperatorRuntime();
404
- runtime.use(module);
405
-
406
- const job = await runtime.executePlan(plan);
407
- console.log(job.status, job.result);
408
- ```
409
-
410
- This public-package usage is compile- and execution-verified by the release
411
- consumer fixture. Internal `src`, `dist`, registry, provider, and storage
412
- subpaths are intentionally unavailable.
413
-
414
- ## Repository development
415
-
416
- Clone the repository:
356
+ ## Installation
357
+
358
+ Install the public runtime package in an application:
359
+
360
+ ```bash
361
+ npm install @veil-runtime/core
362
+ ```
363
+
364
+ Create and execute a capability through the public API:
365
+
366
+ ```ts
367
+ import {
368
+ createCapability,
369
+ OperatorRuntime,
370
+ type CapabilityModule,
371
+ type ExecutionPlan,
372
+ } from '@veil-runtime/core';
373
+
374
+ const echo = createCapability<{ value: string }, string>({
375
+ name: 'example.echo',
376
+ version: '1.0.0',
377
+ description: 'Return the provided value',
378
+ risk: 'read',
379
+ async execute({ input }) {
380
+ return input.value;
381
+ },
382
+ });
383
+
384
+ const module: CapabilityModule = {
385
+ manifest: {
386
+ name: 'example',
387
+ version: '1.0.0',
388
+ capabilities: [echo.name],
389
+ },
390
+ capabilities: [echo],
391
+ };
392
+
393
+ const plan: ExecutionPlan = {
394
+ version: '1.0',
395
+ steps: [{
396
+ id: 'echo',
397
+ capability: echo.name,
398
+ capabilityVersion: echo.version,
399
+ input: { value: 'Hello from Veil' },
400
+ }],
401
+ };
402
+
403
+ const runtime = new OperatorRuntime();
404
+ runtime.use(module);
405
+
406
+ const job = await runtime.executePlan(plan);
407
+ console.log(job.status, job.result);
408
+ ```
409
+
410
+ This public-package usage is compile- and execution-verified by the release
411
+ consumer fixture. Internal `src`, `dist`, registry, provider, and storage
412
+ subpaths are intentionally unavailable.
413
+
414
+ ### Contextual execution authorization
415
+
416
+ An application may supply a runtime-scoped authorizer. Veil resolves and
417
+ validates the step input before invoking it, and does not start a denied
418
+ capability:
419
+
420
+ ```ts
421
+ import {
422
+ OperatorRuntime,
423
+ type ExecutionAuthorizer,
424
+ } from '@veil-runtime/core';
425
+
426
+ const authorizer: ExecutionAuthorizer = {
427
+ async authorize({ capability, input }) {
428
+ if (
429
+ capability.name === 'deploy.trigger' &&
430
+ typeof input === 'object' &&
431
+ input !== null &&
432
+ 'environment' in input &&
433
+ input.environment === 'production'
434
+ ) {
435
+ return {
436
+ decision: 'deny',
437
+ reason: 'Production deployment is not allowed.',
438
+ };
439
+ }
440
+
441
+ return { decision: 'allow' };
442
+ },
443
+ };
444
+
445
+ const runtime = new OperatorRuntime({ authorizer });
446
+ ```
447
+
448
+ ## Repository development
449
+
450
+ Clone the repository:
417
451
 
418
452
  ```bash
419
453
  git clone git@github.com:veil-runtime/veil.git
@@ -478,3 +512,11 @@ Veil will:
478
512
  3. Generate an `ExecutionPlan`.
479
513
  4. Execute the plan through `OperatorRuntime`.
480
514
  5. Return the completed job.
515
+
516
+ ---
517
+
518
+ # License and branding
519
+
520
+ Veil Core is licensed under Apache-2.0. Copyright 2026 Mustapha Keraan.
521
+ Veil names, logos, and branding are governed separately; see
522
+ [TRADEMARKS.md](TRADEMARKS.md) for the brand policy.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { OperatorRuntime, operatorRuntime } from './runtime/operator-runtime.js';
2
2
  export type { ExecutePlanOptions, RunJobOptions } from './runtime/operator-runtime.js';
3
+ export type { OperatorRuntimeOptions } from './runtime/operator-runtime.js';
4
+ export type { CapabilityAuthorizationContext, CapabilityAuthorizationDecision, ExecutionAuthorizer, } from './runtime/permissions/execution-authorizer.js';
3
5
  export type { ExecutionPlan, ExecutionStep, Planner, PlannerContext, ResultReference, } from './runtime/planner/planner.js';
4
6
  export type { ExecutionCaller, ExecutionContext } from './runtime/execution/execution-context.js';
5
7
  export type { Capability, CapabilityInputField, CapabilityRisk, } from './runtime/registry/capability.js';
@@ -10,4 +12,5 @@ export type { JobStep, JobStepStatus } from './runtime/jobs/job-step.js';
10
12
  export type { JobStatus } from './runtime/jobs/job-status.js';
11
13
  export type { JobEvent } from './runtime/jobs/job-event.js';
12
14
  export type { RuntimeEvent } from './runtime/events/runtime-event.js';
15
+ export { McpAdapter } from './integrations/mcp/inbound/mcp-adapter.js';
13
16
  export * from './sdk/index.js';
package/dist/index.js CHANGED
@@ -14,8 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.operatorRuntime = exports.OperatorRuntime = void 0;
17
+ exports.McpAdapter = exports.operatorRuntime = exports.OperatorRuntime = void 0;
18
18
  var operator_runtime_js_1 = require("./runtime/operator-runtime.js");
19
19
  Object.defineProperty(exports, "OperatorRuntime", { enumerable: true, get: function () { return operator_runtime_js_1.OperatorRuntime; } });
20
20
  Object.defineProperty(exports, "operatorRuntime", { enumerable: true, get: function () { return operator_runtime_js_1.operatorRuntime; } });
21
+ var mcp_adapter_js_1 = require("./integrations/mcp/inbound/mcp-adapter.js");
22
+ Object.defineProperty(exports, "McpAdapter", { enumerable: true, get: function () { return mcp_adapter_js_1.McpAdapter; } });
21
23
  __exportStar(require("./sdk/index.js"), exports);
@@ -0,0 +1,3 @@
1
+ import * as z from 'zod/v4';
2
+ import { CapabilityInputField } from '../../../runtime/registry/capability.js';
3
+ export declare function createMcpInputSchema(inputSchema: Record<string, CapabilityInputField>): Record<string, z.ZodType>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createMcpInputSchema = createMcpInputSchema;
37
+ const z = __importStar(require("zod/v4"));
38
+ function createFieldSchema(field) {
39
+ let schema;
40
+ switch (field.type) {
41
+ case 'string':
42
+ schema = z.string();
43
+ break;
44
+ case 'number':
45
+ schema = z.number();
46
+ break;
47
+ case 'boolean':
48
+ schema = z.boolean();
49
+ break;
50
+ case 'array':
51
+ schema = z.array(z.unknown());
52
+ break;
53
+ case 'object':
54
+ schema = z.record(z.string(), z.unknown());
55
+ break;
56
+ default:
57
+ schema = z.unknown();
58
+ break;
59
+ }
60
+ if (field.description) {
61
+ schema = schema.describe(field.description);
62
+ }
63
+ if (!field.required) {
64
+ schema = schema.optional();
65
+ }
66
+ return schema;
67
+ }
68
+ function createMcpInputSchema(inputSchema) {
69
+ return Object.fromEntries(Object.entries(inputSchema).map(([name, field]) => [
70
+ name,
71
+ createFieldSchema(field),
72
+ ]));
73
+ }
@@ -0,0 +1,8 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { OperatorRuntime } from '../../../runtime/operator-runtime.js';
3
+ export declare class McpAdapter {
4
+ private readonly runtime;
5
+ readonly server: McpServer;
6
+ constructor(runtime: OperatorRuntime);
7
+ private registerCapabilities;
8
+ }
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.McpAdapter = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
6
+ const capability_schema_js_1 = require("./capability-schema.js");
7
+ class McpAdapter {
8
+ runtime;
9
+ server;
10
+ constructor(runtime) {
11
+ this.runtime = runtime;
12
+ this.server =
13
+ new mcp_js_1.McpServer({
14
+ name: 'veil',
15
+ version: '0.1.0',
16
+ });
17
+ this.registerCapabilities();
18
+ }
19
+ registerCapabilities() {
20
+ const capabilities = this.runtime.listCapabilities();
21
+ for (const capability of capabilities) {
22
+ this.server.registerTool(capability.name, {
23
+ description: capability.description,
24
+ inputSchema: (0, capability_schema_js_1.createMcpInputSchema)(capability.inputSchema),
25
+ }, async (input) => {
26
+ try {
27
+ const plan = {
28
+ version: '1.0',
29
+ goal: `Execute MCP tool ${capability.name}`,
30
+ metadata: {
31
+ source: 'mcp',
32
+ tool: capability.name,
33
+ },
34
+ steps: [
35
+ {
36
+ id: (0, node_crypto_1.randomUUID)(),
37
+ capability: capability.name,
38
+ input,
39
+ reason: 'Requested through MCP',
40
+ },
41
+ ],
42
+ };
43
+ const job = await this.runtime.executePlan(plan);
44
+ const step = job.steps[0];
45
+ if (!step) {
46
+ return {
47
+ content: [
48
+ {
49
+ type: 'text',
50
+ text: 'Veil execution completed without a job step result',
51
+ },
52
+ ],
53
+ isError: true,
54
+ };
55
+ }
56
+ if (step.status ===
57
+ 'failed') {
58
+ return {
59
+ content: [
60
+ {
61
+ type: 'text',
62
+ text: step.error ??
63
+ 'Veil capability execution failed',
64
+ },
65
+ ],
66
+ isError: true,
67
+ };
68
+ }
69
+ return {
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: JSON.stringify(step.result ??
74
+ null, null, 2),
75
+ },
76
+ ],
77
+ };
78
+ }
79
+ catch (error) {
80
+ const message = error instanceof Error
81
+ ? error.message
82
+ : 'Unknown Veil execution error';
83
+ return {
84
+ content: [
85
+ {
86
+ type: 'text',
87
+ text: message,
88
+ },
89
+ ],
90
+ isError: true,
91
+ };
92
+ }
93
+ });
94
+ }
95
+ }
96
+ }
97
+ exports.McpAdapter = McpAdapter;
@@ -1,4 +1,4 @@
1
- export type JobEventType = 'job.created' | 'planning.started' | 'planning.completed' | 'approval.requested' | 'approval.granted' | 'execution.started' | 'capability.started' | 'capability.completed' | 'capability.failed' | 'job.completed' | 'job.failed' | 'job.cancelled' | 'job.reviewed';
1
+ export type JobEventType = 'job.created' | 'planning.started' | 'planning.completed' | 'approval.requested' | 'approval.granted' | 'execution.started' | 'capability.denied' | 'capability.started' | 'capability.completed' | 'capability.failed' | 'job.completed' | 'job.failed' | 'job.cancelled' | 'job.reviewed';
2
2
  export interface JobEvent {
3
3
  id: string;
4
4
  jobId: string;
@@ -1,15 +1,16 @@
1
+ import { ExecutionAuthorizer } from '../permissions/execution-authorizer.js';
1
2
  import { ExecutionPlan } from '../planner/planner.js';
2
3
  import { ExecutionCaller } from '../execution/execution-context.js';
3
4
  import { Job, JobOutcome } from './job.js';
4
5
  import { JobStatus } from './job-status.js';
5
6
  import { JobListFilter } from './job-store.js';
6
7
  declare class JobManager {
7
- executePlan(plan: ExecutionPlan, caller?: ExecutionCaller): Promise<Job>;
8
+ executePlan(plan: ExecutionPlan, caller?: ExecutionCaller, authorizer?: ExecutionAuthorizer): Promise<Job>;
8
9
  create(goal: string, planner?: string): Promise<Job>;
9
10
  get(id: string): Promise<Job | undefined>;
10
11
  list(filter?: JobListFilter): Promise<Job[]>;
11
12
  setStatus(id: string, status: JobStatus): Promise<Job>;
12
- execute(id: string, caller?: ExecutionCaller): Promise<Job>;
13
+ execute(id: string, caller?: ExecutionCaller, authorizer?: ExecutionAuthorizer): Promise<Job>;
13
14
  review(id: string, outcome: JobOutcome, notes?: string): Promise<Job>;
14
15
  private addEvent;
15
16
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.jobManager = void 0;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const registry_js_1 = require("../registry/registry.js");
6
- const permissions_js_1 = require("../permissions/permissions.js");
6
+ const execution_authorizer_js_1 = require("../permissions/execution-authorizer.js");
7
7
  const plan_validator_js_1 = require("../execution/plan-validator.js");
8
8
  const result_reference_js_1 = require("../execution/result-reference.js");
9
9
  const memory_event_bus_js_1 = require("../events/memory-event-bus.js");
@@ -13,7 +13,7 @@ const console_log_sink_js_1 = require("../logging/console-log-sink.js");
13
13
  const composite_log_sink_js_1 = require("../logging/composite-log-sink.js");
14
14
  const sqlite_log_sink_js_1 = require("../logging/sqlite-log-sink.js");
15
15
  class JobManager {
16
- async executePlan(plan, caller) {
16
+ async executePlan(plan, caller, authorizer = execution_authorizer_js_1.defaultExecutionAuthorizer) {
17
17
  if (!plan.steps.length) {
18
18
  throw new Error('Execution plan contains no steps');
19
19
  }
@@ -35,7 +35,7 @@ class JobManager {
35
35
  job.updatedAt =
36
36
  new Date().toISOString();
37
37
  await job_store_js_1.jobStore.update(job);
38
- return this.execute(job.id, caller);
38
+ return this.execute(job.id, caller, authorizer);
39
39
  }
40
40
  async create(goal, planner) {
41
41
  if (!goal?.trim()) {
@@ -74,7 +74,7 @@ class JobManager {
74
74
  await job_store_js_1.jobStore.update(job);
75
75
  return job;
76
76
  }
77
- async execute(id, caller) {
77
+ async execute(id, caller, authorizer = execution_authorizer_js_1.defaultExecutionAuthorizer) {
78
78
  const job = await job_store_js_1.jobStore.get(id);
79
79
  if (!job) {
80
80
  throw new Error(`Job not found: ${id}`);
@@ -92,17 +92,6 @@ class JobManager {
92
92
  if (!capability) {
93
93
  throw new Error(`Capability not found: ${step.capability}`);
94
94
  }
95
- const permission = (0, permissions_js_1.checkPermission)(capability.risk);
96
- if (!permission.allowed) {
97
- throw new Error(permission.reason ??
98
- `Capability not permitted: ${step.capability}`);
99
- }
100
- step.status = 'running';
101
- step.startedAt = new Date().toISOString();
102
- this.addEvent(job, 'capability.started', {
103
- stepId: step.id,
104
- capability: step.capability,
105
- });
106
95
  try {
107
96
  const completedSteps = job.steps.slice(0, job.steps.indexOf(step));
108
97
  const resolvedInput = (0, result_reference_js_1.resolveResultReferences)(step.input, completedSteps);
@@ -112,6 +101,37 @@ class JobManager {
112
101
  .map((validationError) => validationError.message)
113
102
  .join('; '));
114
103
  }
104
+ const authorization = await authorizer.authorize({
105
+ jobId: job.id,
106
+ stepId: step.id,
107
+ capability: {
108
+ name: capability.name,
109
+ version: capability.version,
110
+ risk: capability.risk,
111
+ },
112
+ input: resolvedInput,
113
+ caller,
114
+ });
115
+ if (authorization.decision === 'deny') {
116
+ const message = authorization.reason ??
117
+ `Capability not permitted: ${step.capability}`;
118
+ step.status = 'failed';
119
+ step.error = message;
120
+ step.completedAt = new Date().toISOString();
121
+ this.addEvent(job, 'capability.denied', {
122
+ stepId: step.id,
123
+ capability: capability.name,
124
+ risk: capability.risk,
125
+ reason: authorization.reason,
126
+ });
127
+ throw new AuthorizationDeniedError(message);
128
+ }
129
+ step.status = 'running';
130
+ step.startedAt = new Date().toISOString();
131
+ this.addEvent(job, 'capability.started', {
132
+ stepId: step.id,
133
+ capability: step.capability,
134
+ });
115
135
  const logger = new console_execution_logger_js_1.ConsoleExecutionLogger(job.id, step.id, new composite_log_sink_js_1.CompositeLogSink([
116
136
  new console_log_sink_js_1.ConsoleLogSink(),
117
137
  new sqlite_log_sink_js_1.SQLiteLogSink(),
@@ -131,6 +151,9 @@ class JobManager {
131
151
  });
132
152
  }
133
153
  catch (error) {
154
+ if (error instanceof AuthorizationDeniedError) {
155
+ throw error;
156
+ }
134
157
  const message = error instanceof Error
135
158
  ? error.message
136
159
  : 'Unknown capability execution error';
@@ -211,4 +234,6 @@ class JobManager {
211
234
  return event;
212
235
  }
213
236
  }
237
+ class AuthorizationDeniedError extends Error {
238
+ }
214
239
  exports.jobManager = new JobManager();
@@ -1,6 +1,7 @@
1
1
  import { Job } from './jobs/job.js';
2
2
  import { JobListFilter } from './jobs/job-store.js';
3
3
  import { ExecutionCaller } from './execution/execution-context.js';
4
+ import { ExecutionAuthorizer } from './permissions/execution-authorizer.js';
4
5
  import { CapabilityModule } from './modules/capability-module.js';
5
6
  import { ExecutionPlan } from './planner/planner.js';
6
7
  export interface RunJobOptions {
@@ -11,7 +12,12 @@ export interface RunJobOptions {
11
12
  export interface ExecutePlanOptions {
12
13
  caller?: ExecutionCaller;
13
14
  }
15
+ export interface OperatorRuntimeOptions {
16
+ readonly authorizer?: ExecutionAuthorizer;
17
+ }
14
18
  export declare class OperatorRuntime {
19
+ private readonly authorizer;
20
+ constructor(options?: OperatorRuntimeOptions);
15
21
  use(module: CapabilityModule): void;
16
22
  executePlan(plan: ExecutionPlan, options?: ExecutePlanOptions): Promise<Job>;
17
23
  run(goal: string, options?: RunJobOptions): Promise<Job>;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.operatorRuntime = exports.OperatorRuntime = void 0;
4
4
  const job_manager_js_1 = require("./jobs/job-manager.js");
5
5
  const job_memory_js_1 = require("./jobs/job-memory.js");
6
+ const execution_authorizer_js_1 = require("./permissions/execution-authorizer.js");
6
7
  const registry_js_1 = require("./registry/registry.js");
7
8
  const planner_registry_js_1 = require("./planner/planner-registry.js");
8
9
  const planner_router_registry_js_1 = require("./planner/planner-router-registry.js");
@@ -21,6 +22,12 @@ function immutableCaller(caller) {
21
22
  });
22
23
  }
23
24
  class OperatorRuntime {
25
+ authorizer;
26
+ constructor(options = {}) {
27
+ this.authorizer =
28
+ options.authorizer ??
29
+ execution_authorizer_js_1.defaultExecutionAuthorizer;
30
+ }
24
31
  use(module) {
25
32
  const declared = new Set(module.manifest.capabilities);
26
33
  for (const capability of module.capabilities) {
@@ -31,7 +38,7 @@ class OperatorRuntime {
31
38
  }
32
39
  }
33
40
  async executePlan(plan, options = {}) {
34
- return job_manager_js_1.jobManager.executePlan(plan, immutableCaller(options.caller));
41
+ return job_manager_js_1.jobManager.executePlan(plan, immutableCaller(options.caller), this.authorizer);
35
42
  }
36
43
  async run(goal, options = {}) {
37
44
  const router = planner_router_registry_js_1.plannerRouterRegistry.getDefault();
@@ -0,0 +1,23 @@
1
+ import { ExecutionCaller } from '../execution/execution-context.js';
2
+ import { CapabilityRisk } from '../registry/capability.js';
3
+ export interface CapabilityAuthorizationContext {
4
+ readonly jobId: string;
5
+ readonly stepId: string;
6
+ readonly capability: {
7
+ readonly name: string;
8
+ readonly version: string;
9
+ readonly risk: CapabilityRisk;
10
+ };
11
+ readonly input: unknown;
12
+ readonly caller?: ExecutionCaller;
13
+ }
14
+ export type CapabilityAuthorizationDecision = {
15
+ readonly decision: 'allow';
16
+ } | {
17
+ readonly decision: 'deny';
18
+ readonly reason?: string;
19
+ };
20
+ export interface ExecutionAuthorizer {
21
+ authorize(context: CapabilityAuthorizationContext): Promise<CapabilityAuthorizationDecision>;
22
+ }
23
+ export declare const defaultExecutionAuthorizer: ExecutionAuthorizer;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultExecutionAuthorizer = void 0;
4
+ const permissions_js_1 = require("./permissions.js");
5
+ exports.defaultExecutionAuthorizer = {
6
+ async authorize({ capability }) {
7
+ const permission = (0, permissions_js_1.checkPermission)(capability.risk);
8
+ if (permission.allowed) {
9
+ return { decision: 'allow' };
10
+ }
11
+ return {
12
+ decision: 'deny',
13
+ reason: permission.reason,
14
+ };
15
+ },
16
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veil-runtime/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "A governed, capability-driven execution runtime",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -30,7 +30,8 @@
30
30
  "files": [
31
31
  "dist",
32
32
  "README.md",
33
- "LICENSE"
33
+ "LICENSE",
34
+ "NOTICE"
34
35
  ],
35
36
  "type": "commonjs",
36
37
  "scripts": {
@@ -55,16 +56,16 @@
55
56
  ],
56
57
  "author": "Mustapha",
57
58
  "dependencies": {
59
+ "@modelcontextprotocol/sdk": "^1.30.0",
60
+ "zod": "^4.4.3",
58
61
  "better-sqlite3": "^13.0.3"
59
62
  },
60
63
  "devDependencies": {
61
- "@modelcontextprotocol/sdk": "^1.30.0",
62
64
  "@types/better-sqlite3": "^9.6.0",
63
65
  "@types/node": "^26.2.0",
64
66
  "fastify": "^5.11.3",
65
67
  "playwright": "^1.62.1",
66
68
  "tsx": "^4.23.12",
67
- "typescript": "^7.0.2",
68
- "zod": "^4.4.3"
69
+ "typescript": "^7.0.2"
69
70
  }
70
71
  }