kcode-k1-chat-thread-actions 0.5.0

In-memory Kmap actions and session state for K1 chat threads
Documentation
# Chat thread actions

`ChatThreadActions::new(Arc<K1AccessKmap>)` creates the in-memory action owner for one chat thread. `bind_authorization` installs the current turn's `AccessContext`, active `ProfileId`, and create `AccessPolicy`; an identical binding of all three values is idempotent, while a binding that differs in any value is rejected until `clear_authorization` is called. The profile ID is metadata for node creation; the policy continues to control authorization. Clearing authorization preserves all session Kmap state.

`launch(&mut self, name, arguments)` supports `CurrentTime`, `KmapCreateNode`, `KmapOpenNode`, `KmapUpdateNode`, `KmapPenalizeNodes`, and `KmapConnectNodes`. Arguments are strict JSON objects with the documented snake_case fields. Kmap IDs are exactly 24 lowercase hexadecimal characters. Invalid arguments return `invalid <ToolName> arguments`, and unknown names return `unknown Ktool`.

`CurrentTime` needs no authorization. Every Kmap action requires a binding. `KmapCreateNode` passes the active profile ID as creation metadata. Kmap dependency errors remain errors, while successful actions return plain text. Open results suppress node components already returned during the session. Loaded-node order, first Open provenance, returned components, and penalties survive authorization clearing and rebinding.

Penalization applies one noncritical, non-useful measurement for each newly penalized loaded node that has Open provenance. Connect completes the directed Automated graph over loaded, unpenalized nodes without replacing existing Navigation or Automated edges.

```rust
use std::sync::Arc;

use kcode_k1_access_kmap::{
    AccessContext, AccessPolicy, K1AccessKmap, ProfileId,
};
use kcode_k1_chat_thread_actions::ChatThreadActions;

fn turn(
    kmap: Arc<K1AccessKmap>,
    context: AccessContext,
    profile_id: ProfileId,
    policy: AccessPolicy,
) -> Result<String, String> {
    let mut actions = ChatThreadActions::new(kmap);
    actions.bind_authorization(context, profile_id, policy)?;
    let result = actions.launch("KmapConnectNodes", "{}")?;
    actions.clear_authorization();
    Ok(result)
}
```