# Build an app on Newday

Start here: https://botfolio.com/agent-start
MCP: https://botfolio.com/v1/mcp
API: https://botfolio.com/v1/openapi

## Before you start: prerequisites and responsible actors

Batteries are scoped platform services your App explicitly binds: for example a development database, Secrets, identity/authz, sync or configured memory/inference. Provisioning a battery and binding runtime access are separate actions; a login alone grants neither.

Agent prerequisites: an admitted account, an OAuth client and grant with the operation scopes, ordinary shell/OpenSSH/Git tools, and an external OCI builder/publisher. Choose the stack and include dependencies in its image before starting. Discover current capabilities and schemas before provisioning. Keep credentials in private client storage, never chat, source or image layers.

Operator prerequisites for SSH development: prepared workspace capacity, enabled runtime/database/artifact services, a compatible image, and a connecting device enrolled and mapped on Headscale. listEnvironmentAccessPeers shows mappings available to your identity; it does not enroll a device. The operator must supply missing infrastructure through its authorized procedures. Record operator handoffs separately from agent actions.

External API access is optional and closed by default. Existing scoped OpenRouter access uses egress_binding with profile openrouter and the owning component_id, explicit operator admission of that Component, execution-bound proxy credentials and a private CONNECT proxy. Supply the provider key through an explicitly bound Component Secret. Discover the egress schema and image transport requirements; direct internet calls remain denied. New providers and package registries need a separate operator destination/authority decision. API traffic/time limits do not imply package-download support.

## 1. Connect and discover

Newday hosts your apps and supplies scoped platform services. Your external coding agent owns planning, source editing, tests and image builds. You can build locally or use an SSH development Environment.

Add https://botfolio.com/v1/mcp as a remote MCP server using OAuth. Clients supporting automatic OAuth registration and PKCE can leave Client ID and Client Secret blank when registration is enabled. Sign in with an admitted Newday account and review access. Otherwise use an operator-admitted OAuth client; never borrow administrator credentials.

Read https://botfolio.com/v1 for discovery and https://botfolio.com/v1/openapi for canonical operation IDs, request schemas, scopes and MCP tool names. Call listCapabilities and list existing Spaces/Apps before creating resources. MCP tools/list is filtered by your authority and configured capabilities. An unavailable capability may need operator setup.

MCP manages lifecycle and resources; it does not provide shell, file-editing or terminal tools. Your agent needs its own shell/SSH tools and an external image builder. If using the repository CLI, newday call OPERATION_ID --args @request.json invokes the canonical operation; there is no newday init or newday dev shortcut. CLI argument files use the exact public parameter names: path IDs such as parent_id at top level, JSON request content under body, and headers as Idempotency-Key or If-Match (not idempotency_key). For example, createSpace takes {"body": {"name": "Example", "slug": "example"}, "Idempotency-Key": "YOUR-UNIQUE-KEY"}.

## 2. Set up development resources

A Space groups Apps. An App contains Components; each Component owns repositories, databases, Secrets and compute. Use createSpace, createApp and createComponent, or reuse the user's selected resources.

Create the release App, then a separate development App in the same Space with development_of set to the release App ID. Create a Component and repository in each. The association does not grant cross-App access. Explicitly provision development databases, Secrets and configured/App batteries in the development Component.

Inspect schemas rather than guessing arguments or translating operation IDs into MCP names. Persist each mutation's original Idempotency-Key and returned Operation ID. Poll getOperation using its state field to succeeded, failed or cancelled; an accepted request is not readiness. After an uncertain create, observe the original intent instead of issuing another create. Supply current ETags where required; reread after a stale-version response.

Use migration database credentials for a separate migration Job and runtime credentials for the app. Keep development and release database, Secret and battery bindings separate. A local OAuth login alone does not provide App runtime access.

## 3. Prepare an image and source

Build a compatible development image externally with your language, dependencies, Git, OpenSSH and an app startup command. Use /workspace for persistent editable source. The image must support the Environment SSH contract; consult the Environment and access schemas. The verified worked example in the Markdown guide supplies complete Python image/source files; it is a synthetic development demonstration, not a production template or universal IDE image.

For SSH compatibility, provide a dev account with UID/GID 10000 and a usable shell, and run the image as 10000:10000. Start /usr/sbin/sshd -D -e -f /var/run/core-environment-access/sshd_config alongside your development server when that mounted config is present. Use Core's supplied configuration and keys; target Ed25519 host keys use the native OpenSSH format. HTTP readiness and a ready access lease do not prove your sshd started: verify an actual strict-host-key SSH command. Run the app on the declared port, expose its readiness path, and preserve the prepared /workspace root permissions.

Use issueRepositoryCredential for scoped OCI publication, push with an ordinary OCI client to the returned repository namespace, then resolveRepositoryManifest for the admitted immutable image reference. Revoke the publication credential after use. Never bake credentials into source or image layers.

Prepare dependencies in the image: development compute has no blanket internet access or host Docker socket. Transfer source using SSH stdin or Git bundles; scoped native Git operations can run externally. New repositories have an initial commit: clone before editing or push a new branch without overwriting it.

## 4. Start and connect over SSH

The operator must prepare workspace capacity and enroll/map your connecting device on the private Headscale network. Discover your authorized mappings with listEnvironmentAccessPeers. Core does not silently enroll a physical device. Request core:environments:access:read and core:environments:access:write alongside the scopes needed for compute and resources.

Call createEnvironment under the development Component using an admitted image digest, artifact_binding, command, resource limits, development workspace/idle settings and private_access with transport headscale and protocol ssh. For battery-connected development use the supported network/broker/database bindings from the schema. The example body below illustrates this configuration; replace every placeholder and use your image's actual startup command. The shown /opt/app/start.sh belongs to the verified worked example.

Call startEnvironment with the current ETag, poll its Operation, and read the resulting execution. Request createEnvironmentAccess with that execution_id, authorized peer_id, ssh_public_key and ttl_seconds, plus the Environment ETag. Refresh nearly expired OAuth tokens first: SSH access is capped by the token's remaining lifetime.

Poll the access Operation and use its returned endpoint and known-hosts record with ordinary OpenSSH as dev from the mapped device. Verify host keys; every restart requires current connection information. Edit and test in /workspace. Keep execution-mounted credentials out of that persistent directory. SSH shells may need an image-owned adapter to access the application's runtime environment.

## 5. Preview and use batteries

Create an owner-only development Route in the same Component. After readiness, selectRoute with environment_id, execution_id and the current Route ETag. Open its returned URL using owner login, or issue a short-lived createRouteCredential (maximum 900 seconds). Never put bearer credentials in URLs.

Run your framework's development server on the declared port and readiness path. HTTP and WebSocket preview support source changes without a new image or execution when your app implements reload. Discover and explicitly configure only the batteries your app needs; runtime identity and bindings scope their use.

## 6. Stop, resume and preserve work

stopEnvironment closes compute, SSH and preview execution access while retaining /workspace. Wait for observed execution cleanup before restarting. Restart creates a fresh execution, runtime credentials and host key; obtain new SSH access and explicitly select the new preview execution.

Execution lifetime is at most eight hours and idle timeout at most one hour. Authenticated SSH sessions and interactive input count as activity; health polling and application output do not keep the Environment alive. Idle expiry retains source. A long control-plane outage can also fence execution; restart/select restores access after cleanup.

Commit and push source regularly. Stopped Environments retain their workspace slot. deleteEnvironment explicitly erases workspace data and frees the slot after verified cleanup; it is not a stop command. Capacity is operator-configured and bounded. Unattended workspace backup scheduling, arbitrary IDE/SFTP support and direct physical-device acceptance are outside the tested terminal-first release.

## Common errors and recovery

Missing capability or an empty peer list: identify the missing scope, configured service or device mapping and ask its responsible operator; do not substitute administrator credentials. Workspace capacity unavailable: stop retains its slot; delete only disposable work you intend to erase, or have the operator prepare approved capacity.

Stale ETag: reread the resource and reconsider the intended change. An Operation still pending or an uncertain create: poll/observe the original intent and target, preserving its Idempotency-Key; do not create a duplicate. Failed startup: inspect public Operation/execution errors and verify the image command, UID, readiness, mounts and bindings before retrying a repaired execution.

SSH lease too short: refresh the OAuth token before issuing new access, then honor the returned expires_at. This does not renew existing sessions. Stale SSH host key or unavailable preview after restart: fetch the new execution, issue new access, use its known-hosts record and select that exact ready execution with a current Route ETag.

Dependency download denied: prepare dependencies externally in the image or request a concrete supported package profile; do not assume the OpenRouter profile admits registries. Wrong-Component database/Secret/battery binding: provision the intended development or release resource separately. resource_in_use during cleanup: observe execution cleanup and retire dependencies through their public operations before deleting catalog parents.

## 7. Release the tested source

Commit the tested workspace source and transfer that exact commit or Git bundle to an external builder. Push through a scoped native Git credential. Build a release image containing that source and publish it into the release Component's repository; resolve its immutable digest.

Use createDeployment with explicit release database, Secret and battery bindings. Wait for readiness, select the release Route and run the same functional checks. The editable workspace itself is not a release artifact.

Revoke temporary publication, SSH and preview credentials after use. Stop the development Environment when finished; delete it only when the user intends to erase the workspace. Report actual test/release results and remaining limitations. Do not claim provider, device or IDE acceptance from synthetic tests.

## 8. Verified worked example

The Markdown guide linked above includes the complete verified Python/PostgreSQL source, exact public calls and ordering, native publication and SSH commands, operation polling, failure recovery and cleanup. It records the actual tested commit, immutable release and explicit operator handoffs; no access to the platform repository is required.

## Example createEnvironment body

Use the development Component as parent_id. This body assumes the verified worked-example image and prepared resources.

```json
{
  "command": [
    "/bin/sh",
    "/opt/app/start.sh"
  ],
  "port": 8080,
  "image": "botfolio.com/core/REPOSITORY_ID@sha256:DIGEST",
  "artifact_binding": {
    "repository_id": "REPOSITORY_ID"
  },
  "cpu_millis": 250,
  "database_binding": {
    "database_id": "DEVELOPMENT_DATABASE_ID"
  },
  "development": {
    "idle_timeout_seconds": 3600,
    "workspace_mib": 1024
  },
  "memory_mib": 256,
  "network": "database",
  "private_access": {
    "protocol": "ssh",
    "transport": "headscale"
  },
  "readiness_path": "/health",
  "scratch_mib": 32,
  "startup_timeout_seconds": 120,
  "timeout_seconds": 7200
}
```

## Verified worked example

Save each file block below under its named relative path in a new directory. The recipe, exact tested source and sanitized receipt are all included; no platform repository access is needed.

# A public Newday SSH-to-immutable-release example

This directory is self-contained: `run.sh`, the public API helpers beside it, and `source/` reproduce a small PostgreSQL-backed HTTP App through development, authenticated preview, SSH edit, retained restart, native Git export, immutable release and disposal of the isolated fixture. `source/` is the exact final tested commit tree, including the corrected `COPY --chown=10000:10000` Dockerfile and `fresh-public-v2` message. `receipt.json` and `source-sha256.json` identify the actual acceptance run. The executable recipe incorporates the actor's fixes; it was syntax-checked after assembly, not replayed as another live acceptance.

The actual run used explicitly selected **gpt-6-astra**, with no fallback. It stayed within a public-documentation/API instruction boundary; this was not an OS sandbox. The run needed an operator-supplied connecting device and one platform SSH host-key encoding repair. See `friction.md` for the full actor mistakes, confirmed failures and explicit handoffs. Success does not mean the initial platform supported an unaided journey.

## Prerequisites and custody

Start at https://botfolio.com/agent-start and its Markdown link. The canonical operations are in https://botfolio.com/v1/openapi. Bring an admitted ordinary OAuth client/grant with the operation scopes, the ordinary `newday` CLI, shell/Python 3/OpenSSH/Git/Docker, and an external OCI builder. The operator must prepare workspace capacity and runtime/database/artifact services and enroll/map a connecting Headscale device. `listEnvironmentAccessPeers` discovers mappings; it does not enroll anything.

The sample needs no provider key, Secret, provider egress or package egress profile. It installs Debian Python/psycopg2/Git/OpenSSH in the external build. The running App uses only `network=database`. The initial Dockerfile base is digest-pinned, but Debian package mirrors remain build-time dependencies: this proves exact source and deployed image identity, not bit-for-bit future rebuilds from mutable mirrors.

Set configurable client locations; no retained account paths or identities are bundled:

```sh
export NEWDAY_CLI=/absolute/path/to/newday
export NEWDAY_CREDENTIALS=/absolute/path/to/private-client-credentials.json
export RUN_DIR=/absolute/path/to/a-new-disposable-run-directory
# If multiple authorized devices exist, select one explicitly:
export NEWDAY_PEER_ID=YOUR_PUBLICLY_LISTED_PEER_ID
./run.sh
```

The installed CLI uses its ordinary client config and performs normal token refresh. Do not revoke the retained login grant. Access lease expiry is independently capped by token lifetime; refresh a nearly expired token before issuing new access and honor the returned expiry.

By default SSH connects to the actual returned endpoint from the mapped device, with strict known-host checking and the returned hostname as HostKeyAlias. The actual acceptance instead used an explicitly supplied loopback adapter standing in for the physical device. Only when an operator supplies that same prerequisite, `NEWDAY_DEVICE_ADAPTER=1` writes the returned endpoint to `RUN_DIR/peer-target` and connects 127.0.0.1:2222. The script does not install an adapter or create peer authority. This is not direct physical-device acceptance.

Run from a new directory. The recipe creates and deletes **only its new disposable Space and descendants**. Its work directory and raw credentials/intents/responses remain private (0700 directory, 0600 files). Bearers never appear in URLs, Git remotes, source or image layers. Native Git uses a private askpass helper, OCI uses private Docker config, and preview sends Authorization headers. The persistent workspace excludes execution credentials; the image's optional runtime-environment adapter stores PG settings only in volatile `/tmp`.

## Exact operation and command order

`run.sh` provides the complete command order. Request bodies and headers are executable literals in the named helpers; none depend on private files from the actual run:

1. `rest.py` reads capabilities, existing Spaces and each Space's Apps, and mapped peers. It creates a unique Space, a release App, a development App with immutable `development_of`, then distinct Components, native repositories and databases. Repository/database Operations are polled to `state=succeeded`.
2. The external Docker build prepares UID/GID 10000 `dev`, its shell, OpenSSH, Python and PostgreSQL driver. `publish.py` issues a same-repository native credential, pushes to its returned OCI namespace, resolves the pushed digest with `resolveRepositoryManifest`, and clones the native Git repository. A new feature branch preserves the initial `main` commit. `revoke-publication.py` retires the temporary credential.
3. `start-dev.py` reads the dev database runtime role, issues an unclaimed migration credential, and creates a separate migration Job using that credential ID and exact same-Component database/artifact bindings. `migrate.py` creates one synthetic table/row and explicitly grants SELECT to the runtime role. Runtime compute receives database_id only, never migration authority.
4. That helper creates/starts a development Environment with CPU 250m, memory 256MiB, scratch 32MiB, database-only network, port 8080, `/health`, startup timeout 120s, 7200s execution limit, retained 1024MiB workspace, 3600s idle limit and Headscale SSH. The image starts Core's supplied sshd config plus the server and preserves the prepared workspace root permissions.
5. `access.py` rereads the Environment immediately before its ETag-checked access mutation, using the exact execution/peer/public-key/TTL. It polls access and writes its returned host-key record. `preview.py` creates an owner-only Route, explicitly selects the ready execution and issues a short-lived preview credential.
6. `ssh-edit.py` tests the initial HTTP/database result over SSH, transfers this example's Git/source via SSH stdin, edits message.txt in `/workspace`, runs the same tests, and commits that tested tree there. `reselect.py` verifies authenticated preview shows the edited result without rebuilding the development image or changing its execution.
7. `stop.py` waits for stop and execution cleanup=complete; the workspace remains retained. `restart.py` creates a fresh execution, `access.py` obtains new access/known-hosts, and `reselect.py` explicitly selects that execution. SSH verifies the exact commit is retained, the worktree is clean, and the edited database-backed response passes.
8. `export-release.py` exports that exact commit as a bundle over SSH, checks it out externally, creates a clean `git archive` build context, and builds the release. `push-tested.py` pushes only a feature branch through a new scoped credential, verifies the native main branch is unchanged, then revokes the credential. The release publishes to the separate release repository and resolves its immutable digest.
9. `start-release.py` runs the same corrected migration against the separate release database/role, then creates a Deployment using that Component's repository/database bindings. `preview.py` selects a separate owner-only release Route and runs the **same test.py checks** for health, exact edited message and database value.
10. `stop.py` preserves the exported workspace until final disposal. `cleanup.py` revokes preview/access leases and observes cleanup, retires Routes, Deployment, Environment/workspace, Jobs, databases/repositories, then deletes catalog parents with fresh ETags. It records exact IDs and observed deletion/absence privately; it never targets pre-existing resources or pool infrastructure.

The public CLI argument envelope is also explicit. For example:

```json
{"parent_id":"SPACE_ID","body":{"name":"Release","slug":"release"},"Idempotency-Key":"PERSISTED_UNIQUE_KEY"}
```

```sh
newday call createApp --args @request.json
```

Header keys are exactly `Idempotency-Key` and `If-Match`. For ETags, JSON encodes the quoted version, for example `"If-Match":"\"3\""`. The REST helper uses internal Python `idempotency_key`/`if_match` arguments and maps those to canonical HTTP headers; those internal names are not CLI argument names.

## Durable recovery

Every REST call records its intent before the request and stores response/headers privately. Mutations retain the original Idempotency-Key and are refused if their intent filename already exists. Polling stops after 30 seconds without a change in state/phase/progress and has a separate 300-second absolute breaker; identical observations reuse one private read log. Adjust these limits only for a justified operation using NEWDAY_OPERATION_IDLE_SECONDS and NEWDAY_OPERATION_DEADLINE_SECONDS. A stalled observer leaves the original Operation intact for investigation. The shell fails fast and refuses to reuse an existing run directory. Do **not** rerun the whole script after a partial failure.

Inspect the saved intent and response privately. If a create returned an Operation, poll **that Operation ID**, then get its exact target. If the response was lost, observe the original intent/target; never invent a new create. Where the service supports replay, repeat only the exact original method/path/body/Idempotency-Key to recover its durable result; one-time secret responses cannot be recovered by replay. Revoke an unclaimed native credential through its returned ID before deliberately replacing it.

A confirmed HTTP 412 means the mutation was rejected. Reread that resource, reconsider the same intended action, and use the returned current ETag with a new labeled intent so the rejected request stays recorded. A failed startup requires public Operation/execution inspection and a repaired source/image before a new execution; cleanup is observed separately. Missing capacity, peer mapping, configured service or unsupported image contract belongs to its operator, with the exact public failure. Do not borrow credentials or bypass the boundary.

To make a single public recovery read from the run directory:

```sh
python3 - <<'PY'
from rest import call
op = call('getOperation', {'id': 'ORIGINAL_OPERATION_ID'}, 'recovery-observe')
print(op['state'], op['phase'])
PY
```

`mutation-inventory.json` is the sanitized ordered actual-run mutation history, including failures and their original operation IDs. It is evidence, not a replay script. Exact commits/digests and all old/new access IDs/fingerprints are in `receipt.json`; source hashes are in `source-sha256.json`.

This is a terminal-first synthetic example, not a production template, arbitrary IDE/SFTP acceptance, real provider acceptance or a physical connecting-device test.

The exact historical source also contains the native generated README and a non-secret `sshd.pid` file inadvertently staged during SSH. They are preserved and hashed so the package remains the actual tested tree. The helper recipe is illustrative; a production scaffold should exclude runtime PID files from source control.


## Complete example files

### File: README.md

````markdown
# A public Newday SSH-to-immutable-release example

This directory is self-contained: `run.sh`, the public API helpers beside it, and `source/` reproduce a small PostgreSQL-backed HTTP App through development, authenticated preview, SSH edit, retained restart, native Git export, immutable release and disposal of the isolated fixture. `source/` is the exact final tested commit tree, including the corrected `COPY --chown=10000:10000` Dockerfile and `fresh-public-v2` message. `receipt.json` and `source-sha256.json` identify the actual acceptance run. The executable recipe incorporates the actor's fixes; it was syntax-checked after assembly, not replayed as another live acceptance.

The actual run used explicitly selected **gpt-6-astra**, with no fallback. It stayed within a public-documentation/API instruction boundary; this was not an OS sandbox. The run needed an operator-supplied connecting device and one platform SSH host-key encoding repair. See `friction.md` for the full actor mistakes, confirmed failures and explicit handoffs. Success does not mean the initial platform supported an unaided journey.

## Prerequisites and custody

Start at https://botfolio.com/agent-start and its Markdown link. The canonical operations are in https://botfolio.com/v1/openapi. Bring an admitted ordinary OAuth client/grant with the operation scopes, the ordinary `newday` CLI, shell/Python 3/OpenSSH/Git/Docker, and an external OCI builder. The operator must prepare workspace capacity and runtime/database/artifact services and enroll/map a connecting Headscale device. `listEnvironmentAccessPeers` discovers mappings; it does not enroll anything.

The sample needs no provider key, Secret, provider egress or package egress profile. It installs Debian Python/psycopg2/Git/OpenSSH in the external build. The running App uses only `network=database`. The initial Dockerfile base is digest-pinned, but Debian package mirrors remain build-time dependencies: this proves exact source and deployed image identity, not bit-for-bit future rebuilds from mutable mirrors.

Set configurable client locations; no retained account paths or identities are bundled:

```sh
export NEWDAY_CLI=/absolute/path/to/newday
export NEWDAY_CREDENTIALS=/absolute/path/to/private-client-credentials.json
export RUN_DIR=/absolute/path/to/a-new-disposable-run-directory
# If multiple authorized devices exist, select one explicitly:
export NEWDAY_PEER_ID=YOUR_PUBLICLY_LISTED_PEER_ID
./run.sh
```

The installed CLI uses its ordinary client config and performs normal token refresh. Do not revoke the retained login grant. Access lease expiry is independently capped by token lifetime; refresh a nearly expired token before issuing new access and honor the returned expiry.

By default SSH connects to the actual returned endpoint from the mapped device, with strict known-host checking and the returned hostname as HostKeyAlias. The actual acceptance instead used an explicitly supplied loopback adapter standing in for the physical device. Only when an operator supplies that same prerequisite, `NEWDAY_DEVICE_ADAPTER=1` writes the returned endpoint to `RUN_DIR/peer-target` and connects 127.0.0.1:2222. The script does not install an adapter or create peer authority. This is not direct physical-device acceptance.

Run from a new directory. The recipe creates and deletes **only its new disposable Space and descendants**. Its work directory and raw credentials/intents/responses remain private (0700 directory, 0600 files). Bearers never appear in URLs, Git remotes, source or image layers. Native Git uses a private askpass helper, OCI uses private Docker config, and preview sends Authorization headers. The persistent workspace excludes execution credentials; the image's optional runtime-environment adapter stores PG settings only in volatile `/tmp`.

## Exact operation and command order

`run.sh` provides the complete command order. Request bodies and headers are executable literals in the named helpers; none depend on private files from the actual run:

1. `rest.py` reads capabilities, existing Spaces and each Space's Apps, and mapped peers. It creates a unique Space, a release App, a development App with immutable `development_of`, then distinct Components, native repositories and databases. Repository/database Operations are polled to `state=succeeded`.
2. The external Docker build prepares UID/GID 10000 `dev`, its shell, OpenSSH, Python and PostgreSQL driver. `publish.py` issues a same-repository native credential, pushes to its returned OCI namespace, resolves the pushed digest with `resolveRepositoryManifest`, and clones the native Git repository. A new feature branch preserves the initial `main` commit. `revoke-publication.py` retires the temporary credential.
3. `start-dev.py` reads the dev database runtime role, issues an unclaimed migration credential, and creates a separate migration Job using that credential ID and exact same-Component database/artifact bindings. `migrate.py` creates one synthetic table/row and explicitly grants SELECT to the runtime role. Runtime compute receives database_id only, never migration authority.
4. That helper creates/starts a development Environment with CPU 250m, memory 256MiB, scratch 32MiB, database-only network, port 8080, `/health`, startup timeout 120s, 7200s execution limit, retained 1024MiB workspace, 3600s idle limit and Headscale SSH. The image starts Core's supplied sshd config plus the server and preserves the prepared workspace root permissions.
5. `access.py` rereads the Environment immediately before its ETag-checked access mutation, using the exact execution/peer/public-key/TTL. It polls access and writes its returned host-key record. `preview.py` creates an owner-only Route, explicitly selects the ready execution and issues a short-lived preview credential.
6. `ssh-edit.py` tests the initial HTTP/database result over SSH, transfers this example's Git/source via SSH stdin, edits message.txt in `/workspace`, runs the same tests, and commits that tested tree there. `reselect.py` verifies authenticated preview shows the edited result without rebuilding the development image or changing its execution.
7. `stop.py` waits for stop and execution cleanup=complete; the workspace remains retained. `restart.py` creates a fresh execution, `access.py` obtains new access/known-hosts, and `reselect.py` explicitly selects that execution. SSH verifies the exact commit is retained, the worktree is clean, and the edited database-backed response passes.
8. `export-release.py` exports that exact commit as a bundle over SSH, checks it out externally, creates a clean `git archive` build context, and builds the release. `push-tested.py` pushes only a feature branch through a new scoped credential, verifies the native main branch is unchanged, then revokes the credential. The release publishes to the separate release repository and resolves its immutable digest.
9. `start-release.py` runs the same corrected migration against the separate release database/role, then creates a Deployment using that Component's repository/database bindings. `preview.py` selects a separate owner-only release Route and runs the **same test.py checks** for health, exact edited message and database value.
10. `stop.py` preserves the exported workspace until final disposal. `cleanup.py` revokes preview/access leases and observes cleanup, retires Routes, Deployment, Environment/workspace, Jobs, databases/repositories, then deletes catalog parents with fresh ETags. It records exact IDs and observed deletion/absence privately; it never targets pre-existing resources or pool infrastructure.

The public CLI argument envelope is also explicit. For example:

```json
{"parent_id":"SPACE_ID","body":{"name":"Release","slug":"release"},"Idempotency-Key":"PERSISTED_UNIQUE_KEY"}
```

```sh
newday call createApp --args @request.json
```

Header keys are exactly `Idempotency-Key` and `If-Match`. For ETags, JSON encodes the quoted version, for example `"If-Match":"\"3\""`. The REST helper uses internal Python `idempotency_key`/`if_match` arguments and maps those to canonical HTTP headers; those internal names are not CLI argument names.

## Durable recovery

Every REST call records its intent before the request and stores response/headers privately. Mutations retain the original Idempotency-Key and are refused if their intent filename already exists. Polling stops after 30 seconds without a change in state/phase/progress and has a separate 300-second absolute breaker; identical observations reuse one private read log. Adjust these limits only for a justified operation using NEWDAY_OPERATION_IDLE_SECONDS and NEWDAY_OPERATION_DEADLINE_SECONDS. A stalled observer leaves the original Operation intact for investigation. The shell fails fast and refuses to reuse an existing run directory. Do **not** rerun the whole script after a partial failure.

Inspect the saved intent and response privately. If a create returned an Operation, poll **that Operation ID**, then get its exact target. If the response was lost, observe the original intent/target; never invent a new create. Where the service supports replay, repeat only the exact original method/path/body/Idempotency-Key to recover its durable result; one-time secret responses cannot be recovered by replay. Revoke an unclaimed native credential through its returned ID before deliberately replacing it.

A confirmed HTTP 412 means the mutation was rejected. Reread that resource, reconsider the same intended action, and use the returned current ETag with a new labeled intent so the rejected request stays recorded. A failed startup requires public Operation/execution inspection and a repaired source/image before a new execution; cleanup is observed separately. Missing capacity, peer mapping, configured service or unsupported image contract belongs to its operator, with the exact public failure. Do not borrow credentials or bypass the boundary.

To make a single public recovery read from the run directory:

```sh
python3 - <<'PY'
from rest import call
op = call('getOperation', {'id': 'ORIGINAL_OPERATION_ID'}, 'recovery-observe')
print(op['state'], op['phase'])
PY
```

`mutation-inventory.json` is the sanitized ordered actual-run mutation history, including failures and their original operation IDs. It is evidence, not a replay script. Exact commits/digests and all old/new access IDs/fingerprints are in `receipt.json`; source hashes are in `source-sha256.json`.

This is a terminal-first synthetic example, not a production template, arbitrary IDE/SFTP acceptance, real provider acceptance or a physical connecting-device test.

The exact historical source also contains the native generated README and a non-secret `sshd.pid` file inadvertently staged during SSH. They are preserved and hashed so the package remains the actual tested tree. The helper recipe is illustrative; a production scaffold should exclude runtime PID files from source control.
````

### File: access.py

````python
from rest import *
label=os.environ.get('ACCESS_LABEL','first')
eid=json.load(open('dev-environment.response.private.json'))['id']; e=call('getEnvironment',{'id':eid},label+'-environment')
peers=call('listEnvironmentAccessPeers',{},label+'-peers')
peer_id=os.environ.get('NEWDAY_PEER_ID')
if not peer_id:
 if len(peers['items'])!=1: raise RuntimeError('Select an authorized mapping with NEWDAY_PEER_ID; no automatic enrollment')
 peer_id=peers['items'][0]['id']
e=call('getEnvironment',{'id':eid},label+'-environment-current')
o=poll(mutate('createEnvironmentAccess',{'id':eid,'if_match':'"'+str(e['version'])+'"','body':{'execution_id':e['execution']['id'],'peer_id':peer_id,'ssh_public_key':(ROOT/'ssh-key.private.pub').read_text().strip(),'ttl_seconds':900}},label+'-access'))
a=call('getEnvironmentAccess',{'id':o['target']['id']},label+'-access-ready'); ep=a['endpoint']
connect_host=ep['host'];connect_port=ep['port']
if os.environ.get('NEWDAY_DEVICE_ADAPTER')=='1':
 (ROOT/'peer-target').write_text(ep['host']+':'+str(ep['port']))
 connect_host='127.0.0.1';connect_port=2222
(ROOT/(label+'-known-hosts')).write_text(ep['known_hosts']+'\n')
(ROOT/'ssh-config.private').write_text('Host fresh\n HostName '+connect_host+'\n Port '+str(connect_port)+'\n User dev\n IdentityFile '+str(ROOT/'ssh-key.private')+'\n IdentitiesOnly yes\n StrictHostKeyChecking yes\n HostKeyAlias '+ep['host']+'\n UserKnownHostsFile '+str(ROOT/(label+'-known-hosts'))+'\n ConnectTimeout 15\n')
print('Access ready; lease expires',a['expires_at'])
````

### File: actor.py

````python
import os,pathlib
ROOT=pathlib.Path.cwd()
os.umask(0o077)
if not os.environ.get('NEWDAY_CREDENTIALS'): raise RuntimeError('Set NEWDAY_CREDENTIALS to ordinary private client storage')
````

### File: cleanup.py

````python
from rest import *
resources={}
for p in sorted(ROOT.glob('*.intent.private.json')):
 try:
  intent=json.load(open(p));op=intent['operation']
  if not op.startswith('create'): continue
  r=json.load(open(str(p).replace('.intent.private.json','.response.private.json')))
  if 'target' in r: rid=r['target']['id']
  else:rid=r.get('id')
  if rid:resources.setdefault(op,{})[rid]=p.name
 except (ValueError,FileNotFoundError):pass
(ROOT/'cleanup-inventory.private.json').write_text(json.dumps(resources,indent=2))
receipt=[]
def record(kind,rid,status):
 receipt.append({'kind':kind,'id':rid,'status':status});(ROOT/'cleanup-receipt.private.json').write_text(json.dumps(receipt,indent=2))
def get(kind,rid,label):return call('get'+kind,{'id':rid},label)
def retire(kind,rid):
 label='cleanup-'+kind+'-'+rid
 r=get(kind,rid,label+'-before')
 if r.get('state')=='deleted':record(kind,rid,'already deleted');return
 args={'id':rid}
 if 'version' in r:args['if_match']='"'+str(r['version'])+'"'
 result=mutate('delete'+kind,args,label+'-delete')
 if 'target' in result:poll(result)
 for i in range(150):
  try:r=get(kind,rid,label+'-after-'+str(i))
  except RuntimeError as e:
   if 'HTTP 404 ' in str(e):record(kind,rid,'HTTP 404 observed');print(kind,'absent');return
   raise
  if r.get('state')=='deleted':
   execution=r.get('execution') or {}
   if not execution or execution.get('cleanup')=='complete':record(kind,rid,'deleted; cleanup observed');print(kind,'deleted');return
  time.sleep(2)
 raise RuntimeError(kind+' deletion not observed')
# Credential histories remain only where API deliberately retains revoked/expired state.
for op,items in resources.items():
 if op!='createRouteCredential':continue
 for rid,label in items.items():
  r=json.load(open(label.replace('.intent.private.json','.response.private.json')))
  call('revokeRouteCredential',{'id':r['route_id'],'credential_id':rid},'cleanup-preview-'+rid);record('RouteCredential',rid,'revoked')
for rid in resources.get('createEnvironmentAccess',{}):
 r=call('getEnvironmentAccess',{'id':rid},'cleanup-access-before-'+rid)
 if r['state'] not in ['revoked','expired']:
  o=mutate('revokeEnvironmentAccess',{'id':rid,'if_match':'"'+str(r['version'])+'"'},'cleanup-access-revoke-'+rid);poll(o)
 for i in range(100):
  r=call('getEnvironmentAccess',{'id':rid},'cleanup-access-after-'+rid+'-'+str(i))
  if r['state'] in ['revoked','expired'] and not r['cleanup_pending']:record('EnvironmentAccess',rid,r['state']+'; cleanup observed');break
  time.sleep(2)
 else:raise RuntimeError('access cleanup not observed')
for kind in ['Route','Deployment','Environment','Job','Database','Repository','Component','App','Space']:
 for rid in resources.get('create'+kind,{}):retire(kind,rid)
print('All fixture catalog/resources retired with public observations')
````

### File: export-release.py

````python
from rest import *
commit=(ROOT/'tested-commit.txt').read_text().strip()
def run(args,label,**kw):
 with open(label+'.private.log','wb') as f:subprocess.run(args,check=True,stdout=f,stderr=f,**kw)
r=subprocess.run(['ssh','-F','ssh-config.private','fresh','cd /workspace && test "$(git rev-parse HEAD)" = '+commit+' && test -z "$(git status --porcelain)" && git bundle create /tmp/tested.bundle HEAD && cat /tmp/tested.bundle'],capture_output=True)
(ROOT/'bundle-export.stderr.private').write_bytes(r.stderr)
if r.returncode:raise RuntimeError('SSH bundle export failed')
(ROOT/'tested.bundle').write_bytes(r.stdout)
run(['git','init','tested-git'],'tested-init')
run(['git','-C','tested-git','fetch','../tested.bundle','HEAD'],'tested-fetch')
run(['git','-C','tested-git','checkout','--detach','FETCH_HEAD'],'tested-checkout')
assert subprocess.check_output(['git','-C','tested-git','rev-parse','HEAD'],text=True).strip()==commit
(ROOT/'release-context').mkdir()
p=subprocess.run(['git','-C','tested-git','archive',commit],capture_output=True,check=True)
subprocess.run(['tar','-xf','-','-C','release-context'],input=p.stdout,check=True)
run(['docker','build','-t','fresh-public-release:example','release-context'],'release-build')
print('External release image built from exact tested Git commit',commit)
````

### File: friction.md

````markdown
# Fresh public developer journey

Model: gpt-6-astra, explicitly selected; no fallback.

Instruction boundary: public agent-start, public API/discovery, ordinary CLI credential/config files, own source and public resources only. No platform repository, handoff, memory, prior examples/proofs or operator internals were read. This is an instruction boundary, not an OS sandbox.

Operator handoff: operator supplied ordinary CLI + existing client OAuth grant and temporarily mapped Headscale connecting device. A loopback transport adapter forwards 127.0.0.1:2222 to the public access endpoint selected by the agent through peer-target. It grants no App/access authority. This is not direct physical-device acceptance.

Observed friction and own corrections:

1. listApps requires a Space parent_id; the first call omitted it and failed locally. Enumerated existing Spaces then listed each one's Apps before mutation.
2. agent-start says newday call --args but does not specify header/body argument mapping. body plus idempotency_key failed locally with Unknown operation arguments. Switched to public OpenAPI-driven REST, obtaining only the ordinary CLI token, preserving exact HTTP intents before sending.
3. Own first Operation poll looked at status instead of the documented state. Interrupted the observer and resumed the original Operation; no repeat creates.
4. First SSH access request got HTTP 412 stale ETag. Reread the Environment immediately before a new access request after the confirmed rejection.
5. First SSH connection through the supplied adapter failed: channel 0: open failed: connect failed: target unavailable. Public Environment/execution and access remained ready without errors. Reported exact IDs to the operator for prerequisite classification; did not inspect infrastructure.
6. Authenticated preview /health passed, but database query returned the app's sanitized 503. Own initial migration omitted an explicit runtime SELECT grant. Corrected via separate short-lived migration credential and Job, using the public database runtime_role.

No provider/package egress profile was added. All image dependencies were prepared in the authorized external Docker builder. The development runtime remained network=database. The app is intentionally tiny: a DB-backed JSON GET response and text-file message reload, not a production template.

7. Operator diagnosis of SSH prerequisite: this image's Debian OpenSSH rejected the Core-mounted Ed25519 host key as invalid format (PKCS#8 representation). Earlier platform image accepted that representation. This was a Core image-contract portability defect. Operator proposed repairing target host-key encoding to standard OpenSSH without changing authority, followed by a platform release. This is an explicit operator inspection/repair dependency and means the journey was not independently self-service on the initial platform version.

The external Dockerfile base was pinned to the exact already-built Debian image digest before the SSH-tested commit, so release source records that selected base. Debian package repositories remain build-time dependencies; an identical source tree and immutable deployed digest are proven, not bit-for-bit reconstruction from future mutable package mirrors.

8. Operator reported repaired Core release ready (generation 36) after its own tests and live verification. Actor resumed only through ordinary public lifecycle. During the stop, the old access was publicly observed revoked with cleanup_pending=false; the old selected preview returned HTTP 503. The original workspace remained retained. Operator also updated the public guide to document the exact CLI header/body envelope and Operation.state; initial friction remains part of this run's history.

9. The first exact-commit release candidate reached a failed migration Job: `/opt/app/migrate.py` was permission denied. Own external helper extracted Git under private umask 077, leaving mode-0600 files, while plain Docker COPY made them root-owned and the image ran as dev. The actor corrected `COPY --chown=10000:10000` inside SSH, reran app tests, and made a new tested commit before rebuilding. No operator help was used for this packaging error. The previous commit/digest/failed Job are retained as historical evidence, not successful release evidence. A mistakenly non-fail-fast shell sequence also created a release Route before noticing no Deployment existed; that exact Route is reused. A confirmed HTTP 412 on final-stop did not stop the Environment; it was reread for the later stop.

10. Final artifact audit found a native generated README and incidental non-secret `sshd.pid` with value 4 in the exact tested tree: `git add .` captured Core's relative PID file during SSH. They are retained in the packaged exact source and included in its byte-for-byte hash check. This is a source hygiene limitation, not a hidden edit to the accepted commit. A production scaffold should direct or exclude such runtime files.

Public fixture cleanup completed, including the failed release candidate's Job. The operator separately reported 17 public 404 checks, absent compute Pods/namespaces, all four access cleanups, zero workspace leases, four empty prepared workspaces with preserved PVC identity, and retired temporary peer authority. The actor did not inspect operator infrastructure.

11. Logging hygiene lapse: initial discovery/debug tool output echoed non-secret public resource/Operation metadata, including the existing Space's owner issuer/subject, despite the task's private-response logging instruction. No bearer, password or private key was printed. Subsequent receipt/package extraction excludes that retained identity and all raw responses; actual temporary credential values were checked absent from the publication package. This lapse is recorded rather than claiming perfect adherence to the logging instruction.
````

### File: mutation-inventory.json

````json
[
  {
    "operation": "createSpace",
    "method": "POST",
    "path": "/v1/spaces",
    "headers": {
      "Idempotency-Key": "c3b63cc2-b11c-4308-8f32-cd8d2a9ae725"
    },
    "body": {
      "name": "Fresh public actor 20260912",
      "slug": "fresh-actor-20260912-b8235d"
    },
    "response_summary": {
      "id": "781e78f6-1c66-4c0a-8a9e-757a17661e50"
    }
  },
  {
    "operation": "createApp",
    "method": "POST",
    "path": "/v1/spaces/781e78f6-1c66-4c0a-8a9e-757a17661e50/apps",
    "headers": {
      "Idempotency-Key": "e70ac7ed-9e95-4d14-8a85-f73e3ea1be70"
    },
    "body": {
      "name": "Release",
      "slug": "release"
    },
    "response_summary": {
      "id": "19ab08e1-5e7a-4d4f-ad73-98a72a69497d"
    }
  },
  {
    "operation": "createApp",
    "method": "POST",
    "path": "/v1/spaces/781e78f6-1c66-4c0a-8a9e-757a17661e50/apps",
    "headers": {
      "Idempotency-Key": "04d0f0d2-779d-458a-9d52-f90a50470dac"
    },
    "body": {
      "name": "Development",
      "slug": "development",
      "development_of": "19ab08e1-5e7a-4d4f-ad73-98a72a69497d"
    },
    "response_summary": {
      "id": "af3879ea-0d91-44b8-bd1d-d8076c90fa30"
    }
  },
  {
    "operation": "createComponent",
    "method": "POST",
    "path": "/v1/apps/19ab08e1-5e7a-4d4f-ad73-98a72a69497d/components",
    "headers": {
      "Idempotency-Key": "b43456bc-37bf-4ffe-9b02-cf6c47370b16"
    },
    "body": {
      "name": "Web",
      "slug": "web"
    },
    "response_summary": {
      "id": "42e75267-c6a7-49c4-aae1-4391d52093a5"
    }
  },
  {
    "operation": "createRepository",
    "method": "POST",
    "path": "/v1/components/42e75267-c6a7-49c4-aae1-4391d52093a5/repositories",
    "headers": {
      "Idempotency-Key": "b936960d-0dc0-4116-8fab-7e482ea01ab8"
    },
    "body": null,
    "response_summary": {
      "id": "e5a67458-ffad-4139-be8a-4e3bbe07de15",
      "state": "pending",
      "target": {
        "id": "ec3926c9-1a77-480e-b4ec-871e39091217",
        "kind": "repository"
      }
    }
  },
  {
    "operation": "createDatabase",
    "method": "POST",
    "path": "/v1/components/42e75267-c6a7-49c4-aae1-4391d52093a5/databases",
    "headers": {
      "Idempotency-Key": "a93f1ec2-b376-4fa0-b8cb-86b5fcba3986"
    },
    "body": null,
    "response_summary": {
      "id": "abe4ed87-7e96-4721-868a-ecec6dcb29ad",
      "state": "pending",
      "target": {
        "id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e",
        "kind": "database"
      }
    }
  },
  {
    "operation": "createComponent",
    "method": "POST",
    "path": "/v1/apps/af3879ea-0d91-44b8-bd1d-d8076c90fa30/components",
    "headers": {
      "Idempotency-Key": "3e1d961a-b076-43f2-b2f8-35c2f450ee39"
    },
    "body": {
      "name": "Web",
      "slug": "web"
    },
    "response_summary": {
      "id": "d6631179-1140-4e68-893e-7c7a54284acf"
    }
  },
  {
    "operation": "createRepository",
    "method": "POST",
    "path": "/v1/components/d6631179-1140-4e68-893e-7c7a54284acf/repositories",
    "headers": {
      "Idempotency-Key": "2442ad64-109d-420f-ad2f-78285140ab17"
    },
    "body": null,
    "response_summary": {
      "id": "e497d322-0f16-457f-85cb-90d8aa30f568",
      "state": "pending",
      "target": {
        "id": "d60ef1d3-e66c-4bba-a179-d46aef2bd21d",
        "kind": "repository"
      }
    }
  },
  {
    "operation": "createDatabase",
    "method": "POST",
    "path": "/v1/components/d6631179-1140-4e68-893e-7c7a54284acf/databases",
    "headers": {
      "Idempotency-Key": "fc8de468-24ee-4e7c-a5fb-7574767e53fa"
    },
    "body": null,
    "response_summary": {
      "id": "d6c1fde9-6710-472c-a28c-ceab42fab495",
      "state": "pending",
      "target": {
        "id": "b71017e7-b95c-4346-84ff-8ddc8305597b",
        "kind": "database"
      }
    }
  },
  {
    "operation": "issueRepositoryCredential",
    "method": "POST",
    "path": "/v1/repositories/d60ef1d3-e66c-4bba-a179-d46aef2bd21d/credentials",
    "headers": {
      "Idempotency-Key": "a9fe632e-6eb3-4392-8170-7a245db263a9"
    },
    "body": {
      "ttl_seconds": 900,
      "actions": [
        "git:read",
        "git:write",
        "oci:read",
        "oci:write"
      ]
    },
    "response_summary": {
      "id": "356f9ae3-52d0-451c-877f-b28afbcb6f1f"
    }
  },
  {
    "operation": "issueDatabaseCredential",
    "method": "POST",
    "path": "/v1/databases/b71017e7-b95c-4346-84ff-8ddc8305597b/credentials",
    "headers": {
      "Idempotency-Key": "32c7708f-06bf-4f1f-9b32-d90d6a59000a"
    },
    "body": {
      "role": "migration",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "8c4759be-fe01-4e9b-86e0-a233a9c79841",
      "state": "pending",
      "target": {
        "id": "b71017e7-b95c-4346-84ff-8ddc8305597b",
        "kind": "database"
      }
    }
  },
  {
    "operation": "createJob",
    "method": "POST",
    "path": "/v1/components/d6631179-1140-4e68-893e-7c7a54284acf/jobs",
    "headers": {
      "Idempotency-Key": "46f6cf12-bac8-4632-9ff9-34e5f02aa4dc"
    },
    "body": {
      "image": "botfolio.com/core/d60ef1d3-e66c-4bba-a179-d46aef2bd21d@sha256:4f7c49bad05d3fed78cc325aed66a4c929d5c8e705312452ccb30653d596191b",
      "command": [
        "python3",
        "/opt/app/migrate.py"
      ],
      "cpu_millis": 250,
      "memory_mib": 256,
      "scratch_mib": 32,
      "network": "database",
      "timeout_seconds": 120,
      "artifact_binding": {
        "repository_id": "d60ef1d3-e66c-4bba-a179-d46aef2bd21d"
      },
      "database_binding": {
        "database_id": "b71017e7-b95c-4346-84ff-8ddc8305597b",
        "credential_id": "e8836c5f-60e8-45a9-8f4e-1b92256ea08b"
      }
    },
    "response_summary": {
      "id": "9771584c-1189-4b22-bad0-40875eef4767",
      "state": "pending",
      "target": {
        "id": "766ab5d7-5fbd-43e0-be88-b4915a728ce8",
        "kind": "job"
      }
    }
  },
  {
    "operation": "createEnvironment",
    "method": "POST",
    "path": "/v1/components/d6631179-1140-4e68-893e-7c7a54284acf/environments",
    "headers": {
      "Idempotency-Key": "151ffac1-c090-400d-9791-0909f147be17"
    },
    "body": {
      "image": "botfolio.com/core/d60ef1d3-e66c-4bba-a179-d46aef2bd21d@sha256:4f7c49bad05d3fed78cc325aed66a4c929d5c8e705312452ccb30653d596191b",
      "command": [
        "/bin/sh",
        "/opt/app/start.sh"
      ],
      "cpu_millis": 250,
      "memory_mib": 256,
      "scratch_mib": 32,
      "network": "database",
      "timeout_seconds": 7200,
      "artifact_binding": {
        "repository_id": "d60ef1d3-e66c-4bba-a179-d46aef2bd21d"
      },
      "database_binding": {
        "database_id": "b71017e7-b95c-4346-84ff-8ddc8305597b"
      },
      "port": 8080,
      "readiness_path": "/health",
      "startup_timeout_seconds": 120,
      "private_access": {
        "transport": "headscale",
        "protocol": "ssh"
      },
      "development": {
        "workspace_mib": 1024,
        "idle_timeout_seconds": 3600
      }
    },
    "response_summary": {
      "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "state": "stopped"
    }
  },
  {
    "operation": "startEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/start",
    "headers": {
      "Idempotency-Key": "a64df624-c5fa-4fa2-89d5-3508a5a0bc11",
      "If-Match": "\"1\""
    },
    "body": null,
    "response_summary": {
      "id": "bbda11a9-04ff-4edf-b22e-f663bdccd412",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "createEnvironmentAccess",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/accesses",
    "headers": {
      "Idempotency-Key": "4a676a13-b472-4f90-918e-a82a65e65799",
      "If-Match": "\"42\""
    },
    "body": {
      "execution_id": "fa6f52d0-2b68-49df-9f3a-f199f6e1303d",
      "peer_id": "e35d21ab-1a73-494c-9b51-2b98c4ff1f0e",
      "ssh_public_key": "<ACTOR_GENERATED_ED25519_PUBLIC_KEY>",
      "ttl_seconds": 900
    },
    "response_summary": {
      "code": "precondition_failed",
      "status": 412
    }
  },
  {
    "operation": "createEnvironmentAccess",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/accesses",
    "headers": {
      "Idempotency-Key": "8aed9fae-cd55-474a-bfe8-1127657d2703",
      "If-Match": "\"48\""
    },
    "body": {
      "execution_id": "fa6f52d0-2b68-49df-9f3a-f199f6e1303d",
      "peer_id": "e35d21ab-1a73-494c-9b51-2b98c4ff1f0e",
      "ssh_public_key": "<ACTOR_GENERATED_ED25519_PUBLIC_KEY>",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "17caed1e-ccc5-41fd-a457-d549a5980132",
      "state": "pending",
      "target": {
        "id": "2f9921f4-204a-4818-a9e1-de7d6c90699b",
        "kind": "environment_access"
      }
    }
  },
  {
    "operation": "createRoute",
    "method": "POST",
    "path": "/v1/components/d6631179-1140-4e68-893e-7c7a54284acf/routes",
    "headers": {
      "Idempotency-Key": "58480d93-24e7-42f0-9978-088a126ca8ab"
    },
    "body": null,
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "active"
    }
  },
  {
    "operation": "selectRoute",
    "method": "PUT",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/selection",
    "headers": {
      "Idempotency-Key": "2c88803c-ab96-4b52-bc6e-b8f4955d863c",
      "If-Match": "\"1\""
    },
    "body": {
      "environment_id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "execution_id": "fa6f52d0-2b68-49df-9f3a-f199f6e1303d"
    },
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "active"
    }
  },
  {
    "operation": "createRouteCredential",
    "method": "POST",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials",
    "headers": {
      "Idempotency-Key": "fcac5e8d-5665-439b-9e1e-634970ea4c2b"
    },
    "body": {
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "a1ddc74c-461b-4754-8060-dd6992445237"
    }
  },
  {
    "operation": "issueDatabaseCredential",
    "method": "POST",
    "path": "/v1/databases/b71017e7-b95c-4346-84ff-8ddc8305597b/credentials",
    "headers": {
      "Idempotency-Key": "a732f66b-81f4-4547-aa2c-7b3fb9436583"
    },
    "body": {
      "role": "migration",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "42a2aea1-809d-4c72-8d82-de9f753fa429",
      "state": "pending",
      "target": {
        "id": "b71017e7-b95c-4346-84ff-8ddc8305597b",
        "kind": "database"
      }
    }
  },
  {
    "operation": "createJob",
    "method": "POST",
    "path": "/v1/components/d6631179-1140-4e68-893e-7c7a54284acf/jobs",
    "headers": {
      "Idempotency-Key": "b0915d4c-6624-4476-b90e-06cc211e7ca5"
    },
    "body": {
      "image": "botfolio.com/core/d60ef1d3-e66c-4bba-a179-d46aef2bd21d@sha256:4f7c49bad05d3fed78cc325aed66a4c929d5c8e705312452ccb30653d596191b",
      "command": [
        "python3",
        "-c",
        "import psycopg2; from psycopg2 import sql; db=psycopg2.connect(''); cur=db.cursor(); cur.execute(sql.SQL('GRANT SELECT ON public.fresh_note TO {}').format(sql.Identifier('ndc_runtime_b71017e7b95c434684ff8ddc8305597b'))); db.commit(); print('runtime SELECT granted')"
      ],
      "cpu_millis": 250,
      "memory_mib": 256,
      "scratch_mib": 32,
      "network": "database",
      "timeout_seconds": 120,
      "artifact_binding": {
        "repository_id": "d60ef1d3-e66c-4bba-a179-d46aef2bd21d"
      },
      "database_binding": {
        "database_id": "b71017e7-b95c-4346-84ff-8ddc8305597b",
        "credential_id": "8b08f2ce-33de-4954-af40-958f77adf9d1"
      }
    },
    "response_summary": {
      "id": "0ce758f6-8fad-40dc-b5c6-1f6ab948af4e",
      "state": "pending",
      "target": {
        "id": "e9cc1756-0cd3-472d-beed-5d49f2165f90",
        "kind": "job"
      }
    }
  },
  {
    "operation": "revokeRepositoryCredential",
    "method": "DELETE",
    "path": "/v1/repositories/d60ef1d3-e66c-4bba-a179-d46aef2bd21d/credentials/356f9ae3-52d0-451c-877f-b28afbcb6f1f",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "356f9ae3-52d0-451c-877f-b28afbcb6f1f"
    }
  },
  {
    "operation": "stopEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/stop",
    "headers": {
      "Idempotency-Key": "baa4b042-2e3e-4a3c-816e-ff5e3a109e75",
      "If-Match": "\"202\""
    },
    "body": null,
    "response_summary": {
      "id": "b2840dda-4829-4e77-8366-75b7d6f7f30a",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "startEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/start",
    "headers": {
      "Idempotency-Key": "edd050e0-3e95-4adc-8c17-e6798f9eae55",
      "If-Match": "\"206\""
    },
    "body": null,
    "response_summary": {
      "id": "19e43d03-f321-4886-8aa1-23f3fda45630",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "createEnvironmentAccess",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/accesses",
    "headers": {
      "Idempotency-Key": "099e0d5d-be1e-4480-9c24-b576fd1e103f",
      "If-Match": "\"234\""
    },
    "body": {
      "execution_id": "193ad5b8-c89f-438f-9cc7-10f6999f7a4d",
      "peer_id": "e35d21ab-1a73-494c-9b51-2b98c4ff1f0e",
      "ssh_public_key": "<ACTOR_GENERATED_ED25519_PUBLIC_KEY>",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "68787bb7-aa5a-4916-b585-a0c550ee68e3",
      "state": "pending",
      "target": {
        "id": "88eb3bb4-0862-40c9-a105-8f6e08578ad8",
        "kind": "environment_access"
      }
    }
  },
  {
    "operation": "selectRoute",
    "method": "PUT",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/selection",
    "headers": {
      "Idempotency-Key": "31659461-0ff0-42fe-8350-e63278550859",
      "If-Match": "\"2\""
    },
    "body": {
      "environment_id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "execution_id": "193ad5b8-c89f-438f-9cc7-10f6999f7a4d"
    },
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "active"
    }
  },
  {
    "operation": "createRouteCredential",
    "method": "POST",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials",
    "headers": {
      "Idempotency-Key": "7afb3a0b-72f2-4f1f-9d99-06356f559128"
    },
    "body": {
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "1031e776-6b9d-407a-b540-8be86679d7fb"
    }
  },
  {
    "operation": "selectRoute",
    "method": "PUT",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/selection",
    "headers": {
      "Idempotency-Key": "c088aadd-c88f-44c5-9da8-1203f838ce9b",
      "If-Match": "\"3\""
    },
    "body": {
      "environment_id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "execution_id": "193ad5b8-c89f-438f-9cc7-10f6999f7a4d"
    },
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "active"
    }
  },
  {
    "operation": "createRouteCredential",
    "method": "POST",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials",
    "headers": {
      "Idempotency-Key": "f6464805-02d3-42a4-9926-5242294b62a1"
    },
    "body": {
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "ca47fdb9-f1d8-43ec-b92b-c5d81bcbe39d"
    }
  },
  {
    "operation": "stopEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/stop",
    "headers": {
      "Idempotency-Key": "47a3bc10-a94f-40c5-9f20-8c04c298678b",
      "If-Match": "\"266\""
    },
    "body": null,
    "response_summary": {
      "id": "c4865d99-322c-4110-a5de-1d8eda709ed3",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "startEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/start",
    "headers": {
      "Idempotency-Key": "2b3dbcfd-ba64-4acf-99f3-57aa331235a9",
      "If-Match": "\"270\""
    },
    "body": null,
    "response_summary": {
      "id": "76ddd06e-d38a-4aa2-bb62-78f6997ca8cf",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "createEnvironmentAccess",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/accesses",
    "headers": {
      "Idempotency-Key": "503069c1-75b3-41b8-9ab3-c09022693ec4",
      "If-Match": "\"298\""
    },
    "body": {
      "execution_id": "661f4f29-ad84-47f4-9efe-a4f49dd8d105",
      "peer_id": "e35d21ab-1a73-494c-9b51-2b98c4ff1f0e",
      "ssh_public_key": "<ACTOR_GENERATED_ED25519_PUBLIC_KEY>",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "6b3320f2-00a5-4f59-9dc2-d61c14cecbb2",
      "state": "pending",
      "target": {
        "id": "d230f55e-a699-4f11-8b0d-ab7b4c4d8f8a",
        "kind": "environment_access"
      }
    }
  },
  {
    "operation": "selectRoute",
    "method": "PUT",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/selection",
    "headers": {
      "Idempotency-Key": "3b1fd14d-3bcb-4836-84d5-bf8a39e3b511",
      "If-Match": "\"4\""
    },
    "body": {
      "environment_id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "execution_id": "661f4f29-ad84-47f4-9efe-a4f49dd8d105"
    },
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "active"
    }
  },
  {
    "operation": "createRouteCredential",
    "method": "POST",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials",
    "headers": {
      "Idempotency-Key": "518730d0-1c72-4bf1-b1eb-cc6fa508a712"
    },
    "body": {
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "195766e3-dee6-413d-9aed-8fe74e19b875"
    }
  },
  {
    "operation": "issueRepositoryCredential",
    "method": "POST",
    "path": "/v1/repositories/d60ef1d3-e66c-4bba-a179-d46aef2bd21d/credentials",
    "headers": {
      "Idempotency-Key": "4a94f1b1-e19f-487a-9ac5-f6f5e6222673"
    },
    "body": {
      "ttl_seconds": 900,
      "actions": [
        "git:read",
        "git:write"
      ]
    },
    "response_summary": {
      "id": "df2ff204-adc9-48d4-bd07-2bcd84b4c14b"
    }
  },
  {
    "operation": "revokeRepositoryCredential",
    "method": "DELETE",
    "path": "/v1/repositories/d60ef1d3-e66c-4bba-a179-d46aef2bd21d/credentials/df2ff204-adc9-48d4-bd07-2bcd84b4c14b",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "df2ff204-adc9-48d4-bd07-2bcd84b4c14b"
    }
  },
  {
    "operation": "issueRepositoryCredential",
    "method": "POST",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials",
    "headers": {
      "Idempotency-Key": "0b28416e-3b48-4822-9290-d51fa7c8fc92"
    },
    "body": {
      "ttl_seconds": 900,
      "actions": [
        "git:read",
        "git:write",
        "oci:read",
        "oci:write"
      ]
    },
    "response_summary": {
      "id": "554909a6-67ae-4bdb-a490-23bfabd1bae1"
    }
  },
  {
    "operation": "issueRepositoryCredential",
    "method": "POST",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials",
    "headers": {
      "Idempotency-Key": "a997644d-ab8b-4f5f-ac20-568c24562faf"
    },
    "body": {
      "ttl_seconds": 900,
      "actions": [
        "git:read",
        "git:write"
      ]
    },
    "response_summary": {
      "id": "738a7661-d4b3-4688-b95b-530580f0ff80"
    }
  },
  {
    "operation": "revokeRepositoryCredential",
    "method": "DELETE",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials/738a7661-d4b3-4688-b95b-530580f0ff80",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "738a7661-d4b3-4688-b95b-530580f0ff80"
    }
  },
  {
    "operation": "issueDatabaseCredential",
    "method": "POST",
    "path": "/v1/databases/9ee528c1-a51b-4e79-a275-d97e2e8f107e/credentials",
    "headers": {
      "Idempotency-Key": "2454089e-8aa8-4672-bc3f-803ec505ddf4"
    },
    "body": {
      "role": "migration",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "33c7c5c7-7452-4a2f-ba74-14064616e958",
      "state": "pending",
      "target": {
        "id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e",
        "kind": "database"
      }
    }
  },
  {
    "operation": "createJob",
    "method": "POST",
    "path": "/v1/components/42e75267-c6a7-49c4-aae1-4391d52093a5/jobs",
    "headers": {
      "Idempotency-Key": "1789fe84-c0df-4087-857a-80dfd6826606"
    },
    "body": {
      "image": "botfolio.com/core/ec3926c9-1a77-480e-b4ec-871e39091217@sha256:f6b2b745b837342385fec591909163208e28aa4e71c8dbec03ebb309997e00da",
      "command": [
        "python3",
        "/opt/app/migrate.py",
        "ndc_runtime_9ee528c1a51b4e79a275d97e2e8f107e"
      ],
      "cpu_millis": 250,
      "memory_mib": 256,
      "scratch_mib": 32,
      "network": "database",
      "timeout_seconds": 120,
      "artifact_binding": {
        "repository_id": "ec3926c9-1a77-480e-b4ec-871e39091217"
      },
      "database_binding": {
        "database_id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e",
        "credential_id": "1b202411-5cb2-464b-a6ca-569d516e2f36"
      }
    },
    "response_summary": {
      "id": "0fb81ceb-63c8-47ea-aba8-04e50934b943",
      "state": "pending",
      "target": {
        "id": "8beb6335-71db-4518-ac76-7ff3b85e0a01",
        "kind": "job"
      }
    }
  },
  {
    "operation": "createRoute",
    "method": "POST",
    "path": "/v1/components/42e75267-c6a7-49c4-aae1-4391d52093a5/routes",
    "headers": {
      "Idempotency-Key": "d3b2ed8f-6510-4726-8de8-f1a0849b1d5d"
    },
    "body": null,
    "response_summary": {
      "id": "2b0fc4df-4e84-4a65-a429-1dabc69f0c11",
      "state": "active"
    }
  },
  {
    "operation": "revokeRepositoryCredential",
    "method": "DELETE",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials/554909a6-67ae-4bdb-a490-23bfabd1bae1",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "554909a6-67ae-4bdb-a490-23bfabd1bae1"
    }
  },
  {
    "operation": "stopEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/stop",
    "headers": {
      "Idempotency-Key": "17205cff-e3c5-47c7-9f05-f294b2671bb9",
      "If-Match": "\"349\""
    },
    "body": null,
    "response_summary": {
      "code": "precondition_failed",
      "status": 412
    }
  },
  {
    "operation": "selectRoute",
    "method": "PUT",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/selection",
    "headers": {
      "Idempotency-Key": "377192e8-51a7-4bee-a8fc-0d2a9d330ecb",
      "If-Match": "\"5\""
    },
    "body": {
      "environment_id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "execution_id": "661f4f29-ad84-47f4-9efe-a4f49dd8d105"
    },
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "active"
    }
  },
  {
    "operation": "createRouteCredential",
    "method": "POST",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials",
    "headers": {
      "Idempotency-Key": "bee076ed-09b9-4768-bcca-2a258f00eb11"
    },
    "body": {
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "182e8438-2d62-492c-a076-9560a8d8e152"
    }
  },
  {
    "operation": "stopEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/stop",
    "headers": {
      "Idempotency-Key": "f19c52fe-382f-48bd-962c-b1131199849c",
      "If-Match": "\"398\""
    },
    "body": null,
    "response_summary": {
      "id": "a981b277-f5db-4680-8bf3-7404a5f7483d",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "startEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/start",
    "headers": {
      "Idempotency-Key": "83d94b8b-ddd7-461b-aa2b-a7c1fbd3a226",
      "If-Match": "\"402\""
    },
    "body": null,
    "response_summary": {
      "id": "b12c50e1-2688-4b45-9692-001305d5518e",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "createEnvironmentAccess",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/accesses",
    "headers": {
      "Idempotency-Key": "61e84e55-fda8-4a0f-9835-d2a9cf2371de",
      "If-Match": "\"429\""
    },
    "body": {
      "execution_id": "233f4315-32bb-4551-a40b-efb132e494c1",
      "peer_id": "e35d21ab-1a73-494c-9b51-2b98c4ff1f0e",
      "ssh_public_key": "<ACTOR_GENERATED_ED25519_PUBLIC_KEY>",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "fed3c7a2-d47d-499b-a70c-967a94e5f0e4",
      "state": "pending",
      "target": {
        "id": "48c15448-d32f-4ed5-b5f4-e7ff5b938f54",
        "kind": "environment_access"
      }
    }
  },
  {
    "operation": "selectRoute",
    "method": "PUT",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/selection",
    "headers": {
      "Idempotency-Key": "cd4d7f58-7026-4912-bfdb-6f31d1a752c3",
      "If-Match": "\"6\""
    },
    "body": {
      "environment_id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "execution_id": "233f4315-32bb-4551-a40b-efb132e494c1"
    },
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "active"
    }
  },
  {
    "operation": "createRouteCredential",
    "method": "POST",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials",
    "headers": {
      "Idempotency-Key": "ae57a571-8a1c-4057-b7af-fad8f08c836a"
    },
    "body": {
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "6cbe57aa-2703-4a76-b022-778c20e71c8e"
    }
  },
  {
    "operation": "issueRepositoryCredential",
    "method": "POST",
    "path": "/v1/repositories/d60ef1d3-e66c-4bba-a179-d46aef2bd21d/credentials",
    "headers": {
      "Idempotency-Key": "72cd30a9-3479-43a0-af0e-32f9d0413983"
    },
    "body": {
      "ttl_seconds": 900,
      "actions": [
        "git:read",
        "git:write"
      ]
    },
    "response_summary": {
      "id": "d957700f-7add-4673-9854-baa7c83eefbd"
    }
  },
  {
    "operation": "revokeRepositoryCredential",
    "method": "DELETE",
    "path": "/v1/repositories/d60ef1d3-e66c-4bba-a179-d46aef2bd21d/credentials/d957700f-7add-4673-9854-baa7c83eefbd",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "d957700f-7add-4673-9854-baa7c83eefbd"
    }
  },
  {
    "operation": "issueRepositoryCredential",
    "method": "POST",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials",
    "headers": {
      "Idempotency-Key": "8b67c561-a5c7-4008-84a9-15135aa0e9c6"
    },
    "body": {
      "ttl_seconds": 900,
      "actions": [
        "git:read",
        "git:write",
        "oci:read",
        "oci:write"
      ]
    },
    "response_summary": {
      "id": "483d9ef6-e2be-484e-91ae-83aeaa015180"
    }
  },
  {
    "operation": "issueRepositoryCredential",
    "method": "POST",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials",
    "headers": {
      "Idempotency-Key": "4000ae24-8c16-4530-ac72-bc073b9f552c"
    },
    "body": {
      "ttl_seconds": 900,
      "actions": [
        "git:read",
        "git:write"
      ]
    },
    "response_summary": {
      "id": "7b4a63b2-6fab-45d7-9036-8cf399076486"
    }
  },
  {
    "operation": "revokeRepositoryCredential",
    "method": "DELETE",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials/7b4a63b2-6fab-45d7-9036-8cf399076486",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "7b4a63b2-6fab-45d7-9036-8cf399076486"
    }
  },
  {
    "operation": "issueDatabaseCredential",
    "method": "POST",
    "path": "/v1/databases/9ee528c1-a51b-4e79-a275-d97e2e8f107e/credentials",
    "headers": {
      "Idempotency-Key": "30d7febc-f259-414e-ae08-531fe373b544"
    },
    "body": {
      "role": "migration",
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "43b69a12-050b-4a39-bcdd-e24705f6ef8b",
      "state": "pending",
      "target": {
        "id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e",
        "kind": "database"
      }
    }
  },
  {
    "operation": "createJob",
    "method": "POST",
    "path": "/v1/components/42e75267-c6a7-49c4-aae1-4391d52093a5/jobs",
    "headers": {
      "Idempotency-Key": "4889534c-ef6f-48e7-af76-dc303994a121"
    },
    "body": {
      "image": "botfolio.com/core/ec3926c9-1a77-480e-b4ec-871e39091217@sha256:6b7d68d3ac1b262bbbdd377c6cbd0e47ef24881c2c40b5cf8cd1e8727f5735cd",
      "command": [
        "python3",
        "/opt/app/migrate.py",
        "ndc_runtime_9ee528c1a51b4e79a275d97e2e8f107e"
      ],
      "cpu_millis": 250,
      "memory_mib": 256,
      "scratch_mib": 32,
      "network": "database",
      "timeout_seconds": 120,
      "artifact_binding": {
        "repository_id": "ec3926c9-1a77-480e-b4ec-871e39091217"
      },
      "database_binding": {
        "database_id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e",
        "credential_id": "d4483f41-4b0b-4163-8eae-52d122aff2eb"
      }
    },
    "response_summary": {
      "id": "a1fe3f98-822c-4c42-bfaa-22d174a7c90c",
      "state": "pending",
      "target": {
        "id": "ccb044f6-bc1a-4ad7-b072-300d3f098481",
        "kind": "job"
      }
    }
  },
  {
    "operation": "createDeployment",
    "method": "POST",
    "path": "/v1/components/42e75267-c6a7-49c4-aae1-4391d52093a5/deployments",
    "headers": {
      "Idempotency-Key": "63924fae-c8fc-4b5f-96f4-03db4f723eb8"
    },
    "body": {
      "image": "botfolio.com/core/ec3926c9-1a77-480e-b4ec-871e39091217@sha256:6b7d68d3ac1b262bbbdd377c6cbd0e47ef24881c2c40b5cf8cd1e8727f5735cd",
      "command": [
        "/bin/sh",
        "/opt/app/start.sh"
      ],
      "cpu_millis": 250,
      "memory_mib": 256,
      "scratch_mib": 32,
      "network": "database",
      "artifact_binding": {
        "repository_id": "ec3926c9-1a77-480e-b4ec-871e39091217"
      },
      "database_binding": {
        "database_id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e"
      },
      "port": 8080,
      "readiness_path": "/health",
      "startup_timeout_seconds": 120
    },
    "response_summary": {
      "id": "09dad17c-6927-47b5-b107-0834e71e6823",
      "state": "pending",
      "target": {
        "id": "96a74a1f-c768-40e8-85cc-1fa89dab21ed",
        "kind": "deployment"
      }
    }
  },
  {
    "operation": "selectRoute",
    "method": "PUT",
    "path": "/v1/routes/2b0fc4df-4e84-4a65-a429-1dabc69f0c11/selection",
    "headers": {
      "Idempotency-Key": "0d49c125-f266-4b8b-a6e0-9ad510f14b9c",
      "If-Match": "\"1\""
    },
    "body": {
      "deployment_id": "96a74a1f-c768-40e8-85cc-1fa89dab21ed",
      "execution_id": "92507730-c38f-48af-b401-3c164c0bfcd8"
    },
    "response_summary": {
      "id": "2b0fc4df-4e84-4a65-a429-1dabc69f0c11",
      "state": "active"
    }
  },
  {
    "operation": "createRouteCredential",
    "method": "POST",
    "path": "/v1/routes/2b0fc4df-4e84-4a65-a429-1dabc69f0c11/credentials",
    "headers": {
      "Idempotency-Key": "8c8d251b-d7ac-4a2a-842a-57d0a1cc03bd"
    },
    "body": {
      "ttl_seconds": 900
    },
    "response_summary": {
      "id": "2966e674-5049-4fb6-b39b-89bd3d549e78"
    }
  },
  {
    "operation": "revokeRepositoryCredential",
    "method": "DELETE",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217/credentials/483d9ef6-e2be-484e-91ae-83aeaa015180",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "483d9ef6-e2be-484e-91ae-83aeaa015180"
    }
  },
  {
    "operation": "stopEnvironment",
    "method": "POST",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d/stop",
    "headers": {
      "Idempotency-Key": "68b1dcc2-589f-4ad4-857f-9b24b96bd79d",
      "If-Match": "\"508\""
    },
    "body": null,
    "response_summary": {
      "id": "3133522c-4fa5-4c04-ae03-80ad9daaa818",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "revokeRouteCredential",
    "method": "DELETE",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials/a1ddc74c-461b-4754-8060-dd6992445237",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "a1ddc74c-461b-4754-8060-dd6992445237"
    }
  },
  {
    "operation": "revokeRouteCredential",
    "method": "DELETE",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials/6cbe57aa-2703-4a76-b022-778c20e71c8e",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "6cbe57aa-2703-4a76-b022-778c20e71c8e"
    }
  },
  {
    "operation": "revokeRouteCredential",
    "method": "DELETE",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials/182e8438-2d62-492c-a076-9560a8d8e152",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "182e8438-2d62-492c-a076-9560a8d8e152"
    }
  },
  {
    "operation": "revokeRouteCredential",
    "method": "DELETE",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials/195766e3-dee6-413d-9aed-8fe74e19b875",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "195766e3-dee6-413d-9aed-8fe74e19b875"
    }
  },
  {
    "operation": "revokeRouteCredential",
    "method": "DELETE",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials/1031e776-6b9d-407a-b540-8be86679d7fb",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "1031e776-6b9d-407a-b540-8be86679d7fb"
    }
  },
  {
    "operation": "revokeRouteCredential",
    "method": "DELETE",
    "path": "/v1/routes/2b0fc4df-4e84-4a65-a429-1dabc69f0c11/credentials/2966e674-5049-4fb6-b39b-89bd3d549e78",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "2966e674-5049-4fb6-b39b-89bd3d549e78"
    }
  },
  {
    "operation": "revokeRouteCredential",
    "method": "DELETE",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8/credentials/ca47fdb9-f1d8-43ec-b92b-c5d81bcbe39d",
    "headers": {},
    "body": null,
    "response_summary": {
      "id": "ca47fdb9-f1d8-43ec-b92b-c5d81bcbe39d"
    }
  },
  {
    "operation": "deleteRoute",
    "method": "DELETE",
    "path": "/v1/routes/9d7bef40-488b-4b1e-8a3a-86238d570eb8",
    "headers": {
      "Idempotency-Key": "8cc0d805-e1f8-4f19-b752-a6c2fe39a46d",
      "If-Match": "\"7\""
    },
    "body": null,
    "response_summary": {
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "state": "deleted"
    }
  },
  {
    "operation": "deleteRoute",
    "method": "DELETE",
    "path": "/v1/routes/2b0fc4df-4e84-4a65-a429-1dabc69f0c11",
    "headers": {
      "Idempotency-Key": "e68f465c-6412-4e4f-913e-bf92c445b3f4",
      "If-Match": "\"2\""
    },
    "body": null,
    "response_summary": {
      "id": "2b0fc4df-4e84-4a65-a429-1dabc69f0c11",
      "state": "deleted"
    }
  },
  {
    "operation": "deleteDeployment",
    "method": "DELETE",
    "path": "/v1/deployments/96a74a1f-c768-40e8-85cc-1fa89dab21ed",
    "headers": {
      "Idempotency-Key": "68c2a2f3-747a-49df-9d73-f946396e7723",
      "If-Match": "\"67\""
    },
    "body": null,
    "response_summary": {
      "id": "ffbb1954-d25a-4507-a54d-e17da46b88ce",
      "state": "pending",
      "target": {
        "id": "96a74a1f-c768-40e8-85cc-1fa89dab21ed",
        "kind": "deployment"
      }
    }
  },
  {
    "operation": "deleteEnvironment",
    "method": "DELETE",
    "path": "/v1/environments/1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
    "headers": {
      "Idempotency-Key": "c6c422f2-89df-4ad8-892f-ab09da52a36c",
      "If-Match": "\"512\""
    },
    "body": null,
    "response_summary": {
      "id": "70b474f5-7956-4172-8eea-ca9f1ecf2d40",
      "state": "pending",
      "target": {
        "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
        "kind": "environment"
      }
    }
  },
  {
    "operation": "deleteJob",
    "method": "DELETE",
    "path": "/v1/jobs/e9cc1756-0cd3-472d-beed-5d49f2165f90",
    "headers": {
      "Idempotency-Key": "7a070c71-9870-469b-9814-f1968108a126",
      "If-Match": "\"25\""
    },
    "body": null,
    "response_summary": {
      "id": "2e22d526-5b83-46d0-98ce-a2189692b030",
      "state": "pending",
      "target": {
        "id": "e9cc1756-0cd3-472d-beed-5d49f2165f90",
        "kind": "job"
      }
    }
  },
  {
    "operation": "deleteJob",
    "method": "DELETE",
    "path": "/v1/jobs/766ab5d7-5fbd-43e0-be88-b4915a728ce8",
    "headers": {
      "Idempotency-Key": "f916f22f-95b9-4b30-98f8-415c56195e2a",
      "If-Match": "\"27\""
    },
    "body": null,
    "response_summary": {
      "id": "a4db70b2-fb54-4637-b51e-1364293046db",
      "state": "pending",
      "target": {
        "id": "766ab5d7-5fbd-43e0-be88-b4915a728ce8",
        "kind": "job"
      }
    }
  },
  {
    "operation": "deleteJob",
    "method": "DELETE",
    "path": "/v1/jobs/ccb044f6-bc1a-4ad7-b072-300d3f098481",
    "headers": {
      "Idempotency-Key": "3f3f8cc9-34df-46b3-a26c-209cee5d624d",
      "If-Match": "\"27\""
    },
    "body": null,
    "response_summary": {
      "id": "d31f06ce-9630-46ca-9224-f87340791c57",
      "state": "pending",
      "target": {
        "id": "ccb044f6-bc1a-4ad7-b072-300d3f098481",
        "kind": "job"
      }
    }
  },
  {
    "operation": "deleteJob",
    "method": "DELETE",
    "path": "/v1/jobs/8beb6335-71db-4518-ac76-7ff3b85e0a01",
    "headers": {
      "Idempotency-Key": "141309a8-e793-4bc2-b42b-c2076d23c09c",
      "If-Match": "\"24\""
    },
    "body": null,
    "response_summary": {
      "id": "74170aae-03f1-4c38-81cd-ff846ed6c428",
      "state": "pending",
      "target": {
        "id": "8beb6335-71db-4518-ac76-7ff3b85e0a01",
        "kind": "job"
      }
    }
  },
  {
    "operation": "deleteDatabase",
    "method": "DELETE",
    "path": "/v1/databases/b71017e7-b95c-4346-84ff-8ddc8305597b",
    "headers": {
      "Idempotency-Key": "9cc11e71-3ac5-40c6-9899-4f996d451404"
    },
    "body": null,
    "response_summary": {
      "id": "ed2a96cd-20d1-4419-9067-be164e217455",
      "state": "pending",
      "target": {
        "id": "b71017e7-b95c-4346-84ff-8ddc8305597b",
        "kind": "database"
      }
    }
  },
  {
    "operation": "deleteDatabase",
    "method": "DELETE",
    "path": "/v1/databases/9ee528c1-a51b-4e79-a275-d97e2e8f107e",
    "headers": {
      "Idempotency-Key": "06d9ebb5-e581-4e08-a70f-9ff97317350e"
    },
    "body": null,
    "response_summary": {
      "id": "a91b2c04-ec47-47fe-b7ee-b2f516ea6561",
      "state": "pending",
      "target": {
        "id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e",
        "kind": "database"
      }
    }
  },
  {
    "operation": "deleteRepository",
    "method": "DELETE",
    "path": "/v1/repositories/d60ef1d3-e66c-4bba-a179-d46aef2bd21d",
    "headers": {
      "Idempotency-Key": "3cc32aa8-6144-4b24-a3f0-4cb03be4ceaf"
    },
    "body": null,
    "response_summary": {
      "id": "d8863e78-ae6f-489c-9496-369fad3902a7",
      "state": "pending",
      "target": {
        "id": "d60ef1d3-e66c-4bba-a179-d46aef2bd21d",
        "kind": "repository"
      }
    }
  },
  {
    "operation": "deleteRepository",
    "method": "DELETE",
    "path": "/v1/repositories/ec3926c9-1a77-480e-b4ec-871e39091217",
    "headers": {
      "Idempotency-Key": "2b8ea8ce-1493-43f8-9cea-761701b77dd6"
    },
    "body": null,
    "response_summary": {
      "id": "99ac0c14-19ef-41d4-9967-94619549d232",
      "state": "pending",
      "target": {
        "id": "ec3926c9-1a77-480e-b4ec-871e39091217",
        "kind": "repository"
      }
    }
  },
  {
    "operation": "deleteComponent",
    "method": "DELETE",
    "path": "/v1/components/d6631179-1140-4e68-893e-7c7a54284acf",
    "headers": {
      "If-Match": "\"1\""
    },
    "body": null,
    "response_summary": {
      "id": "d6631179-1140-4e68-893e-7c7a54284acf"
    }
  },
  {
    "operation": "deleteComponent",
    "method": "DELETE",
    "path": "/v1/components/42e75267-c6a7-49c4-aae1-4391d52093a5",
    "headers": {
      "If-Match": "\"1\""
    },
    "body": null,
    "response_summary": {
      "id": "42e75267-c6a7-49c4-aae1-4391d52093a5"
    }
  },
  {
    "operation": "deleteApp",
    "method": "DELETE",
    "path": "/v1/apps/af3879ea-0d91-44b8-bd1d-d8076c90fa30",
    "headers": {
      "If-Match": "\"1\""
    },
    "body": null,
    "response_summary": {
      "id": "af3879ea-0d91-44b8-bd1d-d8076c90fa30"
    }
  },
  {
    "operation": "deleteApp",
    "method": "DELETE",
    "path": "/v1/apps/19ab08e1-5e7a-4d4f-ad73-98a72a69497d",
    "headers": {
      "If-Match": "\"1\""
    },
    "body": null,
    "response_summary": {
      "id": "19ab08e1-5e7a-4d4f-ad73-98a72a69497d"
    }
  },
  {
    "operation": "deleteSpace",
    "method": "DELETE",
    "path": "/v1/spaces/781e78f6-1c66-4c0a-8a9e-757a17661e50",
    "headers": {
      "If-Match": "\"1\""
    },
    "body": null,
    "response_summary": {
      "id": "781e78f6-1c66-4c0a-8a9e-757a17661e50"
    }
  }
]
````

### File: preview.py

````python
from rest import *
name=os.environ.get('FIXTURE_STAGE','dev'); label=os.environ.get('PREVIEW_LABEL',name)
c=json.load(open(name+'-component.response.private.json'))
r=mutate('createRoute',{'parent_id':c['id']},label+'-route')
e=json.load(open('dev-running.response.private.json')) if name=='dev' else json.load(open('release-running.response.private.json'))
r=mutate('selectRoute',{'id':r['id'],'if_match':'"'+str(r['version'])+'"','body':{('environment_id' if name=='dev' else 'deployment_id'):e['id'],'execution_id':e['execution']['id']}},label+'-route-selected')
a=mutate('createRouteCredential',{'id':r['id'],'body':{'ttl_seconds':900}},label+'-route-credential')
(ROOT/(label+'-preview-token.private')).write_text(a['secret'])
q=subprocess.run(['python3','source/test.py',r['origin'],os.environ.get('EXPECTED_MESSAGE','fresh-public-v1'),str(ROOT/(label+'-preview-token.private'))],capture_output=True,text=True)
(ROOT/(label+'-preview-test.private.log')).write_text(q.stdout+q.stderr)
print('Preview test exit',q.returncode)
if q.returncode: raise RuntimeError('Preview failed: '+q.stderr.splitlines()[-1])
````

### File: publish.py

````python
from rest import *
import base64,pathlib
name=os.environ.get('FIXTURE_STAGE','dev'); r=json.load(open(name+'-repo-get.response.private.json'))
c=mutate('issueRepositoryCredential',{'id':r['id'],'body':{'ttl_seconds':900,'actions':['git:read','git:write','oci:read','oci:write']}},name+'-publication')
p=ROOT/(name+'-docker-private');p.mkdir(exist_ok=True)
(p/'config.json').write_text(json.dumps({'auths':{'botfolio.com':{'auth':base64.b64encode((c['username']+':'+c['secret']).encode()).decode()}}}))
def run(args,**kw):
 with open(name+'-native.private.log','a') as f: subprocess.run(args,check=True,stdout=f,stderr=f,**kw)
run(['docker','tag','fresh-public-'+name+':example',r['image']+':fresh-example'])
run(['docker','--config',str(p),'push',r['image']+':fresh-example'])
dig=subprocess.check_output(['docker','image','inspect',r['image']+':fresh-example','--format','{{json .RepoDigests}}'],text=True)
digest=next(x.split('@')[1] for x in json.loads(dig) if x.startswith(r['image']+'@'))
resolved=call('resolveRepositoryManifest',{'id':r['id'],'digest':digest},name+'-resolved');print(name,'digest',digest,'resolved',resolved)
# Askpass returns the scoped native credential only to Git, never in URLs or logs.
ask=ROOT/(name+'-askpass.private.py'); ask.write_text('#!/usr/bin/env python3\nimport json,sys\nc=json.load(open('+repr(str(ROOT/(name+'-publication.response.private.json')))+'))\nprint(c["username"] if "Username" in sys.argv[1] else c["secret"])\n');ask.chmod(0o700)
env={**os.environ,'GIT_ASKPASS':str(ask),'GIT_TERMINAL_PROMPT':'0'}
run(['git','clone',r['clone_url'],name+'-git'],env=env)
print(name,'initial native branch preserved')
````

### File: push-tested.py

````python
from rest import *
name=os.environ.get('FIXTURE_STAGE','dev');r=json.load(open(name+'-repo-get.response.private.json'));commit=(ROOT/'tested-commit.txt').read_text().strip()
c=mutate('issueRepositoryCredential',{'id':r['id'],'body':{'ttl_seconds':900,'actions':['git:read','git:write']}},name+'-tested-publication')
ask=ROOT/(name+'-tested-askpass.private.py');ask.write_text('#!/usr/bin/env python3\nimport json,sys\nc=json.load(open('+repr(str(ROOT/(name+'-tested-publication.response.private.json')))+'))\nprint(c["username"] if "Username" in sys.argv[1] else c["secret"])\n');ask.chmod(0o700)
env={**os.environ,'GIT_ASKPASS':str(ask),'GIT_TERMINAL_PROMPT':'0'}
with open(name+'-tested-push.private.log','w') as f:subprocess.run(['git','-C','tested-git','push',r['clone_url'],commit+':refs/heads/fresh-public-work'],env=env,check=True,stdout=f,stderr=f)
refs=subprocess.check_output(['git','ls-remote',r['clone_url']],env=env,text=True);(ROOT/(name+'-native-refs.private.txt')).write_text(refs)
assert commit+'\trefs/heads/fresh-public-work' in refs
initial=subprocess.check_output(['git','-C',name+'-git','rev-parse','refs/heads/main'],text=True).strip()
assert initial+'\trefs/heads/main' in refs
call('revokeRepositoryCredential',{'id':r['id'],'credential_id':c['id']},name+'-tested-publication-revoked')
print(name,'tested commit published; initial main preserved; publication credential revoked')
````

### File: receipt.json

````json
{
  "model": "gpt-6-astra",
  "fallback": false,
  "final_tested_commit": "1b2d19f95d8820053757ca371db19858163d0f8c",
  "tree": "0263bde7775511cf47894b0e8d6f33cc719af878",
  "bundle_sha256": "9abe3884314e67858c1bdd17fc4c87f6200cd10f02bf017db504cdf946131617",
  "development_digest": "sha256:4f7c49bad05d3fed78cc325aed66a4c929d5c8e705312452ccb30653d596191b",
  "release_digest": "sha256:6b7d68d3ac1b262bbbdd377c6cbd0e47ef24881c2c40b5cf8cd1e8727f5735cd",
  "source_files": [
    "Dockerfile",
    "README.md",
    "app.py",
    "message.txt",
    "migrate.py",
    "sshd.pid",
    "start.sh",
    "test.py",
    "with-app-env.py"
  ],
  "separation": {
    "dev": {
      "app": "af3879ea-0d91-44b8-bd1d-d8076c90fa30",
      "component": "d6631179-1140-4e68-893e-7c7a54284acf",
      "repository": "d60ef1d3-e66c-4bba-a179-d46aef2bd21d",
      "database": "b71017e7-b95c-4346-84ff-8ddc8305597b"
    },
    "release": {
      "app": "19ab08e1-5e7a-4d4f-ad73-98a72a69497d",
      "component": "42e75267-c6a7-49c4-aae1-4391d52093a5",
      "repository": "ec3926c9-1a77-480e-b4ec-871e39091217",
      "database": "9ee528c1-a51b-4e79-a275-d97e2e8f107e"
    }
  },
  "ssh_access_history": [
    {
      "stage": "first-retry",
      "access_id": "2f9921f4-204a-4818-a9e1-de7d6c90699b",
      "execution_id": "fa6f52d0-2b68-49df-9f3a-f199f6e1303d",
      "host_key_fingerprint": "SHA256:DVINZXZrtAOYhwVWAWkS5AsSCM1dsqQTWvCViKTEexw",
      "expires_at": "2026-09-12T11:27:52Z",
      "observed_state": "revoked",
      "cleanup_pending": false
    },
    {
      "stage": "post-repair",
      "access_id": "88eb3bb4-0862-40c9-a105-8f6e08578ad8",
      "execution_id": "193ad5b8-c89f-438f-9cc7-10f6999f7a4d",
      "host_key_fingerprint": "SHA256:3reGwFH53AR3fKhmnXoKwlnV21efHcK4eTvkgpx+pHk",
      "expires_at": "2026-09-12T11:38:18Z",
      "observed_state": "revoked",
      "cleanup_pending": false
    },
    {
      "stage": "persistence",
      "access_id": "d230f55e-a699-4f11-8b0d-ab7b4c4d8f8a",
      "execution_id": "661f4f29-ad84-47f4-9efe-a4f49dd8d105",
      "host_key_fingerprint": "SHA256:1/INEgn/fwwO7rpGomrmARpZYBc03YChbr27ofns4no",
      "expires_at": "2026-09-12T11:38:18Z",
      "observed_state": "revoked",
      "cleanup_pending": false
    },
    {
      "stage": "final-persistence",
      "access_id": "48c15448-d32f-4ed5-b5f4-e7ff5b938f54",
      "execution_id": "233f4315-32bb-4551-a40b-efb132e494c1",
      "host_key_fingerprint": "SHA256:vwFhIzunsL2CbVy1G21o56wP69Nhve7SraHTAbpowks",
      "expires_at": "2026-09-12T11:42:49Z",
      "observed_state": "revoked",
      "cleanup_pending": false
    }
  ],
  "release_identity_verified": true,
  "release_deployment_id": "96a74a1f-c768-40e8-85cc-1fa89dab21ed",
  "release_execution_id": "92507730-c38f-48af-b401-3c164c0bfcd8",
  "same_functional_checks": "passed SSH, edited preview, final-commit restart preview, separate release preview",
  "failed_candidate": {
    "commit": "69ee8fc304d677a724c3b979d85f3c6004e48249",
    "digest": "sha256:f6b2b745b837342385fec591909163208e28aa4e71c8dbec03ebb309997e00da",
    "reason": "source ownership denied migration script read"
  },
  "old_access_denial": {
    "access_id": "88eb3bb4-0862-40c9-a105-8f6e08578ad8",
    "ssh_exit": 255,
    "stderr": "kex_exchange_identification: read: Connection reset by peer\nConnection reset by 127.0.0.1 port 2222",
    "old_preview_status": 503
  },
  "status": "complete after explicit operator platform repair",
  "source_sha256": {
    "Dockerfile": "28d9c1ff8b21fd9b27837e1e9f2c3ae61bd22361e3727739aea8e31b532a6500",
    "README.md": "d23d479f30eb8eb4bfe96c1b3ab15d413bd4cc8a0fa337ebc1866d5962f898c9",
    "app.py": "b14c5256e8720b6df52437b8395a3fc86c9b59286139c7d1f8b6e41c30122eb8",
    "message.txt": "afcf5534a1c4acaeb9e8e950a7df1bbda98afdd2c5ac60924baa69abd6b1a38e",
    "migrate.py": "c36b09c4ded20f81b1123309189c4823faab388f97dea96688427e448e82fe10",
    "sshd.pid": "7de1555df0c2700329e815b93b32c571c3ea54dc967b89e81ab73b9972b72d1d",
    "start.sh": "be7cbb07089a93a3250e2c470651addbbef10fc9aaf805eadace006625d0441f",
    "test.py": "8dae23e7efd9e19ea4398b175760ab8b8bed66da155ec4c29aacbd58c5124cad",
    "with-app-env.py": "cce7aa9b6937f4b715876a1f0a229325c349ee5c8c336521333174b1eaca384c"
  },
  "commit_lineage": [
    "1b2d19f95d8820053757ca371db19858163d0f8c",
    "69ee8fc304d677a724c3b979d85f3c6004e48249",
    "69ad42c98dbdd25e5dff8c14b61b20b587a8b882",
    "b51cb0faba7cbe37a0757b293ed7b2eaf7430733"
  ],
  "packaged_source_verified_byte_for_byte_against_commit": true,
  "cleanup": [
    {
      "kind": "RouteCredential",
      "id": "a1ddc74c-461b-4754-8060-dd6992445237",
      "status": "revoked"
    },
    {
      "kind": "RouteCredential",
      "id": "6cbe57aa-2703-4a76-b022-778c20e71c8e",
      "status": "revoked"
    },
    {
      "kind": "RouteCredential",
      "id": "182e8438-2d62-492c-a076-9560a8d8e152",
      "status": "revoked"
    },
    {
      "kind": "RouteCredential",
      "id": "195766e3-dee6-413d-9aed-8fe74e19b875",
      "status": "revoked"
    },
    {
      "kind": "RouteCredential",
      "id": "1031e776-6b9d-407a-b540-8be86679d7fb",
      "status": "revoked"
    },
    {
      "kind": "RouteCredential",
      "id": "2966e674-5049-4fb6-b39b-89bd3d549e78",
      "status": "revoked"
    },
    {
      "kind": "RouteCredential",
      "id": "ca47fdb9-f1d8-43ec-b92b-c5d81bcbe39d",
      "status": "revoked"
    },
    {
      "kind": "EnvironmentAccess",
      "id": "48c15448-d32f-4ed5-b5f4-e7ff5b938f54",
      "status": "revoked; cleanup observed"
    },
    {
      "kind": "EnvironmentAccess",
      "id": "2f9921f4-204a-4818-a9e1-de7d6c90699b",
      "status": "revoked; cleanup observed"
    },
    {
      "kind": "EnvironmentAccess",
      "id": "d230f55e-a699-4f11-8b0d-ab7b4c4d8f8a",
      "status": "revoked; cleanup observed"
    },
    {
      "kind": "EnvironmentAccess",
      "id": "88eb3bb4-0862-40c9-a105-8f6e08578ad8",
      "status": "revoked; cleanup observed"
    },
    {
      "kind": "Route",
      "id": "9d7bef40-488b-4b1e-8a3a-86238d570eb8",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Route",
      "id": "2b0fc4df-4e84-4a65-a429-1dabc69f0c11",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Deployment",
      "id": "96a74a1f-c768-40e8-85cc-1fa89dab21ed",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Environment",
      "id": "1d1d9cb6-5505-48ba-a64c-a80ef83ce64d",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Job",
      "id": "e9cc1756-0cd3-472d-beed-5d49f2165f90",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Job",
      "id": "766ab5d7-5fbd-43e0-be88-b4915a728ce8",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Job",
      "id": "ccb044f6-bc1a-4ad7-b072-300d3f098481",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Job",
      "id": "8beb6335-71db-4518-ac76-7ff3b85e0a01",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Database",
      "id": "b71017e7-b95c-4346-84ff-8ddc8305597b",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Database",
      "id": "9ee528c1-a51b-4e79-a275-d97e2e8f107e",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Repository",
      "id": "d60ef1d3-e66c-4bba-a179-d46aef2bd21d",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Repository",
      "id": "ec3926c9-1a77-480e-b4ec-871e39091217",
      "status": "deleted; cleanup observed"
    },
    {
      "kind": "Component",
      "id": "d6631179-1140-4e68-893e-7c7a54284acf",
      "status": "HTTP 404 observed"
    },
    {
      "kind": "Component",
      "id": "42e75267-c6a7-49c4-aae1-4391d52093a5",
      "status": "HTTP 404 observed"
    },
    {
      "kind": "App",
      "id": "af3879ea-0d91-44b8-bd1d-d8076c90fa30",
      "status": "HTTP 404 observed"
    },
    {
      "kind": "App",
      "id": "19ab08e1-5e7a-4d4f-ad73-98a72a69497d",
      "status": "HTTP 404 observed"
    },
    {
      "kind": "Space",
      "id": "781e78f6-1c66-4c0a-8a9e-757a17661e50",
      "status": "HTTP 404 observed"
    }
  ],
  "operator_reported_independent_cleanup": {
    "public_404_checks": 17,
    "compute_pods_and_namespaces_absent": true,
    "access_cleanup_complete": 4,
    "workspace_leases": 0,
    "empty_workspaces": 4,
    "pool_pvc_identity_preserved": true,
    "temporary_peer_revoked": true,
    "provenance": "Reported by operator parent; actor did not inspect infrastructure"
  },
  "operator_handoffs": [
    "Ordinary CLI/client grant and temporary mapped Headscale connecting-device adapter supplied before run",
    "Operator inspected SSH failure and repaired Core target Ed25519 host-key encoding from PKCS#8 to OpenSSH; actor resumed through public lifecycle after operator release-ready notice",
    "Operator retired temporary peer and independently verified infrastructure cleanup"
  ],
  "limits": [
    "Instruction boundary, not OS sandbox",
    "Temporary loopback connecting-device adapter, not physical device acceptance",
    "Initial platform needed operator repair; not unaided self-service on original release",
    "No provider calls, package egress, IDE/SFTP or production-fitness acceptance",
    "Exact tested tree contains native generated README and incidental non-secret sshd.pid=4; preserved for source identity",
    "Executable corrected recipe assembled and syntax-checked after live run; not replayed as a second live run",
    "Initial debug tool output echoed non-secret public resource metadata including retained Space owner issuer/subject; publication excludes it; no credentials/private keys were printed"
  ],
  "assembled_recipe_post_review_checks": {
    "poll_inactivity_seconds": 30,
    "absolute_breaker_seconds": 300,
    "mocked_stall_progress_absolute_cases": "passed",
    "restart_checks_exact_head_and_clean_tree": true,
    "python_and_shell_syntax": "passed",
    "live_replayed": false
  }
}
````

### File: reselect.py

````python
from rest import *
label=os.environ.get('SELECT_LABEL','post-repair');message=os.environ.get('EXPECTED_MESSAGE','fresh-public-v1')
eid=json.load(open('dev-environment.response.private.json'))['id'];e=call('getEnvironment',{'id':eid},label+'-route-environment')
rid=json.load(open('dev-route.response.private.json'))['id'];r=call('getRoute',{'id':rid},label+'-route-before')
r=mutate('selectRoute',{'id':rid,'if_match':'"'+str(r['version'])+'"','body':{'environment_id':eid,'execution_id':e['execution']['id']}},label+'-route-selected')
a=mutate('createRouteCredential',{'id':rid,'body':{'ttl_seconds':900}},label+'-route-credential'); (ROOT/(label+'-preview-token.private')).write_text(a['secret'])
t=subprocess.run(['python3','source/test.py',r['origin'],message,label+'-preview-token.private'],capture_output=True,text=True)
(ROOT/(label+'-preview-test.private.log')).write_text(t.stdout+t.stderr)
if t.returncode: raise RuntimeError('preview failed '+t.stderr.splitlines()[-1])
print('Authenticated preview PASS',message)
````

### File: rest.py

````python
from actor import ROOT
import json,os,subprocess,time,uuid,urllib.request,urllib.error
schema=json.load(open(ROOT/'openapi.json'))
ops={o['operationId']:(m.upper(),p,o) for p,ms in schema['paths'].items() for m,o in ms.items() if isinstance(o,dict) and 'operationId' in o}
def call(op,args=None,label=None):
 args=args or {}; label=label or op+'-'+uuid.uuid4().hex[:8]
 method,path,desc=ops[op]; headers={}; body=args.get('body')
 for param in desc.get('parameters',[]):
  name=param['name']; key={'Idempotency-Key':'idempotency_key','If-Match':'if_match'}.get(name,name)
  if key not in args: continue
  if param['in']=='path': path=path.replace('{'+name+'}',str(args[key]))
  elif param['in']=='header': headers[name]=str(args[key])
  elif param['in']=='query': path+=('&' if '?' in path else '?')+urllib.parse.urlencode({name:args[key]})
 intent={'operation':op,'method':method,'path':path,'headers':headers,'body':body}
 intent_path=ROOT/(label+'.intent.private.json')
 if method!='GET' and intent_path.exists(): raise RuntimeError('Existing mutation intent: observe it before continuing: '+str(intent_path))
 intent_path.write_text(json.dumps(intent,indent=2))
 token=subprocess.check_output([str(ROOT/'newday'),'token'],text=True).strip()
 headers={**headers,'Authorization':'Bearer '+token,'Content-Type':'application/json'}
 req=urllib.request.Request(os.environ.get('NEWDAY_ORIGIN','https://botfolio.com').rstrip('/')+path,headers=headers,method=method,data=json.dumps(body).encode() if body is not None else None)
 try: r=urllib.request.urlopen(req,timeout=60)
 except urllib.error.HTTPError as e: r=e
 raw=r.read(); (ROOT/(label+'.response.private.json')).write_bytes(raw)
 (ROOT/(label+'.headers.private.json')).write_text(json.dumps(dict(r.headers)))
 if r.status>=400: raise RuntimeError(op+' HTTP '+str(r.status)+' '+raw.decode()[:1500])
 return json.loads(raw) if raw else {}
def mutate(op,args=None,label=None):
 args=dict(args or {}); args.setdefault('idempotency_key',str(uuid.uuid4())); return call(op,args,label)
def poll(op):
 started=last_change=time.monotonic(); previous=None
 idle_limit=float(os.environ.get('NEWDAY_OPERATION_IDLE_SECONDS','30'))
 absolute_limit=float(os.environ.get('NEWDAY_OPERATION_DEADLINE_SECONDS','300'))
 while True:
  # Reuse a read-only observation file; identical polls are not progress.
  o=call('getOperation',{'id':op['id']},'poll-'+str(uuid.UUID(op['id'])))
  if o.get('state') in ['succeeded','failed','cancelled']:
   if o['state']!='succeeded': raise RuntimeError(json.dumps(o))
   return o
  now=time.monotonic(); meaningful=(o.get('state'),o.get('phase'),o.get('progress'))
  if meaningful!=previous: previous=meaningful;last_change=now
  if now-last_change>=idle_limit: raise RuntimeError('Operation stalled: observe original '+op['id'])
  if now-started>=absolute_limit: raise RuntimeError('Operation absolute deadline: observe original '+op['id'])
  time.sleep(2)
if __name__=='__main__':
 call('listCapabilities',{},'discovery-capabilities')
 spaces=call('listSpaces',{},'discovery-spaces')
 for existing in spaces['items']: call('listApps',{'parent_id':existing['id']},'discovery-apps-'+existing['id'])
 call('listEnvironmentAccessPeers',{},'discovery-peers')
 s=mutate('createSpace',{'body':{'name':'Public developer example','slug':'public-example-'+uuid.uuid4().hex[:6]}},'space'); print('Space',s['id'])
 release=mutate('createApp',{'parent_id':s['id'],'body':{'name':'Release','slug':'release'}},'release-app')
 dev=mutate('createApp',{'parent_id':s['id'],'body':{'name':'Development','slug':'development','development_of':release['id']}},'dev-app')
 for name,app in [('release',release),('dev',dev)]:
  c=mutate('createComponent',{'parent_id':app['id'],'body':{'name':'Web','slug':'web'}},name+'-component')
  for kind in ['Repository','Database']:
   o=mutate('create'+kind,{'parent_id':c['id']},name+'-'+kind.lower()); print(name,kind,poll(o)['state'])
````

### File: restart.py

````python
from rest import *
label=os.environ.get('RESTART_LABEL','post-repair')
eid=json.load(open('dev-environment.response.private.json'))['id'];e=call('getEnvironment',{'id':eid},label+'-before')
assert e['state']=='stopped' and e['execution']['cleanup']=='complete'
o=poll(mutate('startEnvironment',{'id':eid,'if_match':'"'+str(e['version'])+'"'},label+'-start'))
e=call('getEnvironment',{'id':eid},label+'-running');print('Restart ready:',e['state'],'new execution',e['execution']['id'])
````

### File: revoke-publication.py

````python
from rest import *
name=os.environ.get('FIXTURE_STAGE','dev')
c=json.load(open(name+'-publication.response.private.json'))
call('revokeRepositoryCredential',{'id':c['repository_id'],'credential_id':c['id']},name+'-publication-revoked')
print(name,'publication credential revoked')
````

### File: run.sh

````sh
#!/bin/sh
# Creates and eventually deletes only a fresh disposable synthetic fixture.
# Run once in a new directory. On failure observe private intents; do not rerun.
set -eu
umask 077
: "${NEWDAY_CLI:?Set the absolute path to your installed ordinary newday CLI}"
: "${NEWDAY_CREDENTIALS:?Set your ordinary private client credential file}"
: "${RUN_DIR:?Set a new absolute working directory}"
case "$RUN_DIR" in /*) ;; *) echo 'RUN_DIR must be absolute' >&2; exit 1;; esac
if [ -e "$RUN_DIR" ]; then echo 'Refusing an existing RUN_DIR; observe its saved intents instead.' >&2; exit 1; fi
package_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
mkdir -m 700 "$RUN_DIR"
cp "$package_dir"/*.py "$RUN_DIR/"
cp -R "$package_dir/source" "$RUN_DIR/source"
ln -s "$NEWDAY_CLI" "$RUN_DIR/newday"
cd "$RUN_DIR"
origin=${NEWDAY_ORIGIN:-https://botfolio.com}
curl -fsSL "$origin/agent-start.md" -o agent-start.md
curl -fsSL "$origin/v1/openapi" -o openapi.json
# Copy final published source, then seed the disposable development demonstration.
printf '%s\n' fresh-public-v1 > source/message.txt
python3 rest.py
# All dependencies are prepared externally; no Environment package egress.
docker build -t fresh-public-dev:example source > dev-build.private.log 2>&1
python3 publish.py
python3 revoke-publication.py
cp source/* dev-git/
git -C dev-git switch -c fresh-public-work
git -C dev-git add .
git -C dev-git -c user.name='Public example actor' -c user.email='example@example.invalid' commit -m 'Add isolated HTTP database example'
tar -C dev-git -cf source-git.private.tar .
python3 start-dev.py
ssh-keygen -t ed25519 -N '' -C public-example -f ssh-key.private > ssh-keygen.private.log
ACCESS_LABEL=first python3 access.py
python3 preview.py
python3 ssh-edit.py
SELECT_LABEL=edited EXPECTED_MESSAGE=fresh-public-v2 python3 reselect.py
STOP_LABEL=persistence-stop python3 stop.py
RESTART_LABEL=persistence python3 restart.py
ACCESS_LABEL=persistence python3 access.py
SELECT_LABEL=persistence EXPECTED_MESSAGE=fresh-public-v2 python3 reselect.py
tested_commit=$(cat tested-commit.txt)
case "$tested_commit" in *[!0-9a-f]*|'') echo 'Invalid tested commit' >&2; exit 1;; esac
[ "${#tested_commit}" -eq 40 ]
ssh -F ssh-config.private fresh "cd /workspace && test \"\$(git rev-parse HEAD)\" = '$tested_commit' && test -z \"\$(git status --porcelain)\" && python3 test.py http://127.0.0.1:8080 fresh-public-v2" > persistence-ssh.private.log 2>&1
python3 export-release.py
python3 push-tested.py
FIXTURE_STAGE=release python3 publish.py
FIXTURE_STAGE=release python3 push-tested.py
FIXTURE_STAGE=release python3 revoke-publication.py
python3 start-release.py
FIXTURE_STAGE=release EXPECTED_MESSAGE=fresh-public-v2 python3 preview.py
STOP_LABEL=final-stop python3 stop.py
python3 cleanup.py
printf '%s\n' 'Disposable journey and observed cleanup completed; preserve private receipts.'
````

### File: source/Dockerfile

````dockerfile
FROM docker.io/library/debian:bookworm-slim@sha256:88200866dfff7ea7f5cbcb6ec7c8a701889efe6fe859fe64d6990e4b07ea4171
RUN apt-get update && apt-get install -y --no-install-recommends python3 python3-psycopg2 openssh-server git ca-certificates && rm -rf /var/lib/apt/lists/* && groupadd -g 10000 dev && useradd -m -u 10000 -g 10000 -s /bin/sh dev && passwd -d dev && mkdir -p /workspace /run/sshd && chown dev:dev /workspace
COPY --chown=10000:10000 . /opt/app/
USER 10000:10000
WORKDIR /workspace
CMD ["/bin/sh", "/opt/app/start.sh"]
````

### File: source/README.md

Save this file without a final newline.

````markdown
# source

Newday Core repository d60ef1d3-e66c-4bba-a179-d46aef2bd21d
````

### File: source/app.py

````python
import http.server,json,os,pathlib,psycopg2
ROOT=pathlib.Path(__file__).parent
class Handler(http.server.BaseHTTPRequestHandler):
 def do_GET(self):
  if self.path=='/health': return self.reply(200,{'ok':True})
  if self.path!='/': return self.reply(404,{'error':'not found'})
  try:
   with psycopg2.connect('') as db:
    with db.cursor() as cur:
     cur.execute('SELECT value FROM public.fresh_note WHERE id=1'); value=cur.fetchone()[0]
   self.reply(200,{'message':(ROOT/'message.txt').read_text().strip(),'database_value':value})
  except Exception: self.reply(503,{'error':'database unavailable'})
 def reply(self,status,value):
  b=json.dumps(value).encode();self.send_response(status);self.send_header('Content-Type','application/json');self.send_header('Content-Length',str(len(b)));self.end_headers();self.wfile.write(b)
http.server.ThreadingHTTPServer(('0.0.0.0',8080),Handler).serve_forever()
````

### File: source/message.txt

````text
fresh-public-v2
````

### File: source/migrate.py

````python
import sys,psycopg2
from psycopg2 import sql
runtime_role=sys.argv[1]
with psycopg2.connect('') as db:
 with db.cursor() as cur:
  cur.execute('CREATE TABLE IF NOT EXISTS public.fresh_note (id integer PRIMARY KEY, value text NOT NULL)')
  cur.execute("INSERT INTO public.fresh_note VALUES (1,'isolated-database-ok') ON CONFLICT (id) DO NOTHING")
  cur.execute(sql.SQL('GRANT SELECT ON public.fresh_note TO {}').format(sql.Identifier(runtime_role)))
print('migration complete; explicit runtime SELECT granted')
````

### File: source/sshd.pid

````text
4
````

### File: source/start.sh

````sh
#!/bin/sh
set -eu
if [ -f /var/run/core-environment-access/sshd_config ]; then
  # Keep injected database environment in volatile scratch, outside the workspace.
  python3 -c 'import json,os; open("/tmp/app-env.json","w").write(json.dumps({k:v for k,v in os.environ.items() if k.startswith("PG")}))'
  chmod 600 /tmp/app-env.json
  /usr/sbin/sshd -D -e -f /var/run/core-environment-access/sshd_config &
  if [ ! -f /workspace/app.py ]; then cp /opt/app/*.py /opt/app/message.txt /workspace/; fi
  cd /workspace
else
  cd /opt/app
fi
exec python3 app.py
````

### File: source/test.py

````python
import json,sys,urllib.request
base=sys.argv[1].rstrip('/');message=sys.argv[2]
headers={}
if len(sys.argv)>3:
 import pathlib
 headers['Authorization']='Bearer '+pathlib.Path(sys.argv[3]).read_text().strip()
def get(path):
 with urllib.request.urlopen(urllib.request.Request(base+path,headers=headers),timeout=20) as r: return json.load(r)
assert get('/health')=={'ok':True}
assert get('/')=={'message':message,'database_value':'isolated-database-ok'}
print('PASS health + exact message + database query')
````

### File: source/with-app-env.py

````python
import json,os,sys
os.environ.update(json.load(open('/tmp/app-env.json')))
os.execvp(sys.argv[1],sys.argv[1:])
````

### File: source-sha256.json

````json
{
  "Dockerfile": "28d9c1ff8b21fd9b27837e1e9f2c3ae61bd22361e3727739aea8e31b532a6500",
  "README.md": "d23d479f30eb8eb4bfe96c1b3ab15d413bd4cc8a0fa337ebc1866d5962f898c9",
  "app.py": "b14c5256e8720b6df52437b8395a3fc86c9b59286139c7d1f8b6e41c30122eb8",
  "message.txt": "afcf5534a1c4acaeb9e8e950a7df1bbda98afdd2c5ac60924baa69abd6b1a38e",
  "migrate.py": "c36b09c4ded20f81b1123309189c4823faab388f97dea96688427e448e82fe10",
  "sshd.pid": "7de1555df0c2700329e815b93b32c571c3ea54dc967b89e81ab73b9972b72d1d",
  "start.sh": "be7cbb07089a93a3250e2c470651addbbef10fc9aaf805eadace006625d0441f",
  "test.py": "8dae23e7efd9e19ea4398b175760ab8b8bed66da155ec4c29aacbd58c5124cad",
  "with-app-env.py": "cce7aa9b6937f4b715876a1f0a229325c349ee5c8c336521333174b1eaca384c"
}
````

### File: ssh-edit.py

````python
from rest import *
def ssh(command,data=None,label='ssh'):
 r=subprocess.run(['ssh','-F','ssh-config.private','fresh',command],input=data,capture_output=True)
 (ROOT/(label+'.stdout.private')).write_bytes(r.stdout);(ROOT/(label+'.stderr.private')).write_bytes(r.stderr)
 if r.returncode: raise RuntimeError(label+' SSH exit '+str(r.returncode)+' '+r.stderr.decode()[:300])
 print(label,'PASS');return r.stdout
ssh('id -u; python3 /workspace/test.py http://127.0.0.1:8080 fresh-public-v1',label='ssh-baseline')
ssh('tar -xf - -C /workspace',data=(ROOT/'source-git.private.tar').read_bytes(),label='ssh-source-transfer')
ssh("cd /workspace && printf '%s\\n' fresh-public-v2 > message.txt && python3 test.py http://127.0.0.1:8080 fresh-public-v2 && git add . && git -c user.name='Fresh public actor' -c user.email='fresh@example.invalid' commit -m 'Test SSH edit and explicit runtime grant' && git rev-parse HEAD && git status --porcelain",label='ssh-edit-test-commit')
commit=ssh('cd /workspace && git rev-parse HEAD',label='tested-commit').decode().strip();(ROOT/'tested-commit.txt').write_text(commit+'\n');print('Tested commit',commit)
````

### File: start-dev.py

````python
from rest import *
def load(n): return json.load(open(n+'.response.private.json'))
c=load('dev-component'); r=load('dev-repo-get'); d=load('dev-database')['target']['id']; image=load('dev-resolved')['image']
db=call('getDatabase',{'id':d},'dev-db-get')
a=poll(mutate('issueDatabaseCredential',{'id':d,'body':{'role':'migration','ttl_seconds':900}},'dev-migration-credential')); print('Migration credential ready')
spec={'image':image,'command':['python3','/opt/app/migrate.py',db['runtime_role']],'cpu_millis':250,'memory_mib':256,'scratch_mib':32,'network':'database','timeout_seconds':120,'artifact_binding':{'repository_id':r['id']},'database_binding':{'database_id':d,'credential_id':a['result']['credential_id']}}
o=poll(mutate('createJob',{'parent_id':c['id'],'body':spec},'dev-migration-job')); print('Migration',o['state'])
spec.update(command=['/bin/sh','/opt/app/start.sh'],database_binding={'database_id':d},timeout_seconds=7200,port=8080,readiness_path='/health',startup_timeout_seconds=120,private_access={'transport':'headscale','protocol':'ssh'},development={'workspace_mib':1024,'idle_timeout_seconds':3600})
e=mutate('createEnvironment',{'parent_id':c['id'],'body':spec},'dev-environment'); print('environment',e['id'])
o=poll(mutate('startEnvironment',{'id':e['id'],'if_match':'"'+str(e['version'])+'"'},'dev-start')); print('Started',o['state'])
e=call('getEnvironment',{'id':e['id']},'dev-running'); print('ready state',e['state'],'execution',e['execution']['id'])
````

### File: start-release.py

````python
from rest import *
def load(n):return json.load(open(n+'.response.private.json'))
c=load('release-component');r=load('release-repo-get');db=call('getDatabase',{'id':load('release-database')['target']['id']},'release-db-get');image=load('release-resolved')['image']
a=poll(mutate('issueDatabaseCredential',{'id':db['id'],'body':{'role':'migration','ttl_seconds':900}},'release-migration-credential'))
spec={'image':image,'command':['python3','/opt/app/migrate.py',db['runtime_role']],'cpu_millis':250,'memory_mib':256,'scratch_mib':32,'network':'database','timeout_seconds':120,'artifact_binding':{'repository_id':r['id']},'database_binding':{'database_id':db['id'],'credential_id':a['result']['credential_id']}}
o=poll(mutate('createJob',{'parent_id':c['id'],'body':spec},'release-migration-job'));print('Release migration Job',o['state'])
spec.pop('timeout_seconds');spec.update(command=['/bin/sh','/opt/app/start.sh'],database_binding={'database_id':db['id']},port=8080,readiness_path='/health',startup_timeout_seconds=120)
o=poll(mutate('createDeployment',{'parent_id':c['id'],'body':spec},'release-deployment'))
d=call('getDeployment',{'id':o['target']['id']},'release-running');print('Release Deployment',d['state'],'execution',d['execution']['state'])
````

### File: stop.py

````python
from rest import *
label=os.environ.get('STOP_LABEL','repair-stop')
eid=json.load(open('dev-environment.response.private.json'))['id']; e=call('getEnvironment',{'id':eid},label+'-before')
o=poll(mutate('stopEnvironment',{'id':eid,'if_match':'"'+str(e['version'])+'"'},label));print('Stop operation',o['state'])
for i in range(150):
 e=call('getEnvironment',{'id':eid},label+'-observed-'+str(i))
 if e['state']=='stopped' and e['execution']['cleanup']=='complete': print('Stopped; execution cleanup complete; workspace retained');break
 time.sleep(2)
else:raise RuntimeError('Cleanup not observed before deadline')
````
