# Changelog

## 0.2.4

- Republish the 0.2.3 contents without personal contact details in the packaged docs. No code changes.

## 0.2.3 (unreleased)

- Add CEL bytes literals, escapes, UTF-8 conversion, concatenation, ordering, size and collection values; support raw/triple literals.
- Check signed/unsigned arithmetic overflow and conversion boundaries; absorb deciding list quantifier values across errors; add has on map fields, dyn and basic scalar conversion overloads.
- Add a seeded expression corpus and explicit upstream surface-gap probes; retain generated API changes. Fix oracle toolchain selection and avoid truncating an executable used by concurrent oracle runs.
- Define the pinned condition environment and function-level comparison. Full CEL compatibility remains unfinished; this revision is not release-ready against that endpoint.


### Rework 1

- Add model-time CEL type/overload validation, Boolean output checks and model rejection comparison. Preserve pinned OpenFGA missing-declared-parameter errors after lazy binding.
- Add typed heterogeneous map keys, map/list macros including three-argument map, type constants/reflection, recursive generic context types and strict scalar/temporal conversions. Reproduce pinned mixed-double rounding using integer-domain rounding; add big.Float-style numeric context narrowing.
- Add all timestamp/duration getters, packed IANA 2026f data and Unicode 17.0.0 tables without runtime OS/Go dependencies. Replace backtracking regex with a code-point Thompson NFA, including groups, counts, flags, boundaries, Unicode/POSIX classes and rejection checks.
- Add default CEL well-known protobuf constructors, scalar/JSON adaptation and independent Any wire decoding. Preserve full int64 timestamp seconds and pinned Go calendar behavior at extreme values. Distinguish Unicode string escapes from byte escapes, preserve BOM, and resolve root-qualified names.
- Add default condition cost 100, configurable engine budget and cooperative host cancellation. Match constant container/conversion optimization and constant primitive membership, including asymmetric mixed-numeric membership behavior. Split and defer generated data initialization for wasm limits and query performance.
- Expand two-seed model/query differential coverage and embed official outcomes on every backend. Keep Local, regex compilation bounds and host deadlines explicit; do not claim full compatibility.

### Rework 2

- Fold repeated identical unary prefixes by parity, retain single-operation costs, and regress default-budget false rejections plus operator/conversion/macro thresholds.
- Align RE2 leading-zero count literals, shorthand-class dash handling and malformed/count-boundary grammar. Reject uppercase 0X literals, trailing-dot numeric tokens and signed NaN conversions; accept valid hexadecimal float separators.
- Accept hashable scalar map keys including double and IPAddress, preserving the pinned constructor/indexing error distinctions and directional numeric lookup. Align null arithmetic model-vs-runtime errors.
- Enforce a controlled 250-expression parser recursion limit on every backend, including direct compile of 10000 nested delimiters. Reject unparenthesized ternaries in true arms.
- Preserve all 25 independent review cases and add systematic families to both seeded oracle runs and offline backend regressions. Default-budget equivalence remains bounded by explicit evidence, not a universal claim.

## 0.2.2

- Add offline fixed-seed release benchmarks for Check, ListObjects and ListUsers across tuple scales, relation shapes and native/JS/wasm-gc backends, with raw samples, latency quantiles, throughput, memory and reverse-graph attribution.
- Document measured query limits and the contract required before adding cross-request caching; no cache or query optimization added.

## 0.2.1

- Add `modules_with_diagnostics` and `collect_module_diagnostics` to collect parse, composition and semantic errors; retain the fail-first `modules_to_model` API. CLI module validation prints every diagnostic (also with `--json`).
- Match all 24 official diagnostics in module fixtures 01/03/04/05, including messages, zero-based source ranges, files and error types; expose module names separately. Compare complete diagnostic multisets without filtering error types.
- Retain Check 516/516, ListObjects 354/354, ListUsers 393/394 (one upstream skip), single-file DSL 29/29, module JSON 2/2, module diagnostics 4/4 and fga.mod 9/9. Fixture 06 remains JSON-only because upstream supplies no module source files.

## 0.2.0

- Reject repeated extensions of the same type within a file and cyclic YAML aliases; bound fga.mod YAML depth and alias expansion.
- Add schema 1.2 module composition, forward type extensions, fga.mod YAML parsing and host-supplied module contents APIs.
- Preserve module/source_info metadata across JSON imports and exports; reject conflicting definitions and validate cross-file references and cycles.
- Add native POSIX / JS fga.mod CLI loading, canonical path containment and model_file support in store tests. Wasm callers supply contents; wasm CLI refuses modular file loading.
- Add two official full-JSON module transformations, four invalid-module rejection checks and nine fga.mod acceptance/rejection checks; retain 29 single-file fixtures. The complex upstream fixture lacks module inputs; only its JSON metadata roundtrip is checked. Complete official diagnostic arrays and YAML intermediate locations remain unsupported.
- Expected generated interfaces: fga AuthModel.metadata; dsl ModuleFile/merge_modules; model parse_mod/modules_to_model; storetest optional check_module_path; language module fixture entrypoints; new host path-containment package.


All notable changes to MoonFGA are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.1.1] - 2026-11-01

- Build ListObjects reverse proofs only for transitive query dependencies; retain fresh reads for writes, deletes and contextual tuples without a shared cache.
- Add reproducible native/JS scale experiments (10k/100k/1m tuples, three fanouts, 20 group levels), latency distributions, process peak RSS and graph-build attribution.
- Add an independent TupleReader snapshot host and executable contracts for exact reads, empty results and host failures; keep the engine API unchanged.


- Fix Check depth accounting: cap full dispatches at 25 while retaining computed aliases and terminal userset/TTU joins; add 29 boundary and mixed-chain regressions.

- Fix CEL logical error absorption, Unicode code point size, and RFC3339 timestamp strings with nanoseconds and numeric offsets.
- Replace per-candidate List evaluation with reverse object proofs and user-set expansion; preserve List condition errors and API-specific depth semantics.
- Record Explain witnesses on the actual successful Check path; share the non-fatal explanation status model between CLI and JS.
- Expand the oracle to five scenario families and 64 frozen upstream regression fixtures; reject failed model/write setup.

- Add a browser playground (`playground/` JS exports, static page in `web/`, GitHub Pages workflow) with a Node smoke test.
- Playground passes the engine's explain result through unchanged and marks an incomplete explanation; `filters` and `tuples` reject malformed values.
- Move `model_file` reading out of `storetest` (`load_store_test` takes an optional reader), so the playground bundle imports no Node modules.
- Fix resolver path cleanup on condition errors, contextual triple shadowing and identifier bounds.
- Add depth/cycle, wildcard exclusion, condition and input regression tests (177 tests per backend).
- Reuse parsed users and index object types; measured native queries improve about 38% on the documented workload.
- Hide engine/store internals and validation helpers before the first published API.
- Add a pinned OpenFGA v1.22.1 differential oracle matching the matrix commit: two seeds, 6570 comparisons, zero differences.
- Fix wildcard intersection witnesses and subtraction in ListUsers; freeze nine counterexamples as regression tests.
- Match OpenFGA contextual condition semantics: Check shadows triples; List APIs combine both streams.
- Align CI installers with official documentation; initialize Windows MSVC and pin Node 22.

## [0.1.0] - 2026-10-31

First public release, published to Mooncakes as
`sundaysebasidian-byte/moonfga@0.1.0`. Requires MoonBit toolchain 0.1.20261028 or newer.

### Added

- OpenFGA schema 1.1 DSL: `model`, `schema 1.1`, `type`, `relations`, `define`,
  direct restrictions (`[user, group#member, user:*, user with cond]`),
  `or` / `and` / `but not`, computed usersets, tuple-to-userset (`X from Y`),
  parentheses, `condition` declarations, and comments.
- AuthorizationModel JSON import/export and a DSL ↔ JSON transformer. Export
  follows `openfga/language`: empty `type_definitions` are omitted and every
  relation receives a `metadata.relations` entry.
- Semantic model validation with line and column positions: unknown types and
  relations, invalid tuple restrictions, forbidden cycles, duplicate
  definitions, and condition parameter checks. Error codes mirror OpenFGA
  (`E2000`, `E2001`, `E2002`, `E2003`, `E2021`, `E2022`, `E2027`).
- Indexed in-memory tuple store (`object#relation`, user indexes), contextual
  tuple overlays, and a `TupleReader` trait for embedding.
- `Check` with depth limit 25, cycle detection, wildcard users, union /
  intersection / difference short-circuiting, tuple-to-userset traversal, and
  conditional relationships.
- `BatchCheck`, `ListObjects`, `ListUsers` (including userset filters),
  `Expand`, and explainable checks that return resolution paths.
- Initial standalone CEL evaluator covering `int`, `uint`, `double`, `bool`, `string`,
  `duration`, `timestamp`, `list`, `map`, and `ipaddress`, with operators,
  ternaries, `exists` / `exists_one` / `all` / `map` / `filter`, and common
  string, time, and network helpers.
- CLI with `validate`, `transform`, `check`, `list-objects`, `list-users`,
  `expand`, and `test` commands. Tuple input accepts JSON, YAML, and
  `object#relation@user` text.
- `.fga.yaml` store test runner supporting `model` / `model_file`, suite and
  per-test tuples, Check / ListObjects / ListUsers assertions, `context`,
  `contextualTuples`, userset filters, and `errorCode`.
- Conformance harness that replays the pinned OpenFGA matrix and the
  `openfga/language` DSL ↔ JSON fixtures, with per-assertion JSON reports and
  configurable pass thresholds (`scripts/conformance.sh`).
- Runnable examples for basic ReBAC, ABAC conditions, and library embedding.

### Conformance

Pinned upstream revisions:

- `openfga/openfga` `44054f542f64e9b9589dd26a595081b3d2cfd942` (v1.22.1)
- `openfga/language` `ed62a11e759a0faa1354404ead761f956469e149`

| API | Passed | Total | Failed | Skipped |
| --- | ---: | ---: | ---: | ---: |
| Check | 516 | 516 | 0 | 0 |
| ListObjects | 354 | 354 | 0 | 0 |
| ListUsers | 393 | 394 | 0 | 1 |
| DSL ↔ JSON fixtures | 29 | 29 | 0 | 0 |

The single skipped ListUsers assertion (`simple_computeduserset_indirect_ref`)
has no top-level expectation or `errorCode` in the upstream file and is
reported as `skip/no_expectation` rather than counted as a pass.

### Known limitations

- No FGA modules (`module` / `extends`); single-file models are fully
  supported.
- No `ReadChanges`; the in-memory store has no change log.
- No persistent or distributed storage, HTTP/gRPC server, pagination, or
  consistency preferences.
- The CEL implementation is an OpenFGA-oriented subset, not the complete CEL
  standard library (for example, `bytes` and regex capture groups are absent).
