martin-loop 0.1.4 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CODE_OF_CONDUCT.md +32 -0
- package/README.md +172 -227
- package/demo/seeded-workspace/README.md +35 -0
- package/demo/seeded-workspace/TASKS.md +29 -0
- package/demo/seeded-workspace/martin.config.yaml +11 -0
- package/demo/seeded-workspace/package.json +8 -0
- package/demo/seeded-workspace/src/invoice-summary.js +11 -0
- package/demo/seeded-workspace/test/invoice-summary.test.js +20 -0
- package/dist/bin/martin-loop.js +0 -0
- package/dist/vendor/adapters/claude-cli.d.ts +19 -4
- package/dist/vendor/adapters/claude-cli.js +55 -24
- package/dist/vendor/adapters/cli-bridge.d.ts +1 -0
- package/dist/vendor/adapters/cli-bridge.js +154 -28
- package/dist/vendor/adapters/counter.d.ts +1 -0
- package/dist/vendor/adapters/counter.js +4 -0
- package/dist/vendor/adapters/git-baseline.d.ts +50 -0
- package/dist/vendor/adapters/git-baseline.js +233 -0
- package/dist/vendor/adapters/index.d.ts +1 -0
- package/dist/vendor/adapters/index.js +1 -0
- package/dist/vendor/adapters/openrouter-adapter.d.ts +15 -0
- package/dist/vendor/adapters/openrouter-adapter.js +302 -0
- package/dist/vendor/adapters/usage.d.ts +48 -0
- package/dist/vendor/adapters/usage.js +66 -0
- package/dist/vendor/adapters/verifier-only.d.ts +7 -0
- package/dist/vendor/adapters/verifier-only.js +57 -0
- package/dist/vendor/cli/bin/exit.d.ts +12 -0
- package/dist/vendor/cli/bin/exit.js +28 -0
- package/dist/vendor/cli/commands/analyze.d.ts +5 -0
- package/dist/vendor/cli/commands/analyze.js +58 -0
- package/dist/vendor/cli/commands/audit-log-verify.d.ts +34 -0
- package/dist/vendor/cli/commands/audit-log-verify.js +99 -0
- package/dist/vendor/cli/commands/audit.d.ts +8 -0
- package/dist/vendor/cli/commands/audit.js +199 -0
- package/dist/vendor/cli/commands/corpus.d.ts +5 -0
- package/dist/vendor/cli/commands/corpus.js +60 -0
- package/dist/vendor/cli/commands/doctor.d.ts +8 -0
- package/dist/vendor/cli/commands/doctor.js +219 -0
- package/dist/vendor/cli/commands/explain.d.ts +17 -0
- package/dist/vendor/cli/commands/explain.js +176 -0
- package/dist/vendor/cli/commands/export.d.ts +5 -0
- package/dist/vendor/cli/commands/export.js +60 -0
- package/dist/vendor/cli/commands/governance.d.ts +8 -0
- package/dist/vendor/cli/commands/governance.js +95 -0
- package/dist/vendor/cli/commands/improve.d.ts +18 -0
- package/dist/vendor/cli/commands/improve.js +396 -0
- package/dist/vendor/cli/commands/init.d.ts +8 -0
- package/dist/vendor/cli/commands/init.js +281 -0
- package/dist/vendor/cli/commands/migration.d.ts +8 -0
- package/dist/vendor/cli/commands/migration.js +67 -0
- package/dist/vendor/cli/commands/prior.d.ts +23 -0
- package/dist/vendor/cli/commands/prior.js +145 -0
- package/dist/vendor/cli/commands/resume.d.ts +21 -0
- package/dist/vendor/cli/commands/resume.js +73 -0
- package/dist/vendor/cli/commands/verify.d.ts +6 -0
- package/dist/vendor/cli/commands/verify.js +43 -0
- package/dist/vendor/cli/index.d.ts +6 -1
- package/dist/vendor/cli/index.js +124 -7
- package/dist/vendor/cli/research/public-corpus.d.ts +43 -0
- package/dist/vendor/cli/research/public-corpus.js +151 -0
- package/dist/vendor/cli/ui/error-card.d.ts +38 -0
- package/dist/vendor/cli/ui/error-card.js +103 -0
- package/dist/vendor/cli/ui/mission-brief.d.ts +41 -0
- package/dist/vendor/cli/ui/mission-brief.js +173 -0
- package/dist/vendor/cli/ui/summary-card.d.ts +34 -0
- package/dist/vendor/cli/ui/summary-card.js +102 -0
- package/dist/vendor/contracts/audit.d.ts +46 -0
- package/dist/vendor/contracts/audit.js +360 -0
- package/dist/vendor/contracts/index.d.ts +3 -1
- package/dist/vendor/contracts/post-phase15.d.ts +240 -0
- package/dist/vendor/contracts/post-phase15.js +166 -0
- package/dist/vendor/core/agent/mandates.d.ts +46 -0
- package/dist/vendor/core/agent/mandates.js +178 -0
- package/dist/vendor/core/agent/receipts.d.ts +38 -0
- package/dist/vendor/core/agent/receipts.js +131 -0
- package/dist/vendor/core/agent/signing.d.ts +17 -0
- package/dist/vendor/core/agent/signing.js +91 -0
- package/dist/vendor/core/attestation/sign.d.ts +25 -0
- package/dist/vendor/core/attestation/sign.js +216 -0
- package/dist/vendor/core/autonomy/autonomous-promotion.d.ts +120 -0
- package/dist/vendor/core/autonomy/autonomous-promotion.js +346 -0
- package/dist/vendor/core/autonomy/envelope-v2.d.ts +29 -0
- package/dist/vendor/core/autonomy/envelope-v2.js +60 -0
- package/dist/vendor/core/autonomy/envelope.d.ts +17 -0
- package/dist/vendor/core/autonomy/envelope.js +27 -0
- package/dist/vendor/core/autonomy/escalation-ledger.d.ts +20 -0
- package/dist/vendor/core/autonomy/escalation-ledger.js +18 -0
- package/dist/vendor/core/autonomy/resume.d.ts +15 -0
- package/dist/vendor/core/autonomy/resume.js +23 -0
- package/dist/vendor/core/circuit/circuit-breaker.d.ts +60 -0
- package/dist/vendor/core/circuit/circuit-breaker.js +143 -0
- package/dist/vendor/core/compiler.d.ts +2 -0
- package/dist/vendor/core/compiler.js +10 -4
- package/dist/vendor/core/context-distillation.d.ts +3 -0
- package/dist/vendor/core/context-distillation.js +44 -0
- package/dist/vendor/core/context-flow/compile-context.d.ts +8 -0
- package/dist/vendor/core/context-flow/compile-context.js +111 -0
- package/dist/vendor/core/context-flow/entities.d.ts +2 -0
- package/dist/vendor/core/context-flow/entities.js +44 -0
- package/dist/vendor/core/context-flow/evaluate-policy.d.ts +2 -0
- package/dist/vendor/core/context-flow/evaluate-policy.js +42 -0
- package/dist/vendor/core/context-flow/index.d.ts +11 -0
- package/dist/vendor/core/context-flow/index.js +24 -0
- package/dist/vendor/core/context-flow/labels.d.ts +3 -0
- package/dist/vendor/core/context-flow/labels.js +17 -0
- package/dist/vendor/core/context-flow/normalizer.d.ts +9 -0
- package/dist/vendor/core/context-flow/normalizer.js +69 -0
- package/dist/vendor/core/context-flow/profiles.d.ts +33 -0
- package/dist/vendor/core/context-flow/profiles.js +36 -0
- package/dist/vendor/core/context-flow/redaction.d.ts +1 -0
- package/dist/vendor/core/context-flow/redaction.js +6 -0
- package/dist/vendor/core/context-flow/sensitivity.d.ts +2 -0
- package/dist/vendor/core/context-flow/sensitivity.js +27 -0
- package/dist/vendor/core/context-flow/sync-preview.d.ts +2 -0
- package/dist/vendor/core/context-flow/sync-preview.js +22 -0
- package/dist/vendor/core/context-flow/token-estimator.d.ts +3 -0
- package/dist/vendor/core/context-flow/token-estimator.js +13 -0
- package/dist/vendor/core/context-flow/types.d.ts +91 -0
- package/dist/vendor/core/context-flow/types.js +2 -0
- package/dist/vendor/core/context-integrity.d.ts +26 -0
- package/dist/vendor/core/context-integrity.js +56 -0
- package/dist/vendor/core/context-utility.d.ts +47 -0
- package/dist/vendor/core/context-utility.js +405 -0
- package/dist/vendor/core/cost/pipeline.d.ts +92 -0
- package/dist/vendor/core/cost/pipeline.js +141 -0
- package/dist/vendor/core/cost/tagged-cost.d.ts +27 -0
- package/dist/vendor/core/cost/tagged-cost.js +55 -0
- package/dist/vendor/core/cost-governor.d.ts +2 -0
- package/dist/vendor/core/cost-governor.js +50 -0
- package/dist/vendor/core/cve/cve-check.d.ts +80 -0
- package/dist/vendor/core/cve/cve-check.js +172 -0
- package/dist/vendor/core/digital-twin/index.d.ts +27 -0
- package/dist/vendor/core/digital-twin/index.js +90 -0
- package/dist/vendor/core/drift/drift-graph.d.ts +47 -0
- package/dist/vendor/core/drift/drift-graph.js +100 -0
- package/dist/vendor/core/drift/objective-lock.d.ts +69 -0
- package/dist/vendor/core/drift/objective-lock.js +88 -0
- package/dist/vendor/core/drift/scope.d.ts +46 -0
- package/dist/vendor/core/drift/scope.js +102 -0
- package/dist/vendor/core/drift/signature-lock.d.ts +48 -0
- package/dist/vendor/core/drift/signature-lock.js +202 -0
- package/dist/vendor/core/drift/stale-proof-gate.d.ts +21 -0
- package/dist/vendor/core/drift/stale-proof-gate.js +19 -0
- package/dist/vendor/core/eval/known-bad-world-runner.d.ts +24 -0
- package/dist/vendor/core/eval/known-bad-world-runner.js +256 -0
- package/dist/vendor/core/evidence/claim-audit.d.ts +18 -0
- package/dist/vendor/core/evidence/claim-audit.js +89 -0
- package/dist/vendor/core/exit-intelligence.d.ts +2 -0
- package/dist/vendor/core/exit-intelligence.js +58 -0
- package/dist/vendor/core/explain/formatter.d.ts +42 -0
- package/dist/vendor/core/explain/formatter.js +171 -0
- package/dist/vendor/core/explain/timeline.d.ts +29 -0
- package/dist/vendor/core/explain/timeline.js +213 -0
- package/dist/vendor/core/failure-taxonomy.d.ts +2 -0
- package/dist/vendor/core/failure-taxonomy.js +76 -0
- package/dist/vendor/core/gateway/index.d.ts +10 -0
- package/dist/vendor/core/gateway/index.js +12 -0
- package/dist/vendor/core/gateway/registry.d.ts +40 -0
- package/dist/vendor/core/gateway/registry.js +97 -0
- package/dist/vendor/core/gateway/transport.d.ts +31 -0
- package/dist/vendor/core/gateway/transport.js +82 -0
- package/dist/vendor/core/gateway/vault.d.ts +19 -0
- package/dist/vendor/core/gateway/vault.js +29 -0
- package/dist/vendor/core/graph/adapters.d.ts +43 -0
- package/dist/vendor/core/graph/adapters.js +91 -0
- package/dist/vendor/core/graph/hotspots.d.ts +22 -0
- package/dist/vendor/core/graph/hotspots.js +30 -0
- package/dist/vendor/core/graph/index.d.ts +1 -0
- package/dist/vendor/core/graph/index.js +2 -0
- package/dist/vendor/core/honey/honey-tokens.d.ts +32 -0
- package/dist/vendor/core/honey/honey-tokens.js +44 -0
- package/dist/vendor/core/index.d.ts +7 -4
- package/dist/vendor/core/index.js +222 -64
- package/dist/vendor/core/learning/bayesian-update.d.ts +31 -0
- package/dist/vendor/core/learning/bayesian-update.js +60 -0
- package/dist/vendor/core/learning/prior-sets.d.ts +42 -0
- package/dist/vendor/core/learning/prior-sets.js +111 -0
- package/dist/vendor/core/learning/promotion-gate.d.ts +17 -0
- package/dist/vendor/core/learning/promotion-gate.js +23 -0
- package/dist/vendor/core/leash/blast-radius.d.ts +42 -0
- package/dist/vendor/core/leash/blast-radius.js +156 -0
- package/dist/vendor/core/leash/policy-leash.d.ts +31 -0
- package/dist/vendor/core/leash/policy-leash.js +117 -0
- package/dist/vendor/core/memo/memo.d.ts +63 -0
- package/dist/vendor/core/memo/memo.js +97 -0
- package/dist/vendor/core/memory/learning-pipeline.d.ts +154 -0
- package/dist/vendor/core/memory/learning-pipeline.js +391 -0
- package/dist/vendor/core/memory/palace.d.ts +84 -0
- package/dist/vendor/core/memory/palace.js +379 -0
- package/dist/vendor/core/merge/ast-merge.d.ts +22 -0
- package/dist/vendor/core/merge/ast-merge.js +350 -0
- package/dist/vendor/core/merge/text-merge.d.ts +12 -0
- package/dist/vendor/core/merge/text-merge.js +182 -0
- package/dist/vendor/core/otel/tracer.d.ts +45 -0
- package/dist/vendor/core/otel/tracer.js +116 -0
- package/dist/vendor/core/parallel/parallel-attempts.d.ts +28 -0
- package/dist/vendor/core/parallel/parallel-attempts.js +41 -0
- package/dist/vendor/core/parallel/scorer.d.ts +24 -0
- package/dist/vendor/core/parallel/scorer.js +65 -0
- package/dist/vendor/core/pattern-detection.d.ts +64 -0
- package/dist/vendor/core/pattern-detection.js +108 -0
- package/dist/vendor/core/persistence/checkpoint.d.ts +44 -0
- package/dist/vendor/core/persistence/checkpoint.js +156 -0
- package/dist/vendor/core/persistence/cleanup.d.ts +22 -0
- package/dist/vendor/core/persistence/cleanup.js +131 -0
- package/dist/vendor/core/persistence/index.d.ts +2 -0
- package/dist/vendor/core/persistence/index.js +1 -0
- package/dist/vendor/core/persistence/runs-reader.d.ts +52 -0
- package/dist/vendor/core/persistence/runs-reader.js +84 -0
- package/dist/vendor/core/persistence/store.d.ts +6 -1
- package/dist/vendor/core/persistence/store.js +5 -0
- package/dist/vendor/core/policy/file-touch-quota.d.ts +60 -0
- package/dist/vendor/core/policy/file-touch-quota.js +105 -0
- package/dist/vendor/core/policy/policy-loader.d.ts +30 -0
- package/dist/vendor/core/policy/policy-loader.js +170 -0
- package/dist/vendor/core/policy/policy-schema.d.ts +55 -0
- package/dist/vendor/core/policy/policy-schema.js +78 -0
- package/dist/vendor/core/policy.d.ts +6 -0
- package/dist/vendor/core/probe/probe.d.ts +49 -0
- package/dist/vendor/core/probe/probe.js +115 -0
- package/dist/vendor/core/proof/patch-proof.d.ts +58 -0
- package/dist/vendor/core/proof/patch-proof.js +84 -0
- package/dist/vendor/core/proof/semantic-probe.d.ts +25 -0
- package/dist/vendor/core/proof/semantic-probe.js +82 -0
- package/dist/vendor/core/recovery/failure-mode-runner.d.ts +29 -0
- package/dist/vendor/core/recovery/failure-mode-runner.js +39 -0
- package/dist/vendor/core/red-blue/red-phase.d.ts +64 -0
- package/dist/vendor/core/red-blue/red-phase.js +141 -0
- package/dist/vendor/core/red-blue/risk-tiers.d.ts +22 -0
- package/dist/vendor/core/red-blue/risk-tiers.js +33 -0
- package/dist/vendor/core/replay/replay.d.ts +85 -0
- package/dist/vendor/core/replay/replay.js +109 -0
- package/dist/vendor/core/router/engine.d.ts +54 -0
- package/dist/vendor/core/router/engine.js +131 -0
- package/dist/vendor/core/router/index.d.ts +1 -0
- package/dist/vendor/core/router/index.js +2 -0
- package/dist/vendor/core/router/trust-calibration.d.ts +57 -0
- package/dist/vendor/core/router/trust-calibration.js +127 -0
- package/dist/vendor/core/run-martin.d.ts +2 -0
- package/dist/vendor/core/run-martin.js +287 -0
- package/dist/vendor/core/security/cve-scanner.d.ts +62 -0
- package/dist/vendor/core/security/cve-scanner.js +178 -0
- package/dist/vendor/core/sentinel/efficiency-sentinel.d.ts +29 -0
- package/dist/vendor/core/sentinel/efficiency-sentinel.js +30 -0
- package/dist/vendor/core/sentinel/progress-guard.d.ts +35 -0
- package/dist/vendor/core/sentinel/progress-guard.js +46 -0
- package/dist/vendor/core/siem/siem-emitter.d.ts +49 -0
- package/dist/vendor/core/siem/siem-emitter.js +157 -0
- package/dist/vendor/core/strategy/attempt-brief.d.ts +22 -0
- package/dist/vendor/core/strategy/attempt-brief.js +89 -0
- package/dist/vendor/core/summarize/diff-summary.d.ts +35 -0
- package/dist/vendor/core/summarize/diff-summary.js +204 -0
- package/dist/vendor/core/surface-signals.d.ts +21 -0
- package/dist/vendor/core/surface-signals.js +139 -0
- package/dist/vendor/core/truth/truth-wall.d.ts +51 -0
- package/dist/vendor/core/truth/truth-wall.js +69 -0
- package/dist/vendor/core/truth-spine.d.ts +26 -0
- package/dist/vendor/core/truth-spine.js +62 -0
- package/dist/vendor/core/types.d.ts +115 -0
- package/dist/vendor/core/types.js +2 -0
- package/dist/vendor/core/verification/tiered-verify.d.ts +17 -0
- package/dist/vendor/core/verification/tiered-verify.js +29 -0
- package/dist/vendor/core/verifier-pyramid.d.ts +32 -0
- package/dist/vendor/core/verifier-pyramid.js +111 -0
- package/dist/vendor/core/workflow-artifacts.d.ts +99 -0
- package/dist/vendor/core/workflow-artifacts.js +668 -0
- package/dist/vendor/core/wrap/supervised-run.d.ts +96 -0
- package/dist/vendor/core/wrap/supervised-run.js +178 -0
- package/docs/assets/cli-animated.svg +139 -0
- package/docs/assets/cli-static.svg +34 -0
- package/docs/assets/github-hero-v2.svg +23 -0
- package/docs/assets/martin-raplph.png.jpg +0 -0
- package/docs/assets/martinloop-logo.png +0 -0
- package/docs/assets/nvidia-inception-program-light.png +0 -0
- package/docs/assets/nvidia-inception-program.png +0 -0
- package/docs/assets/phase3c-sidesidebyside-demo.html +228 -0
- package/docs/assets/side-by-side.svg +134 -0
- package/docs/oss/CLAUDE-CODE-WALKTHROUGH.md +142 -0
- package/docs/oss/EXAMPLES.md +9 -1
- package/docs/oss/OSS-BOUNDARY-REPORT.json +109 -113
- package/docs/oss/OSS-BOUNDARY-REPORT.md +48 -48
- package/docs/oss/QUICKSTART.md +39 -4
- package/docs/oss/RALPH-LOOP-SAFETY.md +113 -0
- package/docs/oss/README.md +7 -4
- package/docs/oss/RELEASE-SURFACE-REPORT.json +46 -45
- package/docs/oss/RELEASE-SURFACE-REPORT.md +36 -35
- package/package.json +129 -49
|
@@ -5,12 +5,15 @@ import { evaluateChangeApprovalLeash, evaluateFilesystemLeash, evaluateSecretLea
|
|
|
5
5
|
import { buildRepoGroundingIndex, loadOrBuildRepoGroundingIndex, queryRepoGroundingIndex, scanPatchForGroundingViolations } from "./grounding.js";
|
|
6
6
|
import { captureRollbackBoundary, restoreRollbackBoundary } from "./rollback.js";
|
|
7
7
|
import { compilePromptPacket } from "./compiler.js";
|
|
8
|
-
import { makeLedgerEvent } from "./persistence/index.js";
|
|
8
|
+
import { makeLedgerEvent, resolveRunsRoot, runDir } from "./persistence/index.js";
|
|
9
|
+
import { runContextIntegrityPrecheck } from "./context-integrity.js";
|
|
9
10
|
export { classifyFailure, computeEvidenceVector, evaluatePatchDecision, evaluateCostGovernor, evaluateBudgetPreflight, inferExit, nextPolicyPhase, policyPhaseToLifecycleState, scorePatchDecision, selectRecoveryRecipe, evaluateVerificationLeash, evaluateFilesystemLeash, evaluateChangeApprovalLeash, evaluateSecretLeash, resolveExecutionProfile, redactSecretsFromText, buildRepoGroundingIndex, loadOrBuildRepoGroundingIndex, queryRepoGroundingIndex, scanPatchForGroundingViolations, captureRollbackBoundary, restoreRollbackBoundary };
|
|
11
|
+
// ─── Context Integrity Pre-gate ──────────────────────────────────────────────
|
|
12
|
+
export { runContextIntegrityPrecheck } from "./context-integrity.js";
|
|
10
13
|
// ─── Prompt packet compiler ──────────────────────────────────────────────────
|
|
11
14
|
export { compilePromptPacket } from "./compiler.js";
|
|
12
15
|
// ─── Persistence (RunStore, LedgerEvent, FileRunStore) ──────────────────────
|
|
13
|
-
export { createFileRunStore, makeLedgerEvent, resolveRunsRoot } from "./persistence/index.js";
|
|
16
|
+
export { createFileRunStore, makeLedgerEvent, readAllLoopRecords, readLatestLoopRecord, readLatestLoopRecordFromFile, readLoopRecordsFromFile, resolveRunsRoot } from "./persistence/index.js";
|
|
14
17
|
export { compileAndPersistContext } from "./persistence/index.js";
|
|
15
18
|
/**
|
|
16
19
|
* Admission gate — must pass before any attempt is executed.
|
|
@@ -126,6 +129,7 @@ export async function runMartin(input) {
|
|
|
126
129
|
runId: loop.loopId,
|
|
127
130
|
payload: { workspaceId: input.workspaceId, projectId: input.projectId }
|
|
128
131
|
}));
|
|
132
|
+
await persistLoopRecordIfSupported(input.store, loop);
|
|
129
133
|
}
|
|
130
134
|
const DEFAULT_FALLBACK_MODELS = [
|
|
131
135
|
"claude-haiku-4-5",
|
|
@@ -136,6 +140,7 @@ export async function runMartin(input) {
|
|
|
136
140
|
let currentAdapterIndex = 0;
|
|
137
141
|
let currentAdapter = adapterChain[currentAdapterIndex] ?? input.adapter;
|
|
138
142
|
let useCompressedContext = false;
|
|
143
|
+
const isVerifyOnly = input.task.mutationMode === "verify_only";
|
|
139
144
|
const executionProfile = resolveExecutionProfile({
|
|
140
145
|
executionProfile: input.task.executionProfile,
|
|
141
146
|
allowedNetworkDomains: input.task.allowedNetworkDomains
|
|
@@ -153,7 +158,8 @@ export async function runMartin(input) {
|
|
|
153
158
|
shouldExit: true,
|
|
154
159
|
lifecycleState: "human_escalation",
|
|
155
160
|
status: "exited",
|
|
156
|
-
reason
|
|
161
|
+
reason,
|
|
162
|
+
...classifySafetyLeashExit(leashDecision, "verifier")
|
|
157
163
|
};
|
|
158
164
|
if (input.store) {
|
|
159
165
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
@@ -169,15 +175,13 @@ export async function runMartin(input) {
|
|
|
169
175
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
170
176
|
kind: "run.exited",
|
|
171
177
|
runId: loop.loopId,
|
|
172
|
-
payload:
|
|
173
|
-
lifecycleState: leashExitDecision.lifecycleState,
|
|
174
|
-
status: leashExitDecision.status,
|
|
175
|
-
reason: leashExitDecision.reason
|
|
176
|
-
}
|
|
178
|
+
payload: createRunExitPayload(leashExitDecision)
|
|
177
179
|
}));
|
|
178
180
|
}
|
|
181
|
+
const finalizedLoop = finalizeLoop(loop, leashExitDecision, now(), idFactory);
|
|
182
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
179
183
|
return {
|
|
180
|
-
loop:
|
|
184
|
+
loop: finalizedLoop,
|
|
181
185
|
decision: leashExitDecision
|
|
182
186
|
};
|
|
183
187
|
}
|
|
@@ -193,7 +197,8 @@ export async function runMartin(input) {
|
|
|
193
197
|
shouldExit: true,
|
|
194
198
|
lifecycleState: "human_escalation",
|
|
195
199
|
status: "exited",
|
|
196
|
-
reason: secretDecision.reason ?? "Safety leash blocked secret-like values in the runtime context."
|
|
200
|
+
reason: secretDecision.reason ?? "Safety leash blocked secret-like values in the runtime context.",
|
|
201
|
+
...classifySafetyLeashExit(secretDecision, "secret")
|
|
197
202
|
};
|
|
198
203
|
if (input.store) {
|
|
199
204
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
@@ -208,15 +213,13 @@ export async function runMartin(input) {
|
|
|
208
213
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
209
214
|
kind: "run.exited",
|
|
210
215
|
runId: loop.loopId,
|
|
211
|
-
payload:
|
|
212
|
-
lifecycleState: secretExitDecision.lifecycleState,
|
|
213
|
-
status: secretExitDecision.status,
|
|
214
|
-
reason: secretExitDecision.reason
|
|
215
|
-
}
|
|
216
|
+
payload: createRunExitPayload(secretExitDecision)
|
|
216
217
|
}));
|
|
217
218
|
}
|
|
219
|
+
const finalizedLoop = finalizeLoop(loop, secretExitDecision, now(), idFactory);
|
|
220
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
218
221
|
return {
|
|
219
|
-
loop:
|
|
222
|
+
loop: finalizedLoop,
|
|
220
223
|
decision: secretExitDecision
|
|
221
224
|
};
|
|
222
225
|
}
|
|
@@ -254,20 +257,52 @@ export async function runMartin(input) {
|
|
|
254
257
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
255
258
|
kind: "run.exited",
|
|
256
259
|
runId: loop.loopId,
|
|
257
|
-
payload:
|
|
258
|
-
lifecycleState: preflightExitDecision.lifecycleState,
|
|
259
|
-
status: preflightExitDecision.status,
|
|
260
|
-
reason: preflightExitDecision.reason
|
|
261
|
-
}
|
|
260
|
+
payload: createRunExitPayload(preflightExitDecision)
|
|
262
261
|
}));
|
|
263
262
|
}
|
|
263
|
+
const finalizedLoop = finalizeLoop(loop, preflightExitDecision, now(), idFactory);
|
|
264
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
264
265
|
return {
|
|
265
|
-
loop:
|
|
266
|
+
loop: finalizedLoop,
|
|
266
267
|
decision: preflightExitDecision
|
|
267
268
|
};
|
|
268
269
|
}
|
|
269
270
|
// GATHER → ADMIT: run admission control before executing
|
|
270
271
|
currentPhase = "ADMIT";
|
|
272
|
+
// T05: Context Integrity Pre-gate — blocks authority inversion / injection before reasoning
|
|
273
|
+
const contextPrecheck = await runContextIntegrityPrecheck(loop.loopId, loop.attempts.length + 1, runDir(resolveRunsRoot(), loop.loopId), {
|
|
274
|
+
userPrompt: distilled.focus,
|
|
275
|
+
history: loop.attempts.map(a => a.summary).join("\n")
|
|
276
|
+
});
|
|
277
|
+
if (contextPrecheck.verdict === "context_poisoning_block") {
|
|
278
|
+
currentPhase = "ABORT";
|
|
279
|
+
const poisoningExitDecision = {
|
|
280
|
+
shouldExit: true,
|
|
281
|
+
lifecycleState: "human_escalation",
|
|
282
|
+
status: "exited",
|
|
283
|
+
reason: "Context Integrity Pre-gate: context poisoning attempt detected.",
|
|
284
|
+
failureClass: "safety_leash_blocked",
|
|
285
|
+
safetySurface: "context_integrity",
|
|
286
|
+
reasonCode: "context_poisoning_blocked"
|
|
287
|
+
};
|
|
288
|
+
if (input.store) {
|
|
289
|
+
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
290
|
+
kind: "safety.violations_found",
|
|
291
|
+
runId: loop.loopId,
|
|
292
|
+
payload: {
|
|
293
|
+
verdict: contextPrecheck.verdict,
|
|
294
|
+
signals: contextPrecheck.detectedSignals,
|
|
295
|
+
source: "context_integrity_pregate"
|
|
296
|
+
}
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
const finalizedLoop = finalizeLoop(loop, poisoningExitDecision, now(), idFactory);
|
|
300
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
301
|
+
return {
|
|
302
|
+
loop: finalizedLoop,
|
|
303
|
+
decision: poisoningExitDecision
|
|
304
|
+
};
|
|
305
|
+
}
|
|
271
306
|
const admissionDecision = evaluateAttemptPolicy({
|
|
272
307
|
request: {
|
|
273
308
|
loopId: loop.loopId,
|
|
@@ -315,15 +350,13 @@ export async function runMartin(input) {
|
|
|
315
350
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
316
351
|
kind: "run.exited",
|
|
317
352
|
runId: loop.loopId,
|
|
318
|
-
payload:
|
|
319
|
-
lifecycleState: exitDecision.lifecycleState,
|
|
320
|
-
status: exitDecision.status,
|
|
321
|
-
reason: exitDecision.reason
|
|
322
|
-
}
|
|
353
|
+
payload: createRunExitPayload(exitDecision)
|
|
323
354
|
}));
|
|
324
355
|
}
|
|
356
|
+
const finalizedLoop = finalizeLoop(loop, exitDecision, now(), idFactory);
|
|
357
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
325
358
|
return {
|
|
326
|
-
loop:
|
|
359
|
+
loop: finalizedLoop,
|
|
327
360
|
decision: exitDecision
|
|
328
361
|
};
|
|
329
362
|
}
|
|
@@ -361,6 +394,7 @@ export async function runMartin(input) {
|
|
|
361
394
|
objective: loop.task.objective,
|
|
362
395
|
verificationPlan: loop.task.verificationPlan,
|
|
363
396
|
...(loop.task.verificationStack ? { verificationStack: loop.task.verificationStack } : {}),
|
|
397
|
+
...(loop.task.mutationMode ? { mutationMode: loop.task.mutationMode } : {}),
|
|
364
398
|
...(loop.task.repoRoot ? { repoRoot: loop.task.repoRoot } : {}),
|
|
365
399
|
...(loop.task.allowedPaths ? { allowedPaths: loop.task.allowedPaths } : {}),
|
|
366
400
|
...(loop.task.deniedPaths ? { deniedPaths: loop.task.deniedPaths } : {}),
|
|
@@ -539,6 +573,92 @@ export async function runMartin(input) {
|
|
|
539
573
|
// returned a non-empty list. A repoRoot alone is insufficient — git may fail (e.g. not
|
|
540
574
|
// a git repo) and silently return [], which would falsely trigger no_code_change.
|
|
541
575
|
const changedFileEvidenceAvailable = result.execution?.changedFiles !== undefined || changedFiles.length > 0;
|
|
576
|
+
if (isVerifyOnly && changedFiles.length > 0) {
|
|
577
|
+
const patchDecision = evaluatePatchDecision({
|
|
578
|
+
verificationPassed: result.verification.passed,
|
|
579
|
+
previousVerifierScore,
|
|
580
|
+
verifierScore: result.verification.passed ? 1 : 0,
|
|
581
|
+
scopeViolationCount: changedFiles.length,
|
|
582
|
+
changedFileCount: changedFiles.length,
|
|
583
|
+
diffNovelty: 1,
|
|
584
|
+
diffStats: result.execution?.diffStats,
|
|
585
|
+
costUsd: getUsageUsd(result.usage),
|
|
586
|
+
summary: result.summary
|
|
587
|
+
});
|
|
588
|
+
const verifyOnlyExitDecision = {
|
|
589
|
+
shouldExit: true,
|
|
590
|
+
lifecycleState: "human_escalation",
|
|
591
|
+
status: "exited",
|
|
592
|
+
reason: "Verify-only mode forbids file changes.",
|
|
593
|
+
failureClass: "safety_leash_blocked",
|
|
594
|
+
safetySurface: "filesystem",
|
|
595
|
+
reasonCode: "verify_only_write_attempt"
|
|
596
|
+
};
|
|
597
|
+
const rollbackOutcome = await restoreRollbackBoundary({
|
|
598
|
+
repoRoot: request.context.repoRoot,
|
|
599
|
+
boundary: rollbackBoundary,
|
|
600
|
+
restoredAt: attemptCompletedAt,
|
|
601
|
+
decision: patchDecision.decision
|
|
602
|
+
});
|
|
603
|
+
if (input.store) {
|
|
604
|
+
const verifyOnlyViolation = {
|
|
605
|
+
kind: "path_not_allowed",
|
|
606
|
+
message: `Verify-only mode forbids changed files: ${changedFiles.join(", ")}`,
|
|
607
|
+
file: changedFiles[0]
|
|
608
|
+
};
|
|
609
|
+
await input.store.writeAttemptArtifacts(loop.loopId, currentAttemptIndex, {
|
|
610
|
+
compiledContext,
|
|
611
|
+
leash: createLeashArtifact({
|
|
612
|
+
surface: "filesystem",
|
|
613
|
+
reason: verifyOnlyExitDecision.reason,
|
|
614
|
+
violations: [verifyOnlyViolation]
|
|
615
|
+
}, currentAttemptIndex),
|
|
616
|
+
patchScore: patchDecision.score,
|
|
617
|
+
patchDecision: toPatchDecisionArtifact(patchDecision),
|
|
618
|
+
...(rollbackBoundary ? { rollbackBoundary } : {}),
|
|
619
|
+
...(rollbackOutcome ? { rollbackOutcome } : {})
|
|
620
|
+
});
|
|
621
|
+
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
622
|
+
kind: "safety.violations_found",
|
|
623
|
+
runId: loop.loopId,
|
|
624
|
+
attemptIndex: currentAttemptIndex,
|
|
625
|
+
payload: {
|
|
626
|
+
surface: "filesystem",
|
|
627
|
+
blocked: true,
|
|
628
|
+
attemptIndex: currentAttemptIndex,
|
|
629
|
+
violations: [
|
|
630
|
+
{
|
|
631
|
+
kind: "path_not_allowed",
|
|
632
|
+
message: verifyOnlyExitDecision.reason,
|
|
633
|
+
files: changedFiles
|
|
634
|
+
}
|
|
635
|
+
]
|
|
636
|
+
}
|
|
637
|
+
}));
|
|
638
|
+
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
639
|
+
kind: "attempt.discarded",
|
|
640
|
+
runId: loop.loopId,
|
|
641
|
+
attemptIndex: currentAttemptIndex,
|
|
642
|
+
payload: {
|
|
643
|
+
decision: patchDecision.decision,
|
|
644
|
+
reason: patchDecision.summary,
|
|
645
|
+
reasonCodes: patchDecision.reasonCodes,
|
|
646
|
+
score: patchDecision.score.score
|
|
647
|
+
}
|
|
648
|
+
}));
|
|
649
|
+
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
650
|
+
kind: "run.exited",
|
|
651
|
+
runId: loop.loopId,
|
|
652
|
+
payload: createRunExitPayload(verifyOnlyExitDecision)
|
|
653
|
+
}));
|
|
654
|
+
}
|
|
655
|
+
const finalizedLoop = finalizeLoop(loop, verifyOnlyExitDecision, now(), idFactory);
|
|
656
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
657
|
+
return {
|
|
658
|
+
loop: finalizedLoop,
|
|
659
|
+
decision: verifyOnlyExitDecision
|
|
660
|
+
};
|
|
661
|
+
}
|
|
542
662
|
const filesystemDecision = evaluateFilesystemLeash({
|
|
543
663
|
repoRoot: request.context.repoRoot,
|
|
544
664
|
changedFiles,
|
|
@@ -561,7 +681,8 @@ export async function runMartin(input) {
|
|
|
561
681
|
shouldExit: true,
|
|
562
682
|
lifecycleState: "human_escalation",
|
|
563
683
|
status: "exited",
|
|
564
|
-
reason: filesystemDecision.reason ?? "Safety leash blocked filesystem changes."
|
|
684
|
+
reason: filesystemDecision.reason ?? "Safety leash blocked filesystem changes.",
|
|
685
|
+
...classifySafetyLeashExit(filesystemDecision, "filesystem")
|
|
565
686
|
};
|
|
566
687
|
const rollbackOutcome = await restoreRollbackBoundary({
|
|
567
688
|
repoRoot: request.context.repoRoot,
|
|
@@ -603,15 +724,13 @@ export async function runMartin(input) {
|
|
|
603
724
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
604
725
|
kind: "run.exited",
|
|
605
726
|
runId: loop.loopId,
|
|
606
|
-
payload:
|
|
607
|
-
lifecycleState: filesystemExitDecision.lifecycleState,
|
|
608
|
-
status: filesystemExitDecision.status,
|
|
609
|
-
reason: filesystemExitDecision.reason
|
|
610
|
-
}
|
|
727
|
+
payload: createRunExitPayload(filesystemExitDecision)
|
|
611
728
|
}));
|
|
612
729
|
}
|
|
730
|
+
const finalizedLoop = finalizeLoop(loop, filesystemExitDecision, now(), idFactory);
|
|
731
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
613
732
|
return {
|
|
614
|
-
loop:
|
|
733
|
+
loop: finalizedLoop,
|
|
615
734
|
decision: filesystemExitDecision
|
|
616
735
|
};
|
|
617
736
|
}
|
|
@@ -638,7 +757,8 @@ export async function runMartin(input) {
|
|
|
638
757
|
lifecycleState: "human_escalation",
|
|
639
758
|
status: "exited",
|
|
640
759
|
reason: changeApprovalDecision.reason ??
|
|
641
|
-
"Safety leash blocked dependency or migration changes that require approval."
|
|
760
|
+
"Safety leash blocked dependency or migration changes that require approval.",
|
|
761
|
+
...classifySafetyLeashExit(changeApprovalDecision, "dependency")
|
|
642
762
|
};
|
|
643
763
|
const rollbackOutcome = await restoreRollbackBoundary({
|
|
644
764
|
repoRoot: request.context.repoRoot,
|
|
@@ -681,15 +801,13 @@ export async function runMartin(input) {
|
|
|
681
801
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
682
802
|
kind: "run.exited",
|
|
683
803
|
runId: loop.loopId,
|
|
684
|
-
payload:
|
|
685
|
-
lifecycleState: approvalExitDecision.lifecycleState,
|
|
686
|
-
status: approvalExitDecision.status,
|
|
687
|
-
reason: approvalExitDecision.reason
|
|
688
|
-
}
|
|
804
|
+
payload: createRunExitPayload(approvalExitDecision)
|
|
689
805
|
}));
|
|
690
806
|
}
|
|
807
|
+
const finalizedLoop = finalizeLoop(loop, approvalExitDecision, now(), idFactory);
|
|
808
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
691
809
|
return {
|
|
692
|
-
loop:
|
|
810
|
+
loop: finalizedLoop,
|
|
693
811
|
decision: approvalExitDecision
|
|
694
812
|
};
|
|
695
813
|
}
|
|
@@ -728,8 +846,8 @@ export async function runMartin(input) {
|
|
|
728
846
|
previousVerifierScore,
|
|
729
847
|
verifierScore: result.verification.passed ? 1 : 0,
|
|
730
848
|
groundingViolationCount: groundingScanResult?.violations.length ?? 0,
|
|
731
|
-
changedFileCount: changedFileEvidenceAvailable ? changedFiles.length : undefined,
|
|
732
|
-
diffNovelty: changedFileEvidenceAvailable ? (changedFiles.length > 0 ? 1 : 0) : undefined,
|
|
849
|
+
changedFileCount: !isVerifyOnly && changedFileEvidenceAvailable ? changedFiles.length : undefined,
|
|
850
|
+
diffNovelty: !isVerifyOnly && changedFileEvidenceAvailable ? (changedFiles.length > 0 ? 1 : 0) : undefined,
|
|
733
851
|
diffStats: result.execution?.diffStats,
|
|
734
852
|
costUsd: getUsageUsd(result.usage),
|
|
735
853
|
summary: result.summary
|
|
@@ -822,15 +940,13 @@ export async function runMartin(input) {
|
|
|
822
940
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
823
941
|
kind: "run.exited",
|
|
824
942
|
runId: loop.loopId,
|
|
825
|
-
payload:
|
|
826
|
-
lifecycleState: patchExitDecision.lifecycleState,
|
|
827
|
-
status: patchExitDecision.status,
|
|
828
|
-
reason: patchExitDecision.reason
|
|
829
|
-
}
|
|
943
|
+
payload: createRunExitPayload(patchExitDecision)
|
|
830
944
|
}));
|
|
831
945
|
}
|
|
946
|
+
const finalizedLoop = finalizeLoop(loop, patchExitDecision, now(), idFactory);
|
|
947
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
832
948
|
return {
|
|
833
|
-
loop:
|
|
949
|
+
loop: finalizedLoop,
|
|
834
950
|
decision: patchExitDecision
|
|
835
951
|
};
|
|
836
952
|
}
|
|
@@ -870,15 +986,13 @@ export async function runMartin(input) {
|
|
|
870
986
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
871
987
|
kind: "run.exited",
|
|
872
988
|
runId: loop.loopId,
|
|
873
|
-
payload:
|
|
874
|
-
lifecycleState: decision.lifecycleState,
|
|
875
|
-
status: decision.status,
|
|
876
|
-
reason: decision.reason
|
|
877
|
-
}
|
|
989
|
+
payload: createRunExitPayload(decision)
|
|
878
990
|
}));
|
|
879
991
|
}
|
|
992
|
+
const finalizedLoop = finalizeLoop(loop, decision, now(), idFactory);
|
|
993
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
880
994
|
return {
|
|
881
|
-
loop:
|
|
995
|
+
loop: finalizedLoop,
|
|
882
996
|
decision
|
|
883
997
|
};
|
|
884
998
|
}
|
|
@@ -893,23 +1007,64 @@ export async function runMartin(input) {
|
|
|
893
1007
|
await input.store.appendLedger(loop.loopId, makeLedgerEvent({
|
|
894
1008
|
kind: "run.exited",
|
|
895
1009
|
runId: loop.loopId,
|
|
896
|
-
payload:
|
|
897
|
-
lifecycleState: decision.lifecycleState,
|
|
898
|
-
status: decision.status,
|
|
899
|
-
reason: decision.reason
|
|
900
|
-
}
|
|
1010
|
+
payload: createRunExitPayload(decision)
|
|
901
1011
|
}));
|
|
902
1012
|
}
|
|
1013
|
+
const finalizedLoop = finalizeLoop(loop, decision, now(), idFactory);
|
|
1014
|
+
await persistLoopRecordIfSupported(input.store, finalizedLoop);
|
|
903
1015
|
return {
|
|
904
|
-
loop:
|
|
1016
|
+
loop: finalizedLoop,
|
|
905
1017
|
decision
|
|
906
1018
|
};
|
|
907
1019
|
}
|
|
1020
|
+
function createRunExitPayload(decision) {
|
|
1021
|
+
return {
|
|
1022
|
+
lifecycleState: decision.lifecycleState,
|
|
1023
|
+
status: decision.status,
|
|
1024
|
+
reason: decision.reason,
|
|
1025
|
+
...(decision.failureClass ? { failureClass: decision.failureClass } : {}),
|
|
1026
|
+
...(decision.safetySurface ? { safetySurface: decision.safetySurface } : {}),
|
|
1027
|
+
...(decision.reasonCode ? { reasonCode: decision.reasonCode } : {})
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
function classifySafetyLeashExit(decision, safetySurface = decision.surface) {
|
|
1031
|
+
return {
|
|
1032
|
+
failureClass: "safety_leash_blocked",
|
|
1033
|
+
safetySurface,
|
|
1034
|
+
reasonCode: safetyLeashReasonCode(decision, safetySurface)
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
function safetyLeashReasonCode(decision, safetySurface) {
|
|
1038
|
+
const kind = decision.violations[0]?.kind;
|
|
1039
|
+
switch (kind) {
|
|
1040
|
+
case "command_blocked":
|
|
1041
|
+
return safetySurface === "verifier" ? "destructive_verifier_command" : "command_blocked";
|
|
1042
|
+
case "network_blocked":
|
|
1043
|
+
return safetySurface === "verifier" ? "verifier_network_blocked" : "network_access_blocked";
|
|
1044
|
+
case "secret_value":
|
|
1045
|
+
return "secret_context_value";
|
|
1046
|
+
case "path_denied":
|
|
1047
|
+
case "protected_path":
|
|
1048
|
+
return "protected_surface_write";
|
|
1049
|
+
case "path_not_allowed":
|
|
1050
|
+
return "surface_write_not_allowed";
|
|
1051
|
+
case "path_outside_repo":
|
|
1052
|
+
return "outside_repo_write";
|
|
1053
|
+
case "dependency_approval_required":
|
|
1054
|
+
return "dependency_approval_required";
|
|
1055
|
+
case "migration_approval_required":
|
|
1056
|
+
return "migration_approval_required";
|
|
1057
|
+
case "config_change_approval_required":
|
|
1058
|
+
return "config_change_approval_required";
|
|
1059
|
+
default:
|
|
1060
|
+
return `${safetySurface}_safety_block`;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
908
1063
|
function finalizeLoop(loop, decision, timestamp, idFactory) {
|
|
909
1064
|
const finalized = appendLoopEvent(loop, {
|
|
910
1065
|
type: "run.completed",
|
|
911
1066
|
lifecycleState: decision.lifecycleState,
|
|
912
|
-
payload:
|
|
1067
|
+
payload: createRunExitPayload(decision)
|
|
913
1068
|
}, { now: timestamp, idFactory });
|
|
914
1069
|
return {
|
|
915
1070
|
...finalized,
|
|
@@ -918,6 +1073,9 @@ function finalizeLoop(loop, decision, timestamp, idFactory) {
|
|
|
918
1073
|
updatedAt: timestamp
|
|
919
1074
|
};
|
|
920
1075
|
}
|
|
1076
|
+
async function persistLoopRecordIfSupported(store, loop) {
|
|
1077
|
+
await store?.writeLoopRecord?.(loop.loopId, loop);
|
|
1078
|
+
}
|
|
921
1079
|
function getAdapterTransport(adapter) {
|
|
922
1080
|
return adapter.metadata.transport ?? (adapter.kind === "agent-cli" ? "cli" : "http");
|
|
923
1081
|
}
|
|
@@ -934,7 +1092,7 @@ function getUsageProvenance(usage) {
|
|
|
934
1092
|
return "actual";
|
|
935
1093
|
}
|
|
936
1094
|
function resolveChangedFiles(result, repoRoot) {
|
|
937
|
-
if (result.execution?.changedFiles
|
|
1095
|
+
if (result.execution?.changedFiles !== undefined) {
|
|
938
1096
|
return result.execution.changedFiles;
|
|
939
1097
|
}
|
|
940
1098
|
if (!repoRoot) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies a single-step Bayesian update to a prior probability.
|
|
3
|
+
*
|
|
4
|
+
* Formula: posterior = (prior * likelihood) / normalizing_constant
|
|
5
|
+
*
|
|
6
|
+
* The normalizing constant ensures the result stays in [0, 1]:
|
|
7
|
+
* Z = prior * likelihood + (1 - prior) * (1 - likelihood)
|
|
8
|
+
*
|
|
9
|
+
* This is the standard Beta-Bernoulli update for binary outcomes.
|
|
10
|
+
* - likelihood > 0.5 → positive evidence → posterior increases
|
|
11
|
+
* - likelihood < 0.5 → negative evidence → posterior decreases
|
|
12
|
+
* - likelihood = 0.5 → no information → posterior unchanged
|
|
13
|
+
*
|
|
14
|
+
* @param prior Current prior probability (0.0 – 1.0)
|
|
15
|
+
* @param likelihood Likelihood of observation given the hypothesis (0.0 – 1.0)
|
|
16
|
+
* @returns Updated posterior probability (0.0 – 1.0)
|
|
17
|
+
*/
|
|
18
|
+
export declare function updatePriorBayesian(prior: number, likelihood: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Applies a Bayesian update to a PriorSet's individual symbol priors
|
|
21
|
+
* using confidence deltas from the hypothesis ledger.
|
|
22
|
+
*
|
|
23
|
+
* confidenceDelta > 0 → validated evidence → likelihood = 0.5 + delta/2
|
|
24
|
+
* confidenceDelta < 0 → invalidated evidence → likelihood = 0.5 + delta/2
|
|
25
|
+
*
|
|
26
|
+
* @param priors Symbol → prior probability map
|
|
27
|
+
* @param symbol The specific symbol to update
|
|
28
|
+
* @param confidenceDelta From hypothesis ledger (−1.0 to +1.0)
|
|
29
|
+
* @returns New priors map with updated value for symbol
|
|
30
|
+
*/
|
|
31
|
+
export declare function updateSymbolPrior(priors: Record<string, number>, symbol: string, confidenceDelta: number): Record<string, number>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// ─── Bayesian Update ─────────────────────────────────────────────────────────
|
|
2
|
+
/**
|
|
3
|
+
* Applies a single-step Bayesian update to a prior probability.
|
|
4
|
+
*
|
|
5
|
+
* Formula: posterior = (prior * likelihood) / normalizing_constant
|
|
6
|
+
*
|
|
7
|
+
* The normalizing constant ensures the result stays in [0, 1]:
|
|
8
|
+
* Z = prior * likelihood + (1 - prior) * (1 - likelihood)
|
|
9
|
+
*
|
|
10
|
+
* This is the standard Beta-Bernoulli update for binary outcomes.
|
|
11
|
+
* - likelihood > 0.5 → positive evidence → posterior increases
|
|
12
|
+
* - likelihood < 0.5 → negative evidence → posterior decreases
|
|
13
|
+
* - likelihood = 0.5 → no information → posterior unchanged
|
|
14
|
+
*
|
|
15
|
+
* @param prior Current prior probability (0.0 – 1.0)
|
|
16
|
+
* @param likelihood Likelihood of observation given the hypothesis (0.0 – 1.0)
|
|
17
|
+
* @returns Updated posterior probability (0.0 – 1.0)
|
|
18
|
+
*/
|
|
19
|
+
export function updatePriorBayesian(prior, likelihood) {
|
|
20
|
+
if (prior < 0 || prior > 1)
|
|
21
|
+
throw new Error(`prior must be in [0, 1], got ${prior}`);
|
|
22
|
+
if (likelihood < 0 || likelihood > 1)
|
|
23
|
+
throw new Error(`likelihood must be in [0, 1], got ${likelihood}`);
|
|
24
|
+
// P(H|E) = P(E|H) * P(H) / P(E)
|
|
25
|
+
// P(E) = P(E|H)*P(H) + P(E|¬H)*P(¬H)
|
|
26
|
+
const pEgivenH = likelihood;
|
|
27
|
+
const pEgivenNotH = 1 - likelihood;
|
|
28
|
+
const pH = prior;
|
|
29
|
+
const pNotH = 1 - prior;
|
|
30
|
+
const pE = pEgivenH * pH + pEgivenNotH * pNotH;
|
|
31
|
+
// Avoid division by zero (shouldn't happen with valid inputs)
|
|
32
|
+
if (pE === 0)
|
|
33
|
+
return prior;
|
|
34
|
+
return (pEgivenH * pH) / pE;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Applies a Bayesian update to a PriorSet's individual symbol priors
|
|
38
|
+
* using confidence deltas from the hypothesis ledger.
|
|
39
|
+
*
|
|
40
|
+
* confidenceDelta > 0 → validated evidence → likelihood = 0.5 + delta/2
|
|
41
|
+
* confidenceDelta < 0 → invalidated evidence → likelihood = 0.5 + delta/2
|
|
42
|
+
*
|
|
43
|
+
* @param priors Symbol → prior probability map
|
|
44
|
+
* @param symbol The specific symbol to update
|
|
45
|
+
* @param confidenceDelta From hypothesis ledger (−1.0 to +1.0)
|
|
46
|
+
* @returns New priors map with updated value for symbol
|
|
47
|
+
*/
|
|
48
|
+
export function updateSymbolPrior(priors, symbol, confidenceDelta) {
|
|
49
|
+
const currentPrior = priors[symbol] ?? 0.5;
|
|
50
|
+
// Map confidenceDelta (−1..+1) to likelihood (0..1)
|
|
51
|
+
// delta=+1.0 → likelihood=1.0 (strong positive evidence)
|
|
52
|
+
// delta=0.0 → likelihood=0.5 (no information)
|
|
53
|
+
// delta=−1.0 → likelihood=0.0 (strong negative evidence)
|
|
54
|
+
const likelihood = Math.max(0, Math.min(1, 0.5 + confidenceDelta / 2));
|
|
55
|
+
return {
|
|
56
|
+
...priors,
|
|
57
|
+
[symbol]: updatePriorBayesian(currentPrior, likelihood)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=bayesian-update.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type PromotionGate = "development" | "backtest" | "shadow" | "live";
|
|
2
|
+
export interface PriorSet {
|
|
3
|
+
priorSetId: string;
|
|
4
|
+
taskClass: string;
|
|
5
|
+
version: number;
|
|
6
|
+
confidence: number;
|
|
7
|
+
priors: Record<string, number>;
|
|
8
|
+
lastUpdatedAt: string;
|
|
9
|
+
promotionGate: PromotionGate;
|
|
10
|
+
sampleCount: number;
|
|
11
|
+
}
|
|
12
|
+
export interface PriorStore {
|
|
13
|
+
priorSets: PriorSet[];
|
|
14
|
+
}
|
|
15
|
+
export interface CreatePriorSetInput {
|
|
16
|
+
priorSetId: string;
|
|
17
|
+
taskClass: string;
|
|
18
|
+
priors: Record<string, number>;
|
|
19
|
+
}
|
|
20
|
+
export declare function createPriorSet(input: CreatePriorSetInput): PriorSet;
|
|
21
|
+
export declare function loadPriorStore(storeDir: string): Promise<PriorStore>;
|
|
22
|
+
export declare function savePriorStore(store: PriorStore, storeDir: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Promotes a PriorSet to the next gate in the sequence.
|
|
25
|
+
* Gates must advance sequentially: development → backtest → shadow → live.
|
|
26
|
+
* Throws if the target gate is not the immediate next gate.
|
|
27
|
+
*/
|
|
28
|
+
export declare function promotePriorSet(priorSetId: string, targetGate: PromotionGate, storeDir: string): Promise<PriorSet>;
|
|
29
|
+
/**
|
|
30
|
+
* Rolls back a PriorSet to the previous gate.
|
|
31
|
+
* Rollback is always available from any gate above development.
|
|
32
|
+
* Throws if already at development.
|
|
33
|
+
*/
|
|
34
|
+
export declare function rollbackPriorSet(priorSetId: string, storeDir: string): Promise<PriorSet>;
|
|
35
|
+
/**
|
|
36
|
+
* Returns all PriorSets from the store.
|
|
37
|
+
*/
|
|
38
|
+
export declare function listPriorSets(storeDir: string): Promise<PriorSet[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Returns a single PriorSet by ID, or null if not found.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getPriorSet(priorSetId: string, storeDir: string): Promise<PriorSet | null>;
|