@codmir/contracts 0.1.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.
@@ -0,0 +1,1233 @@
1
+ /**
2
+ * @fileoverview
3
+ * Codmir Contract Schema v1
4
+ *
5
+ * Contracts are versioned, JSON-serializable, and deterministic.
6
+ * They define what autonomous agents are allowed to do, their triggers,
7
+ * permissions, steps, and execution policies.
8
+ */
9
+ type IsoDateString = string;
10
+ type ContractId = string;
11
+ type ContractVersion = string;
12
+ type StepId = string;
13
+ type RunId = string;
14
+ type EventName = string;
15
+ type JsonValue = string | number | boolean | null | {
16
+ [k: string]: JsonValue;
17
+ } | JsonValue[];
18
+ /**
19
+ * Permission types that a contract can request.
20
+ * Engine/Policy adapter enforces these before any action.
21
+ */
22
+ type Permission = {
23
+ kind: "event:emit";
24
+ pattern: string;
25
+ } | {
26
+ kind: "event:read";
27
+ pattern: string;
28
+ } | {
29
+ kind: "storage:read";
30
+ scope: string;
31
+ } | {
32
+ kind: "storage:write";
33
+ scope: string;
34
+ } | {
35
+ kind: "repo:read";
36
+ scope: string;
37
+ } | {
38
+ kind: "repo:write";
39
+ scope: string;
40
+ } | {
41
+ kind: "http:request";
42
+ domains: string[];
43
+ } | {
44
+ kind: "secrets:read";
45
+ keys: string[];
46
+ } | {
47
+ kind: "llm:invoke";
48
+ models?: string[];
49
+ };
50
+ /**
51
+ * Contract trigger definition.
52
+ * Specifies which events can start a new run of this contract.
53
+ */
54
+ type ContractTrigger = {
55
+ type: "event";
56
+ /**
57
+ * Event pattern support:
58
+ * - exact match: "ticket.created"
59
+ * - wildcard: "ticket.*"
60
+ */
61
+ event: string;
62
+ /**
63
+ * Optional filter conditions on event payload.
64
+ * Engine evaluates these deterministically.
65
+ */
66
+ where?: Record<string, JsonValue>;
67
+ };
68
+ type RetryPolicy = {
69
+ maxAttempts: number;
70
+ backoffMs: number;
71
+ backoffMultiplier?: number;
72
+ };
73
+ type StepTimeout = {
74
+ /** Hard timeout in milliseconds */
75
+ ms: number;
76
+ };
77
+ /**
78
+ * Deterministic condition expression for branching and step guards.
79
+ * Evaluated against run context (JSON-like object).
80
+ */
81
+ type ConditionExpr = {
82
+ op: "eq";
83
+ path: string;
84
+ value: JsonValue;
85
+ } | {
86
+ op: "neq";
87
+ path: string;
88
+ value: JsonValue;
89
+ } | {
90
+ op: "gt";
91
+ path: string;
92
+ value: number;
93
+ } | {
94
+ op: "gte";
95
+ path: string;
96
+ value: number;
97
+ } | {
98
+ op: "lt";
99
+ path: string;
100
+ value: number;
101
+ } | {
102
+ op: "lte";
103
+ path: string;
104
+ value: number;
105
+ } | {
106
+ op: "and";
107
+ exprs: ConditionExpr[];
108
+ } | {
109
+ op: "or";
110
+ exprs: ConditionExpr[];
111
+ } | {
112
+ op: "not";
113
+ expr: ConditionExpr;
114
+ } | {
115
+ op: "exists";
116
+ path: string;
117
+ } | {
118
+ op: "contains";
119
+ path: string;
120
+ value: string;
121
+ } | {
122
+ op: "startsWith";
123
+ path: string;
124
+ value: string;
125
+ } | {
126
+ op: "endsWith";
127
+ path: string;
128
+ value: string;
129
+ };
130
+ type StepKind = "task" | "llm" | "emit" | "wait" | "branch" | "transform" | "approval" | "skill" | "audit";
131
+ type StepBase = {
132
+ id: StepId;
133
+ name: string;
134
+ kind: StepKind;
135
+ timeout?: StepTimeout;
136
+ retry?: RetryPolicy;
137
+ /**
138
+ * If present, the step is skipped unless condition resolves true.
139
+ * Condition must be deterministic (based on run context).
140
+ */
141
+ if?: ConditionExpr;
142
+ /**
143
+ * Next step pointer. Some step kinds may override this (branch/wait).
144
+ */
145
+ next?: StepId | null;
146
+ /**
147
+ * Optional description for documentation/debugging.
148
+ */
149
+ description?: string;
150
+ };
151
+ /**
152
+ * Task step - executes a named task in runtime (Railway).
153
+ */
154
+ type TaskStep = StepBase & {
155
+ kind: "task";
156
+ /**
157
+ * A runtime-registered task name, e.g. "analyze-ticket", "apply-patch".
158
+ */
159
+ task: string;
160
+ /**
161
+ * Inputs are pulled from run context (event payload + accumulated outputs).
162
+ * Engine resolves {{path}} templates deterministically.
163
+ */
164
+ input: Record<string, JsonValue>;
165
+ /**
166
+ * Where to store the step output in run context.
167
+ * Example: "steps.analyzeTicket"
168
+ */
169
+ saveAs?: string;
170
+ };
171
+ /**
172
+ * LLM step - calls intelligence adapter.
173
+ */
174
+ type LlmStep = StepBase & {
175
+ kind: "llm";
176
+ model?: string;
177
+ /**
178
+ * Messages or prompt template. Keep JSON-serializable.
179
+ */
180
+ prompt: Record<string, JsonValue>;
181
+ /**
182
+ * Where to store the LLM response in run context.
183
+ */
184
+ saveAs?: string;
185
+ /**
186
+ * Optional system prompt.
187
+ */
188
+ systemPrompt?: string;
189
+ /**
190
+ * Temperature for generation (0-1).
191
+ */
192
+ temperature?: number;
193
+ /**
194
+ * Max tokens for response.
195
+ */
196
+ maxTokens?: number;
197
+ };
198
+ /**
199
+ * Emit step - emits an event to the event bus.
200
+ */
201
+ type EmitStep = StepBase & {
202
+ kind: "emit";
203
+ event: EventName;
204
+ payload: Record<string, JsonValue>;
205
+ };
206
+ /**
207
+ * Wait step - waits for an external event to arrive.
208
+ */
209
+ type WaitStep = StepBase & {
210
+ kind: "wait";
211
+ /**
212
+ * Wait for a specific event name/pattern to arrive.
213
+ * When matched, engine stores it and proceeds.
214
+ */
215
+ event: string;
216
+ /**
217
+ * Where to store the received event payload in run context.
218
+ */
219
+ saveEventAs?: string;
220
+ /**
221
+ * Alternative next step if timeout is reached.
222
+ */
223
+ nextOnTimeout?: StepId | null;
224
+ };
225
+ /**
226
+ * Branch step - conditional branching based on run context.
227
+ */
228
+ type BranchStep = StepBase & {
229
+ kind: "branch";
230
+ branches: Array<{
231
+ when: ConditionExpr;
232
+ next: StepId;
233
+ }>;
234
+ defaultNext: StepId;
235
+ };
236
+ /**
237
+ * Transform step - pure data transformation within run context.
238
+ */
239
+ type TransformStep = StepBase & {
240
+ kind: "transform";
241
+ /**
242
+ * Transformations to apply to run context.
243
+ * Each key is a destination path, value is a template or expression.
244
+ */
245
+ transforms: Record<string, JsonValue>;
246
+ };
247
+ /**
248
+ * Approval step - human-in-the-loop gate (Overseer pattern).
249
+ * Pauses execution until approved/denied by authorized actor.
250
+ */
251
+ type ApprovalStep = StepBase & {
252
+ kind: "approval";
253
+ /**
254
+ * Human-readable description of what is being approved.
255
+ */
256
+ prompt: string;
257
+ /**
258
+ * Users/roles who can approve this step.
259
+ */
260
+ approvers?: string[];
261
+ /**
262
+ * Next step if approved.
263
+ */
264
+ nextOnApproved: StepId;
265
+ /**
266
+ * Next step if denied (optional - run fails if not specified).
267
+ */
268
+ nextOnDenied?: StepId | null;
269
+ /**
270
+ * Timeout behavior - defaults to deny.
271
+ */
272
+ timeoutAction?: "deny" | "approve" | "fail";
273
+ /**
274
+ * Context data to show the approver.
275
+ */
276
+ context?: Record<string, JsonValue>;
277
+ };
278
+ /**
279
+ * Skill step - executes a fine-tuned skill (Claude Code integration).
280
+ */
281
+ type SkillStep = StepBase & {
282
+ kind: "skill";
283
+ /**
284
+ * ID of the skill to execute.
285
+ * @example "tickets.plan", "code.review", "tests.generate"
286
+ */
287
+ skillId: string;
288
+ /**
289
+ * Input to pass to the skill (templates resolved from run context).
290
+ */
291
+ input: Record<string, JsonValue>;
292
+ /**
293
+ * Where to save skill output in run context.
294
+ */
295
+ saveAs?: string;
296
+ /**
297
+ * Next step after skill completes.
298
+ */
299
+ next?: StepId | null;
300
+ };
301
+ /**
302
+ * Audit step - audits code changes with AI analysis (Governor pattern).
303
+ * Fetches changes between commits, analyzes with full context, generates findings.
304
+ */
305
+ type AuditStep = StepBase & {
306
+ kind: "audit";
307
+ /**
308
+ * Target repository (path or URL).
309
+ */
310
+ repository: string;
311
+ /**
312
+ * From commit reference (SHA, tag, or branch).
313
+ * Templates allowed: {{event.payload.baseCommit}}
314
+ */
315
+ fromCommit: string;
316
+ /**
317
+ * To commit reference (SHA, tag, or branch).
318
+ * Templates allowed: {{event.payload.headCommit}}
319
+ */
320
+ toCommit: string;
321
+ /**
322
+ * Include conversation context in analysis.
323
+ */
324
+ includeConversation?: boolean;
325
+ /**
326
+ * Include AI reasoning context in analysis.
327
+ */
328
+ includeReasoning?: boolean;
329
+ /**
330
+ * Minimum severity to report.
331
+ */
332
+ minSeverity?: "critical" | "high" | "medium" | "low" | "info";
333
+ /**
334
+ * Auto-approve if no issues above threshold.
335
+ */
336
+ autoApproveThreshold?: "critical" | "high" | "medium" | "low";
337
+ /**
338
+ * Where to save audit result in run context.
339
+ */
340
+ saveAs?: string;
341
+ /**
342
+ * Next step after audit completes.
343
+ */
344
+ next?: StepId | null;
345
+ /**
346
+ * Next step if audit fails or rejects.
347
+ */
348
+ nextOnReject?: StepId | null;
349
+ };
350
+ type ContractStep = TaskStep | LlmStep | EmitStep | WaitStep | BranchStep | TransformStep | ApprovalStep | SkillStep | AuditStep;
351
+ /**
352
+ * Expected duration category for smart sync/async routing.
353
+ */
354
+ type ExpectedDuration = "instant" | "quick" | "medium" | "long";
355
+ /**
356
+ * Execution mode preference.
357
+ */
358
+ type ExecutionMode = "sync" | "async" | "auto";
359
+ /**
360
+ * Execution hints for realtime/voice callers.
361
+ * Helps the engine decide whether to wait for completion or return immediately.
362
+ */
363
+ type ExecutionHints = {
364
+ /**
365
+ * Expected duration category for smart routing:
366
+ * - instant: < 2s (DB write, simple API call)
367
+ * - quick: 2-30s (external API, light processing)
368
+ * - medium: 30s-5min (code analysis, file operations)
369
+ * - long: > 5min (deployments, heavy computation)
370
+ */
371
+ expectedDuration: ExpectedDuration;
372
+ /**
373
+ * Override: max milliseconds voice/realtime callers should wait.
374
+ * Default is derived from expectedDuration.
375
+ */
376
+ syncThreshold?: number;
377
+ /**
378
+ * Preferred execution mode:
379
+ * - sync: Caller waits for result (blocking)
380
+ * - async: Fire-and-forget, notify via events
381
+ * - auto: Engine decides based on expectedDuration (default)
382
+ */
383
+ mode?: ExecutionMode;
384
+ /**
385
+ * Can the caller interrupt/cancel mid-execution?
386
+ */
387
+ interruptible?: boolean;
388
+ /**
389
+ * Human-friendly message for async acknowledgment.
390
+ * Example: "I'm deploying that now, I'll let you know when it's ready."
391
+ */
392
+ asyncAckMessage?: string;
393
+ };
394
+ /**
395
+ * Default sync thresholds per duration category (in milliseconds).
396
+ */
397
+ declare const DURATION_SYNC_THRESHOLDS: Record<ExpectedDuration, number>;
398
+ type ContractLimits = {
399
+ /**
400
+ * Total run time cap enforced by engine.
401
+ */
402
+ maxRunMs: number;
403
+ /**
404
+ * Maximum number of steps executed to avoid infinite loops.
405
+ */
406
+ maxSteps: number;
407
+ /**
408
+ * Maximum LLM invocations per run.
409
+ */
410
+ maxLlmCalls?: number;
411
+ /**
412
+ * Maximum total tokens consumed per run.
413
+ */
414
+ maxTokens?: number;
415
+ };
416
+ type ContractOutputs = {
417
+ /**
418
+ * Events emitted at run completion (success).
419
+ */
420
+ onCompleted?: Array<{
421
+ event: EventName;
422
+ payload: Record<string, JsonValue>;
423
+ }>;
424
+ /**
425
+ * Events emitted at run failure.
426
+ */
427
+ onFailed?: Array<{
428
+ event: EventName;
429
+ payload: Record<string, JsonValue>;
430
+ }>;
431
+ /**
432
+ * Events emitted when run is cancelled.
433
+ */
434
+ onCancelled?: Array<{
435
+ event: EventName;
436
+ payload: Record<string, JsonValue>;
437
+ }>;
438
+ };
439
+ /**
440
+ * Codmir Contract v1
441
+ *
442
+ * A contract is a declarative agreement describing:
443
+ * - What the agent is allowed to do
444
+ * - What inputs it may consume
445
+ * - What outputs it may emit
446
+ * - What events advance or terminate execution
447
+ * - What resources it can touch
448
+ *
449
+ * Contracts are portable, auditable, and replayable.
450
+ */
451
+ type CodmirContract = {
452
+ /**
453
+ * Schema version for forward compatibility.
454
+ */
455
+ schemaVersion: "codmir.contract.v1";
456
+ /**
457
+ * Unique contract identifier.
458
+ */
459
+ id: ContractId;
460
+ /**
461
+ * Semantic version of this contract.
462
+ */
463
+ version: ContractVersion;
464
+ /**
465
+ * Human-readable title.
466
+ */
467
+ title: string;
468
+ /**
469
+ * Optional description.
470
+ */
471
+ description?: string;
472
+ /**
473
+ * Events that can trigger a new run of this contract.
474
+ */
475
+ triggers: ContractTrigger[];
476
+ /**
477
+ * Permissions required by this contract.
478
+ */
479
+ permissions: Permission[];
480
+ /**
481
+ * Execution limits.
482
+ */
483
+ limits: ContractLimits;
484
+ /**
485
+ * Entry point step ID.
486
+ */
487
+ entryStepId: StepId;
488
+ /**
489
+ * Step definitions forming the execution graph.
490
+ */
491
+ steps: ContractStep[];
492
+ /**
493
+ * Optional output events.
494
+ */
495
+ outputs?: ContractOutputs;
496
+ /**
497
+ * Execution hints for voice/realtime callers.
498
+ * Helps decide sync vs async execution based on expected duration.
499
+ */
500
+ execution?: ExecutionHints;
501
+ /**
502
+ * Optional tags for categorization.
503
+ */
504
+ tags?: string[];
505
+ /**
506
+ * Optional creation timestamp.
507
+ */
508
+ createdAt?: IsoDateString;
509
+ /**
510
+ * Optional author/owner.
511
+ */
512
+ author?: string;
513
+ /**
514
+ * Optional metadata.
515
+ */
516
+ metadata?: Record<string, JsonValue>;
517
+ };
518
+ /**
519
+ * Summary of a contract for registry listing.
520
+ */
521
+ type ContractSummary = {
522
+ id: ContractId;
523
+ version: ContractVersion;
524
+ title: string;
525
+ description?: string;
526
+ triggers: string[];
527
+ tags?: string[];
528
+ createdAt?: IsoDateString;
529
+ };
530
+ /**
531
+ * Contract registry query options.
532
+ */
533
+ type ContractQuery = {
534
+ id?: ContractId;
535
+ triggerEvent?: string;
536
+ tags?: string[];
537
+ limit?: number;
538
+ offset?: number;
539
+ };
540
+
541
+ /**
542
+ * @fileoverview
543
+ * Grace Foundation Schema Extensions
544
+ *
545
+ * "Social contract between AI and humanity"
546
+ *
547
+ * These types extend the core Codmir contract schema with:
548
+ * - Ethical impact assessment
549
+ * - Reversibility guarantees
550
+ * - Economic constraints
551
+ * - Societal impact scoring
552
+ * - Human dignity protections
553
+ *
554
+ * Every contract that uses Grace extensions must be:
555
+ * - Transparent: All actions logged and traceable
556
+ * - Consensual: Explicit permission scope
557
+ * - Reversible: Every action undoable
558
+ * - Accountable: Task attribution and versioning
559
+ * - Bounded: Economic and resource limits
560
+ */
561
+
562
+ /**
563
+ * Ethical impact categories for contract assessment.
564
+ */
565
+ type EthicalImpactCategory = "user_data" | "financial" | "public_systems" | "employment" | "privacy" | "security" | "environmental" | "accessibility" | "content_generation";
566
+ /**
567
+ * Severity levels for ethical impact.
568
+ */
569
+ type ImpactSeverity = "none" | "low" | "medium" | "high" | "critical";
570
+ /**
571
+ * Individual ethical impact assessment.
572
+ */
573
+ type EthicalImpact = {
574
+ category: EthicalImpactCategory;
575
+ severity: ImpactSeverity;
576
+ description?: string;
577
+ mitigations?: string[];
578
+ };
579
+ /**
580
+ * Full ethical impact assessment for a contract.
581
+ */
582
+ type EthicalAssessment = {
583
+ /**
584
+ * Individual impact assessments by category.
585
+ */
586
+ impacts: EthicalImpact[];
587
+ /**
588
+ * Overall risk score (0-100).
589
+ * Computed from individual impacts.
590
+ */
591
+ overallRiskScore: number;
592
+ /**
593
+ * Human-readable summary of ethical considerations.
594
+ */
595
+ summary?: string;
596
+ /**
597
+ * Whether this contract requires human review before execution.
598
+ */
599
+ requiresHumanReview: boolean;
600
+ /**
601
+ * Specific roles that must approve high-impact contracts.
602
+ */
603
+ requiredApprovers?: string[];
604
+ };
605
+ /**
606
+ * Reversibility configuration for a contract.
607
+ */
608
+ type ReversibilityConfig = {
609
+ /**
610
+ * Whether all actions in this contract are reversible.
611
+ */
612
+ fullyReversible: boolean;
613
+ /**
614
+ * Create a snapshot before execution begins.
615
+ */
616
+ snapshotBeforeExecution: boolean;
617
+ /**
618
+ * Retain snapshots for this duration (ms).
619
+ * Default: 7 days
620
+ */
621
+ snapshotRetentionMs?: number;
622
+ /**
623
+ * Steps that are explicitly irreversible.
624
+ * Engine will require extra confirmation for these.
625
+ */
626
+ irreversibleSteps?: string[];
627
+ /**
628
+ * Rollback strategy if execution fails midway.
629
+ */
630
+ rollbackStrategy: "full" | "partial" | "none";
631
+ /**
632
+ * Custom rollback contract to execute on failure.
633
+ */
634
+ rollbackContractId?: string;
635
+ };
636
+ /**
637
+ * Cost units for economic tracking.
638
+ */
639
+ type CostUnit = "credits" | "usd" | "tokens";
640
+ /**
641
+ * Budget configuration for a contract.
642
+ */
643
+ type BudgetConfig = {
644
+ /**
645
+ * Maximum budget for this contract execution.
646
+ */
647
+ maxBudget: number;
648
+ /**
649
+ * Unit of the budget.
650
+ */
651
+ unit: CostUnit;
652
+ /**
653
+ * Alert threshold (percentage of budget).
654
+ * Default: 80
655
+ */
656
+ alertThreshold?: number;
657
+ /**
658
+ * Action when budget is exceeded.
659
+ */
660
+ onExceeded: "pause" | "fail" | "notify";
661
+ /**
662
+ * Whether to refund unused budget.
663
+ */
664
+ refundUnused: boolean;
665
+ };
666
+ /**
667
+ * Resource allocation for compute fairness.
668
+ */
669
+ type ResourceAllocation = {
670
+ /**
671
+ * CPU allocation (vCPU cores).
672
+ */
673
+ cpu?: number;
674
+ /**
675
+ * Memory allocation (GB).
676
+ */
677
+ memory?: number;
678
+ /**
679
+ * GPU allocation (boolean or specific type).
680
+ */
681
+ gpu?: boolean | string;
682
+ /**
683
+ * Maximum execution time (ms).
684
+ */
685
+ maxExecutionTime: number;
686
+ /**
687
+ * Priority level for scheduling.
688
+ */
689
+ priority: "low" | "normal" | "high" | "critical";
690
+ /**
691
+ * Estimated carbon footprint (gCO2e).
692
+ */
693
+ estimatedCarbonFootprint?: number;
694
+ };
695
+ /**
696
+ * Workforce impact assessment.
697
+ */
698
+ type WorkforceImpact = {
699
+ /**
700
+ * Does this contract automate human tasks?
701
+ */
702
+ automatesHumanTasks: boolean;
703
+ /**
704
+ * Estimated human hours displaced per execution.
705
+ */
706
+ estimatedDisplacementHours?: number;
707
+ /**
708
+ * Does this contract augment human capabilities?
709
+ */
710
+ augmentsHumans: boolean;
711
+ /**
712
+ * Skills that humans should develop alongside this automation.
713
+ */
714
+ recommendedHumanSkills?: string[];
715
+ };
716
+ /**
717
+ * Societal impact assessment.
718
+ */
719
+ type SocietalImpact = {
720
+ /**
721
+ * Workforce displacement/augmentation analysis.
722
+ */
723
+ workforce?: WorkforceImpact;
724
+ /**
725
+ * Does this benefit underserved communities?
726
+ */
727
+ benefitsUnderserved?: boolean;
728
+ /**
729
+ * Potential for misuse.
730
+ */
731
+ misuseRisk: ImpactSeverity;
732
+ /**
733
+ * Safeguards against misuse.
734
+ */
735
+ misuseSafeguards?: string[];
736
+ };
737
+ /**
738
+ * Grace Foundation extensions for CodmirContract.
739
+ *
740
+ * Add these fields to your contract to enable Grace governance.
741
+ */
742
+ type GraceExtensions = {
743
+ /**
744
+ * Grace schema version.
745
+ */
746
+ graceVersion: "grace.v1";
747
+ /**
748
+ * Ethical impact assessment.
749
+ */
750
+ ethics: EthicalAssessment;
751
+ /**
752
+ * Reversibility configuration.
753
+ */
754
+ reversibility: ReversibilityConfig;
755
+ /**
756
+ * Economic constraints.
757
+ */
758
+ budget?: BudgetConfig;
759
+ /**
760
+ * Resource allocation.
761
+ */
762
+ resources?: ResourceAllocation;
763
+ /**
764
+ * Societal impact assessment.
765
+ */
766
+ societalImpact?: SocietalImpact;
767
+ /**
768
+ * Human oversight configuration.
769
+ */
770
+ humanOversight: {
771
+ /**
772
+ * Minimum human checkpoints required.
773
+ */
774
+ minCheckpoints: number;
775
+ /**
776
+ * Allow autonomous execution without human oversight?
777
+ */
778
+ allowAutonomous: boolean;
779
+ /**
780
+ * Escalation path for issues.
781
+ */
782
+ escalationPath?: string[];
783
+ };
784
+ /**
785
+ * Transparency requirements.
786
+ */
787
+ transparency: {
788
+ /**
789
+ * Log all decisions with reasoning.
790
+ */
791
+ logDecisions: boolean;
792
+ /**
793
+ * Make execution logs available to affected parties.
794
+ */
795
+ logsAccessible: boolean;
796
+ /**
797
+ * Audit trail retention (days).
798
+ */
799
+ auditRetentionDays: number;
800
+ };
801
+ };
802
+ /**
803
+ * Grace policy rule types.
804
+ */
805
+ type GracePolicyRule = {
806
+ type: "require_approval";
807
+ when: GracePolicyCondition;
808
+ } | {
809
+ type: "deny";
810
+ when: GracePolicyCondition;
811
+ reason: string;
812
+ } | {
813
+ type: "modify_scope";
814
+ when: GracePolicyCondition;
815
+ modifications: Record<string, JsonValue>;
816
+ } | {
817
+ type: "add_checkpoint";
818
+ when: GracePolicyCondition;
819
+ checkpoint: string;
820
+ } | {
821
+ type: "require_human_review";
822
+ when: GracePolicyCondition;
823
+ };
824
+ /**
825
+ * Conditions for policy rules.
826
+ */
827
+ type GracePolicyCondition = {
828
+ op: "risk_above";
829
+ threshold: number;
830
+ } | {
831
+ op: "touches_category";
832
+ category: EthicalImpactCategory;
833
+ } | {
834
+ op: "budget_above";
835
+ amount: number;
836
+ unit: CostUnit;
837
+ } | {
838
+ op: "not_reversible";
839
+ } | {
840
+ op: "production_deployment";
841
+ } | {
842
+ op: "affects_multiple_users";
843
+ threshold: number;
844
+ } | {
845
+ op: "and";
846
+ conditions: GracePolicyCondition[];
847
+ } | {
848
+ op: "or";
849
+ conditions: GracePolicyCondition[];
850
+ };
851
+ /**
852
+ * Audit event for Grace governance tracking.
853
+ */
854
+ type GraceAuditEvent = {
855
+ id: string;
856
+ timestamp: string;
857
+ runId: string;
858
+ contractId: string;
859
+ type: "contract.submitted" | "ethics.assessed" | "approval.requested" | "approval.granted" | "approval.denied" | "checkpoint.reached" | "budget.alert" | "budget.exceeded" | "rollback.initiated" | "rollback.completed" | "human.override" | "policy.violated" | "policy.enforced";
860
+ actor: {
861
+ type: "human" | "ai" | "system";
862
+ id: string;
863
+ name?: string;
864
+ };
865
+ details: Record<string, JsonValue>;
866
+ /**
867
+ * Hash of previous audit event for chain integrity.
868
+ */
869
+ previousHash?: string;
870
+ };
871
+ /**
872
+ * Default Grace extensions for a new contract.
873
+ */
874
+ declare const DEFAULT_GRACE_EXTENSIONS: GraceExtensions;
875
+ /**
876
+ * Calculate overall risk score from impacts.
877
+ */
878
+ declare function calculateRiskScore(impacts: EthicalImpact[]): number;
879
+ /**
880
+ * Determine if human review is required based on impacts.
881
+ */
882
+ declare function requiresHumanReview(impacts: EthicalImpact[]): boolean;
883
+ /**
884
+ * Grace Foundation principles as machine-readable rules.
885
+ */
886
+ declare const GRACE_PRINCIPLES: {
887
+ readonly transparency: "Every action logged, every decision traceable";
888
+ readonly consent: "Explicit permission scope, no implicit access";
889
+ readonly reversibility: "Every AI action must be undoable";
890
+ readonly accountability: "Task attribution, versioned modifications";
891
+ readonly economicBoundaries: "Token usage limit, execution cost cap";
892
+ readonly humanDignity: "AI augments, never replaces human judgment on critical decisions";
893
+ readonly fairness: "Distributed power must not centralize control";
894
+ readonly sustainability: "Prefer renewable-powered compute when available";
895
+ };
896
+
897
+ /**
898
+ * @fileoverview
899
+ * Contract validation utilities.
900
+ * Validates contracts are structurally correct before execution.
901
+ */
902
+
903
+ /**
904
+ * Validation error with details.
905
+ */
906
+ declare class ContractValidationError extends Error {
907
+ readonly field?: string | undefined;
908
+ readonly details?: unknown | undefined;
909
+ constructor(message: string, field?: string | undefined, details?: unknown | undefined);
910
+ }
911
+ /**
912
+ * Validation result type.
913
+ */
914
+ type ValidationResult = {
915
+ valid: true;
916
+ } | {
917
+ valid: false;
918
+ errors: ContractValidationError[];
919
+ };
920
+ /**
921
+ * Validate a contract with strict structural rules.
922
+ * Keep this deterministic and side-effect free.
923
+ *
924
+ * @param contract - Contract to validate
925
+ * @throws ContractValidationError if invalid
926
+ */
927
+ declare function validateContract(contract: CodmirContract): void;
928
+ /**
929
+ * Validate a contract and return a result object.
930
+ * Does not throw.
931
+ */
932
+ declare function validateContractSafe(contract: CodmirContract): ValidationResult;
933
+ /**
934
+ * Check if a contract has a specific permission.
935
+ */
936
+ declare function hasPermission(contract: CodmirContract, kind: string, scope?: string): boolean;
937
+
938
+ /**
939
+ * @fileoverview
940
+ * Condition expression evaluation for contracts.
941
+ * All evaluations are deterministic and side-effect free.
942
+ */
943
+
944
+ /**
945
+ * Evaluate a deterministic condition expression against a JSON context.
946
+ *
947
+ * @param ctx - Run context object (JSON-like)
948
+ * @param expr - Condition expression to evaluate
949
+ * @returns true if the condition is satisfied
950
+ *
951
+ * @example
952
+ * ```ts
953
+ * const ctx = { status: "open", priority: 3 };
954
+ * evalCondition(ctx, { op: "eq", path: "status", value: "open" });
955
+ * // => true
956
+ * ```
957
+ */
958
+ declare function evalCondition(ctx: Record<string, JsonValue>, expr: ConditionExpr): boolean;
959
+ /**
960
+ * Validate that a condition expression is structurally valid.
961
+ * @throws Error if the expression is invalid
962
+ */
963
+ declare function validateCondition(expr: ConditionExpr): void;
964
+ /**
965
+ * Create a simple equality condition.
966
+ */
967
+ declare function eq(path: string, value: JsonValue): ConditionExpr;
968
+ /**
969
+ * Create a not-equals condition.
970
+ */
971
+ declare function neq(path: string, value: JsonValue): ConditionExpr;
972
+ /**
973
+ * Create an exists condition.
974
+ */
975
+ declare function exists(path: string): ConditionExpr;
976
+ /**
977
+ * Create an AND condition.
978
+ */
979
+ declare function and(...exprs: ConditionExpr[]): ConditionExpr;
980
+ /**
981
+ * Create an OR condition.
982
+ */
983
+ declare function or(...exprs: ConditionExpr[]): ConditionExpr;
984
+ /**
985
+ * Create a NOT condition.
986
+ */
987
+ declare function not(expr: ConditionExpr): ConditionExpr;
988
+ /**
989
+ * Create a greater-than condition.
990
+ */
991
+ declare function gt(path: string, value: number): ConditionExpr;
992
+ /**
993
+ * Create a greater-than-or-equal condition.
994
+ */
995
+ declare function gte(path: string, value: number): ConditionExpr;
996
+ /**
997
+ * Create a less-than condition.
998
+ */
999
+ declare function lt(path: string, value: number): ConditionExpr;
1000
+ /**
1001
+ * Create a less-than-or-equal condition.
1002
+ */
1003
+ declare function lte(path: string, value: number): ConditionExpr;
1004
+ /**
1005
+ * Create a contains condition (string or array).
1006
+ */
1007
+ declare function contains(path: string, value: string): ConditionExpr;
1008
+ /**
1009
+ * Create a startsWith condition.
1010
+ */
1011
+ declare function startsWith(path: string, value: string): ConditionExpr;
1012
+ /**
1013
+ * Create an endsWith condition.
1014
+ */
1015
+ declare function endsWith(path: string, value: string): ConditionExpr;
1016
+
1017
+ /**
1018
+ * @fileoverview
1019
+ * Template resolution utilities for contracts.
1020
+ * Supports {{path}} syntax for extracting values from run context.
1021
+ */
1022
+
1023
+ /**
1024
+ * Safely get a nested value by dot path from a JSON-like object.
1025
+ * @param obj - Source object
1026
+ * @param path - Dot-separated path (e.g., "trigger.ticketId")
1027
+ * @returns The value at the path, or undefined if not found
1028
+ *
1029
+ * @example
1030
+ * ```ts
1031
+ * getByPath({ trigger: { ticketId: "123" } }, "trigger.ticketId")
1032
+ * // => "123"
1033
+ * ```
1034
+ */
1035
+ declare function getByPath(obj: Record<string, JsonValue>, path: string): JsonValue | undefined;
1036
+ /**
1037
+ * Set a nested value by dot path, creating objects along the way.
1038
+ * @param obj - Target object (mutated in place)
1039
+ * @param path - Dot-separated path
1040
+ * @param value - Value to set
1041
+ *
1042
+ * @example
1043
+ * ```ts
1044
+ * const ctx = {};
1045
+ * setByPath(ctx, "steps.analyze.output", { summary: "..." });
1046
+ * // ctx => { steps: { analyze: { output: { summary: "..." } } } }
1047
+ * ```
1048
+ */
1049
+ declare function setByPath(obj: Record<string, JsonValue>, path: string, value: JsonValue): void;
1050
+ /**
1051
+ * Delete a nested value by dot path.
1052
+ * @param obj - Target object (mutated in place)
1053
+ * @param path - Dot-separated path
1054
+ */
1055
+ declare function deleteByPath(obj: Record<string, JsonValue>, path: string): void;
1056
+ /**
1057
+ * Check if a string is a template reference.
1058
+ */
1059
+ declare function isTemplate(value: string): boolean;
1060
+ /**
1061
+ * Extract path from a template string.
1062
+ * @returns The path if it's a template, null otherwise
1063
+ */
1064
+ declare function extractTemplatePath(value: string): string | null;
1065
+ /**
1066
+ * Resolve templates of the form "{{some.path}}" inside JSON values deterministically.
1067
+ *
1068
+ * Supports:
1069
+ * - Strings equal to "{{path}}" → replaced with value at path
1070
+ * - Objects/arrays → recursively resolved
1071
+ * - Other primitives → passed through unchanged
1072
+ *
1073
+ * @param ctx - Run context object (JSON-like)
1074
+ * @param input - Input value containing potential templates
1075
+ * @returns Resolved value with templates replaced
1076
+ *
1077
+ * @example
1078
+ * ```ts
1079
+ * const ctx = { trigger: { ticketId: "T-123" } };
1080
+ * resolveTemplates(ctx, { id: "{{trigger.ticketId}}" });
1081
+ * // => { id: "T-123" }
1082
+ * ```
1083
+ */
1084
+ declare function resolveTemplates(ctx: Record<string, JsonValue>, input: JsonValue): JsonValue;
1085
+ /**
1086
+ * Resolve a step input object using run context.
1087
+ * Convenience wrapper around resolveTemplates.
1088
+ */
1089
+ declare function resolveStepInput(ctx: Record<string, JsonValue>, input: Record<string, JsonValue>): Record<string, JsonValue>;
1090
+ /**
1091
+ * Deep clone a JSON value.
1092
+ */
1093
+ declare function cloneJson<T extends JsonValue>(value: T): T;
1094
+ /**
1095
+ * Merge two JSON objects shallowly.
1096
+ */
1097
+ declare function mergeJson(target: Record<string, JsonValue>, source: Record<string, JsonValue>): Record<string, JsonValue>;
1098
+ /**
1099
+ * Deep merge two JSON objects.
1100
+ */
1101
+ declare function deepMergeJson(target: Record<string, JsonValue>, source: Record<string, JsonValue>): Record<string, JsonValue>;
1102
+
1103
+ /**
1104
+ * @fileoverview
1105
+ * Example contract: Ticket Triage Workflow
1106
+ *
1107
+ * This contract demonstrates an autonomous agent that:
1108
+ * 1. Analyzes incoming tickets
1109
+ * 2. Classifies priority and category
1110
+ * 3. Assigns to appropriate team
1111
+ * 4. Emits status updates
1112
+ */
1113
+
1114
+ /**
1115
+ * Ticket Triage Contract
1116
+ *
1117
+ * Triggered by: ticket.created
1118
+ * Permissions: Read tickets, emit events, invoke LLM
1119
+ */
1120
+ declare const ticketTriageContract: CodmirContract;
1121
+
1122
+ /**
1123
+ * @fileoverview
1124
+ * Example contract: Code Review Workflow
1125
+ *
1126
+ * This contract demonstrates an autonomous agent that:
1127
+ * 1. Analyzes pull request changes
1128
+ * 2. Checks for code quality issues
1129
+ * 3. Suggests improvements
1130
+ * 4. Posts review comments
1131
+ * 5. Waits for author response (human-in-the-loop)
1132
+ */
1133
+
1134
+ /**
1135
+ * Code Review Contract
1136
+ *
1137
+ * Triggered by: github.pull_request.opened, github.pull_request.synchronize
1138
+ * Permissions: Read repo, emit events, invoke LLM, post comments
1139
+ */
1140
+ declare const codeReviewContract: CodmirContract;
1141
+
1142
+ /**
1143
+ * @fileoverview
1144
+ * PR Analysis Contract
1145
+ *
1146
+ * This contract is triggered by GitHub App webhooks (not GitHub Actions)
1147
+ * when a pull request is opened, synchronized, or reopened.
1148
+ *
1149
+ * It replaces the ai-pr-review.yml GitHub Actions workflow with
1150
+ * event-driven execution through the Codmir engine.
1151
+ */
1152
+
1153
+ /**
1154
+ * PR Analysis Contract
1155
+ *
1156
+ * Triggered by: github.pull_request.opened, github.pull_request.synchronize, github.pull_request.reopened
1157
+ * Permissions: Read repo, emit events, invoke LLM, post comments via HTTP
1158
+ */
1159
+ declare const prAnalysisContract: CodmirContract;
1160
+ /**
1161
+ * Enhanced PR Analysis Contract with LLM review
1162
+ *
1163
+ * This version includes AI-powered code review in addition to static analysis.
1164
+ * Use this for more comprehensive reviews.
1165
+ */
1166
+ declare const prAnalysisWithLlmContract: CodmirContract;
1167
+
1168
+ /**
1169
+ * @fileoverview
1170
+ * Voice Create Ticket Contract
1171
+ *
1172
+ * Creates a ticket/issue from a voice command.
1173
+ * This is a fast, synchronous action (instant duration).
1174
+ */
1175
+
1176
+ declare const voiceCreateTicketContract: CodmirContract;
1177
+
1178
+ /**
1179
+ * @fileoverview
1180
+ * Voice Search Codebase Contract
1181
+ *
1182
+ * Searches the codebase for patterns, functions, or files from voice command.
1183
+ * This is a quick action (2-30s depending on codebase size).
1184
+ */
1185
+
1186
+ declare const voiceSearchCodebaseContract: CodmirContract;
1187
+
1188
+ /**
1189
+ * @fileoverview
1190
+ * Voice Deploy Preview Contract
1191
+ *
1192
+ * Deploys a preview environment from a voice command.
1193
+ * This is a long-running action that requires approval (async).
1194
+ */
1195
+
1196
+ declare const voiceDeployPreviewContract: CodmirContract;
1197
+
1198
+ /**
1199
+ * @fileoverview
1200
+ * Voice Save Note Contract
1201
+ *
1202
+ * Saves a note or snippet from a voice command.
1203
+ * This is a fast, synchronous action (instant duration).
1204
+ */
1205
+
1206
+ declare const voiceSaveNoteContract: CodmirContract;
1207
+
1208
+ /**
1209
+ * @fileoverview
1210
+ * Voice Contract Registry
1211
+ *
1212
+ * Central registry for all voice action contracts.
1213
+ * Provides lookup by contract ID or action name.
1214
+ */
1215
+
1216
+ /**
1217
+ * All registered voice contracts.
1218
+ */
1219
+ declare const VOICE_CONTRACTS: Record<string, CodmirContract>;
1220
+ /**
1221
+ * Get a voice contract by its ID.
1222
+ * @param contractId - Contract ID (e.g., "voice.create-ticket")
1223
+ * @returns The contract or undefined if not found
1224
+ */
1225
+ declare function getVoiceContract(contractId: string): CodmirContract | undefined;
1226
+ /**
1227
+ * Get a voice contract by the action name from the event catalog.
1228
+ * @param actionName - Action name (e.g., "create_ticket")
1229
+ * @returns The contract or undefined if not found
1230
+ */
1231
+ declare function getVoiceContractForAction(actionName: string): CodmirContract | undefined;
1232
+
1233
+ export { type ApprovalStep, type AuditStep, type BranchStep, type BudgetConfig, type CodmirContract, type ConditionExpr, type ContractId, type ContractLimits, type ContractOutputs, type ContractQuery, type ContractStep, type ContractSummary, type ContractTrigger, ContractValidationError, type ContractVersion, type CostUnit, DEFAULT_GRACE_EXTENSIONS, DURATION_SYNC_THRESHOLDS, type EmitStep, type EthicalAssessment, type EthicalImpact, type EthicalImpactCategory, type EventName, type ExecutionHints, type ExecutionMode, type ExpectedDuration, GRACE_PRINCIPLES, type GraceAuditEvent, type GraceExtensions, type GracePolicyCondition, type GracePolicyRule, type ImpactSeverity, type IsoDateString, type JsonValue, type LlmStep, type Permission, type ResourceAllocation, type RetryPolicy, type ReversibilityConfig, type RunId, type SkillStep, type SocietalImpact, type StepBase, type StepId, type StepKind, type StepTimeout, type TaskStep, type TransformStep, VOICE_CONTRACTS, type ValidationResult, type WaitStep, type WorkforceImpact, and, calculateRiskScore, cloneJson, codeReviewContract, contains, deepMergeJson, deleteByPath, endsWith, eq, evalCondition, exists, extractTemplatePath, getByPath, getVoiceContract, getVoiceContractForAction, gt, gte, hasPermission, isTemplate, lt, lte, mergeJson, neq, not, or, prAnalysisContract, prAnalysisWithLlmContract, requiresHumanReview, resolveStepInput, resolveTemplates, setByPath, startsWith, ticketTriageContract, validateCondition, validateContract, validateContractSafe, voiceCreateTicketContract, voiceDeployPreviewContract, voiceSaveNoteContract, voiceSearchCodebaseContract };