# Release 0.4.4 — Accept canonical JSON-escaped exact values

**Coordinated packages:** `ds4-context-core`, `ds4-context-reference-adapter`, and `ds4-context-engine` 0.4.4.
**Implementation commit:** `ad6e4c8`.

## Summary

Behavior patch. Compaction summary validation now accepts a backticked exact
value that occurs literally in the evidence in its canonical JSON-escaped
rendering, not only as written. The accepted rendering widens; the evidence does
not: canonical JSON escaping is injective, so a decoded value passes only when
its encoded text is literally present. The diagnostics probe budget rises from
4000 to 24000 evidence-source scans. The eight-bullet and 25% repair bounds, the
fail-closed fallback to Pi default compaction, the summarizer prompt, the SQLite
schema and every provider-facing default are unchanged.

## Changes

- `packages/core/src/compaction/summary-contract.ts`:
  - `unsupportedExactMatches` also accepts a span whose `jsonEscaped` rendering
    occurs literally in the segment source, the ordered child-summary content or
    the file-operation inventory. `jsonEscaped` is the transform the diagnostics
    classifier already used for `escaped-form-present`, so the accepted domain
    and the reported class agree.
  - `UNSUPPORTED_SPAN_PROBE_BUDGET` rises from 4000 to 24000 source scans.
- `tests/unit/summary-contract.test.ts`: acceptance for a decoded value whose
  escaped rendering is present; continued rejection when the escaped rendering
  is absent and for an escaped span whose raw form is present; the default budget
  is 24000 and an explicit 4000 budget still saturates without overspending.
- `tests/integration/compaction.test.ts`: a segment whose evidence carries
  literal JSON escapes and a summary that quotes the decoded value commits with
  `validationStatus: "valid"` instead of falling back.
- `docs/COMPACTION.md`: the summary contract and the diagnostics section.
- `docs/ADR/065-exact-value-escaped-equivalence.md` records the decision.

## Why

Production sessions failed closed on `unsupported-exact-value` /
`repair=too-many-bullets` with 30/20, 23/19, 19/15, 17/11 and 16/12 unsupported
spans and affected bullets. The report added in 0.4.2 and made interpretable in
0.4.3 attributed the last observed run: 11 of 16 spans were
`escaped-form-present`, no span was established as absent (`no-near-miss` was
zero), and the shape histogram (`quote` 11, `colon` 11, `json-punctuation` 9, no
`backslash`) showed decoded values rather than identifiers. The values were
present in the evidence; only the rendering differed. The remaining candidates
for the five unanalysed spans were model-dependent and unverifiable offline,
while escape equivalence is deterministic and testable: the new integration test
fails on 0.4.3 and passes on 0.4.4.

## Privacy and safety

- Acceptance still requires a literal occurrence in the evidence, and canonical
  JSON escaping is injective, so no invented value can pass; the validation path
  reads the same sanitized sources as before.
- Diagnostics stay class-only: the budget change alters how many lookups the
  classifier may spend, never what it emits. The probe runs only after a
  validation failure has already been decided.
- No provider call, network access or configuration change is involved in this
  release.

## Compatibility and persistence

- No migrations, no schema change (still 16), no new configuration key, and no
  change to any provider-facing default.
- The summarizer prompt is unchanged; only the accepted rendering widens.
- `escaped-form-present` stays in the report taxonomy but is no longer expected
  in reports, because validation accepts the same canonical rendering that the
  classifier probes.

## Measured scope and limitations

The effect on a real session is not verified by this release. If escape
equivalence was the binding cause, the next production compaction should not
produce `compaction.custom_fallback`; if one appears, its report now covers only
spans that are not canonical-escape-equivalent, with a budget large enough to
finish the near-miss analysis for a handful of candidates. The 25% removal bound
and the fail-closed fallback remain in force, so an unsupported set that exceeds
the repair bounds still falls back to Pi default compaction.

## Validation

On Node 26.5.1 the release passed `npm run check` (99 Vitest files, 632 tests,
TypeScript builds and root typecheck), deterministic `npm run quality:compare`
(candidate `0.9875` against baseline `0.808156`), `npm run schema:context-persistence`
(`passed: true`), and `npm run pack:check` in a clean consumer for all three
packages at 0.4.4 (247 core files, 7 reference-adapter files, 103 extension
files). No provider calls are involved in this release procedure.

## Publication and registry verification

Published manually in dependency order from `10f0e0c`: `ds4-context-core@0.4.4`,
then `ds4-context-reference-adapter@0.4.4`, then `ds4-context-engine@0.4.4`, all
with the default `latest` tag, after `npm run pack:check` on the same commit.

The first seven `npm run registry:check -- 0.4.4` attempts failed while the
published metadata was still propagating; the eighth, some minutes later,
reported "Verified all DS4 registry packages at exact version 0.4.4". For all
three packages `npm view <package> dist-tags.latest` resolves to 0.4.4.

Annotated tag `v0.4.4` and the GitHub Release were created from `10f0e0c`. No
provider calls are involved in this release procedure; the classifier runs only
after a validation failure has already been decided, and no session data,
credentials, or provider payloads were read or written while preparing it.
