About NAC3

Spec version: 2.2 stable (+ v2.3 interop preview).

NAC3 = Native Agent Contract.

A small, public spec that lets web UIs be driven by AI agents, voice runners, and accessibility tools the way they're driven by humans today: by clicking, typing, and reading -- but with names that machines can resolve, events that machines can wait on, and a provenance trail that distinguishes a real user from a synthetic caller.

NAC3 sits next to ARIA, not on top of it. Where ARIA standardised the accessibility tree so screen readers and switch devices could operate the same UI a sighted user sees, NAC3 standardises the agent tree so a voice command, an LLM intermediary, or an RPA bot can do the same thing without per-app glue code.

What you write

A handful of HTML attributes (data-nac-id, data-nac-role, data-nac-action, data-nac-plugin) plus an optional JS manifest that names the things on the page and the verbs they accept. The runtime resolves names to elements and dispatches to them.

What you get

caller -- a voice runner, a Playwright spec, an LLM intermediary, a keyboard macro, an accessibility tool.

(nac:action:succeeded, nac:tab:activated, nac:field:changed, ...) so the caller knows when each step finished.

contract -- so a UI redesign does not break automation.

tells a downstream system whether a click came from a real user or from another agent.

What NAC3 is not

whatever. NAC3 is a thin contract layered on top of whatever you already render.

to NAC.click('deals.save') is your problem (or your vendor's); see guides/LLM_WIRING.md for a reference.

NAC3 adds a parallel layer; many adopters end up with both role="button" and data-nac-role="action" on the same element.

Status

HMAC + isTrusted, i18n strict mode, validator. Production reference is example.php.

become NAC-driven via ~80 lines of setup). Reference: example-v20-full.php.

matrix, matrix-singletree subkinds; dt_add_row, dt_edit_cell, aggregates, transactional commit). Reference: example-v21-data-table.php.

validator (manifest_role_unknown, tab_id_manifest_role_drift, manifest_dom_role_mismatch). New NAC.bindAction(el, handler, ctx) helper bakes the nac:action:succeeded contract into the runtime. New flag NAC.STRICT_VALIDATION toggles findings between warning-only (default in 2.2) and throwing (default in 2.3). This is what npm install @nac3/runtime ships today. See docs/NAC_V22_ROADMAP.md for the full changelog.

true. NAC.bindTab(el, handler, ctx) companion for tab widgets. Optional opt-in: streaming chat dispatch.

Where to start

intermediary.

Governance

NAC3 is currently stewarded by Yujin. The spec is Apache 2.0; the reference runtime is MIT. Yujin commits to moving NAC3 to a neutral foundation (W3C community group, Linux Foundation, or equivalent industry body) if and when adoption justifies neutral governance. Until then, spec changes follow the RFC process in CONTRIBUTING.md with a public comment period of at least 14 days for any change to the public API or wire format.

The Apache 2.0 + MIT licensing guarantees that the spec and runtime survive any change in Yujin's corporate status. Adopters can fork either, run either, and ship either, today and after Yujin no longer exists.

Authorship

NAC3 is authored and maintained by Yujin (rpaforce.com). Apache-2.0. Contributions welcome -- see CONTRIBUTING.md.