@martinloop/mcp 0.3.9 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +82 -141
  2. package/dist/discovery-metadata.d.ts +1 -1
  3. package/dist/discovery-metadata.js +1 -1
  4. package/dist/resources.d.ts +1 -2
  5. package/dist/resources.js +62 -98
  6. package/dist/server-validation.d.ts +1 -1
  7. package/dist/server-validation.js +16 -11
  8. package/dist/server.d.ts +23 -0
  9. package/dist/server.js +192 -15
  10. package/dist/tools/doctor.js +5 -4
  11. package/dist/tools/get-status.d.ts +2 -0
  12. package/dist/tools/get-status.js +1 -0
  13. package/dist/tools/preflight.d.ts +2 -0
  14. package/dist/tools/preflight.js +43 -3
  15. package/dist/tools/run-dossier.d.ts +3 -1
  16. package/dist/tools/run-dossier.js +40 -2
  17. package/dist/tools/run-loop.d.ts +5 -3
  18. package/dist/tools/run-loop.js +15 -9
  19. package/dist/tools/tool-errors.js +1 -1
  20. package/dist/tools/tool-response.js +9 -2
  21. package/dist/tools/tool-support.d.ts +4 -2
  22. package/dist/tools/tool-support.js +6 -15
  23. package/dist/vendor/adapters/claude-cli.d.ts +2 -2
  24. package/dist/vendor/adapters/claude-cli.js +97 -69
  25. package/dist/vendor/adapters/cli-bridge.d.ts +9 -1
  26. package/dist/vendor/adapters/cli-bridge.js +54 -13
  27. package/dist/vendor/adapters/codex-launcher.d.ts +61 -1
  28. package/dist/vendor/adapters/codex-launcher.js +118 -19
  29. package/dist/vendor/adapters/index.d.ts +2 -4
  30. package/dist/vendor/adapters/index.js +2 -4
  31. package/dist/vendor/adapters/openai-compatible.d.ts +2 -3
  32. package/dist/vendor/adapters/openai-compatible.js +80 -15
  33. package/dist/vendor/adapters/verifier-only.js +9 -4
  34. package/dist/vendor/contracts/adapter-capabilities.d.ts +1 -1
  35. package/dist/vendor/contracts/context-handoff.d.ts +100 -0
  36. package/dist/vendor/contracts/context-handoff.js +11 -0
  37. package/dist/vendor/contracts/context-manifest.d.ts +195 -0
  38. package/dist/vendor/contracts/context-manifest.js +17 -0
  39. package/dist/vendor/contracts/context-shadow.d.ts +75 -0
  40. package/dist/vendor/contracts/context-shadow.js +8 -0
  41. package/dist/vendor/contracts/delivery.d.ts +47 -0
  42. package/dist/vendor/contracts/delivery.js +18 -0
  43. package/dist/vendor/contracts/exits.d.ts +126 -0
  44. package/dist/vendor/contracts/exits.js +32 -0
  45. package/dist/vendor/contracts/index.d.ts +55 -6
  46. package/dist/vendor/contracts/index.js +24 -0
  47. package/dist/vendor/contracts/mission.d.ts +102 -0
  48. package/dist/vendor/contracts/mission.js +64 -0
  49. package/dist/vendor/contracts/operator.d.ts +3 -1
  50. package/dist/vendor/contracts/operator.js +2 -1
  51. package/dist/vendor/contracts/verified-handoff.d.ts +106 -0
  52. package/dist/vendor/contracts/verified-handoff.js +40 -0
  53. package/dist/vendor/core/context-chain-gate.d.ts +89 -0
  54. package/dist/vendor/core/context-chain-gate.js +173 -0
  55. package/dist/vendor/core/context-compiler.d.ts +53 -0
  56. package/dist/vendor/core/context-compiler.js +261 -0
  57. package/dist/vendor/core/context-handoff.d.ts +42 -0
  58. package/dist/vendor/core/context-handoff.js +167 -0
  59. package/dist/vendor/core/context-shadow.d.ts +39 -0
  60. package/dist/vendor/core/context-shadow.js +200 -0
  61. package/dist/vendor/core/delivery/index.d.ts +6 -0
  62. package/dist/vendor/core/delivery/index.js +4 -0
  63. package/dist/vendor/core/delivery/message-client.d.ts +18 -0
  64. package/dist/vendor/core/delivery/message-client.js +38 -0
  65. package/dist/vendor/core/delivery/message-ledger.d.ts +35 -0
  66. package/dist/vendor/core/delivery/message-ledger.js +97 -0
  67. package/dist/vendor/core/delivery/message-schema.d.ts +16 -0
  68. package/dist/vendor/core/delivery/message-schema.js +111 -0
  69. package/dist/vendor/core/delivery/update-check.d.ts +19 -0
  70. package/dist/vendor/core/delivery/update-check.js +107 -0
  71. package/dist/vendor/core/exit-signal.d.ts +88 -0
  72. package/dist/vendor/core/exit-signal.js +339 -0
  73. package/dist/vendor/core/exits.d.ts +41 -0
  74. package/dist/vendor/core/exits.js +258 -0
  75. package/dist/vendor/core/grounding.d.ts +2 -1
  76. package/dist/vendor/core/grounding.js +40 -5
  77. package/dist/vendor/core/index.d.ts +47 -6
  78. package/dist/vendor/core/index.js +1102 -670
  79. package/dist/vendor/core/mission/aggregate.d.ts +27 -0
  80. package/dist/vendor/core/mission/aggregate.js +42 -0
  81. package/dist/vendor/core/mission/index.d.ts +2 -0
  82. package/dist/vendor/core/mission/index.js +1 -0
  83. package/dist/vendor/core/persistence/compiler.d.ts +8 -0
  84. package/dist/vendor/core/persistence/compiler.js +156 -0
  85. package/dist/vendor/core/persistence/context-handoff-store.d.ts +68 -0
  86. package/dist/vendor/core/persistence/context-handoff-store.js +112 -0
  87. package/dist/vendor/core/persistence/index.d.ts +4 -0
  88. package/dist/vendor/core/persistence/index.js +2 -0
  89. package/dist/vendor/core/persistence/ledger.d.ts +1 -1
  90. package/dist/vendor/core/persistence/mission-store.d.ts +56 -0
  91. package/dist/vendor/core/persistence/mission-store.js +281 -0
  92. package/dist/vendor/core/persistence/runs-reader.d.ts +2 -0
  93. package/dist/vendor/core/policy.d.ts +2 -0
  94. package/dist/vendor/core/policy.js +11 -8
  95. package/dist/vendor/core/red-blue/red-phase.d.ts +2 -1
  96. package/dist/vendor/core/red-blue/red-phase.js +3 -3
  97. package/dist/vendor/core/red-blue/risk-tiers.d.ts +2 -4
  98. package/dist/vendor/core/red-blue/risk-tiers.js +1 -3
  99. package/dist/vendor/core/rollback.js +15 -1
  100. package/dist/vendor/core/routing.d.ts +0 -42
  101. package/dist/vendor/core/routing.js +4 -154
  102. package/dist/vendor/core/savings.d.ts +13 -0
  103. package/dist/vendor/core/savings.js +22 -0
  104. package/dist/vendor/core/termination-store.d.ts +15 -0
  105. package/dist/vendor/core/termination-store.js +44 -0
  106. package/dist/vendor/core/verified-handoff.d.ts +72 -0
  107. package/dist/vendor/core/verified-handoff.js +238 -0
  108. package/package.json +4 -10
  109. package/server.json +3 -3
  110. package/dist/vendor/adapters/stub-agent-cli.d.ts +0 -8
  111. package/dist/vendor/adapters/stub-agent-cli.js +0 -40
  112. package/dist/vendor/adapters/stub-direct-provider.d.ts +0 -8
  113. package/dist/vendor/adapters/stub-direct-provider.js +0 -12
@@ -0,0 +1,18 @@
1
+ /**
2
+ * R4 Delivery — M1 Contract
3
+ *
4
+ * Shared with Lane B (Control Plane). Do not modify unilaterally.
5
+ * The server selects one message; the client never downloads the catalog.
6
+ */
7
+ export const DELIVERY_MESSAGE_SCHEMA_VERSION = "delivery-message/1";
8
+ export const DELIVERY_RECORD_SCHEMA_VERSION = "delivery-record/1";
9
+ export const MESSAGE_SELECTION_RESPONSE_SCHEMA_VERSION = "martin-message-selection/1";
10
+ export const ALLOWED_ACTION_TYPES = [
11
+ "upgrade_cli",
12
+ "upgrade_mcp",
13
+ "submit_feedback",
14
+ "open_release_notes",
15
+ "dismiss",
16
+ "view_spend_report",
17
+ "view_run_explain",
18
+ ];
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Exit contracts for the MartinLoop Eight-Exit Runtime.
3
+ *
4
+ * Precedence rationale (product decision — changing EXIT_PRECEDENCE in core
5
+ * requires updating this paragraph in the same commit):
6
+ * 1. human_interrupt and external_event outrank all others — they represent
7
+ * authority external to the run's own evidence and cannot be argued with.
8
+ * 2. wall_clock, budget_cap, and turn_cap all outrank goal_met — governance
9
+ * limits (time, cost, iterations) cannot be overridden by a simultaneously
10
+ * verified goal; resource limits rank wall_clock > budget_cap > turn_cap.
11
+ * 3. turn_cap is suppressed at signal-generation time when the goal is already
12
+ * met, so goal_met and turn_cap cannot co-occur in a well-formed evaluation.
13
+ * Completing on the final permitted iteration is legitimate success, not an
14
+ * overrun; turn_cap fires only when iterations are exhausted without
15
+ * verified completion.
16
+ * 4. goal_met outranks error_threshold and no_progress — a deterministically
17
+ * verified result takes priority over soft progress signals.
18
+ */
19
+ export declare const EXIT_POLICY_VERSION: "exit-policy/1";
20
+ export declare const EXIT_EVALUATION_VERSION: "exit-evaluation/1";
21
+ export declare const EXIT_SIGNAL_VERSION: "exit-signal/1";
22
+ export declare const TERMINATION_ENVELOPE_VERSION: "termination/1";
23
+ export declare const EXIT_KINDS: readonly ["goal_met", "turn_cap", "budget_cap", "wall_clock", "no_progress", "human_interrupt", "error_threshold", "external_event"];
24
+ export type ExitKind = (typeof EXIT_KINDS)[number];
25
+ export type ExitEvaluationPhase = "pre_run" | "pre_attempt" | "post_attempt" | "before_retry" | "during_attempt";
26
+ export type ExternalEventDisposition = "satisfied" | "superseded" | "cancelled";
27
+ export interface ExternalExitEvent {
28
+ source: string;
29
+ event: string;
30
+ disposition: ExternalEventDisposition;
31
+ observedAt: string;
32
+ subject?: string;
33
+ reason?: string;
34
+ evidenceUri?: string;
35
+ }
36
+ export interface ExitPolicyV1 {
37
+ schemaVersion: typeof EXIT_POLICY_VERSION;
38
+ goal: {
39
+ verifierRequired: boolean;
40
+ minimumScore: number;
41
+ };
42
+ turns: {
43
+ max: number;
44
+ };
45
+ budget: {
46
+ maxUsd: number;
47
+ maxTokens: number;
48
+ };
49
+ wallClock: {
50
+ maxElapsedMs: number;
51
+ deadlineAt?: string;
52
+ };
53
+ progress: {
54
+ windowSize: number;
55
+ unchangedStateLimit: number;
56
+ };
57
+ errors: {
58
+ maxConsecutive: number;
59
+ };
60
+ humanInterrupt: {
61
+ enabled: boolean;
62
+ };
63
+ externalEvent: {
64
+ enabled: boolean;
65
+ };
66
+ }
67
+ export interface ExitSignalV1 {
68
+ schemaVersion: typeof EXIT_SIGNAL_VERSION;
69
+ runId: string;
70
+ kind: "human_interrupt" | "external_event";
71
+ requestedAt: string;
72
+ requestedBy: string;
73
+ reason?: string;
74
+ externalEvent?: ExternalExitEvent;
75
+ }
76
+ export interface ExitSnapshotV1 {
77
+ phase: ExitEvaluationPhase;
78
+ evaluatedAt: string;
79
+ runStartedAtMs: number;
80
+ nowMs: number;
81
+ turnsUsed: number;
82
+ actualUsd: number;
83
+ tokensUsed: number;
84
+ result?: {
85
+ status: "completed" | "failed";
86
+ verificationPassed: boolean;
87
+ verifierScore: number;
88
+ };
89
+ recentStateHashes: string[];
90
+ consecutiveErrors: number;
91
+ humanInterrupt?: ExitSignalV1;
92
+ externalEvent?: ExternalExitEvent;
93
+ trajectoryStop?: {
94
+ shouldStop: boolean;
95
+ reason: string;
96
+ };
97
+ }
98
+ export interface ExitMatchV1 {
99
+ kind: ExitKind;
100
+ reason: string;
101
+ evidence: Record<string, unknown>;
102
+ }
103
+ export interface ExitEvaluationV1 {
104
+ schemaVersion: typeof EXIT_EVALUATION_VERSION;
105
+ policyVersion: typeof EXIT_POLICY_VERSION;
106
+ shouldExit: boolean;
107
+ primary?: ExitKind;
108
+ matched: ExitKind[];
109
+ phase: ExitEvaluationPhase;
110
+ evaluatedAt: string;
111
+ matches: ExitMatchV1[];
112
+ }
113
+ export type TerminationEnvelopeV1 = {
114
+ schemaVersion: typeof TERMINATION_ENVELOPE_VERSION;
115
+ class: "operational_exit";
116
+ exit: ExitEvaluationV1;
117
+ } | {
118
+ schemaVersion: typeof TERMINATION_ENVELOPE_VERSION;
119
+ class: "guard_stop";
120
+ guard: {
121
+ reasonCode: string;
122
+ reason: string;
123
+ failureClass?: string;
124
+ safetySurface?: string;
125
+ };
126
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Exit contracts for the MartinLoop Eight-Exit Runtime.
3
+ *
4
+ * Precedence rationale (product decision — changing EXIT_PRECEDENCE in core
5
+ * requires updating this paragraph in the same commit):
6
+ * 1. human_interrupt and external_event outrank all others — they represent
7
+ * authority external to the run's own evidence and cannot be argued with.
8
+ * 2. wall_clock, budget_cap, and turn_cap all outrank goal_met — governance
9
+ * limits (time, cost, iterations) cannot be overridden by a simultaneously
10
+ * verified goal; resource limits rank wall_clock > budget_cap > turn_cap.
11
+ * 3. turn_cap is suppressed at signal-generation time when the goal is already
12
+ * met, so goal_met and turn_cap cannot co-occur in a well-formed evaluation.
13
+ * Completing on the final permitted iteration is legitimate success, not an
14
+ * overrun; turn_cap fires only when iterations are exhausted without
15
+ * verified completion.
16
+ * 4. goal_met outranks error_threshold and no_progress — a deterministically
17
+ * verified result takes priority over soft progress signals.
18
+ */
19
+ export const EXIT_POLICY_VERSION = "exit-policy/1";
20
+ export const EXIT_EVALUATION_VERSION = "exit-evaluation/1";
21
+ export const EXIT_SIGNAL_VERSION = "exit-signal/1";
22
+ export const TERMINATION_ENVELOPE_VERSION = "termination/1";
23
+ export const EXIT_KINDS = [
24
+ "goal_met",
25
+ "turn_cap",
26
+ "budget_cap",
27
+ "wall_clock",
28
+ "no_progress",
29
+ "human_interrupt",
30
+ "error_threshold",
31
+ "external_event"
32
+ ];
@@ -1,9 +1,19 @@
1
+ /**
2
+ * Contracts for the Martin Loop agentic system.
3
+ *
4
+ * This module defines the core type contracts and data structures for autonomous agent loop management,
5
+ * including loop lifecycle states, task definitions, budget tracking, cost accounting, verification,
6
+ * patch decisions, telemetry, and governance policies. It provides the public API surface for
7
+ * creating and managing loop records, handling events, validating batches, and tracking
8
+ * portfolio snapshots and routing economics.
9
+ */
10
+ import type { TerminationEnvelopeV1 } from "./exits.js";
1
11
  export type LoopStatus = "queued" | "running" | "verifying" | "completed" | "failed" | "exited";
2
- export type LoopLifecycleState = "created" | "running" | "verifying" | "completed" | "budget_exit" | "diminishing_returns" | "stuck_exit" | "human_escalation";
12
+ export type LoopLifecycleState = "created" | "running" | "verifying" | "completed" | "budget_exit" | "diminishing_returns" | "stuck_exit" | "human_escalation" | "wall_clock" | "error_threshold" | "external_event";
3
13
  export declare const FAILURE_CLASSES: readonly ["logic_error", "hallucination", "syntax_error", "type_error", "test_regression", "scope_creep", "no_progress", "repo_grounding_failure", "verification_failure", "environment_mismatch", "budget_pressure", "safety_leash_blocked", "sandbox_write_blocked"];
4
14
  export type FailureClass = (typeof FAILURE_CLASSES)[number];
5
15
  export type InterventionType = "compress_context" | "change_model" | "tighten_task" | "switch_adapter" | "run_verifier" | "escalate_human" | "stop_loop";
6
- export type LoopEventType = "run.started" | "attempt.started" | "attempt.completed" | "failure.classified" | "intervention.selected" | "verification.completed" | "budget.updated" | "run.completed";
16
+ export type LoopEventType = "run.started" | "attempt.started" | "attempt.completed" | "failure.classified" | "intervention.selected" | "verification.completed" | "budget.updated" | "run.completed" | "run.terminated";
7
17
  export interface LoopTask {
8
18
  title: string;
9
19
  objective: string;
@@ -12,6 +22,8 @@ export interface LoopTask {
12
22
  verificationTimeoutMs?: number;
13
23
  verificationStack?: VerificationStep[];
14
24
  mutationMode?: MutationMode;
25
+ /** Explicit task-authority evidence that all definition-of-done criteria were satisfied before execution. */
26
+ definitionOfDonePreSatisfied?: boolean;
15
27
  executionProfile?: ExecutionProfile;
16
28
  allowedNetworkDomains?: string[];
17
29
  approvalPolicy?: ApprovalPolicy;
@@ -54,17 +66,27 @@ export interface LoopCost {
54
66
  estimatedUsd?: number;
55
67
  provenance?: CostProvenance;
56
68
  providerSettlement?: ProviderUsageSettlement;
69
+ savingsBaseline?: {
70
+ usd: number;
71
+ source: "measured_control" | "operator_supplied" | "fixture";
72
+ provenance: CostProvenance;
73
+ };
57
74
  }
58
- export type UsageSettlementSource = "claude_json" | "codex_jsonl" | "gemini_json" | "estimated_fallback" | "unavailable";
75
+ export type UsageSettlementSource = "claude_json" | "codex_jsonl" | "gemini_json" | "openai_compatible_json" | "estimated_fallback" | "unavailable";
59
76
  export interface ProviderUsageSettlement {
60
77
  providerId: string;
61
- model: string;
78
+ model?: string;
62
79
  transport?: "cli" | "http" | "routed_http";
63
80
  source: UsageSettlementSource;
64
81
  inputTokens: number;
65
82
  cachedInputTokens?: number;
66
83
  outputTokens: number;
67
84
  reasoningOutputTokens?: number;
85
+ cacheCreationInputTokens?: number;
86
+ billingMode?: "metered_api" | "subscription" | "local_unmetered" | "unknown";
87
+ modelSource?: "provider_reported" | "explicit_override" | "provider_configured" | "agent_default" | "unavailable";
88
+ pricingSource?: "provider_reported_total" | "static_catalog" | "blended_fallback" | "none";
89
+ pricingVersion?: string;
68
90
  rawUsageAvailable: boolean;
69
91
  settledAt: string;
70
92
  }
@@ -73,6 +95,16 @@ export interface ReceiptScope {
73
95
  workingDirectory?: string;
74
96
  invocationRoot?: string;
75
97
  runsRoot?: string;
98
+ /** Sandbox mode the mission requested before execution. */
99
+ requestedSandbox?: "read-only" | "workspace-write" | "danger-full-access";
100
+ /** Effective sandbox capability detected by pre-run filesystem probe. */
101
+ effectiveSandbox?: "read-only" | "workspace-write" | "unknown";
102
+ /** Absolute path that the filesystem write probe tested. */
103
+ writableRoot?: string;
104
+ /** How the effective sandbox was determined. */
105
+ capabilitySource?: "probe" | "configured" | "unknown";
106
+ /** Enforced demo changes (DEMO.md-only enforcement output). */
107
+ demoChangedFiles?: string[];
76
108
  }
77
109
  export type ReceiptIntegrityState = "verified" | "unsigned" | "tamper_detected" | "relocated" | "material_missing" | "selector_noncanonical";
78
110
  export interface ReceiptIntegritySummary {
@@ -119,7 +151,7 @@ export interface LoopAttempt {
119
151
  attemptId: string;
120
152
  index: number;
121
153
  adapterId: string;
122
- model: string;
154
+ model?: string;
123
155
  startedAt: string;
124
156
  completedAt?: string;
125
157
  summary?: string;
@@ -156,6 +188,8 @@ export interface LoopRecord {
156
188
  receiptScope?: ReceiptScope;
157
189
  receiptIntegrity?: ReceiptIntegritySummary;
158
190
  routingEconomics?: RoutingEconomics;
191
+ /** Canonical termination identity written by finishFromEvaluation. Present when run ended via exit policy. */
192
+ terminationEnvelope?: TerminationEnvelopeV1;
159
193
  }
160
194
  export interface LoopRecordDraft {
161
195
  loopId?: string;
@@ -175,6 +209,7 @@ export interface LoopRecordDraft {
175
209
  updatedAt?: string;
176
210
  receiptScope?: ReceiptScope;
177
211
  receiptIntegrity?: ReceiptIntegritySummary;
212
+ terminationEnvelope?: TerminationEnvelopeV1;
178
213
  }
179
214
  export type { MartinErrorCategory, MartinOutputMode, MartinRunListFilters, MartinRunSelector } from "./operator.js";
180
215
  export { MARTIN_ERROR_CATEGORIES } from "./operator.js";
@@ -310,7 +345,7 @@ export interface MachineState {
310
345
  * Cost provenance label — every budget metric must carry this.
311
346
  * Never conflate actual with estimated or unavailable.
312
347
  */
313
- export type CostProvenance = "actual" | "estimated" | "unavailable";
348
+ export type CostProvenance = "actual" | "calculated" | "estimated" | "unavailable";
314
349
  /**
315
350
  * Per-attempt budget preflight estimate produced before admission.
316
351
  * Used to gate attempts before any tokens are spent.
@@ -410,3 +445,17 @@ export { cloneIdentityAttestation, cloneIdentityClaims, cloneIdentityToken } fro
410
445
  export type { IdentityAttestation, IdentityClaims, IdentityToken } from "./identity.js";
411
446
  export { cloneCircuitBreakDecision, cloneTrajectoryAssessment } from "./trajectory.js";
412
447
  export type { CircuitBreakDecision, TrajectoryAssessment, TrajectorySignal } from "./trajectory.js";
448
+ export { EXIT_KINDS, EXIT_POLICY_VERSION, EXIT_EVALUATION_VERSION, EXIT_SIGNAL_VERSION, TERMINATION_ENVELOPE_VERSION } from "./exits.js";
449
+ export type { ExitKind, ExitEvaluationPhase, ExternalEventDisposition, ExternalExitEvent, ExitPolicyV1, ExitSignalV1, ExitSnapshotV1, ExitMatchV1, ExitEvaluationV1, TerminationEnvelopeV1 } from "./exits.js";
450
+ export { ALLOWED_ACTION_TYPES, DELIVERY_MESSAGE_SCHEMA_VERSION, DELIVERY_RECORD_SCHEMA_VERSION, MESSAGE_SELECTION_RESPONSE_SCHEMA_VERSION } from "./delivery.js";
451
+ export type { ActionType, DeliveryMessage, DeliveryRecord, MessageKind, MessageSelectionResponse, UpdateAvailableField } from "./delivery.js";
452
+ export { CONTEXT_SHADOW_MANIFEST_VERSION, CONTEXT_C5_VERSION } from "./context-shadow.js";
453
+ export type { ContextC5EnvelopeV1, ContextEvidence, ContextShadowDecisionV1, ContextShadowManifestV1, ContextShadowSegmentInput, ContextShadowSegmentKind } from "./context-shadow.js";
454
+ export { CONTEXT_MANIFEST_VERSION, CONTEXT_LEDGER_VERSION } from "./context-manifest.js";
455
+ export type { ContinuationCheckpoint, ContextBudget, ContextCandidateDecision, ContextFaultRequest, ContextFaultResult, ContextKind, ContextLedgerEntry, ContextManifest, ContextObject, ContextPolicy, ContextPriority, ContextSensitivity, ContextTrust, TaskItem, UsageEvidence } from "./context-manifest.js";
456
+ export { EVIDENCE_STATUSES, EXECUTION_MODES, TEST_INTEGRITY_STATUSES, TEST_INTEGRITY_VERDICTS, VERIFIED_HANDOFF_OUTCOMES, } from "./verified-handoff.js";
457
+ export type { EvidenceStatus, ExecutionMode, TestIntegrityStatus, TestIntegrityVerdict, VerifiedHandoffCheckV1, VerifiedHandoffOutcome, VerifiedHandoffRecoveryV1, VerifiedHandoffRequirementV1, VerifiedHandoffScopeV1, VerifiedHandoffTestIntegrityV1, VerifiedHandoffV1, } from "./verified-handoff.js";
458
+ export { HANDOFF_SCHEMA_VERSION } from "./context-handoff.js";
459
+ export type { ChainIntegrityState, ContextCircuitBreakResult, ContextExclusionDecision, ContextHandoffArtifact, ContextHandoffClaim, ContextHandoffReceipt, ContextHandoffVerification, HandoffClaimState } from "./context-handoff.js";
460
+ export { MISSION_SCHEMA_VERSION, MISSION_STATUSES, ALLOWED_MISSION_TRANSITIONS, createMissionRecord, isMissionTransitionAllowed } from './mission.js';
461
+ export type { MissionStatus, MissionDecision, MissionBudget, MissionCost, MissionRunLink, MissionRunRole, MissionApproval, MissionOutcome, MissionEvent, MissionEventKind, MissionRecord, MissionDraft } from './mission.js';
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Contracts for the Martin Loop agentic system.
3
+ *
4
+ * This module defines the core type contracts and data structures for autonomous agent loop management,
5
+ * including loop lifecycle states, task definitions, budget tracking, cost accounting, verification,
6
+ * patch decisions, telemetry, and governance policies. It provides the public API surface for
7
+ * creating and managing loop records, handling events, validating batches, and tracking
8
+ * portfolio snapshots and routing economics.
9
+ */
1
10
  export const FAILURE_CLASSES = [
2
11
  "logic_error",
3
12
  "hallucination",
@@ -53,6 +62,7 @@ export function createLoopRecord(draft, options = {}) {
53
62
  updatedAt: draft.updatedAt ?? now,
54
63
  ...(draft.receiptScope ? { receiptScope: draft.receiptScope } : {}),
55
64
  ...(draft.receiptIntegrity ? { receiptIntegrity: draft.receiptIntegrity } : {}),
65
+ ...(draft.terminationEnvelope ? { terminationEnvelope: draft.terminationEnvelope } : {}),
56
66
  ...(draft.teamId ? { teamId: draft.teamId } : {})
57
67
  };
58
68
  }
@@ -210,6 +220,8 @@ function nextStatus(current, eventType) {
210
220
  return "verifying";
211
221
  case "run.completed":
212
222
  return current === "failed" ? "failed" : "completed";
223
+ case "run.terminated":
224
+ return "exited";
213
225
  default:
214
226
  return current;
215
227
  }
@@ -223,3 +235,15 @@ export { DEFAULT_ROUTING_POLICY } from "./execution-policy.js";
223
235
  export { cloneContextGraphSnapshot } from "./context-graph.js";
224
236
  export { cloneIdentityAttestation, cloneIdentityClaims, cloneIdentityToken } from "./identity.js";
225
237
  export { cloneCircuitBreakDecision, cloneTrajectoryAssessment } from "./trajectory.js";
238
+ export { EXIT_KINDS, EXIT_POLICY_VERSION, EXIT_EVALUATION_VERSION, EXIT_SIGNAL_VERSION, TERMINATION_ENVELOPE_VERSION } from "./exits.js";
239
+ // ─── R4 Delivery — M1 Contract ──────────────────────────────────────────────
240
+ export { ALLOWED_ACTION_TYPES, DELIVERY_MESSAGE_SCHEMA_VERSION, DELIVERY_RECORD_SCHEMA_VERSION, MESSAGE_SELECTION_RESPONSE_SCHEMA_VERSION } from "./delivery.js";
241
+ // ─── Context Shadow — A-CTX-0 ────────────────────────────────────────────────
242
+ export { CONTEXT_SHADOW_MANIFEST_VERSION, CONTEXT_C5_VERSION } from "./context-shadow.js";
243
+ // ─── Context Runtime — A-CTX-1 ───────────────────────────────────────────────
244
+ export { CONTEXT_MANIFEST_VERSION, CONTEXT_LEDGER_VERSION } from "./context-manifest.js";
245
+ // ─── Track A — Verified Handoff ───────────────────────────────────────────────
246
+ export { EVIDENCE_STATUSES, EXECUTION_MODES, TEST_INTEGRITY_STATUSES, TEST_INTEGRITY_VERDICTS, VERIFIED_HANDOFF_OUTCOMES, } from "./verified-handoff.js";
247
+ // ─── Context Handoff — A-CTX-2 ───────────────────────────────────────────────
248
+ export { HANDOFF_SCHEMA_VERSION } from "./context-handoff.js";
249
+ export { MISSION_SCHEMA_VERSION, MISSION_STATUSES, ALLOWED_MISSION_TRANSITIONS, createMissionRecord, isMissionTransitionAllowed } from './mission.js';
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Mission Governance contracts — C2
3
+ *
4
+ * A MissionRecord governs one software mission: intent → budget → runs →
5
+ * verification → decision → receipt. It never replaces LoopRecord; it
6
+ * aggregates above it.
7
+ *
8
+ * Invariants:
9
+ * - One accountable human owner per mission.
10
+ * - State transitions are append-only in the ledger.
11
+ * - Ledger is the authority; mission.json is a rebuildable cache.
12
+ * - A mission cannot become "verified" without verified run evidence.
13
+ * - A mission cannot become "shipped" without an explicit ship decision.
14
+ * - Unknown schema versions fail closed.
15
+ * - Budgets cannot be raised silently.
16
+ */
17
+ export declare const MISSION_SCHEMA_VERSION: "martin.mission.v1";
18
+ export declare const MISSION_STATUSES: readonly ["planned", "running", "blocked", "verified", "shipped", "rolled_back", "killed"];
19
+ export type MissionStatus = (typeof MISSION_STATUSES)[number];
20
+ export declare const ALLOWED_MISSION_TRANSITIONS: Record<MissionStatus, readonly MissionStatus[]>;
21
+ export type MissionDecision = "ship" | "retry" | "rollback" | "kill";
22
+ export interface MissionBudget {
23
+ maxUsd: number;
24
+ maxTokens: number;
25
+ maxRuns: number;
26
+ maxConcurrentRuns: number;
27
+ }
28
+ export interface MissionCost {
29
+ /** Sum of actualUsd across all linked runs. */
30
+ totalActualUsd: number;
31
+ /** Number of linked runs with status "completed" (verified outcome). */
32
+ verifiedOutcomeCount: number;
33
+ /** Number of linked runs regardless of outcome. */
34
+ totalRunCount: number;
35
+ }
36
+ export type MissionRunRole = "primary" | "experiment" | "validation";
37
+ export interface MissionRunLink {
38
+ loopId: string;
39
+ role: MissionRunRole;
40
+ attachedAt: string;
41
+ /** Set to true when the linked run completed with verification passed. */
42
+ verifiedOutcome?: boolean;
43
+ /** Actual cost of this run in USD. */
44
+ actualUsd?: number;
45
+ }
46
+ export interface MissionApproval {
47
+ approvalId: string;
48
+ kind: "ship" | "budget_increase" | "scope_change";
49
+ decision: "approved" | "denied";
50
+ approvedBy: string;
51
+ approvedAt: string;
52
+ note?: string;
53
+ }
54
+ export interface MissionOutcome {
55
+ decision: MissionDecision;
56
+ decidedAt: string;
57
+ decidedBy: string;
58
+ note?: string;
59
+ }
60
+ export type MissionEventKind = "mission.created" | "mission.status_changed" | "mission.run_attached" | "mission.run_verified" | "mission.approved" | "mission.closed" | "mission.collision_blocked";
61
+ export interface MissionEvent {
62
+ eventId: string;
63
+ kind: MissionEventKind;
64
+ missionId: string;
65
+ timestamp: string;
66
+ payload: Record<string, unknown>;
67
+ }
68
+ export interface MissionRecord {
69
+ schemaVersion: typeof MISSION_SCHEMA_VERSION;
70
+ missionId: string;
71
+ /** Monotonically increasing write counter. Used for CAS enforcement. */
72
+ revision: number;
73
+ title: string;
74
+ objective: string;
75
+ ownerId: string;
76
+ workspaceId: string;
77
+ projectId: string;
78
+ status: MissionStatus;
79
+ budget: MissionBudget;
80
+ cost: MissionCost;
81
+ runLinks: MissionRunLink[];
82
+ approvals: MissionApproval[];
83
+ outcome?: MissionOutcome;
84
+ acceptanceCriteria: string[];
85
+ createdAt: string;
86
+ updatedAt: string;
87
+ }
88
+ export interface MissionDraft {
89
+ missionId?: string;
90
+ title: string;
91
+ objective: string;
92
+ ownerId: string;
93
+ workspaceId: string;
94
+ projectId: string;
95
+ budget: MissionBudget;
96
+ acceptanceCriteria?: string[];
97
+ }
98
+ export declare function createMissionRecord(draft: MissionDraft, options?: {
99
+ now?: () => string;
100
+ idFactory?: (prefix: string) => string;
101
+ }): MissionRecord;
102
+ export declare function isMissionTransitionAllowed(from: MissionStatus, to: MissionStatus): boolean;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Mission Governance contracts — C2
3
+ *
4
+ * A MissionRecord governs one software mission: intent → budget → runs →
5
+ * verification → decision → receipt. It never replaces LoopRecord; it
6
+ * aggregates above it.
7
+ *
8
+ * Invariants:
9
+ * - One accountable human owner per mission.
10
+ * - State transitions are append-only in the ledger.
11
+ * - Ledger is the authority; mission.json is a rebuildable cache.
12
+ * - A mission cannot become "verified" without verified run evidence.
13
+ * - A mission cannot become "shipped" without an explicit ship decision.
14
+ * - Unknown schema versions fail closed.
15
+ * - Budgets cannot be raised silently.
16
+ */
17
+ export const MISSION_SCHEMA_VERSION = "martin.mission.v1";
18
+ // ─── Status and transitions ───────────────────────────────────────────────────
19
+ export const MISSION_STATUSES = [
20
+ "planned",
21
+ "running",
22
+ "blocked",
23
+ "verified",
24
+ "shipped",
25
+ "rolled_back",
26
+ "killed"
27
+ ];
28
+ export const ALLOWED_MISSION_TRANSITIONS = {
29
+ planned: ["running", "killed"],
30
+ running: ["blocked", "verified", "rolled_back", "killed"],
31
+ blocked: ["running", "rolled_back", "killed"],
32
+ verified: ["shipped", "running", "rolled_back", "killed"],
33
+ shipped: [],
34
+ rolled_back: ["running", "killed"],
35
+ killed: []
36
+ };
37
+ // ─── Factory ──────────────────────────────────────────────────────────────────
38
+ export function createMissionRecord(draft, options = {}) {
39
+ const now = options.now ?? (() => new Date().toISOString());
40
+ const makeId = options.idFactory ?? ((prefix) => `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`);
41
+ const ts = now();
42
+ return {
43
+ schemaVersion: MISSION_SCHEMA_VERSION,
44
+ missionId: draft.missionId ?? makeId("mission"),
45
+ revision: 0,
46
+ title: draft.title,
47
+ objective: draft.objective,
48
+ ownerId: draft.ownerId,
49
+ workspaceId: draft.workspaceId,
50
+ projectId: draft.projectId,
51
+ status: "planned",
52
+ budget: { ...draft.budget },
53
+ cost: { totalActualUsd: 0, verifiedOutcomeCount: 0, totalRunCount: 0 },
54
+ runLinks: [],
55
+ approvals: [],
56
+ acceptanceCriteria: draft.acceptanceCriteria ?? [],
57
+ createdAt: ts,
58
+ updatedAt: ts
59
+ };
60
+ }
61
+ // ─── Transition guard ─────────────────────────────────────────────────────────
62
+ export function isMissionTransitionAllowed(from, to) {
63
+ return ALLOWED_MISSION_TRANSITIONS[from].includes(to);
64
+ }
@@ -1,8 +1,9 @@
1
- export declare const MARTIN_ERROR_CATEGORIES: readonly ["invalid_input", "environment", "auth", "not_found", "store_unreadable", "verification_failed", "policy_blocked", "budget_exit", "transient"];
1
+ export declare const MARTIN_ERROR_CATEGORIES: readonly ["invalid_input", "environment", "auth", "not_found", "store_unreadable", "verification_failed", "policy_blocked", "budget_exit", "transient", "install_failed"];
2
2
  export type MartinErrorCategory = (typeof MARTIN_ERROR_CATEGORIES)[number];
3
3
  export type MartinOutputMode = "human" | "json" | "quiet";
4
4
  export interface MartinRunSelector {
5
5
  runsDir?: string;
6
+ workspaceId?: string;
6
7
  file?: string;
7
8
  loopId?: string;
8
9
  latest?: boolean;
@@ -10,6 +11,7 @@ export interface MartinRunSelector {
10
11
  }
11
12
  export interface MartinRunListFilters {
12
13
  runsDir?: string;
14
+ workspaceId?: string;
13
15
  limit?: number;
14
16
  status?: string;
15
17
  lifecycleState?: string;
@@ -7,5 +7,6 @@ export const MARTIN_ERROR_CATEGORIES = [
7
7
  "verification_failed",
8
8
  "policy_blocked",
9
9
  "budget_exit",
10
- "transient"
10
+ "transient",
11
+ "install_failed"
11
12
  ];
@@ -0,0 +1,106 @@
1
+ import type { CostProvenance, LoopLifecycleState, LoopStatus, ReceiptIntegritySummary } from "./index.js";
2
+ export declare const VERIFIED_HANDOFF_OUTCOMES: readonly ["VERIFIED", "STOPPED", "NEEDS_REVIEW"];
3
+ export type VerifiedHandoffOutcome = (typeof VERIFIED_HANDOFF_OUTCOMES)[number];
4
+ export declare const EXECUTION_MODES: readonly ["governed", "verification_only", "simulated"];
5
+ export type ExecutionMode = (typeof EXECUTION_MODES)[number];
6
+ export declare const EVIDENCE_STATUSES: readonly ["PASSED", "FAILED", "CONTRADICTED", "NOT_RUN", "NOT_EVALUATED"];
7
+ export type EvidenceStatus = (typeof EVIDENCE_STATUSES)[number];
8
+ /**
9
+ * Granular internal/runtime state. Retained for diagnosis, policy,
10
+ * receipts and engineering review.
11
+ */
12
+ export declare const TEST_INTEGRITY_STATUSES: readonly ["UNCHANGED", "AUTHORIZED_CHANGE", "PREVENTED", "DETECTED_AND_ROLLED_BACK", "DETECTED_NEEDS_REVIEW", "NOT_EVALUATED"];
13
+ export type TestIntegrityStatus = (typeof TEST_INTEGRITY_STATUSES)[number];
14
+ /**
15
+ * Stable public-facing verdict used by CLI, MCP, JSON/Markdown handoffs
16
+ * and the website. Do not make each renderer collapse states independently.
17
+ */
18
+ export declare const TEST_INTEGRITY_VERDICTS: readonly ["VERIFIED", "TAMPERING_DETECTED", "NOT_EVALUATED"];
19
+ export type TestIntegrityVerdict = (typeof TEST_INTEGRITY_VERDICTS)[number];
20
+ export interface VerifiedHandoffCheckV1 {
21
+ command: string;
22
+ status: EvidenceStatus;
23
+ exitCode?: number;
24
+ timedOut?: boolean;
25
+ detail?: string;
26
+ }
27
+ export interface VerifiedHandoffRequirementV1 {
28
+ requirement: string;
29
+ status: "PROVEN" | "FAILED" | "UNRESOLVED" | "NOT_EVALUATED";
30
+ evidence?: string[];
31
+ }
32
+ export interface VerifiedHandoffScopeV1 {
33
+ status: "WITHIN_SCOPE" | "VIOLATION_REJECTED" | "NEEDS_REVIEW" | "NOT_EVALUATED";
34
+ allowedPaths: string[];
35
+ deniedPaths: string[];
36
+ changedFiles: string[];
37
+ violations: string[];
38
+ }
39
+ export interface VerifiedHandoffTestIntegrityV1 {
40
+ /** Public rendering contract. */
41
+ verdict: TestIntegrityVerdict;
42
+ /** Granular runtime state for diagnosis and evidence. */
43
+ status: TestIntegrityStatus;
44
+ protectedPaths: string[];
45
+ changedProtectedPaths: string[];
46
+ findings: Array<{
47
+ filePath: string;
48
+ issue: string;
49
+ severity: "high" | "medium" | "low";
50
+ detail: string;
51
+ }>;
52
+ summary: string;
53
+ }
54
+ export interface VerifiedHandoffRecoveryV1 {
55
+ rollbackBoundaryAvailable: boolean;
56
+ rollbackAttempted: boolean;
57
+ rollbackSucceeded?: boolean;
58
+ isolatedRef?: string;
59
+ nextCommand?: string;
60
+ summary: string;
61
+ }
62
+ export interface VerifiedHandoffV1 {
63
+ schemaVersion: "1.0.0";
64
+ handoffId: string;
65
+ loopId: string;
66
+ generatedAt: string;
67
+ task: {
68
+ title: string;
69
+ objective: string;
70
+ };
71
+ definitionOfDone: {
72
+ acceptanceCriteria: string[];
73
+ verificationPlan: string[];
74
+ };
75
+ outcome: VerifiedHandoffOutcome;
76
+ /** Added compatibly in 1.0.0; missing legacy values must be treated as non-governed. */
77
+ executionMode?: ExecutionMode;
78
+ /** Only an explicit true value is eligible for a governed VERIFIED claim. */
79
+ governanceClaimEligible?: boolean;
80
+ sourceStatus: {
81
+ status: LoopStatus;
82
+ lifecycleState: LoopLifecycleState;
83
+ };
84
+ verification: {
85
+ status: EvidenceStatus;
86
+ summary: string;
87
+ checks: VerifiedHandoffCheckV1[];
88
+ warnings: string[];
89
+ };
90
+ requirements: VerifiedHandoffRequirementV1[];
91
+ scope: VerifiedHandoffScopeV1;
92
+ testIntegrity: VerifiedHandoffTestIntegrityV1;
93
+ unresolvedWork: string[];
94
+ stopReason?: string;
95
+ recovery: VerifiedHandoffRecoveryV1;
96
+ usage: {
97
+ attempts: number;
98
+ actualUsd: number;
99
+ estimatedUsd?: number;
100
+ tokensIn: number;
101
+ tokensOut: number;
102
+ costProvenance: CostProvenance;
103
+ };
104
+ receiptIntegrity: ReceiptIntegritySummary;
105
+ nextAction: string;
106
+ }