/** * Contracts for the Martin Loop agentic system. * * This module defines the core type contracts and data structures for autonomous agent loop management, * including loop lifecycle states, task definitions, budget tracking, cost accounting, verification, * patch decisions, telemetry, and governance policies. It provides the public API surface for * creating and managing loop records, handling events, validating batches, and tracking * portfolio snapshots and routing economics. */ import type { TerminationEnvelopeV1 } from "./exits.js"; import type { AgentExecutionIntent } from "./agent-execution.js"; export { DEFAULT_AGENT_EXECUTION_INTENT, DEFAULT_PROVIDER_EXECUTION_TIMEOUT_MS, GOVERNED_AUTONOMOUS_BOUNDARY, normalizeProviderExecutionTimeoutMs } from "./agent-execution.js"; export type { AgentExecutionIntent } from "./agent-execution.js"; export type LoopStatus = "queued" | "running" | "verifying" | "completed" | "failed" | "exited"; export type LoopLifecycleState = "created" | "running" | "verifying" | "completed" | "budget_exit" | "diminishing_returns" | "stuck_exit" | "human_escalation" | "wall_clock" | "error_threshold" | "external_event"; 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"]; export type FailureClass = (typeof FAILURE_CLASSES)[number]; export type InterventionType = "compress_context" | "change_model" | "tighten_task" | "switch_adapter" | "run_verifier" | "escalate_human" | "stop_loop"; export type LoopEventType = "run.started" | "attempt.started" | "attempt.completed" | "failure.classified" | "intervention.selected" | "verification.completed" | "budget.updated" | "run.completed" | "run.terminated"; export interface LoopTask { title: string; objective: string; repoRoot?: string; verificationPlan: string[]; verificationTimeoutMs?: number; verificationStack?: VerificationStep[]; mutationMode?: MutationMode; /** Explicit task-authority evidence that all definition-of-done criteria were satisfied before execution. */ definitionOfDonePreSatisfied?: boolean; executionProfile?: ExecutionProfile; allowedNetworkDomains?: string[]; approvalPolicy?: ApprovalPolicy; /** Provider-neutral execution posture. Defaults to governed autonomous execution. */ agentExecutionIntent?: AgentExecutionIntent; /** Hard wall-clock limit for one provider coding process. */ providerExecutionTimeoutMs?: number; /** Glob patterns for files the agent is allowed to modify. Empty = no restriction. */ allowedPaths?: string[]; /** Glob patterns for files the agent must never modify. */ deniedPaths?: string[]; /** Human-readable acceptance criteria injected into the prompt as a checklist. */ acceptanceCriteria?: string[]; } export type ExecutionProfile = "strict_local" | "ci_safe" | "staging_controlled" | "research_untrusted"; export type MutationMode = "edit"; export interface ApprovalPolicy { dependencyAdds?: boolean; migrations?: boolean; configChanges?: boolean; externalWrites?: boolean; } export interface VerificationStep { /** Shell command to run. */ command: string; /** Classification for reporting and intervention selection. */ type: "lint" | "typecheck" | "test_targeted" | "test_full" | "custom"; /** Stop the verification stack immediately on failure. Defaults to true. */ fastFail?: boolean; /** Relative weight for partial scoring (0.0-1.0). */ weight?: number; } export interface LoopBudget { maxUsd: number; softLimitUsd: number; maxIterations: number; maxTokens?: number; } export interface LoopCost { actualUsd: number; avoidedUsd: number; tokensIn: number; tokensOut: number; estimatedUsd?: number; provenance?: CostProvenance; providerSettlement?: ProviderUsageSettlement; savingsBaseline?: { usd: number; source: "measured_control" | "operator_supplied" | "fixture"; provenance: CostProvenance; }; } export type UsageSettlementSource = "claude_json" | "codex_jsonl" | "gemini_json" | "openai_compatible_json" | "estimated_fallback" | "unavailable"; export interface ProviderUsageSettlement { providerId: string; model?: string; transport?: "cli" | "http" | "routed_http"; source: UsageSettlementSource; inputTokens: number; cachedInputTokens?: number; outputTokens: number; reasoningOutputTokens?: number; cacheCreationInputTokens?: number; billingMode?: "metered_api" | "subscription" | "local_unmetered" | "unknown"; modelSource?: "provider_reported" | "explicit_override" | "provider_configured" | "agent_default" | "unavailable"; pricingSource?: "provider_reported_total" | "static_catalog" | "blended_fallback" | "none"; pricingVersion?: string; rawUsageAvailable: boolean; settledAt: string; } export interface ReceiptScope { repoRoot?: string; workingDirectory?: string; invocationRoot?: string; runsRoot?: string; /** Sandbox mode the mission requested before execution. */ requestedSandbox?: "read-only" | "workspace-write" | "danger-full-access"; /** Effective sandbox capability detected by pre-run filesystem probe. */ effectiveSandbox?: "read-only" | "workspace-write" | "unknown"; /** Absolute path that the filesystem write probe tested. */ writableRoot?: string; /** How the effective sandbox was determined. */ capabilitySource?: "probe" | "configured" | "unknown"; agentExecutionIntent?: AgentExecutionIntent; providerExecutionTimeoutMs?: number; /** Enforced demo changes (DEMO.md-only enforcement output). */ demoChangedFiles?: string[]; } export type ReceiptIntegrityState = "verified" | "unsigned" | "tamper_detected" | "relocated" | "material_missing" | "selector_noncanonical"; export interface ReceiptIntegritySummary { state: ReceiptIntegrityState; keyId?: string; signedAt?: string; loopRecordSha256?: string; ledgerSha256?: string; ledgerHeadHash?: string; entryCount?: number; reason?: string; warnings?: string[]; } export interface LoopArtifact { artifactId: string; kind: "diff" | "trace" | "report" | "transcript" | "screenshot" | "other"; label: string; uri: string; } export type CallStage = "routing" | "planning" | "execution" | "verification" | "retry" | "rollback" | "receipt"; export type AgentRole = "manager" | "router" | "planner" | "worker" | "verifier" | "reviewer" | "fixer" | "system"; export interface FirstDelta { detected: boolean; timestampMs?: number; filePath?: string; changeType?: "create" | "modify" | "delete" | "patch_proposed"; /** Elapsed ms from run start to first meaningful workspace change. */ timeToFirstDeltaMs?: number; } export interface RoutingEconomics { preworkCostUsd: number; executionCostUsd: number; verificationCostUsd: number; retryCostUsd: number; totalCostUsd: number; preworkBurnPct: number; timeToFirstDeltaMs?: number; firstDelta?: FirstDelta; costPerAcceptedChange?: number; routeRecommendation?: "same_route" | "direct_worker" | "manager_required" | "consensus_required"; routeRecommendationReason?: string; } export interface LoopAttempt { attemptId: string; index: number; adapterId: string; model?: string; startedAt: string; completedAt?: string; summary?: string; failureClass?: FailureClass; intervention?: InterventionType; /** Actionable diagnosis from failure classification, injected into the next attempt's prompt. */ diagnosticHint?: string; /** Which stage of the run lifecycle this attempt represents. */ callStage?: CallStage; } export interface LoopEvent { eventId: string; type: LoopEventType; timestamp: string; lifecycleState: LoopLifecycleState; payload: Record; } export interface LoopRecord { loopId: string; workspaceId: string; projectId: string; teamId?: string; status: LoopStatus; lifecycleState: LoopLifecycleState; task: LoopTask; budget: LoopBudget; cost: LoopCost; artifacts: LoopArtifact[]; attempts: LoopAttempt[]; events: LoopEvent[]; metadata: Record; createdAt: string; updatedAt: string; receiptScope?: ReceiptScope; receiptIntegrity?: ReceiptIntegritySummary; routingEconomics?: RoutingEconomics; /** Canonical termination identity written by finishFromEvaluation. Present when run ended via exit policy. */ terminationEnvelope?: TerminationEnvelopeV1; } export interface LoopRecordDraft { loopId?: string; workspaceId: string; projectId: string; teamId?: string; status?: LoopStatus; lifecycleState?: LoopLifecycleState; task: LoopTask; budget?: Partial; cost?: Partial; artifacts?: LoopArtifact[]; attempts?: LoopAttempt[]; events?: LoopEvent[]; metadata?: Record; createdAt?: string; updatedAt?: string; receiptScope?: ReceiptScope; receiptIntegrity?: ReceiptIntegritySummary; terminationEnvelope?: TerminationEnvelopeV1; } export type { MartinErrorCategory, MartinOutputMode, MartinRunListFilters, MartinRunSelector } from "./operator.js"; export { MARTIN_ERROR_CATEGORIES } from "./operator.js"; export interface LoopEventDraft { type: LoopEventType; lifecycleState?: LoopLifecycleState; payload: Record; timestamp?: string; } export type TelemetryEnvironment = "local" | "ci" | "staging" | "production"; export interface TelemetrySource { runtimeVersion: string; adapterId: string; provider: string; model: string; } export interface TelemetryEvent { eventId: string; loopId: string; attemptId?: string; type: LoopEventType; lifecycleState: LoopLifecycleState; timestamp: string; sequence: number; payload: Record; } export interface TelemetryEventDraft { loopId: string; attemptId?: string; type: LoopEventType; lifecycleState: LoopLifecycleState; timestamp?: string; payload: Record; } export interface TelemetryEnvelope { schemaVersion: string; envelopeId: string; workspaceId: string; projectId: string; ingestKeyId: string; environment: TelemetryEnvironment; emittedAt: string; sequence: number; source: TelemetrySource; events: TelemetryEvent[]; } export interface TelemetryEnvelopeDraft { schemaVersion?: string; workspaceId: string; projectId: string; ingestKeyId: string; environment: TelemetryEnvironment; source: TelemetrySource; events: TelemetryEventDraft[]; } export interface TelemetryLoopSnapshot { loopId: string; status: LoopStatus; lifecycleState: LoopLifecycleState; cost: LoopCost; } export interface TelemetryBatch { workspaceId: string; projectId: string; loops: TelemetryLoopSnapshot[]; } export interface ValidationResult { ok: boolean; errors: string[]; } export interface PortfolioSnapshot { totalActualUsd: number; totalAvoidedUsd: number; totalTokensIn: number; totalTokensOut: number; activeLoops: number; optimizedLoops: number; failuresCaught: number; averageExitSeconds: number; } export interface ContractOptions { now?: string; idFactory?: (prefix: string) => string; } export declare const DEFAULT_BUDGET: LoopBudget; export declare const EMPTY_COST: LoopCost; export declare function createLoopRecord(draft: LoopRecordDraft, options?: ContractOptions): LoopRecord; export declare function appendLoopEvent(loop: LoopRecord, eventDraft: LoopEventDraft, options?: ContractOptions): LoopRecord; export declare function validateTelemetryBatch(batch: TelemetryBatch): ValidationResult; export declare function buildPortfolioSnapshot(loops: LoopRecord[]): PortfolioSnapshot; export declare function createTelemetryEnvelope(draft: TelemetryEnvelopeDraft, options?: ContractOptions): TelemetryEnvelope; export declare function validateTelemetryEnvelope(envelope: TelemetryEnvelope): ValidationResult; export type PolicyPhase = "GATHER" | "ADMIT" | "PATCH" | "VERIFY" | "RECOVER" | "ESCALATE" | "ABORT" | "HANDOFF"; export interface EvidenceVector { /** Count of compile/build errors in the last attempt output. */ compileErrors: number; /** Count of TypeScript type errors. */ typeErrors: number; /** Count of failing test cases. */ failingTests: number; /** Verifier score 0.0–1.0 (1.0 = full pass). */ verifierScore: number; /** Patch novelty 0.0–1.0 (0.0 = identical to previous attempt). */ diffNovelty: number; /** Number of forbidden files touched by the last patch. */ forbiddenTouchedFileCount: number; /** Count of unresolvable symbols/modules referenced in the patch. */ missingSymbolCount: number; /** Actual USD cost divided by verifier score improvement. */ costPerProgressUnit: number; /** How many times this failure surface has been retried. */ retryCountForSurface: number; /** Safety risk score 0.0–1.0 from leash evaluation. */ safetyRiskScore: number; } export interface MachineState { phase: PolicyPhase; currentAttempt: number; activeModel: string; remainingBudgetUsd: number; /** Retry counter per FailureClass surface. */ attemptCountersBySurface: Record; lastFailureSurface?: FailureClass; lastVerifierScore: number; openAlerts: string[]; policyHistory: Array<{ phase: PolicyPhase; reason: string; timestamp: string; }>; } /** * Cost provenance label — every budget metric must carry this. * Never conflate actual with estimated or unavailable. */ export type CostProvenance = "actual" | "calculated" | "estimated" | "unavailable"; /** * Per-attempt budget preflight estimate produced before admission. * Used to gate attempts before any tokens are spent. */ export interface BudgetPreflightEstimate { estimatedPromptTokens: number; estimatedToolOverheadTokens: number; estimatedOutputTokensMax: number; estimatedVerifierCostUsd: number; estimatedAttemptCostUsd: number; provenance: CostProvenance; } /** * Actual cost settlement written to the ledger after an attempt completes. * Separates patch cost from verification cost. */ export interface BudgetSettlement { runId: string; attemptIndex: number; patchCost: { usd: number; tokensIn: number; tokensOut: number; provenance: CostProvenance; }; verificationCost: { usd: number; provenance: CostProvenance; }; providerSettlement?: ProviderUsageSettlement; totalActualUsd: number; preflightEstimateUsd: number; varianceUsd: number; settledAt: string; } export type PatchDecision = "KEEP" | "DISCARD" | "ESCALATE" | "HANDOFF"; export type PatchDecisionReasonCode = "verifier_passed" | "verifier_regressed" | "grounding_failure" | "scope_violation" | "no_code_change" | "large_diff_no_improvement" | "low_novelty_no_progress" | "human_approval_required" | "safety_violation" | "verifier_not_improved"; export interface PatchScore { score: number; verifierScore: number; verifierDelta: number; groundingViolationCount: number; scopeViolationCount: number; safetyViolationCount: number; changedFileCount: number; diffRiskScore: number; noveltyScore: number; costUsd: number; reasonCodes: PatchDecisionReasonCode[]; } export interface PatchDecisionArtifact { decision: PatchDecision; summary: string; reasonCodes: PatchDecisionReasonCode[]; } export type RollbackBoundaryStrategy = "git_head_plus_snapshot" | "no_repo_root"; export interface RollbackFileSnapshot { path: string; existed: boolean; encoding: "base64"; contentBase64?: string; } export interface RollbackBoundaryArtifact { strategy: RollbackBoundaryStrategy; capturedAt: string; headRef?: string; trackedDirtyFiles: string[]; untrackedFiles: string[]; snapshots: RollbackFileSnapshot[]; } export type RollbackOutcomeStatus = "restored" | "not_required" | "failed" | "unavailable"; export interface RollbackOutcomeArtifact { attempted: boolean; status: RollbackOutcomeStatus; restoredAt: string; decision: PatchDecision; before: { trackedDirtyFiles: string[]; untrackedFiles: string[]; }; after: { trackedDirtyFiles: string[]; untrackedFiles: string[]; }; restoredFiles: string[]; deletedFiles: string[]; error?: string; } export { createGovernanceSnapshot } from "./governance.js"; export type { DestructiveActionPolicy, GovernanceSnapshot, PolicyProfile, TelemetryDestination } from "./governance.js"; export { cloneExecutionPolicy } from "./execution-policy.js"; export type { ExecutionPolicy, ExecutionPolicyCompileInput, ExecutionPolicyConfigInput, ExecutionPolicyDefaults, ExecutionPolicyProvenanceEntry, ExecutionPolicyRequestInput, RoutingPolicy, RoutingMode } from "./execution-policy.js"; export { DEFAULT_ROUTING_POLICY } from "./execution-policy.js"; export { cloneContextGraphSnapshot } from "./context-graph.js"; export type { ContextGraphBuildOptions, ContextGraphEdge, ContextGraphHit, ContextGraphNode, ContextGraphNodeKind, ContextGraphSnapshot, ContextQuery } from "./context-graph.js"; export { cloneIdentityAttestation, cloneIdentityClaims, cloneIdentityToken } from "./identity.js"; export type { IdentityAttestation, IdentityClaims, IdentityToken } from "./identity.js"; export { cloneCircuitBreakDecision, cloneTrajectoryAssessment } from "./trajectory.js"; export type { CircuitBreakDecision, TrajectoryAssessment, TrajectorySignal } from "./trajectory.js"; export { EXIT_KINDS, EXIT_POLICY_VERSION, EXIT_EVALUATION_VERSION, EXIT_SIGNAL_VERSION, TERMINATION_ENVELOPE_VERSION } from "./exits.js"; export type { ExitKind, ExitEvaluationPhase, ExternalEventDisposition, ExternalExitEvent, ExitPolicyV1, ExitSignalV1, ExitSnapshotV1, ExitMatchV1, ExitEvaluationV1, TerminationEnvelopeV1 } from "./exits.js"; export { ALLOWED_ACTION_TYPES, DELIVERY_MESSAGE_SCHEMA_VERSION, DELIVERY_RECORD_SCHEMA_VERSION, MESSAGE_SELECTION_RESPONSE_SCHEMA_VERSION } from "./delivery.js"; export type { ActionType, DeliveryMessage, DeliveryRecord, MessageKind, MessageSelectionResponse, UpdateAvailableField } from "./delivery.js"; export { CONTEXT_SHADOW_MANIFEST_VERSION, CONTEXT_C5_VERSION } from "./context-shadow.js"; export type { ContextC5EnvelopeV1, ContextEvidence, ContextShadowDecisionV1, ContextShadowManifestV1, ContextShadowSegmentInput, ContextShadowSegmentKind } from "./context-shadow.js"; export { CONTEXT_MANIFEST_VERSION, CONTEXT_LEDGER_VERSION } from "./context-manifest.js"; export type { ContinuationCheckpoint, ContextBudget, ContextCandidateDecision, ContextFaultRequest, ContextFaultResult, ContextKind, ContextLedgerEntry, ContextManifest, ContextObject, ContextPolicy, ContextPriority, ContextSensitivity, ContextTrust, TaskItem, UsageEvidence } from "./context-manifest.js"; export { EVIDENCE_STATUSES, EXECUTION_MODES, TEST_INTEGRITY_STATUSES, TEST_INTEGRITY_VERDICTS, VERIFIED_HANDOFF_OUTCOMES, } from "./verified-handoff.js"; export type { EvidenceStatus, ExecutionMode, TestIntegrityStatus, TestIntegrityVerdict, VerifiedHandoffCheckV1, VerifiedHandoffOutcome, VerifiedHandoffRecoveryV1, VerifiedHandoffRequirementV1, VerifiedHandoffScopeV1, VerifiedHandoffTestIntegrityV1, VerifiedHandoffV1, } from "./verified-handoff.js"; export { HANDOFF_SCHEMA_VERSION } from "./context-handoff.js"; export type { ChainIntegrityState, ContextCircuitBreakResult, ContextExclusionDecision, ContextHandoffArtifact, ContextHandoffClaim, ContextHandoffReceipt, ContextHandoffVerification, HandoffClaimState } from "./context-handoff.js"; export { MISSION_SCHEMA_VERSION, MISSION_STATUSES, ALLOWED_MISSION_TRANSITIONS, createMissionRecord, isMissionTransitionAllowed } from './mission.js'; export type { MissionStatus, MissionDecision, MissionBudget, MissionCost, MissionRunLink, MissionRunRole, MissionApproval, MissionOutcome, MissionEvent, MissionEventKind, MissionRecord, MissionDraft } from './mission.js';