# Data and keys

Where a World's data lives, which credentials grant access, and which operations use the network.
The [model](./the-model.md) defines the distinction between a simulated branch and a real root.

## Where your data lives

The local product stores configuration and state under `.volter/`:

```text
.volter/
  world.json            portable configuration
  handlers/ seeds/      scenario rules and seed source
  .gitignore            excludes live state and credentials
  world.env             generated live environment
  current               checked-out branch
  worlds/<branch>/      instance record, service data and process logs
```

The kernel’s `VOLTER_STATE_DIR` setting accepts relative directories, including nested paths.
Absolute paths and `..` components are refused before storage creation or removal.

The log has one entry model. In the file store, inherited entries and branch entries occupy
separate segments (`events.jsonl` and `actions.jsonl`). Immutable descriptors under `views/`
retain segment ranges, their hashes and their storage dependencies. A branch records its parent
view and position. A URL parent's cache shares unchanged rows in `origin.jsonl`;
`origin-head.json` selects the latest complete fetch. Older views and checkpoints remain local. These files do not represent independent
mirror and action truth systems. Package-specific payloads may occupy additional files.

A World fetched from a real root can hold real records in plain text. Running-state directories
are created owner-only (`0700`) and files owner-only (`0600`), without encryption at rest.
Protect the disk and keep instance data out of version control and diagnostic bundles.

## Stopping and deleting

`volter world down` stops compute and retains state for the next `up`.
`down --purge` deletes the stopped branch's instance directory after verified teardown.
`reset` discards the current branch's state, boots and seeds default data; it keeps the origin,
so a later pull can fetch that history again. Local descendants can still depend on this
branch’s history by path: reset and purge refuse while a registered child or a child in the
current World tree references it. Ordinary stop retains that history. See
[branch lifetime and legacy compatibility](./the-model.md) before removing old storage.

Prune removes eligible stopped instance files separately from stopping. It never infers ownership
from age or stops a live World to make room. Failed or uncertain cleanup retains its records.
Do not manually remove state behind a live process. See the
[operator CLI](../reference/cli.md#volter-world) for ownership and cleanup commands.

File deletion is not secure erasure and does not remove backups. Immutable BlobStore payloads
may be hardlinked across Worlds on the same filesystem; deleting one owner leaves the other
owner's bytes available until the last owning file is removed.

## Vendor credentials

A twin that holds its keys issues the app's: its package names a credential endpoint and the env names
it fills, `init` writes `$issue:<twin>` for each of those names the app declares while that twin
is in the World, and `up` asks the running twin's credential endpoint once it is up and sets the names to what
it answers — a key the twin made and will accept, the same one on every boot of that World. A
name no twin issued (an endpoint that failed, or a twin no longer in the World) is left unset, with a
message; no service or app is ever handed the `$issue:` marker. Stripe's credential endpoint also issues the
webhook signing secrets, and an endpoint made for the app is signed with them, so the app
verifies its first delivery with no key copied from a dashboard.

Other names use fake credentials. An SDK that parses credentials locally may need a
structurally valid throwaway key, produced by the runtime's fake-credential generator. A twin's
secrets are drawn from a seed its World makes once at random, so no one computes them from what
the World shows.
Tokens can encode a synthetic identity; the twin manifest explains its authentication behavior.

A real-system root holds the vendor credential sealed beside that World. Refresh and real
execution open it through the kernel's custody and executor paths. `volter twin <vendor> credential`
seals it from what is piped in, from a vault the person is signed in to (`kv/vendors/<vendor>`), or
from the repo's `.env`; a vault is never required, and neither a World's apps nor a command run in
a World receives the sign-in (`BAO_*`, `VAULT_*`). A client can use that World
without receiving the vendor credential. The authority of its World token still matters:
a token with write access to a root using `auto` deployment can cause real vendor writes.

## World tokens

A World token grants access to a shared World. A read token grants history and vendor-API reads;
it does not grant writes. Clone and remote configuration store tokens in the user's configuration
directory (`~/.config/volter/credentials.json`, or the XDG equivalent), keyed by remote URL.
Treat these tokens as credentials and keep them out of committed files and diagnostic output.
The [HTTP API](../reference/http-api.md) specifies token scope and the separate host admin token.

## Network activity

Simulated vendor requests use local state; they do not call the real vendor. Clone, fetch and
push can contact another World. Refresh contacts the configured vendor, and real-system writes
or deployment contact it through the root's executor. Installing packages contacts a registry.

The local runtime has no analytics, crash reporting or update check. Sandbox mode governs
cooperating clients through injection and proxy settings. Raw sockets and binaries that ignore
those settings require a separate enforced network boundary for a zero-egress guarantee.
