# Runtime context

Harn exposes logical runtime identity through `runtime_context()`. This is the
task/thread abstraction Harn code should use for observability and debugging;
raw OS thread IDs are not part of the stable language surface.

`task_current()` is an alias for `runtime_context()`.

```harn
let ctx = runtime_context()
log(ctx.task_id)
log(ctx.parent_task_id)
log(ctx.root_task_id)
```

## Stable fields

These fields are stable API and always present. Unavailable values are `nil`.

| Field | Description |
|---|---|
| `task_id` | Current logical task id |
| `parent_task_id` | Parent logical task id, or `nil` for the root task |
| `root_task_id` | Root logical task id for this execution tree |
| `task_name` | Runtime label such as `root`, `spawn`, `parallel`, `parallel each`, or `parallel settle` |
| `task_group_id` | Shared id for siblings created by one `parallel` operation |
| `scope_id` | Optional host/runtime scope id |
| `workflow_id`, `run_id`, `stage_id`, `worker_id` | Workflow and delegated-worker identity when available |
| `agent_session_id`, `parent_agent_session_id`, `root_agent_session_id`, `agent_name` | Agent-loop session identity when available |
| `trigger_id`, `trigger_event_id`, `binding_key`, `tenant_id`, `provider` | Trigger-dispatch identity when available |
| `trace_id`, `span_id` | Current tracing identity when available |
| `scheduler_key`, `runner`, `capacity_class` | Scheduler/runtime hints when available |
| `context_values` | Task-local values for the current logical task |
| `cancelled` | Whether the current task has observed cancellation |

## Context values

Task-local values are stored on the current logical task. Children created by
`spawn`, `parallel`, `parallel each`, and `parallel settle` inherit a snapshot of
the parent values. Later child writes do not mutate the parent, and later parent
writes do not affect already-created children.

```harn
runtime_context_set("tenant", "acme")

let result = parallel each ["a", "b"] { item ->
  runtime_context_get("tenant")
}

assert_eq(result, ["acme", "acme"])
```

| Function | Description |
|---|---|
| `runtime_context_values()` | Return the current task-local values as a dict |
| `runtime_context_get(key, default?)` | Return a task-local value, `default`, or `nil` |
| `runtime_context_set(key, value)` | Set a task-local value and return the previous value or `nil` |
| `runtime_context_clear(key)` | Clear a task-local value and return the previous value or `nil` |

## Copying vs sharing

`spawn`, `parallel`, `parallel each`, and `parallel settle` create isolated
interpreter instances. Normal bindings, lists, dicts, structs, and task-local
context values are copied into the child at creation time. Later assignment in
one task does not mutate another task's binding.

Explicit handle values are shared by design:

| Handle | Shared behavior |
|---|---|
| `channel(...)` | Message transport shared by every task that receives the handle |
| `atomic(...)` | Shared integer cell |
| `sync_*_acquire(...)` | Shared named synchronization runtime |
| `shared_cell(...)` / `shared_map(...)` | Scoped process-local shared state |
| `mailbox_open(...)` | Targeted actor-style inbox |

`agent_loop` calls do not share transcript internals with tasks. A named
`session_id` shares durable transcript history through the agent session store.
`spawn_agent` workers get their own worker/session lineage; use explicit
mailboxes, shared state handles, `agent_state_*`, or host storage when a parent
and worker need data exchange outside the transcript.

## Debug fields

`runtime_context().debug` contains best-effort introspection for tools:
`active_task_ids`, `waiting_reason`, `cancelled`, and `held_synchronization`.
These fields are intended for diagnostics and may grow as the scheduler gains
more structured-concurrency and synchronization primitives.
