Skip to content

STJ.Observer 2.0 on Observer.Core - #10

Merged
vfofanov merged 10 commits into
mainfrom
feat/r1-on-core
Oct 5, 2026
Merged

vfofanov merged 10 commits into
mainfrom
feat/r1-on-core

Conversation

@vfofanov

@vfofanov vfofanov commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

DragoAnt.System.Text.Json.Observer 2.0, rebuilt on DragoAnt.Observer.Core 1.0 (DragoAnt/Observer#2). Migration: docs/migrating-to-2.0.md.

What CI uses: the inline job checks out DragoAnt/Observer at the Observer-Ref: line below (else the same branch name, else main) and builds with -p:DragoAntObserverLocal=true. Once Core 1.0.0 is on nuget.org, switch back to the shared caller.

Breaking changes

  • The format-neutral types moved to DragoAnt.Observer. The package adds an implicit using; turn it off with DragoAntObserverImplicitUsing=false.
  • Renames (Q46): JsonValuePolicyBuilder → JsonAnyDepthBuilder, Match(a, b) → Path(a, b), ObserveResult → MaskResult.
  • Options are init-only; JsonObserverOptions is a record derived from ObserverOptions.
  • Comments (K20) are allow-listed by default; the HTTP handler drops them.

Added

  • MaskFlags (K9).
  • Mask(MaskTag) with the HMAC hash.
  • Span<char> overloads.
  • Explain.
  • JsonValueRule<TContext>.
Deviations from plan 01
  • release.yml cannot pass until Core is published.
  • Plan 02 items are not done here: the README rewrite, the trailing-output doc, the Span<char> allocation budget, and the Http re-audit.
  • The Depth flag is set at MaxDepth - 1.
  • A line comment at EOF with no newline is not read.

Tests: 1228 (net8 + net10). Allocation gate: 0 B, including the tag and hash rules.

Observer-Ref: feat/r1-core

- DragoAntObserverLocal=true swaps the DragoAnt.Observer.Core package for

  a ProjectReference into ../Observer (DragoAntObserverRoot)

- CI checks out DragoAnt/Observer (same branch, else main) and builds with

  the switch on until Core 1.0.0 is published
- moved types come from Core under their final names: MaskTag, MaskKind
  (Omit is Null), MaskResult, MaskStatus (NotJson is Unrecognized),
  PathExplanation, PathOutcome, UnknownMemberPolicy, NoContext,
  DataPath, NameMatch and Names
- JsonObserverOptions derives from ObserverOptions; JsonShapeOptions and
  JsonBodyLoggingContext have init properties; JsonShapeOptions.UnknownTag
- strategies are ValueMaskStrategy writing to a MaskValueWriter
- one custom rule delegate, JsonValueRule<TContext>, and JsonValuePolicy
  accepting ValuePolicy for any context; LegacyAllowList removed
- one masking verb Mask(tag | replacement | strategy) with MaskNulls;
  Relative is AnyDepth, multi-name Match is Path
- Explain takes a ValueKind; FindMember and the case flag are internal
- the package imports DragoAnt.Observer (DragoAntObserverImplicitUsing)
- net8.0 and net10.0 only
- InputTruncated, OutputCapped, ValueCut, TrailingData (data after the
  root, which used to read as Masked), InvalidUtf8Replaced, Depth
- Masked now means no flag: trailing data and replaced UTF-8 report
  Truncated with the whole document written
- the reader allows comments when the policy or a rule may keep one,
  and skips them otherwise at no cost
- Before / Inline / After ownership by line, rules via .Comment(kinds,
  rule) after any path rule, masked owners write kept comments masked
- kept comments are written as block comments and count toward
  MaxOutputBytes; shape observers follow the policy
- the HTTP body logger drops every comment (CommentPolicy.DropAll)
- Mask(ReadOnlySpan<char>, IBufferWriter<byte> | IBufferWriter<char>)
  and Read(ReadOnlySpan<char>) for both observer types
- JsonObserver.Read(...) reports status and flags without a context
- Explain rejects wildcards and tags, and declares the
  DragoAnt.ObserverPath string syntax
- tests pin that existing Mask(null) / Mask("...") calls stay unambiguous
- package validation baseline 1.0.2 (the unlisted 9.0.0 / 9999.0.0 are
  stray uploads, not baselines)
- CompatibilitySuppressions.xml lists every intended 1.0.2 -> 2.0
  break, so any other break fails the pack
- the buildTransitive props are packed by MSBuildKit
- CHANGELOG: changed-breaking items 13-27 for the Core move, the hash,
  flags, renames and TFMs, plus the missing IgnoreNullsJsonTokenType line
- docs/migrating-to-2.0.md: rename table, hash and comment changes,
  the .NET 10 SDK requirement coming with Observer 1.1 / 1.2; doc-tested
- AllocationTests add a Last4 + keyed Hash observer to the 0 B budgets
- CI packs the solution, which runs package validation against 1.0.2
The picker looked only for an Observer branch named like this one, so a PR whose
Observer branch has a different name built against main. An 'Observer-Ref:'
line in the PR body now wins, then the same branch name, then main.
A forced 0.0.0-ci version made the assembly 0.0.0.0, so package validation
rejected it against the 1.0.2 baseline. The kit derives the CI version from
VersionPrefix, as the shared workflow does.
@vfofanov
vfofanov marked this pull request as ready for review October 5, 2026 09:25
@vfofanov
vfofanov merged commit 1294fe7 into main Oct 5, 2026
1 check passed
@vfofanov
vfofanov deleted the feat/r1-on-core branch October 5, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant