---
url: >-
  https://adk.nht.io/api/@nhtio/adk/batteries/orchestration/encoding/functions/planDigest.md
---

# Function: planDigest()

```ts
function planDigest(view: RawPlanView): string;
```

Defined in: [src/batteries/orchestration/encoding.ts:228](https://github.com/NHTIO/ADK/blob/v1.20260906.0/src/src/batteries/orchestration/encoding.ts#L228)

Compute the canonical, LOSSLESS digest of a `RawPlanView`.

## Parameters

| Parameter | Type                                                   | Description                            |
| --------- | ------------------------------------------------------ | -------------------------------------- |
| `view`    | [`RawPlanView`](../../types/interfaces/RawPlanView.md) | The folded plan content at a revision. |

## Returns

`string`

A hex sha256 digest over the canonical, lossless encoding of `view`.

## Remarks

Every approval binds to this digest, so it must be a faithful fingerprint of the plan content
the operator actually saw — never a lossy one that could authorise a plan they did not see.

The strategy: recursively sort PLAIN-OBJECT keys only (leaving every encoder-owned value —
`Date`, `RegExp`, `Map`, `Set`, typed arrays, `ArrayBuffer`, `DataView`, bigint, luxon values,
and `NodeRef`/`ParamRef` instances — untouched), then `sha256(encode(sortedSkeleton))`. The
encoder is the authority on how each value serialises, and it round-trips the reference classes
and the whole `EncodableValue` domain losslessly, so the digest is stable across key order while
remaining collision-free across semantically-different plans.

This is the second of the two digest strategies considered. The first — `canonicalStringify`
from `src/lib/utils/canonical_json.ts` — was rejected because it walks objects with
`Object.keys`, and `Date`, `RegExp`, `Map` and `Set` have no enumerable own keys, so it collapses
each to `{}`. That is proven to collide: `{pattern: /^inv-\d+$/i, when: <date A>, m: Map{k=>1}}`
and `{pattern: /^cust-\d+$/, when: <date B>, m: Map{z=>9}}` both canonicalise to
`{"m":{},"pattern":{},"when":{}}`. An approval bound to that digest would authorise a plan the
operator never saw. This implementation sorts only plain-object keys and never replaces the
encoder's representation of the values it owns.
