Skip to content
Merged
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
78 changes: 60 additions & 18 deletions docs/guides/quickstart.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
# Quickstart: your first lease in five minutes
# Quickstart: your first lease

This is the shortest path from zero to a live lease, a refused permit, and an
auditable ledger. The examples exercise Interlock's admission gate; they do
not sandbox code outside the gate or stop an action that is already running.

## 0. Install in a supported environment

Interlock requires Python 3.11 or newer, and its build backend requires
`setuptools>=68`. From a scratch directory, clone the repository, create a
virtual environment with a supported interpreter, and install the checked-out
package:

```bash
git clone https://github.com/marsojuji-cmyk/interlock.git
cd interlock
python3 -m venv .venv # python3 must be 3.11+; use python3.11 etc. if needed
. .venv/bin/activate
python -m pip install --upgrade "setuptools>=68"
python -m pip install .
```

This is the fastest path from zero to a live lease, a refused permit, and
an auditable ledger.
Every Python block below runs in order, as one session, with `python` from
this activated environment. This guide needs no pytest install.

## 1. Create the interlock

```python
from interlock import Interlock
from pathlib import Path

from interlock import EStopEngaged, FaultActive, Interlock

ilk = Interlock()
```
Expand All @@ -20,8 +42,9 @@ You now hold four components: `.leases` (the lease manager), `.estop`
lease = ilk.grant(resource="docs:write", holder="demo-agent", ttl_seconds=300)
```

Authority now exists, and it expires in 300 seconds. Nothing else in the
system can act on `docs:write` without this lease.
Authority now exists, and this example lease is short-lived. Nothing else in
the system can pass the gate for `docs:write` without this lease. Admission
checks the e-stop, lease state, and resource faults at the time of entry.

## 3. Exercise it through the gate

Expand All @@ -31,26 +54,45 @@ with ilk.permit(lease, action="write", target="notes.md"):
```

The gate checks, in order: e-stop clear, lease issued by this `Interlock`
and live, no gating fault on `docs:write`. If any check fails, the context
manager raises instead of yielding — `EStopEngaged`, `LeaseNotIssued`,
`LeaseExpired`/`LeaseRevoked`, or `FaultActive`.
and live, and no gating fault on `docs:write`. If any check fails, the
context manager raises instead of yielding: `EStopEngaged`,
`LeaseNotIssued`, `LeaseExpired`/`LeaseRevoked`, or `FaultActive`. The check
controls admission to the context. It is not an OS sandbox, and it cannot
interrupt an action that has already started.

## 4. Watch a fault refuse

```python
ilk.faults.report(code="DISK_FULL", severity="major", resource="docs:write")
fault = ilk.faults.report(
code="DISK_FULL", severity="major", resource="docs:write"
)

try:
with ilk.permit(lease, action="write", target="notes.md"):
Path("notes.md").write_text("should not be admitted")
except FaultActive:
pass
else:
raise AssertionError("the active fault must refuse admission")

assert fault.id is not None
ilk.faults.clear(fault.id)
with ilk.permit(lease, action="write", target="notes.md"):
... # raises FaultActive — the refusal is appended to the ledger
Path("notes.md").write_text("resumed")
```

Clear the fault to resume: `ilk.faults.clear(fault.id)`.
The refused entry is appended to the ledger. Clearing the fault permits a
new admission; it does not retroactively authorize the refused action.

## 5. Halt everything, then release

```python
ilk.estop.engage("taking a look")
# every permit now raises EStopEngaged, on every resource
try:
with ilk.permit(lease, action="write", target="notes.md"):
raise AssertionError("e-stop must refuse admission")
except EStopEngaged:
pass
ilk.estop.release() # deliberate, never automatic
```

Expand All @@ -74,8 +116,8 @@ ilk.ledger.close()

## Next steps

- `docs/concepts/leases.md` — why authority must decay.
- `docs/concepts/estop-and-faults.md` — the one halt and the gating bus.
- `docs/concepts/claims.md` — provenance, review dates, falsifiers.
- `docs/concepts/ledger.md` — the self-describing run log.
- `CHARTER.md` — the full design rationale and safety caveats.
- `docs/concepts/leases.md`: why authority must decay.
- `docs/concepts/estop-and-faults.md`: the one halt and the gating bus.
- `docs/concepts/claims.md`: provenance, review dates, falsifiers.
- `docs/concepts/ledger.md`: the self-describing run log.
- `CHARTER.md`: the full design rationale and safety caveats.
Loading