# ECHO Authority Conservation — reference 0.1

Status: an optional, bounded reference profile with simulated effects. Run the
[browser challenge](index.html), or download `/conservation-runtime.zip` and run:

```sh
node conservation/demo.mjs race
node conservation/demo.mjs offline
node conservation/demo.mjs timeout
node --test scripts/conservation-regressions.mjs
# Install cryptography==46.0.0 for the Python verifier and cross-language tests.
python3 conservation/verify.py EVIDENCE.json INDEPENDENT_PINS.json
node conservation/verify.mjs EVIDENCE.json INDEPENDENT_PINS.json
```

Node 22.13+ is required for built-in SQLite; Node 24 is recommended. The core,
Node demonstration and JavaScript verifier have no third-party dependencies.
The two-process demo creates private temporary directories with encrypted test
keys, durable owner/executor databases, and synthetic public evidence. It prints
the directory. Test key passphrases are discarded at exit; this is not a user vault.
The browser uses volatile in-page stores and simulated time. Reloading starts a
different demonstration, never a recovery of existing authority.

## Three running pieces

1. **Conservation:** one coordinator reserves a total allowance across two pinned
   execution services. Offline executors spend only preallocated, disjoint slices.
2. **Minimal action evidence:** a signed export contains one root, slice, challenge,
   delegate approval and executor receipt. Other allocations and journal entries
   are absent. It is not a zero-knowledge proof.
3. **Strict translation:** two explicit simulation adapters translate the same
   exact merchant, integer amount and currency. Unsupported fields, capabilities,
   currencies and adapters refuse. There is no natural-language interpretation,
   inferred user intent, OAuth/AP2 integration, or production payment adapter.

This profile is `ECHO-CONSERVATION/1`. All HAP-1, WebAuthn and PULSE signed bytes
and semantics remain unchanged. It imports HAP's existing canonical encoding and
key-fingerprint helpers; this does not turn its evidence into HAP authority. A
GENESIS number does not grant an allowance. No token, account, Money Musk service
or network connection is needed after downloading the kit.

## Guarantee and assumptions

For one correctly operated root:

```
sum(all issued slice amounts) <= the root's approved ceiling
sum(consumed amounts in each slice) <= that slice's amount
```

Both limits include uncertain, failed and stopped actions. Issued slices are
**never refunded or reassigned in this version**, including unused expired slices.
Consumption precedes calling the effect. A replay, new agent identity or new
request ID cannot create extra allowance through these gates.

These properties require a trustworthy owner/coordinator, a single authoritative
durable store for that root, correctly pinned keys, and one durable execution
state per executor identity. The owner-only allocation API is not exposed to
agents. Operators provision executor/delegate/adapter pairs independently. All
effect credentials stay at the enforcing executor; alternate raw tools must not
bypass it. A malicious issuer, malicious executor, cloned executor state, or
restoration of all state to an earlier snapshot can defeat these assumptions.
An owner can explicitly issue another independent root; this protocol does not
impose a universal spending limit across all roots, accounts or payment rails.

SQLite uses the existing HAP private-directory, WAL, FULL-synchronous and CAS
adapter. Separate coordinator handles serialize reservations in that same
database. This is not a multi-region consensus database. Missing state fails
closed unless explicit new provisioning was requested. Normal restarts preserve
consumption and revocation. This kit does not provide anti-rollback hardware,
independent witnesses, global non-equivocation, or restoration authorization.

The Node demonstration runs two **project implementations in separate processes
on one host**. Its inherited IPC harness is not a public RPC server or sandbox for
hostile agents. Third-party implementation, independent operator deployment and
real-provider validation remain separate work.

## Root, slices and live dispatch

The owner signs a root: a random 128-bit identifier, owner-key fingerprint,
ceiling (1–1,000,000,000 integer EUR cents), exact merchant, issuance and expiry.
Root lifetime is at most 24 hours. There are at most eight provisioned pairs and
128 allocations. Each allocation binds an exact executor key, delegate key and
one supported adapter, along with amount, 1–16 uses and a maximum five-second
lifetime. The owner commits the whole slice before returning it. Reusing an
allocation ID with identical input returns the same slice; altered input refuses.

1. The executor verifies the root and slice against independently retained pins.
2. It compiles the exact action and persists a signed, random pending challenge.
   The challenge binds root digest, slice digest, executor, delegate, adapter,
   full intent, command digest and deadline. Its deadline cannot exceed the slice.
3. The delegate verifies those bindings and signs the challenge digest with its
   separate key. A copied signature cannot approve another command or audience.
4. The executor verifies the approval and exact compiled command. Its durable
   transaction consumes the pending challenge, amount and use before any effect.
5. After storage acknowledgement, a final synchronous check refuses expired,
   locally stopped or authentically revoked work before invoking the callback.
6. A receipt records `DISPATCHED` if the configured callback returned, `UNKNOWN`
   if it threw, or `STOPPED` when the final gate refused. The pre-effect durable
   record is `CONSUMED`. Failure to save a later receipt leaves it consumed.

There is no automatic dispatch retry, refund, or settlement claim. The callback
gets a challenge-derived idempotency key and a `notAfter` deadline. Integrators
must enforce them at the actual irreversible operation; a callback that queues
work or performs additional asynchronous steps must recheck there. Database
commit and an external effect are not one atomic transaction. Use read-only
provider reconciliation before deciding what happened to an uncertain action.

The core snapshots external input before awaiting work. All amounts are safe
integers. The finite adapters reject unknown fields and round-trip their output
to the same exact intent. An extra condition such as `recurring`, even when the
adapter could ignore it, is rejected. This narrow profile makes no guarantee
about arbitrary API semantics or natural-language consent.

## Revocation, time and disconnection

An owner revoke prevents further allocations and produces an owner-signed revoke
bound to the root digest. An executor authenticates it before latching a stop and
persisting it. Invalid revoke messages cannot cancel valid work. A received revoke
fences callbacks still waiting on their consumption write acknowledgement; the
acknowledged revoked state survives restart. A local `stop()` latches the current
executor instance; use signed revocation for durable stop across restarts.

Disconnected executors cannot learn a revoke they have not received. They may
dispatch only within their already-issued five-second slice and fresh challenge.
They cannot obtain extra allowance while the owner is unreachable. An action
already dispatched cannot be recalled. Clock high-water marks detect observed
rollback across normal restarts, including refused expired requests. This is
software clock checking, not trusted hardware time or physical proximity proof.
These leases establish no human presence, legal identity or biological liveness.

## Wire and signatures

Canonical ASCII JSON follows the unchanged HAP grammar: lexicographically sorted
object keys, no duplicate keys, no extra whitespace (one trailing newline allowed),
no floating point, exponent spellings, negative zero or unsafe integers. This
profile's wire parser limits input to 64 KiB. All signed record shapes are exact;
unknown fields refuse. SHA-256 hashes canonical bytes. Ed25519 signatures cover:

```
ECHO-CONSERVATION/1/<kind> + "\n" + canonical(record without signature)
```

Kinds are `root`, `slice`, `challenge`, `approval`, `receipt` and `revoke`.
Schema is the same profile prefix followed by `/kind`. Hashes and public keys
are lowercase 64-character hex; signatures are 128-character hex. Root, slice
and challenge IDs are lowercase 32-character random hex. Identity fingerprints
use the existing `hash({schema:"HAP-1/key",publicKey})` helper. Golden inputs and
hostile mutations can be reproduced by the test suite.

Independently supplied pins contain exactly `rootId`, `issuer`, `executor`,
`delegate`, and `adapter`. A key included in an evidence file never establishes
its own trust. Demo pin files generated alongside evidence are setup examples;
they are not proof of an independent pairing ceremony.

## Evidence and privacy boundaries

An export contains only `schema`, `root`, `slice`, `challenge`, `approval` and
`receipt`. Its root ceiling, merchant, action amount, timestamps, public-key
fingerprints and adapter remain visible and can be linkable. There is no wallet
key, private signing key, raw heartbeat, biography, unrelated journal, or entire
allocation ledger. This avoids HAP's full-journal disclosure for this new profile;
it does not retrofit selective disclosure into HAP-1.

JavaScript and Python inspect the same signatures, scope, times and digest
bindings without consuming state. A valid result explicitly states:

- `historical: true`
- `authorizesExecution: false`
- `globalConservationProven: false`
- `settlementProven: false`

The verifier proves who signed the statements under the retained keys, not that
the issuer never issued a hidden slice or that an executor/provider behaved
honestly. `DISPATCHED` is an executor claim that its callback returned. It is not
payment settlement or a physical result. Both verifiers are authored by this
project, not independent audits or evidence of external adoption.

## Verification and next extensions

`scripts/conservation-regressions.mjs` exercises competing coordinator handles,
24 simultaneous allocation requests, per-slice concurrency, replay, key and
audience substitutions, parser ambiguity, scope changes, altered signed records,
missing state, normal restarts, uncertain effects, delayed/failed storage
acknowledgements, expiry and received revocation before dispatch. The Node demo
uses real SQLite and separate processes. Python agrees with JavaScript on the
positive and hostile evidence cases. Browser checks exercise all six scenarios,
export, verification, tampering and mobile layout. Passing these checks is bounded
reference evidence, not a claim of being unhackable or first in the world.

Further research: a reviewed cross-operator protocol and independent deployments;
privacy proofs for hidden aggregate accounting; and narrowly specified bridges to
real authorization/payment standards. These are not implemented by this release.
