# nsx.lock

The resolution lock. Records, per board, the exact commit and content hash of every module an nsx sync would materialize. NSX writes it; you do not edit it by hand.

## Fields

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| schema_version | int (4) | 4 | Lock schema version. NSX writes it on every lock; a lock that declares an older one is regenerated, and a lock missing it is read as the current version. |
| targets | map of board to lock section, required |  | One resolution per board, so an app can be locked for several boards at once. |
| targets.<board>.generated_at | string (ISO 8601), required |  | When this section was resolved. |
| targets.<board>.nsx_tool.version | string |  | neuralspotx version that produced the section. |
| targets.<board>.manifest.path | string, required | nsx.yml | Manifest the section was resolved from. |
| targets.<board>.manifest.hash | string, required |  | Content hash of that manifest. A mismatch is the drift --frozen rejects. |
| targets.<board>.target.board | string, required |  | Board this section resolves. |
| targets.<board>.target.soc | string, required |  | SoC of that board. |
| targets.<board>.target.toolchain | string, required |  | Toolchain the section was resolved for. |
| targets.<board>.modules | map of module name to entry, required |  | The full resolved closure, not just the direct dependencies. |
| modules.<name>.project | string, required |  | Registry project that provides the module. |
| modules.<name>.kind | string (git, packaged, local, vendored, unresolved), required | git | How the module was resolved, which decides what the resolved block carries. |
| modules.<name>.constraint | string, required |  | Constraint the resolution satisfied. |
| modules.<name>.resolved.url | string |  | Upstream repository. Present for git and unresolved kinds. |
| modules.<name>.resolved.tag | string |  | Tag the commit carries, when the constraint matched one. |
| modules.<name>.resolved.commit | string |  | Exact commit vendored. Present for git and unresolved kinds. |
| modules.<name>.resolved.tool_version | string |  | neuralspotx version that supplied a packaged module. |
| modules.<name>.resolved.vendored_at | string, required |  | Path under the app where the module is materialized. |
| modules.<name>.resolved.content_hash | string, required |  | SHA-256 of the vendored tree. The SBOM reports this and sync verifies it. |
| modules.<name>.resolved.acquired_at | string (ISO 8601), required |  | When the module was fetched. |

## Example

```yaml
schema_version: 4
targets:
  apollo510_evb:
    generated_at: '2026-09-03T23:02:17+00:00'
    nsx_tool:
      version: 0.7.17
    manifest:
      path: nsx.yml
      hash: sha256:1c975664f58e7a6ee643a0bc37c90d8535543812703c6d3502595cc5f9992cef
    target:
      board: apollo510_evb
      soc: apollo510
      toolchain: arm-none-eabi-gcc
    modules:
      nsx-ambiqsuite:
        project: nsx-ambiq-sdk
        kind: git
        constraint: v5.2.26
        resolved:
          url: https://github.com/AmbiqAI/nsx-ambiq-sdk.git
          tag: v5.2.26
          commit: ba0621638d57b71a7b0d4f76ddccf0706745ad77
          vendored_at: modules/nsx-ambiq-sdk
          content_hash: sha256:da17c45a3cf02797d1703f3c55beea770078cb2cb8829c7211413877089a559e
          acquired_at: '2026-08-04T04:01:24+00:00'
```

## How it is read

NSX reads `nsx.lock` through `neuralspotx.nsx_lock.read_lock_file`, which raises `NSXLockError` when the document is invalid. The supported `schema_version` is `4`.

**Unknown keys:** Rejected in effect. The lock is read into frozen dataclasses, so only the keys below survive a round trip.
