kcode-commit-session 0.1.2

Atomic, idempotent materialization of completed Kennedy sessions into Kweb
Documentation
# API

`kcode-commit-session` exposes one synchronous business operation:

```rust
pub fn commit_session(
    database: &kcode_kweb_db::KwebDb,
    receipt_database: &std::path::Path,
    request: CommitRequest,
) -> Result<CommitReceipt, Error>;
```

`CommitRequest` contains a stable idempotency key, provenance author and source
time, a sealed archive payload, already encoded object payloads keyed by
`pending:N`, planned node creates keyed by `pending:N`, and planned canonical
node updates keyed by `NodeId`.

```rust
pub struct CommitRequest {
    pub idempotency_key: String,
    pub author: String,
    pub source_created_at: chrono::DateTime<chrono::Utc>,
    pub archive: Vec<u8>,
    pub objects: BTreeMap<String, Vec<u8>>,
    pub creates: BTreeMap<String, PlannedNode>,
    pub updates: BTreeMap<NodeId, PlannedNode>,
}
```

`PlannedNode` uses strings only where a reference may still be pending.
Canonical node and object references must parse as Kweb IDs. Owners are
`"unowned"`, `"self"`, a canonical node ID, or a pending node ID.

```rust
pub struct PlannedNode {
    pub short_name: String,
    pub short_description: String,
    pub long_description: String,
    pub owner: String,
    pub fixed_connections: Vec<String>,
    pub recent_connections: Vec<String>,
    pub objects: Vec<String>,
    pub attach_session_archive: bool,
}
```

The receipt uses Kweb's ID types:

```rust
pub struct CommitReceipt {
    pub transaction_id: Option<TransactionId>,
    pub session_object_id: ObjectId,
    pub node_ids: BTreeMap<String, NodeId>,
    pub object_ids: BTreeMap<String, ObjectId>,
}
```

Receipts serialize to Kennedy's existing camel-case checkpoint representation.
`PlannedNode::attach_session_archive` serializes as the historical
`includeSessionObject` field and also accepts `attachSessionArchive`.

`Error::kind()` returns `InvalidInput`, `NotFound`, `Conflict`, or `Internal`.
A conflict means the idempotency key already names a different version-2
request. The display text is suitable for diagnostics; adapters should hide
`Internal` details from remote callers.

The caller must provide the global scheduling policy for receipt-database
writes. The function opens and migrates the receipt database on each call.