# Changelog

## [1.4.0] - 2026-06-13

- Add `LocationSpoofDetector` (antispoofing): a kinematic-plausibility gate that
  detects GNSS/GPS spoofing and teleport attacks against a frame's pose claim —
  impossible implied velocity, impossible acceleration, the stationary-then-jump
  GNSS pull-off signature, and pose-timestamp regression. Standalone and
  non-breaking; exported from `gridstamp/antispoofing`. Configurable thresholds
  (`maxSpeedMps`, `maxAccelMps2`, `staticJumpMeters`, `staticSpeedMps`). Frames
  with no pose pass through unchanged. 9 new tests. This is a kinematic gate, not
  a signal-level receiver check — pair with hardware-attested capture for a full
  proof-of-presence story.

## [1.3.1] - 2026-06-10

Stable release of the 1.3.1-beta.1 content, promoted to `latest` the same day
(beta soak was green; the only test failures are the long-documented
pre-existing stress-suite issues, identical in 1.3.0).

## [1.3.1-beta.1] - 2026-06-10

Published to npm under the `beta` dist-tag.

- Fix concurrent MCP HTTP sessions (`64e4f26`).
- Resolve Dependabot audit findings; vitest at 4.1.8 (patched line).
- Test status at publish: 318/320 passing. The 2 failures are the documented
  pre-existing stress-suite issues (ProofChain chain-validation bug tracked in
  the security backlog + Windows/Node heap-growth flakiness) — see the
  1.3.0-beta.1 known-issues notes below; no regressions from this release.

## [1.3.0-beta.1] - 2026-04-23

### IETF COSE Merkle Tree Proofs terminology + RFC 9052 envelope

- **`draft-ietf-cose-merkle-tree-proofs-18` terminology aliases** on the
  Remote ID Merkle layer (`src/remoteid/merkle-cose.ts`). Every
  `InclusionProof` now exposes IETF-aligned fields alongside the legacy
  ones: `leaf_index` (was `index`), `tree_size` (was `leafCount`),
  `audit_path` (was `siblings`), `root_hash` (was `root`). The legacy
  names are unchanged and continue to be populated on the same object,
  so no existing caller breaks. New `TreeHead` type captures the IETF
  `{ tree_size, root_hash, timestamp }` summary. `COSE_MerkleInclusionProof`
  is exported as a type alias for `InclusionProof` for spec-literal
  readability. `SpatialProof` (image-similarity, not a Merkle tree) is
  intentionally left alone — forcing IETF tree terminology there would
  hurt clarity.
- **RFC 9052 COSE_Sign1 envelope helper** (`wrapInCOSESign1`,
  `verifyCOSESign1`, `encodeCoseMerklePayload`, `buildSig_structure`,
  `buildTreeHead`). Takes a `TreeHead` + `InclusionProof` and produces a
  canonical CBOR 4-tuple `[protected, unprotected, payload, signature]`
  signed with the same Ed25519 keypair that signs the underlying Remote
  ID logs. Protected header declares `alg = -8` (EdDSA, RFC 9053 §2.2).
  The existing per-log signing path is unchanged — COSE_Sign1 is
  additive, for regulator-facing receipts.
- **MCP `proof_chain` / `verify_proof_chain` tool descriptions** now
  use IETF language ("inclusion proof", "tree head", "leaf hash",
  "audit path", "root hash"). Tool names and input schemas are
  unchanged. The other 10 MCP tools are not modified in this release.
- **Dependency**: adds `cbor-x` (no transitive deps) for COSE_Sign1
  CBOR encoding per RFC 9052.
- **Tests**: `tests/remoteid/ietf-alias.test.ts` verifies legacy +
  IETF fields are byte-equal on every proof, and that
  `COSE_MerkleInclusionProof` is structurally identical to
  `InclusionProof`. `tests/remoteid/cose-sign1.test.ts` verifies the
  envelope is valid CBOR, decodes to the expected 4-element array,
  declares `alg: -8`, and round-trips signature verification with
  tamper rejection.

### Known issues (inherited)

- `tests/stress/stress-200k.test.ts` chain-validation failure on the
  50,000-sequential-spatial-proofs test carries over from v1.2.0. This
  is a pre-existing `ProofChain` validation bug tracked in the security
  backlog, out of scope for this release.
- 200K heap-growth stress test Windows + Node 22 flakiness from v1.1.2
  is still present; see that release's notes.

## 1.1.2 — Internal hardening

- `ProofChain` now validates-on-load. Constructing a chain from persisted proofs walks every link (hash continuity, temporal ordering, robotId consistency) and throws if any check fails. A `{ skipValidate: true }` option is exposed on the constructor for test fixtures that build deliberately-invalid chains to exercise `verify()`; the standalone `verifyProofChain()` helper uses it to preserve its documented "return a verification result" contract for broken inputs.
- RRT* pathfinding now draws random samples from `node:crypto.randomBytes` instead of `Math.random()`. Pathfinding output feeds `ProofChain` as evidence in proof-of-presence; predictable samples would let an adversary precompute a trajectory that the chain then blesses.
- Splat serialization used by the Merkle integrity layer pins its JSON key order explicitly. Previously the tree was byte-stable by accident (object-literal key insertion order); now the key list is declared in the `JSON.stringify` replacer so refactors can't silently break hash continuity. `shCoeffs` order is preserved verbatim — it is part of the spec.
- MCP telemetry wrapper is wired up. Per-tool latency + outcome now POST to `/portal/log-usage` with a 2s `AbortSignal` so a portal outage can't block tool responses. The dead `wrappedHandleTool` function has been removed.

### Known issues

- The 200K "full security guarantees" heap-growth stress test (`tests/stress/stress-200k.test.ts`) is flaky on Windows + Node 22; observed growth 4.5x–5.5x vs a 4.0x threshold. Heap leak is separately covered by a tighter controlled test in the same file that still passes. Threshold re-tune tracked separately.
