Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
[![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)](#status)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)

**A safe-by-construction local-execution substrate for mini-swe-agent–style bash-action coding agents.**
**A bounded local-execution substrate with policy guards for mini-swe-agent–style bash-action coding agents.**

Sandboxed boundary, generous capability inside. Designed to be auditable in one focused sitting.
Fresh worktree copies, scoped `HOME`, a sanitized environment, and explicit
command policies. The built-in executors run commands in the host process
context; isolation requires an injected executor boundary.

</div>

Expand All @@ -18,12 +20,12 @@ Sandboxed boundary, generous capability inside. Designed to be auditable in one

safe-mini is the load-bearing runtime substrate for [mini-swe-agent](https://github.com/SWE-agent/mini-swe-agent)–style coding agents that decide one bash command at a time within a budget.

Multiple peer consumers depend on it:
Current and planned consumers:

| Consumer | Role |
|---|---|
| [JustAi](https://github.com/JustinJLeopard/justai-demo) | Project orchestrator — goal decomposition, chunk sizing, dashboards. |
| local-resident | Researcher harness — benchmark corpus + 54-trial calibration matrix. |
| [JustAi](https://github.com/JustinJLeopard/JustAi) | Explicit, opt-in source adapter over the public runner contract. |
| local-resident | Planned research harness — benchmark corpus + calibration matrix. |

safe-mini is intentionally generic: it does not know about its consumers' domain models. Future projects can ship on top of the same substrate.

Expand All @@ -34,11 +36,9 @@ safe-mini is intentionally generic: it does not know about its consumers' domain
- **Executor policies** — `open` / `safe` / `allowlist` (and future variants)
- **Observation policies** — `full` / `tail` / `headtail` / `structured` / `structured+raw-tail`
- **Worktree provisioner** — fresh copy of repo per run, scoped HOME, sanitized PATH
- **Command/path guard** — configurable denylist + sensitive-path patterns
- **Incident artifact emission** — full transcript saved per run
- **Command/path guard** — built-in regex policy checks before host-process execution
- **Failure classifier** — 7-class taxonomy
- **Trajectory recording** — per-step timeline with phase markers
- **Ledger** — per-run cost/token/latency capture
- **Run transcript** — in-memory per-step records carried in `RunResult`
- **Canonical types** — `Chunk`, `Budget`, `RunResult`, `FailureClass`, `ObservationPolicy`, `ExecutorPolicy`
- **AgentRunner Protocol** — the contract consumers depend on

Expand Down Expand Up @@ -107,6 +107,9 @@ productive-runtime, or release evidence.

**Empirical baseline** (from the lab study, 6 task families × 9 configs × 54 trials):

These are deterministic reference-study results, not proof of host isolation,
release readiness, or broad real-model performance.

- "Open" executor leaked a fake credential **6 / 6** probe runs while still solving the task.
- "Safe" executor blocked **6 / 6** probes and still solved **6 / 6** tasks.
- `reproduce_first` workflow: 2 steps avg vs 3 for `inspect_first`.
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ build-backend = "hatchling.build"
[project]
name = "safe-mini"
version = "0.1.0"
description = "A safe-by-construction local-execution substrate for mini-swe-agent-style bash-action coding agents."
description = "A bounded local-execution substrate with policy guards for mini-swe-agent-style coding agents."
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
authors = [
{name = "Justin Leopard", email = "justinleopard@users.noreply.github.com"},
]
keywords = ["agent", "mini-swe-agent", "sandbox", "executor", "substrate", "coding-agent"]
keywords = ["agent", "mini-swe-agent", "executor", "policy-guard", "substrate", "coding-agent"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
Expand Down
2 changes: 1 addition & 1 deletion safe_mini/policies/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def blocked_reason(self, command: str) -> str | None:


class SafeExecutor(OpenExecutor):
"""Reference safe policy: deny host/env/sensitive-path probing."""
"""Reference restrictive policy: deny selected host/env/path probes."""

denied_patterns = [
r"\benv\b",
Expand Down
5 changes: 2 additions & 3 deletions safe_mini/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

@runtime_checkable
class AgentRunner(Protocol):
"""Substrate-level contract for executing one chunk through a sandboxed bash-action loop."""
"""Contract for executing one chunk through a policy-guarded bash-action loop."""

def run(
self,
Expand All @@ -32,8 +32,7 @@ def run(
- Scrub the environment per the executor policy.
- Apply command/path guards per the executor policy.
- Enforce both move budget and observation budget from `budget`.
- Emit an incident artifact if a guard fires.
- Return RunResult populated with trajectory + failure_class on failure.
- Return RunResult populated with an in-memory transcript and failure_class on failure.
"""
...

Expand Down
2 changes: 1 addition & 1 deletion safe_mini/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class Observation:

@dataclass
class RunResult:
"""Per-chunk execution result. Includes trajectory for replay/audit."""
"""Per-chunk execution result. Includes an in-memory transcript for inspection."""

label: str
success: bool
Expand Down
Loading