# @xyo-network/dapp-kit

Portable, environment-neutral model and validation contracts for headless XL1
dApps.

The package contains pure schemas, canonical document encoding/hashing,
deterministic cross-document validation, neutral lifecycle ownership facades,
durable effect contracts, and capability-driven XL1 transaction reconciliation.
Dapp-kit
documents use RFC 8785 JCS with document-kind domain separation and SHA-256;
this codec is intentionally distinct from XYO payload and Bound Witness hashing.
Current policy models cover actor effect authority,
datalake access/protection/availability constraints, and opaque auxiliary-store
capability bindings. Projection models add reducer/input declarations,
per-chain floors, durable capability bindings, and verifiable checkpoint
positions. Deterministic reducer and publication traces cover canonical input
order, exact redelivery, historical protocol input, immutable generation
hashing, and verified publish-head-last visibility. Coordination models make
non-canonical side-channel criticality, limits, detached-signing capabilities,
replay, audience, and expiry explicit.
The D-029 neutral foundation adds version-aware document domains, stable event
identity, complete accepted-byte fingerprints, strict event draft/record
schemas, and pure append decisions for new, duplicate, and colliding events.
It also defines retained/external event-stream and event-subscription resource
requests, exact subscription-to-stream dependencies, `idle | scheduled |
running | blocked` cursor transitions, fresh lease fences, exact durable
consumer outcome proofs, retry-bound poison blocking, and a bounded `for await`
pump over injected stream/subscription/consumer ports. Atomic append/read port
contracts and a coalescing, generation-fenced wake-outbox state machine ensure
that stale delivery completion cannot clear a newer request. This is neutral
model and deterministic runtime evidence; it does not claim a crash-durable
event provider, fan-out adapter, provider wake delivery, or exactly-once
transport.
External observation models bind declared source, provenance/finality evidence,
and typed content hashes while generic outbound actuation remains rejected in
V1. Pure lifecycle transitions cover bounded boot, pre-ready stop, draining,
failure teardown, and idempotent terminal stop. Status documents keep health,
liveness, readiness, per-operation writability, convergence, and incarnation
identity separate. `planXl1TransactionEffect()` derives the next baseline action
from a valid append-only receipt. `createXl1TransactionEffectReconciler()`
dispatches that action through stage-specific injected capabilities and checks
returned evidence against the planned content, transaction, or inclusion.
`recoverEffectJournal()` captures a finite, effect-ID-ordered snapshot of every
incomplete durable receipt, reconstructs each prepared prefix, selects a
reconciler from its durable identity, and returns bounded
complete/pending/cancelled/effect-limit state. The
package performs no provider acquisition, actor construction, key custody,
replay scheduling, or ambient host access. Capability-driven operations call
only the explicitly supplied ports; concrete transports remain host adapters.

`isEffectPreparationCompactable()` requires durable signed evidence and the
receipt summary's latest verified availability for every required content hash.
Later known content loss prevents compaction even after finality. Retaining
material increases storage/private-material lifetime; this predicate does not
define authorized repair for arbitrary codecs. Already admitted signed work
resumes its exact prepared prefix without recreating compacted preparation,
including after availability regression. The selected repair capability must
validate its retained codec/body evidence; absent material stays pending or
fails closed. The concrete Node hydrated codec retains repairable body/ciphertext
bytes in the signed receipt; automatic ongoing loss detection is separate.

`ObjectStoreReader` and `ObjectStoreWriter` define the portable byte-object
capability used by projection and checkpoint resources. The contract includes
conditional writes, content metadata, deterministic listing, and paging without
exposing a filesystem path, S3 bucket, database handle, or provider lifecycle.
`PrefixedObjectStore` and `RoutedObjectStore` compose least-scope logical views;
concrete durable implementations remain host adapters.

`DatalakeObjectStore` maps byte objects to immutable XYO payloads and logical
references in an injected atomic control store. It verifies payload readback
before publishing a reference, preserves `ifNotExists` / `ifMatch` semantics,
and retains payloads after failed writes or reference deletion.
`DatalakeObjectReader` needs only read capabilities, including anonymous public
viewers. Both validate original-byte SHA-256/size separately from SDK payload
identity. `stat` validates reference metadata without fetching content.
Defaults bound objects to 16 MiB, references to 64 KiB, and complete listings to
10,000 keys / 10,001 pages. Hex envelopes require roughly twice the original
byte budget at the transport. Transport deadlines, authentication, durable
atomicity, and exact-operation retries belong to the supplied capabilities.
This bridge does not provision or qualify a storage backend.

V1 side-channel envelopes use domain-separated JCS/SHA-256 signing hashes and
XYO-compatible compact secp256k1 signature bytes. The neutral validator invokes
an injected detached-signature verifier keyed by the authorized sender role; it
does not own keys, construct accounts, or import a concrete signer/verifier.

Identity bindings remain opaque capabilities. Optional deterministic metadata
records canonical XL1 BIP-44 child paths, expected addresses, exact-chain scope,
and explicit rotation without carrying mnemonic or private-key material.

This package is licensed under the GNU Lesser General Public License version 3
only (`LGPL-3.0-only`), not "or later", as its manifest declares; the full terms
are in the `LICENSE` file included in this package. Earlier versions were published with
`UNLICENSED` metadata, and this statement does not describe them. The
repository's remaining governance decisions (maintainer approval, schema
allocation, and compatibility and upgrade policy) are still open.

`evaluateDappReleaseEvidence` and `recheckDappReleaseEvidence` provide pure,
strict release eligibility over supplied source, workflow and deployment evidence.
Latest runs and deployment statuses supersede earlier successes; snapshots bind
exact source and run attempts. These APIs grant no deployment authority and do
not replace provider receipts, fencing or application recovery. See the repository's
`docs/BETA_RELEASE_EVIDENCE.md` for the adapter contract and evidence boundaries.

The additive D-040 engine model exports `DappEngineConfigurationZod`,
`DappEngineStatusZod`, `validateDappEngineStatus`,
`validateDappEngineSystemReference` and `validateDappEngineSystemReplacement`.
It preserves per-system launch/incarnation identity, required/isolated policy,
profile selection, and offline or chain/genesis bindings. Aggregate readiness
is separate from per-operation writability and per-network convergence. These
functions validate supplied documents; they do not launch systems, verify an
endpoint's chain identity, replace a graph, or authorize a write.

`launchDappEngine` owns multiple injected existing DappLaunch handles under the
engine model. It returns before boot, validates launcher coverage and identity,
aggregates required/isolated failure, and requests every child stop before
awaiting teardown. The ownership facade exposes status, readiness, terminal
failure, stop and trusted-host `replaceSystem`/`bindSystemWork`; it exposes no child ports or
locators. Replacement requires an exact current reference and fresh launch ID,
closes and drains the old graph before acquiring the new one, and preserves its
logical identity, network and failure policy while allowing a profile change.
Unrelated ready systems remain available. Stop owns in-flight replacement;
retired launch/incarnation IDs cannot be reused to revive stale references.
Explicit stop retains all observed lifecycle/cleanup failures, including isolated
failures, in an AggregateError. Both launch and session expose passive
`whenStopped()`: the same retained promise as `stop()`, settling after complete
teardown without initiating it. `whenTerminal()` remains the failure-only signal. `bindSystemWork` checks an exact ready reference
and delegates dynamic work ownership to the existing child session. Session
`bindWork` reserves ownership before a synchronous work factory runs, retains
detached work through drainage, and closes every registered owner before system
teardown. The port package uses this seam for engine-aware dispatch; platform
transport integration and recovery admission have separate qualification gates.

### Operation recovery readiness

`DappOperationRecoveryProfileZod` classifies selected operations as read-only,
externally recovered or kit-journal-backed. `DappOperationRecoverySnapshotZod`
reports one operation's safe readiness against an exact engine/incarnation,
plan, network/genesis and opaque authority scope. `validateDappOperationRecoveryAdmission`
checks binding, capability kind, required guarantees and readiness. Its success
is neither authorization nor durability qualification. Uncertain, pending,
unavailable and corrupt outcomes remain explicit; a read-only check requires
no private snapshot. The kit receipt executor remains authoritative for its own
operations, and this model never synthesizes a second durable journal.

The language-neutral vectors are in `conformance/recovery/admission.json` and
run through public package imports in Node and Chromium. Browser write admission
still requires the selected adapter's actual interruption/exclusion evidence.

### Bounded current-head observation

`createDappHeadObserverState`, `requestDappHeadObservation`,
`claimDappHeadObservation` and `completeDappHeadObservation` retain one cell per
exact source hash and logical consumer. Requests coalesce a position-only hint;
completion accepts an independently verified `{ sourceHash, position, root }`.
Request timestamps are validated host metadata and coalesce their maximum;
generations and conditional commits order requests even when captured times
arrive out of order. Lease and dispatch operations use their actual injected
clock without clamping it to request metadata. Canonical XL1 time remains chain
evidence; request metadata never advances verified freshness or changes a lease
duration. Completion retains its acquisition, expiry and verification checks.
Verified heads never regress or change root at the same position. Captured
generations and lease fences preserve concurrent arrivals and reject stale or
expired workers. `reserveDappHeadObserverScheduling` and
`finishDappHeadObserverScheduling` bound disposable dispatch reservations;
`recoverDappHeadObservation` supports quiet-source refresh and lease recovery.
The `running` status describes a persisted lease, not a live process. This mode
does not append per-hint events/results or provide complete history; use the
separate finalized replay and durable event contracts when those are required.
