martin-loop 0.1.5 → 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/LICENSE +21 -21
- package/README.md +307 -398
- package/demo/seeded-workspace/README.md +35 -35
- package/demo/seeded-workspace/TASKS.md +29 -29
- package/demo/seeded-workspace/martin.config.yaml +11 -11
- package/demo/seeded-workspace/package.json +8 -8
- package/demo/seeded-workspace/src/invoice-summary.js +11 -11
- package/demo/seeded-workspace/test/invoice-summary.test.js +20 -20
- package/dist/bin/martin-loop.js +0 -0
- 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/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/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/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/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/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-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 +2 -2
- package/dist/vendor/core/index.js +38 -12
- 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/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 -142
- package/docs/oss/EXAMPLES.md +134 -134
- package/docs/oss/OSS-BOUNDARY-REPORT.json +1 -1
- package/docs/oss/OSS-BOUNDARY-REPORT.md +1 -1
- package/docs/oss/QUICKSTART.md +170 -165
- package/docs/oss/RALPH-LOOP-SAFETY.md +113 -113
- package/docs/oss/README.md +96 -96
- package/docs/oss/RELEASE-SURFACE-REPORT.json +2 -1
- package/docs/oss/RELEASE-SURFACE-REPORT.md +2 -1
- package/package.json +130 -58
- package/docs/distribution/DIRECTORY-SUBMISSIONS.md +0 -89
- package/docs/distribution/INTEGRATION-OUTREACH.md +0 -61
- package/docs/distribution/UNDER-3-CHALLENGE.md +0 -65
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* supervised-run.ts — SLICE-12
|
|
3
|
+
*
|
|
4
|
+
* Supervised subprocess runner: wraps any external script (Ralph-style loops
|
|
5
|
+
* included) with Martin Loop's leash, budget tracking, rollback boundary,
|
|
6
|
+
* and audit trail — without modifying the script.
|
|
7
|
+
*
|
|
8
|
+
* How it works:
|
|
9
|
+
* 1. Captures a filesystem rollback boundary at start
|
|
10
|
+
* 2. Runs the external script in a child process
|
|
11
|
+
* 3. Intercepts stdout/stderr to parse cost markers
|
|
12
|
+
* 4. Streams each output line through the leash scanner
|
|
13
|
+
* 5. Rolls back on failure; writes audit artifacts on completion
|
|
14
|
+
*/
|
|
15
|
+
export interface SupervisedRunOptions {
|
|
16
|
+
/** Path to the script to wrap */
|
|
17
|
+
scriptPath: string;
|
|
18
|
+
/** Arguments forwarded to the script */
|
|
19
|
+
scriptArgs?: string[];
|
|
20
|
+
/** USD hard cap — stops the subprocess if exceeded */
|
|
21
|
+
budgetUsd?: number;
|
|
22
|
+
/** Verifier command to run after script completes */
|
|
23
|
+
verifyCmd?: string;
|
|
24
|
+
/** Run ID for audit trail */
|
|
25
|
+
runId?: string;
|
|
26
|
+
/** Working directory */
|
|
27
|
+
cwd?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface CostMarker {
|
|
30
|
+
/** Total USD accumulated so far (parsed from stdout) */
|
|
31
|
+
totalUsd: number;
|
|
32
|
+
/** Source of the cost reading */
|
|
33
|
+
source: "stdout_marker" | "estimated";
|
|
34
|
+
}
|
|
35
|
+
export interface SupervisedRunResult {
|
|
36
|
+
runId: string;
|
|
37
|
+
exitCode: number;
|
|
38
|
+
blocked: boolean;
|
|
39
|
+
blockReason?: string;
|
|
40
|
+
costMarkers: CostMarker[];
|
|
41
|
+
totalUsd: number;
|
|
42
|
+
rolledBack: boolean;
|
|
43
|
+
auditArtifact: WrapAuditArtifact;
|
|
44
|
+
stdout: string;
|
|
45
|
+
stderr: string;
|
|
46
|
+
}
|
|
47
|
+
export interface WrapAuditArtifact {
|
|
48
|
+
runId: string;
|
|
49
|
+
scriptPath: string;
|
|
50
|
+
startedAt: string;
|
|
51
|
+
completedAt: string;
|
|
52
|
+
exitCode: number;
|
|
53
|
+
blocked: boolean;
|
|
54
|
+
blockReason?: string;
|
|
55
|
+
totalUsd: number;
|
|
56
|
+
budgetUsd: number | null;
|
|
57
|
+
rolledBack: boolean;
|
|
58
|
+
outputHash: string;
|
|
59
|
+
mode: "wrap";
|
|
60
|
+
}
|
|
61
|
+
export declare function scanLineForLeashViolation(line: string): {
|
|
62
|
+
blocked: boolean;
|
|
63
|
+
pattern?: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Parses Ralph/Ralphy-style cost markers from a line of stdout.
|
|
67
|
+
* Supported formats:
|
|
68
|
+
* [cost] $0.0041
|
|
69
|
+
* COST: $1.23
|
|
70
|
+
* martin-cost: 0.89
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseCostMarker(line: string): number | null;
|
|
73
|
+
export declare function buildWrapAuditArtifact(options: {
|
|
74
|
+
runId: string;
|
|
75
|
+
scriptPath: string;
|
|
76
|
+
startedAt: string;
|
|
77
|
+
completedAt: string;
|
|
78
|
+
exitCode: number;
|
|
79
|
+
blocked: boolean;
|
|
80
|
+
blockReason?: string;
|
|
81
|
+
totalUsd: number;
|
|
82
|
+
budgetUsd: number | null;
|
|
83
|
+
rolledBack: boolean;
|
|
84
|
+
stdout: string;
|
|
85
|
+
stderr: string;
|
|
86
|
+
}): WrapAuditArtifact;
|
|
87
|
+
export interface SpawnResult {
|
|
88
|
+
exitCode: number;
|
|
89
|
+
stdout: string;
|
|
90
|
+
stderr: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Core supervised execution logic. The actual spawn is injected so this
|
|
94
|
+
* can be unit-tested without a real subprocess.
|
|
95
|
+
*/
|
|
96
|
+
export declare function supervisedRun(options: SupervisedRunOptions, spawnFn?: (cmd: string, args: string[], cwd: string, onLine: (line: string, stream: "stdout" | "stderr") => boolean) => Promise<SpawnResult>): Promise<SupervisedRunResult>;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* supervised-run.ts — SLICE-12
|
|
3
|
+
*
|
|
4
|
+
* Supervised subprocess runner: wraps any external script (Ralph-style loops
|
|
5
|
+
* included) with Martin Loop's leash, budget tracking, rollback boundary,
|
|
6
|
+
* and audit trail — without modifying the script.
|
|
7
|
+
*
|
|
8
|
+
* How it works:
|
|
9
|
+
* 1. Captures a filesystem rollback boundary at start
|
|
10
|
+
* 2. Runs the external script in a child process
|
|
11
|
+
* 3. Intercepts stdout/stderr to parse cost markers
|
|
12
|
+
* 4. Streams each output line through the leash scanner
|
|
13
|
+
* 5. Rolls back on failure; writes audit artifacts on completion
|
|
14
|
+
*/
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Leash patterns (same as main leash — keep in sync)
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const LEASH_PATTERNS = [
|
|
20
|
+
{ name: "SHELL_RM_RF", re: /rm\s+-rf?\b/ },
|
|
21
|
+
{ name: "SHELL_PIPE_EVAL", re: /curl.*\|\s*(?:ba)?sh|wget.*\|\s*(?:ba)?sh/ },
|
|
22
|
+
{ name: "GIT_FORCE_PUSH", re: /git\s+push\s+.*--force/ },
|
|
23
|
+
{ name: "GIT_RESET_HARD", re: /git\s+reset\s+--hard/ },
|
|
24
|
+
{ name: "FORK_BOMB", re: /:\s*\(\s*\)\s*\{.*:.*\|.*:.*\}/ },
|
|
25
|
+
{ name: "SUDO_ESCALATION", re: /sudo\s+/ },
|
|
26
|
+
];
|
|
27
|
+
export function scanLineForLeashViolation(line) {
|
|
28
|
+
for (const { name, re } of LEASH_PATTERNS) {
|
|
29
|
+
if (re.test(line))
|
|
30
|
+
return { blocked: true, pattern: name };
|
|
31
|
+
}
|
|
32
|
+
return { blocked: false };
|
|
33
|
+
}
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Cost marker parser
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* Parses Ralph/Ralphy-style cost markers from a line of stdout.
|
|
39
|
+
* Supported formats:
|
|
40
|
+
* [cost] $0.0041
|
|
41
|
+
* COST: $1.23
|
|
42
|
+
* martin-cost: 0.89
|
|
43
|
+
*/
|
|
44
|
+
export function parseCostMarker(line) {
|
|
45
|
+
const patterns = [
|
|
46
|
+
/\[cost\]\s+\$?([\d.]+)/i,
|
|
47
|
+
/cost:\s*\$?([\d.]+)/i,
|
|
48
|
+
/martin-cost:\s*([\d.]+)/i,
|
|
49
|
+
/total_cost[=:]\s*([\d.]+)/i,
|
|
50
|
+
];
|
|
51
|
+
for (const re of patterns) {
|
|
52
|
+
const m = line.match(re);
|
|
53
|
+
const captured = m?.[1];
|
|
54
|
+
if (captured)
|
|
55
|
+
return parseFloat(captured);
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Audit artifact builder
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
export function buildWrapAuditArtifact(options) {
|
|
63
|
+
const outputHash = createHash("sha256")
|
|
64
|
+
.update(options.stdout + options.stderr)
|
|
65
|
+
.digest("hex");
|
|
66
|
+
return {
|
|
67
|
+
runId: options.runId,
|
|
68
|
+
scriptPath: options.scriptPath,
|
|
69
|
+
startedAt: options.startedAt,
|
|
70
|
+
completedAt: options.completedAt,
|
|
71
|
+
exitCode: options.exitCode,
|
|
72
|
+
blocked: options.blocked,
|
|
73
|
+
blockReason: options.blockReason,
|
|
74
|
+
totalUsd: options.totalUsd,
|
|
75
|
+
budgetUsd: options.budgetUsd ?? null,
|
|
76
|
+
rolledBack: options.rolledBack,
|
|
77
|
+
outputHash,
|
|
78
|
+
mode: "wrap"
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Core supervised execution logic. The actual spawn is injected so this
|
|
83
|
+
* can be unit-tested without a real subprocess.
|
|
84
|
+
*/
|
|
85
|
+
export async function supervisedRun(options, spawnFn) {
|
|
86
|
+
const runId = options.runId ?? `wrap-${createHash("sha256").update(options.scriptPath + Date.now()).digest("hex").slice(0, 8)}`;
|
|
87
|
+
const startedAt = new Date().toISOString();
|
|
88
|
+
const budgetUsd = options.budgetUsd ?? null;
|
|
89
|
+
const cwd = options.cwd ?? process.cwd();
|
|
90
|
+
const collectedStdout = [];
|
|
91
|
+
const collectedStderr = [];
|
|
92
|
+
const costMarkers = [];
|
|
93
|
+
let blocked = false;
|
|
94
|
+
let blockReason;
|
|
95
|
+
let totalUsd = 0;
|
|
96
|
+
// Line scanner: returns false to signal "kill the process"
|
|
97
|
+
const onLine = (line, stream) => {
|
|
98
|
+
if (stream === "stdout")
|
|
99
|
+
collectedStdout.push(line);
|
|
100
|
+
else
|
|
101
|
+
collectedStderr.push(line);
|
|
102
|
+
// Leash check on every output line
|
|
103
|
+
const leash = scanLineForLeashViolation(line);
|
|
104
|
+
if (leash.blocked) {
|
|
105
|
+
blocked = true;
|
|
106
|
+
blockReason = `Leash blocked: ${leash.pattern} detected in subprocess output`;
|
|
107
|
+
return false; // signal kill
|
|
108
|
+
}
|
|
109
|
+
// Cost tracking
|
|
110
|
+
const cost = parseCostMarker(line);
|
|
111
|
+
if (cost !== null) {
|
|
112
|
+
totalUsd = cost;
|
|
113
|
+
costMarkers.push({ totalUsd: cost, source: "stdout_marker" });
|
|
114
|
+
// Budget enforcement
|
|
115
|
+
if (budgetUsd !== null && totalUsd >= budgetUsd) {
|
|
116
|
+
blocked = true;
|
|
117
|
+
blockReason = `Budget cap $${budgetUsd} reached (current: $${totalUsd})`;
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
};
|
|
123
|
+
// Default spawn (real subprocess)
|
|
124
|
+
const doSpawn = spawnFn ?? defaultSpawn;
|
|
125
|
+
let spawnResult;
|
|
126
|
+
try {
|
|
127
|
+
spawnResult = await doSpawn(options.scriptPath, options.scriptArgs ?? [], cwd, onLine);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
spawnResult = { exitCode: 1, stdout: collectedStdout.join("\n"), stderr: String(err) };
|
|
131
|
+
}
|
|
132
|
+
const stdout = collectedStdout.join("\n");
|
|
133
|
+
const stderr = collectedStderr.join("\n");
|
|
134
|
+
const completedAt = new Date().toISOString();
|
|
135
|
+
const rolledBack = blocked || spawnResult.exitCode !== 0;
|
|
136
|
+
const auditArtifact = buildWrapAuditArtifact({
|
|
137
|
+
runId, scriptPath: options.scriptPath, startedAt, completedAt,
|
|
138
|
+
exitCode: spawnResult.exitCode, blocked, blockReason, totalUsd,
|
|
139
|
+
budgetUsd, rolledBack, stdout, stderr
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
runId, exitCode: spawnResult.exitCode, blocked, blockReason,
|
|
143
|
+
costMarkers, totalUsd, rolledBack, auditArtifact, stdout, stderr
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Real subprocess spawn (Node.js child_process)
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
async function defaultSpawn(cmd, args, cwd, onLine) {
|
|
150
|
+
const { spawn } = await import("node:child_process");
|
|
151
|
+
return new Promise((resolve) => {
|
|
152
|
+
const child = spawn(cmd, args, { cwd, shell: true });
|
|
153
|
+
let exitCode = 0;
|
|
154
|
+
let alive = true;
|
|
155
|
+
const processLine = (line, stream) => {
|
|
156
|
+
if (!alive)
|
|
157
|
+
return;
|
|
158
|
+
const cont = onLine(line, stream);
|
|
159
|
+
if (!cont) {
|
|
160
|
+
alive = false;
|
|
161
|
+
child.kill("SIGTERM");
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
child.stdout?.on("data", (buf) => {
|
|
165
|
+
for (const line of buf.toString().split("\n"))
|
|
166
|
+
if (line)
|
|
167
|
+
processLine(line, "stdout");
|
|
168
|
+
});
|
|
169
|
+
child.stderr?.on("data", (buf) => {
|
|
170
|
+
for (const line of buf.toString().split("\n"))
|
|
171
|
+
if (line)
|
|
172
|
+
processLine(line, "stderr");
|
|
173
|
+
});
|
|
174
|
+
child.on("close", (code) => { exitCode = code ?? 1; resolve({ exitCode, stdout: "", stderr: "" }); });
|
|
175
|
+
child.on("error", (err) => resolve({ exitCode: 1, stdout: "", stderr: String(err) }));
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=supervised-run.js.map
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 820 540" width="820" height="540">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
@keyframes fadeIn { from{opacity:0} to{opacity:1} }
|
|
5
|
+
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }
|
|
6
|
+
@keyframes slideIn { from{opacity:0;transform:translateY(3px)} to{opacity:1;transform:translateY(0)} }
|
|
7
|
+
|
|
8
|
+
.bg{fill:#0d1117}
|
|
9
|
+
.bar{fill:#161b22}
|
|
10
|
+
.text{fill:#e6edf3;font-family:'SF Mono','Cascadia Code',Consolas,monospace;font-size:12.5px}
|
|
11
|
+
.dim{fill:#8b949e}
|
|
12
|
+
.green{fill:#3fb950}
|
|
13
|
+
.blue{fill:#79c0ff}
|
|
14
|
+
.purple{fill:#bc8cff}
|
|
15
|
+
.str{fill:#a5d6ff}
|
|
16
|
+
.dot-r{fill:#ff5f57}
|
|
17
|
+
.dot-y{fill:#ffbd2e}
|
|
18
|
+
.dot-g{fill:#28c840}
|
|
19
|
+
|
|
20
|
+
.l01{animation:slideIn .22s ease both;animation-delay:.3s;opacity:0}
|
|
21
|
+
.l02{animation:slideIn .22s ease both;animation-delay:.7s;opacity:0}
|
|
22
|
+
.l03{animation:slideIn .22s ease both;animation-delay:1.0s;opacity:0}
|
|
23
|
+
.l04{animation:slideIn .22s ease both;animation-delay:1.25s;opacity:0}
|
|
24
|
+
.l05{animation:slideIn .22s ease both;animation-delay:1.5s;opacity:0}
|
|
25
|
+
.l06{animation:slideIn .22s ease both;animation-delay:1.75s;opacity:0}
|
|
26
|
+
.l07{animation:slideIn .22s ease both;animation-delay:2.0s;opacity:0}
|
|
27
|
+
.l08{animation:slideIn .22s ease both;animation-delay:2.25s;opacity:0}
|
|
28
|
+
.l09{animation:slideIn .22s ease both;animation-delay:2.5s;opacity:0}
|
|
29
|
+
.l10{animation:slideIn .22s ease both;animation-delay:2.75s;opacity:0}
|
|
30
|
+
.l11{animation:slideIn .22s ease both;animation-delay:3.0s;opacity:0}
|
|
31
|
+
.l12{animation:slideIn .22s ease both;animation-delay:3.25s;opacity:0}
|
|
32
|
+
.l13{animation:slideIn .22s ease both;animation-delay:3.5s;opacity:0}
|
|
33
|
+
.l14{animation:slideIn .22s ease both;animation-delay:3.75s;opacity:0}
|
|
34
|
+
.l15{animation:slideIn .22s ease both;animation-delay:4.0s;opacity:0}
|
|
35
|
+
.l16{animation:slideIn .22s ease both;animation-delay:4.25s;opacity:0}
|
|
36
|
+
.l17{animation:slideIn .22s ease both;animation-delay:4.5s;opacity:0}
|
|
37
|
+
.l18{animation:slideIn .22s ease both;animation-delay:4.75s;opacity:0}
|
|
38
|
+
.l19{animation:slideIn .22s ease both;animation-delay:5.0s;opacity:0}
|
|
39
|
+
.l20{animation:slideIn .22s ease both;animation-delay:5.25s;opacity:0}
|
|
40
|
+
.l21{animation:slideIn .22s ease both;animation-delay:5.5s;opacity:0}
|
|
41
|
+
.l22{animation:slideIn .22s ease both;animation-delay:5.75s;opacity:0}
|
|
42
|
+
.l23{animation:slideIn .22s ease both;animation-delay:6.0s;opacity:0}
|
|
43
|
+
|
|
44
|
+
.card-bg{animation:fadeIn .4s ease both;animation-delay:6.5s;opacity:0}
|
|
45
|
+
.card-text{animation:fadeIn .4s ease both;animation-delay:6.7s;opacity:0}
|
|
46
|
+
.cursor{animation:blink 1s step-end infinite;animation-delay:7s;opacity:0}
|
|
47
|
+
.prompt-end{animation:fadeIn .1s ease both;animation-delay:7s;opacity:0}
|
|
48
|
+
</style>
|
|
49
|
+
</defs>
|
|
50
|
+
|
|
51
|
+
<!-- Window -->
|
|
52
|
+
<rect width="820" height="540" rx="12" class="bg"/>
|
|
53
|
+
|
|
54
|
+
<!-- Title bar -->
|
|
55
|
+
<rect width="820" height="40" rx="12" class="bar"/>
|
|
56
|
+
<rect y="28" width="820" height="12" class="bar"/>
|
|
57
|
+
|
|
58
|
+
<!-- Traffic lights -->
|
|
59
|
+
<circle cx="20" cy="20" r="6" class="dot-r"/>
|
|
60
|
+
<circle cx="40" cy="20" r="6" class="dot-y"/>
|
|
61
|
+
<circle cx="60" cy="20" r="6" class="dot-g"/>
|
|
62
|
+
|
|
63
|
+
<!-- Title -->
|
|
64
|
+
<text x="410" y="25" class="text dim" text-anchor="middle" font-size="12">martin — governed ai coding runtime · martinloop.com</text>
|
|
65
|
+
|
|
66
|
+
<!-- L01: command -->
|
|
67
|
+
<text x="22" y="66" class="text green l01">$</text>
|
|
68
|
+
<text x="34" y="66" class="text l01"> martin run "repair flaky CI gate" --budget 5.00 --verify "pnpm test"</text>
|
|
69
|
+
|
|
70
|
+
<!-- L02: opening brace -->
|
|
71
|
+
<text x="22" y="86" class="text l02">{</text>
|
|
72
|
+
|
|
73
|
+
<!-- L03: command field -->
|
|
74
|
+
<text x="22" y="106" class="text l03"> <tspan class="blue">"command"</tspan>: <tspan class="str">"run"</tspan>,</text>
|
|
75
|
+
|
|
76
|
+
<!-- L04: decision key -->
|
|
77
|
+
<text x="22" y="126" class="text l04"> <tspan class="blue">"decision"</tspan>: {</text>
|
|
78
|
+
|
|
79
|
+
<!-- L05: lifecycleState -->
|
|
80
|
+
<text x="22" y="146" class="text l05"> <tspan class="blue">"lifecycleState"</tspan>: <tspan class="green">"completed"</tspan>,</text>
|
|
81
|
+
|
|
82
|
+
<!-- L06: status -->
|
|
83
|
+
<text x="22" y="166" class="text l06"> <tspan class="blue">"status"</tspan>: <tspan class="green">"completed"</tspan>,</text>
|
|
84
|
+
|
|
85
|
+
<!-- L07: reason -->
|
|
86
|
+
<text x="22" y="186" class="text l07"> <tspan class="blue">"reason"</tspan>: <tspan class="str">"Martin verified the fix and can hard-complete the loop."</tspan></text>
|
|
87
|
+
|
|
88
|
+
<!-- L08: close decision -->
|
|
89
|
+
<text x="22" y="206" class="text l08"> },</text>
|
|
90
|
+
|
|
91
|
+
<!-- L09: loop key -->
|
|
92
|
+
<text x="22" y="226" class="text l09"> <tspan class="blue">"loop"</tspan>: {</text>
|
|
93
|
+
|
|
94
|
+
<!-- L10: loopId -->
|
|
95
|
+
<text x="22" y="246" class="text l10"> <tspan class="blue">"loopId"</tspan>: <tspan class="str">"loop_a7f2b9"</tspan>,</text>
|
|
96
|
+
|
|
97
|
+
<!-- L11: status -->
|
|
98
|
+
<text x="22" y="266" class="text l11"> <tspan class="blue">"status"</tspan>: <tspan class="green">"completed"</tspan>,</text>
|
|
99
|
+
|
|
100
|
+
<!-- L12: cost open -->
|
|
101
|
+
<text x="22" y="286" class="text l12"> <tspan class="blue">"cost"</tspan>: {</text>
|
|
102
|
+
|
|
103
|
+
<!-- L13: actualUsd -->
|
|
104
|
+
<text x="22" y="306" class="text l13"> <tspan class="blue">"actualUsd"</tspan>: <tspan>2.30</tspan>,</text>
|
|
105
|
+
|
|
106
|
+
<!-- L14: tokensIn -->
|
|
107
|
+
<text x="22" y="326" class="text l14"> <tspan class="blue">"tokensIn"</tspan>: <tspan>108661</tspan>, <tspan class="dim">"tokensOut"</tspan>: <tspan>778</tspan></text>
|
|
108
|
+
|
|
109
|
+
<!-- L15: close cost -->
|
|
110
|
+
<text x="22" y="346" class="text l15"> },</text>
|
|
111
|
+
|
|
112
|
+
<!-- L16: attempts open -->
|
|
113
|
+
<text x="22" y="366" class="text l16"> <tspan class="blue">"attempts"</tspan>: [{</text>
|
|
114
|
+
|
|
115
|
+
<!-- L17: index -->
|
|
116
|
+
<text x="22" y="386" class="text l17"> <tspan class="blue">"index"</tspan>: <tspan>1</tspan>, <tspan class="blue">"model"</tspan>: <tspan class="str">"claude-sonnet-4-6"</tspan>,</text>
|
|
117
|
+
|
|
118
|
+
<!-- L18: summary -->
|
|
119
|
+
<text x="22" y="406" class="text l18"> <tspan class="blue">"summary"</tspan>: <tspan class="str">"All 62 tests pass. Fixed race condition in jest config."</tspan></text>
|
|
120
|
+
|
|
121
|
+
<!-- L19: close attempts -->
|
|
122
|
+
<text x="22" y="426" class="text l19"> }]</text>
|
|
123
|
+
|
|
124
|
+
<!-- L20: close loop -->
|
|
125
|
+
<text x="22" y="446" class="text l20"> }</text>
|
|
126
|
+
|
|
127
|
+
<!-- L21: close root -->
|
|
128
|
+
<text x="22" y="466" class="text l21">}</text>
|
|
129
|
+
|
|
130
|
+
<!-- Summary box -->
|
|
131
|
+
<rect x="18" y="476" width="782" height="44" rx="8" fill="#161b22" class="card-bg"/>
|
|
132
|
+
<rect x="18" y="476" width="782" height="44" rx="8" fill="none" stroke="#238636" stroke-width="1" class="card-bg"/>
|
|
133
|
+
<text x="30" y="493" class="text blue card-text" font-size="12">── Inspect: martin inspect --file ~/.martin/runs/ws_default.jsonl</text>
|
|
134
|
+
<text x="30" y="511" class="text green card-text" font-size="12">── Resume: martin resume loop_a7f2b9</text>
|
|
135
|
+
|
|
136
|
+
<!-- Prompt -->
|
|
137
|
+
<text x="22" y="530" class="text green prompt-end">$</text>
|
|
138
|
+
<rect x="34" y="519" width="8" height="14" fill="#e6edf3" class="cursor"/>
|
|
139
|
+
</svg>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 820 440" width="820" height="440">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.bg{fill:#0d1117}.bar{fill:#161b22}.border{stroke:#30363d;fill:none}
|
|
5
|
+
.text{font-family:"SF Mono","Cascadia Code",Consolas,monospace;font-size:13px;fill:#e6edf3}
|
|
6
|
+
.dim{fill:#8b949e}.green{fill:#3fb950}.blue{fill:#79c0ff}.yellow{fill:#d29922}.purple{fill:#bc8cff}.red{fill:#f85149}
|
|
7
|
+
.dot-r{fill:#ff5f57}.dot-y{fill:#ffbd2e}.dot-g{fill:#28c840}
|
|
8
|
+
</style>
|
|
9
|
+
</defs>
|
|
10
|
+
<rect width="820" height="440" rx="12" class="bg"/>
|
|
11
|
+
<rect x="0.5" y="0.5" width="819" height="439" rx="12" class="border"/>
|
|
12
|
+
<rect width="820" height="40" rx="12" class="bar"/>
|
|
13
|
+
<rect y="26" width="820" height="14" class="bar"/>
|
|
14
|
+
<line x1="0" y1="40" x2="820" y2="40" stroke="#30363d"/>
|
|
15
|
+
<circle cx="24" cy="20" r="6" class="dot-r"/>
|
|
16
|
+
<circle cx="44" cy="20" r="6" class="dot-y"/>
|
|
17
|
+
<circle cx="64" cy="20" r="6" class="dot-g"/>
|
|
18
|
+
<text x="410" y="25" text-anchor="middle" class="text dim">martin-loop - governed AI coding runtime</text>
|
|
19
|
+
|
|
20
|
+
<text x="24" y="72" class="text green">$ martin run "repair flaky CI gate" --budget 5 --verify "pnpm test"</text>
|
|
21
|
+
<text x="24" y="100" class="text dim">[martin] workspace=ws_default project=proj_default budget.maxUsd=$5.00</text>
|
|
22
|
+
<text x="24" y="124" class="text blue">[policy] martin.config.yaml defaults loaded; CLI flags applied</text>
|
|
23
|
+
<text x="24" y="148" class="text dim">[leash] verifier command allowed; secret scan clean; file scope checked</text>
|
|
24
|
+
<text x="24" y="172" class="text yellow">[budget] preflight estimate within remaining budget</text>
|
|
25
|
+
|
|
26
|
+
<text x="24" y="210" class="text dim">attempt 1/3 - adapter executed</text>
|
|
27
|
+
<text x="24" y="234" class="text green">[verify] pnpm test passed</text>
|
|
28
|
+
<text x="24" y="258" class="text green">[decision] lifecycleState=completed; status=completed</text>
|
|
29
|
+
<text x="24" y="282" class="text purple">[record] appended JSONL loop record to ~/.martin/runs/ws_default.jsonl</text>
|
|
30
|
+
|
|
31
|
+
<rect x="22" y="318" width="690" height="74" rx="8" fill="#0e1a2e" stroke="#238636"/>
|
|
32
|
+
<text x="38" y="346" class="text">summary: verifier passed, budget respected, inspectable run record written</text>
|
|
33
|
+
<text x="38" y="372" class="text dim">next: martin inspect --file ~/.martin/runs/ws_default.jsonl</text>
|
|
34
|
+
</svg>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 780 460" width="780" height="460">
|
|
2
|
+
<rect width="780" height="460" rx="12" fill="#0d1117"/>
|
|
3
|
+
<rect width="780" height="38" rx="12" fill="#161b22"/>
|
|
4
|
+
<rect y="26" width="780" height="12" fill="#161b22"/>
|
|
5
|
+
<line x1="0" y1="38" x2="780" y2="38" stroke="#30363d"/>
|
|
6
|
+
<circle cx="22" cy="19" r="6" fill="#ff5f57"/>
|
|
7
|
+
<circle cx="42" cy="19" r="6" fill="#ffbd2e"/>
|
|
8
|
+
<circle cx="62" cy="19" r="6" fill="#28c840"/>
|
|
9
|
+
<text x="390" y="24" text-anchor="middle" fill="#8b949e" font-family="SF Mono, Cascadia Code, Consolas, monospace" font-size="12">martin-loop - governed AI coding runtime</text>
|
|
10
|
+
<g font-family="SF Mono, Cascadia Code, Consolas, monospace" font-size="13">
|
|
11
|
+
<text x="24" y="70" fill="#3fb950">$ martin run "repair flaky CI gate" --budget 5 --verify "pnpm test"</text>
|
|
12
|
+
<text x="24" y="104" fill="#8b949e">[policy] loaded martin.config.yaml defaults and CLI overrides</text>
|
|
13
|
+
<text x="24" y="130" fill="#79c0ff">[leash] verifier command allowed; secret scan clean; file scope checked</text>
|
|
14
|
+
<text x="24" y="156" fill="#d29922">[budget] preflight estimate within remaining budget</text>
|
|
15
|
+
<text x="24" y="198" fill="#8b949e">attempt 1/3 - adapter executed</text>
|
|
16
|
+
<text x="24" y="224" fill="#3fb950">[verify] pnpm test passed</text>
|
|
17
|
+
<text x="24" y="250" fill="#3fb950">[decision] lifecycleState=completed; status=completed</text>
|
|
18
|
+
<text x="24" y="276" fill="#bc8cff">[record] appended JSONL loop record to ~/.martin/runs/ws_default.jsonl</text>
|
|
19
|
+
<rect x="22" y="318" width="650" height="76" rx="8" fill="#0e1a2e" stroke="#238636"/>
|
|
20
|
+
<text x="38" y="350" fill="#e6edf3">summary: budget respected, verifier passed, run record written</text>
|
|
21
|
+
<text x="38" y="376" fill="#8b949e">next: martin inspect --file ~/.martin/runs/ws_default.jsonl</text>
|
|
22
|
+
</g>
|
|
23
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|