# Path C — `kind = 'NclTransform`

Phase B per ADR-030 — **declarable today, executive backend deferred**.
A declarative NCL data-transform spec (target file + JSONPath selector
+ operation + value expression) that needs no Rust handler. Awaits an
interpreter backend in `ontoref-daemon` once the expressive-power
trigger fires (≥3 real ops proven expressible in this shape).

## Files

| File | Purpose |
| --- | --- |
| [`rename_ontology_node.ncl`](rename_ontology_node.ncl) | Catalog declaration with `kind = 'NclTransform` and a fully-populated `body` |

## What the `body` declares

| Field | Value | Meaning |
| --- | --- | --- |
| `target` | `.ontology/core.ncl` | NCL file to mutate (relative to project root) |
| `selector` | `$.nodes[?(@.id == $inputs.node_id)].name` | JSONPath into the exported value, with `$inputs.<field>` substitution |
| `operation` | `'Set` | Replace the selected location (`'Set` \| `'Append` \| `'Remove` \| `'Merge`) |
| `value_expr` | `$inputs.new_name` | NCL expression evaluated in op context, supplying the new value |

## Today's runtime behaviour

Dispatching against a stock daemon returns:

```
HTTP/1.1 501 Not Implemented
{
  "error": "missing_executive_backend",
  "kind":  "NclTransform",
  "op_id": "rename_ontology_node",
  "hint":  "awaits ADR-030 trigger — expressive-power proof for >=3 real ops"
}
```

This is intentional per ADR-034 constraint
`non-rust-kinds-declarable-not-executable-without-flag`. The op is a
first-class catalog entry; cross-project consumers can read its
contract via ADR-028 content-addressed catalog ontologies.

## When the executive backend lands

The interpreter will:

1. Load `target` via `nickel export`.
2. Apply the `operation` at every match of `selector`, substituting
   `$inputs.*` with the actual op invocation inputs and computing
   `value_expr` in the op's context.
3. Re-canonicalise and write back.
4. Run the post-validators.
5. Sign the canonical state delta as the witness.

The host runtime synthesises the ondaod context for the
`evaluate_ondaod` pre-validator BEFORE invoking the transform — that is
the structural guarantee the ADR-034 Hard constraint
`non-rust-kinds-require-ondaod-pre` enforces at typecheck time.

## When NOT to use

- The op needs cryptographic operations (signing, hashing beyond
  blake3-canonical) → use Path A `'Rust`.
- The op spans multiple files or coordinates effects across non-NCL
  artifacts (oplog, blobs, registry mutations) → use Path A `'Rust`.
- The op needs control-flow (branches, loops, conditionals beyond a
  single JSONPath transform) → use Path A `'Rust`.

`'NclTransform` is for the trivial CRUD subset — set a name, append to
an array, remove an entry, merge a record. That subset is empirically
~80% of catalog ops once a substrate matures; the trigger is whether
real-world experience confirms that ratio.

## References

- [ADR-034 — Catalog extensibility beyond Rust](../../../.ontoref/adrs/adr-034-catalog-extensibility-beyond-rust.ncl)
- [ADR-030 mechanism #5 — InterpretedNclOps](../../../.ontoref/adrs/adr-030-catalog-discovery-cross-project.ncl)
- [`schema-future.ncl::NclTransformBody`](../schema-future.ncl)
