Vivarium.Changeset
0.6.0
dotnet add package Vivarium.Changeset --version 0.6.0
NuGet\Install-Package Vivarium.Changeset -Version 0.6.0
<PackageReference Include="Vivarium.Changeset" Version="0.6.0" />
<PackageVersion Include="Vivarium.Changeset" Version="0.6.0" />
<PackageReference Include="Vivarium.Changeset" />
paket add Vivarium.Changeset --version 0.6.0
#r "nuget: Vivarium.Changeset, 0.6.0"
#:package Vivarium.Changeset@0.6.0
#addin nuget:?package=Vivarium.Changeset&version=0.6.0
#tool nuget:?package=Vivarium.Changeset&version=0.6.0
Vivarium.Changeset — .NET reference SDK
Construct, canonicalize, fingerprint, and validate Vivarium Changeset documents. Contains no apply logic — appliers (e.g. vivarium-stage) are consumers of this format, not part of this SDK.
No runtime dependencies beyond the BCL. Targets .NET 10. Same surface as the
TypeScript reference SDK; fingerprints are byte-identical
across the two (proven by the shared conformance fixtures, including the
interop-jcs-edges vector).
Usage
using System.Text.Json.Nodes;
using Vivarium.Changeset;
// the artifact's current source, and the source the agent proposes
var currentSource = "export function LoanScreen() { /* current */ }";
var nextSource = "export function LoanScreen() { /* renders dueDate */ }";
var doc = new ChangesetBuilder(
intent: "Add a due-date to the loan screen",
producedBy: "my-agent",
createdAt: DateTimeOffset.UtcNow.ToString("o")) // caller supplies the clock
.AddSchemaOp((JsonObject)JsonNode.Parse("""
{ "op": "field.add", "entity": "loan",
"field": { "name": "dueDate", "type": "date" },
"explanation": "Stores the loan's due date" }
""")!)
.AddUiPatch(
artifactId: "screen-loans",
baseContent: currentSource, // null for creation
newContent: nextSource, // review diff + base fingerprint are derived, never hand-written
explanation: "Renders the due-date field")
.Finalize(); // validates, stamps fingerprint — or throws with structured errors
Verifying on the consuming side. Unlike Finalize, these APIs report — they do not
throw; a conforming applier checks the results and refuses on failure (spec §7):
var result = ChangesetValidator.Validate(doc); // spec §8 layer 1 — structure, vocabulary, diff consistency
if (!result.Valid)
throw new InvalidOperationException($"refusing changeset: {string.Join(", ", result.Errors.Select(e => e.Path))}");
if (!ChangesetFingerprint.Verify(doc)) // spec §6 — content-addressed integrity
throw new InvalidOperationException("refusing changeset: fingerprint mismatch");
Recording a review. The approval record's fingerprint is taken from the document, never
passed in, so it names exactly what was reviewed; a document that was never finalized, or
changed after it was, is refused. The caller supplies the clock, as for createdAt:
var approved = ChangesetApproval.Add(
doc,
approvedBy: "reviewer@example.com", // opaque to the SDK
approvedAt: DateTimeOffset.UtcNow.ToString("o"), // RFC 3339 date-time (spec §7)
comment: "Checked the due-date rendering"); // optional
// approved["approvals"][0]["fingerprint"] equals doc["fingerprint"] — approvals sit outside the hash
Which approvals an applier trusts, and where records are kept, are the applier's decision (spec §7) — this only builds a record the gate can check.
verified-diff@0 UI patches (spec 0.2)
Surgical edits ride as a strict-dialect unified diff instead of a full artifact
re-emission. ChangesetValidator.Validate covers the document-only layer; before
applying, an applier MUST run the base-supplied layer (spec §8 layer 2):
using System.Text.Json.Nodes;
using Vivarium.Changeset;
var baseContent = "const title = \"Loans\";\n";
var nextContent = "const title = \"Active loans\";\n";
var patch = new JsonObject
{
["profile"] = "verified-diff@0",
["artifactId"] = "screen-loans",
["baseFingerprint"] = ChangesetFingerprint.OfArtifact(baseContent),
["diff"] = VerifiedDiff.Create(baseContent, nextContent), // deterministic, fail-closed dialect (spec §5.2.2)
["newFingerprint"] = ChangesetFingerprint.OfArtifact(nextContent),
["explanation"] = "Rename the title only",
};
var verdict = VerifiedDiff.VerifyAgainstBase(patch, baseContent); // ① base fingerprint ② apply + result fingerprint
if (!verdict.Ok)
throw new InvalidOperationException("refusing patch: " + verdict.Errors[0].Message);
_ = verdict.NewContent; // exactly what the reviewer's diff described
Surface
| Type | Members |
|---|---|
JsonCanonicalizer |
Canonicalize, CanonicalBytes — RFC 8785 (JCS) |
ChangesetFingerprint |
Of, Stamp, Verify, OfArtifact, Prefix |
UnifiedDiff |
Create, Apply, ReverseApply |
VerifiedDiff |
Create, Apply, ParseStrict, VerifyAgainstBase — spec §5.2.2 dialect |
ChangesetValidator |
Validate, SupportedSpecVersions, BaseStateKinds |
ChangesetBuilder |
AddSchemaOp, AddUiPatch, AddVerifiedDiffPatch, AddDataPatch, ToDraft, Finalize |
ChangesetApproval |
Add — spec §7 |
Conformance
dotnet test runs the unit suite plus the shared spec/fixtures/
corpus — the same vectors the TypeScript SDK runs. The fixtures are generated by the
TypeScript reference implementation; this SDK reproduces them exactly.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Vivarium.Changeset:
| Package | Downloads |
|---|---|
|
Vivarium.Stage
Changeset lifecycle core: the branch → simulate → apply → rollback state machine, fingerprint gate with drift refusal, append-only release ledger, and the backend adapter boundary with an executable conformance suite. Hosting-neutral library. |
GitHub repositories
This package is not used by any popular GitHub repositories.